package org.eclipse.swt.tests.junit;

/*
 * (c) Copyright IBM Corp. 2000, 2002. All rights reserved.
 * This file is made available under the terms of the Common Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-v10.html
 */

import org.eclipse.swt.*;
import org.eclipse.swt.graphics.*;
import junit.framework.*;
import junit.textui.*;

/**
 * Automated Test Suite for class org.eclipse.swt.graphics.Rectangle
 *
 * @see org.eclipse.swt.graphics.Rectangle
 */
public class Test_org_eclipse_swt_graphics_Rectangle extends SwtTestCase {

public Test_org_eclipse_swt_graphics_Rectangle(String name) {
	super(name);
}

public static void main(String[] args) {
	TestRunner.run(suite());
}

protected void setUp() {
}

protected void tearDown() {
}

public void test_ConstructorIIII(){
	// Test new Rectangle (int x, int y, int width, int height)
	Rectangle r = new Rectangle(3, 4, 5, 6);
	assertEquals(3, r.x);
	assertEquals(4, r.y);
	assertEquals(5, r.width);
	assertEquals(6, r.height);

	r = new Rectangle(-4, -3, -2, -1);
	assertEquals(-4, r.x);
	assertEquals(-3, r.y);
	assertEquals(-2, r.width);
	assertEquals(-1, r.height);

	r = new Rectangle(500000, 700000, 200000, 100000);
	assertEquals(500000, r.x);
	assertEquals(700000, r.y);
	assertEquals(200000, r.width);
	assertEquals(100000, r.height);
}

/**
 * Destructively replaces the x, y, width and height values
 * in the receiver with ones which represent the union of the
 * rectangles specified by the receiver and the given rectangle.
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the argument is null</li>
 * </ul>
 */
public void test_addLorg_eclipse_swt_graphics_Rectangle(){
	Rectangle r1 = new Rectangle(1, 2, 3, 4);
	Rectangle r2 = new Rectangle(3, 3, 2, 2);
	r1.add(r2);
	assertEquals("Rectangle add incorrect", new Rectangle(1, 2, 4, 4), r1);

	r1.add(r2);
	assertEquals("Rectangle add incorrect", new Rectangle(1, 2, 4, 4), r1);
	
	r1 = new Rectangle(1, 2, 3, 4);
	r2 = new Rectangle(3, 3, 0, 0);
	r1.add(r2);
	assertEquals("Rectangle add incorrect", new Rectangle(1, 2, 3, 4), r1);

	r1 = new Rectangle(1, 2, 3, 4);
	r2 = new Rectangle(6, 6, 0, 0);
	r1.add(r2);
	assertEquals("Rectangle add incorrect", new Rectangle(1, 2, 5, 4), r1);

	try {
		r1.add(null);
		fail("No exception thrown for rectangle == null");
	} catch (IllegalArgumentException e) {
	}
}

/**
 * Returns <code>true</code> if the point specified by the
 * arguments is inside the area specified by the receiver.
 */
public void test_containsII(){
	Rectangle r = new Rectangle(1, 2, 3, 4);
	assertTrue("Rectangle should contain point (1, 2)", r.contains(1, 2));

	assertTrue("Rectangle should contain point (3, 4)", r.contains(3, 4));

	assertTrue("Rectangle should contain point (3, 5)", r.contains(3, 5));

//	assertTrue("Rectangle should contain point (3, 6)", r.contains(3, 6));
//
//	assertTrue("Rectangle should contain point (4, 5)", r.contains(4, 5));
//
//	assertTrue("Rectangle should contain point (4, 6)", r.contains(4, 6));

	assertTrue("Rectangle should not contain point (9, 10)", !r.contains(9, 10));

	assertTrue("Rectangle should not contain point (-1, -1)", !r.contains(-1, -1));
}

/**
 * Returns <code>true</code> if the given point is inside the
 * area specified by the receiver.
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the argument is null</li>
 * </ul>
 */
public void test_containsLorg_eclipse_swt_graphics_Point(){
	Rectangle r = new Rectangle(1, 2, 3, 4);
	assertTrue("Rectangle should contain Point(1, 2)", r.contains(new Point(1, 2)));

	assertTrue("Rectangle should contain Point(3, 4)", r.contains(new Point(3, 4)));

	assertTrue("Rectangle should contain point (3, 5)", r.contains(new Point(3, 5)));

//	assertTrue("Rectangle should contain point (3, 6)", r.contains(new Point(3, 6)));
//
//	assertTrue("Rectangle should contain point (4, 5)", r.contains(new Point(4, 5)));
//
//	assertTrue("Rectangle should contain Point(4, 6)", r.contains(new Point(4, 6)));

	assertTrue("Rectangle should not contain Point(9, 10)", !r.contains(new Point(9, 10)));

	assertTrue("Rectangle should not contain point (-1, -1)", !r.contains(new Point(-1, -1)));

	try {
		r.contains(null);
		fail("No exception thrown for rectangle == null");
	} catch (IllegalArgumentException e) {
	}
}

public void test_equalsLjava_lang_Object(){
	Rectangle r1 = new Rectangle(5, 4, 3, 2);
	Rectangle r2 = new Rectangle(5, 4, 3, 2);
	assertTrue("Rectangles should be equal", r1.equals(r2));

	r2 = new Rectangle(3, 4, 5, 6);
	assertTrue("Rectangles should not be equal", !r1.equals(r2));

	r2 = new Rectangle(2, 3, 4, 5);
	assertTrue("Rectangles should not be equal", !r1.equals(r2));

	r2 = new Rectangle(5, 4, 2, 3);
	assertTrue("Rectangles should not be equal", !r1.equals(r2));

	r2 = new Rectangle(4, 5, 3, 2);
	assertTrue("Rectangles should not be equal", !r1.equals(r2));
}

public void test_hashCode(){
	Rectangle r1 = new Rectangle(5, 4, 3, 2);
	Rectangle r2 = new Rectangle(5, 4, 3, 2);
	assertTrue("Rectangles should have the same hashCode", r1.hashCode() == r2.hashCode());
}

/**
 * Returns a new rectangle which represents the intersection
 * of the receiver and the given rectangle. 
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the argument is null</li>
 * </ul>
 */
public void test_intersectionLorg_eclipse_swt_graphics_Rectangle(){
	Rectangle r1 = new Rectangle(1, 2, 3, 4);
	Rectangle r2 = new Rectangle(3, 3, 2, 2);
	assertEquals("Rectangle intersection incorrect", new Rectangle(3, 3, 1, 2), r1.intersection(r2));

	r2 = new Rectangle(3, 3, 0, 0);
	assertEquals("Rectangle intersection incorrect", new Rectangle(3, 3, 0, 0), r1.intersection(r2));

	r2 = new Rectangle(3, 3, -1, -1);
	assertEquals("Rectangle intersection incorrect", new Rectangle(0, 0, 0, 0), r1.intersection(r2));

	try {
		r1.intersection(null);
		fail("No exception thrown for rectangle == null");
	} catch (IllegalArgumentException e) {
	}
}

/**
 * Returns <code>true</code> if the given rectangle intersects
 * with the receiver and <code>false</code> otherwise.
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the argument is null</li>
 * </ul>
 */
public void test_intersectsLorg_eclipse_swt_graphics_Rectangle(){
	Rectangle r1 = new Rectangle(1, 2, 3, 4);
	Rectangle r2 = new Rectangle(2, 3, 7, 8);
	assertTrue("Rectangle(1, 2, 3, 4) should intersect Rectangle(2, 3, 7, 8)", r1.intersects(r2));
	assertTrue("Rectangle(2, 3, 7, 8) should intersect Rectangle(1, 2, 3, 4)", r2.intersects(r1));

	r2 = new Rectangle(200, 300, 400, 500);
	assertTrue("Rectangle(1, 2, 3, 4) should not intersect Rectangle(200, 300, 400, 500)", !r1.intersects(r2));
	assertTrue("Rectangle(200, 300, 400, 500) should not intersect Rectangle(1, 2, 3, 4)", !r2.intersects(r1));
	
	r2 = new Rectangle(3, 3, 0, 0);
	assertTrue("Rectangle(1, 2, 3, 4) should intersect Rectangle(3, 3, 0, 0)", r1.intersects(r2));
	assertTrue("Rectangle(3, 3, 0, 0) should intersect Rectangle(1, 2, 3, 4)", r2.intersects(r1));

	r2 = new Rectangle(3, 3, -1, -1);
	assertTrue("Rectangle(1, 2, 3, 4) should not intersect Rectangle(3, 3, -1, -1)", !r1.intersects(r2));
	assertTrue("Rectangle(3, 3, -1, -1) should not intersect Rectangle(1, 2, 3, 4)", !r2.intersects(r1));

	try {
		r1.intersects(null);
		fail("No exception thrown for rectangle == null");
	} catch (IllegalArgumentException e) {
	}
}

/**
 * Returns <code>true</code> if the receiver does not cover any
 * area in the (x, y) coordinate plane, and <code>false</code> if
 * the receiver does cover some area in the plane.
 * <p>
 * A rectangle is considered to <em>cover area</em> in the 
 * (x, y) coordinate plane if both its width and height are 
 * non-zero.
 * </p>
 */
public void test_isEmpty(){
	Rectangle r = new Rectangle(1, 2, 0, 0);
	assertTrue("Rectangle is empty", r.isEmpty());

	r = new Rectangle(1, 2, -3, -4);
	assertTrue("Rectangle is empty", r.isEmpty());

	r = new Rectangle(1, 2, 3, 4);
	assertTrue("Rectangle is not empty", !r.isEmpty());
}

public void test_toString(){
	Rectangle r = new Rectangle(3, 4, 5, 6);
	assertNotNull(r.toString());
	assertTrue(r.toString().length() > 0);
	assertEquals("Rectangle {3, 4, 5, 6}", r.toString());
}

/**
 * Returns a new rectangle which represents the union of
 * the receiver and the given rectangle.
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the argument is null</li>
 * </ul>
 */
public void test_unionLorg_eclipse_swt_graphics_Rectangle(){
	Rectangle r1 = new Rectangle(1, 2, 3, 4);
	Rectangle r2 = new Rectangle(3, 3, 2, 2);
	assertEquals("Rectangle union incorrect", new Rectangle(1, 2, 4, 4), r1.union(r2));
	
	r2 = new Rectangle(3, 3, 0, 0);
	assertEquals("Rectangle union incorrect", new Rectangle(1, 2, 3, 4), r1.union(r2));

	r2 = new Rectangle(3, 3, -1, -1);
	assertEquals("Rectangle union incorrect", new Rectangle(1, 2, 3, 4), r1.union(r2));

	try {
		r1.union(null);
		fail("No exception thrown for rectangle == null");
	} catch (IllegalArgumentException e) {
	}
}

public static Test suite() {
	TestSuite suite = new TestSuite();
	java.util.Vector methodNames = methodNames();
	java.util.Enumeration e = methodNames.elements();
	while (e.hasMoreElements()) {
		suite.addTest(new Test_org_eclipse_swt_graphics_Rectangle((String)e.nextElement()));
	}
	return suite;
}
public static java.util.Vector methodNames() {
	java.util.Vector methodNames = new java.util.Vector();
	methodNames.addElement("test_ConstructorIIII");
	methodNames.addElement("test_addLorg_eclipse_swt_graphics_Rectangle");
	methodNames.addElement("test_containsII");
	methodNames.addElement("test_containsLorg_eclipse_swt_graphics_Point");
	methodNames.addElement("test_equalsLjava_lang_Object");
	methodNames.addElement("test_hashCode");
	methodNames.addElement("test_intersectionLorg_eclipse_swt_graphics_Rectangle");
	methodNames.addElement("test_intersectsLorg_eclipse_swt_graphics_Rectangle");
	methodNames.addElement("test_isEmpty");
	methodNames.addElement("test_toString");
	methodNames.addElement("test_unionLorg_eclipse_swt_graphics_Rectangle");
	return methodNames;
}
protected void runTest() throws Throwable {
	if (getName().equals("test_ConstructorIIII")) test_ConstructorIIII();
	else if (getName().equals("test_addLorg_eclipse_swt_graphics_Rectangle")) test_addLorg_eclipse_swt_graphics_Rectangle();
	else if (getName().equals("test_containsII")) test_containsII();
	else if (getName().equals("test_containsLorg_eclipse_swt_graphics_Point")) test_containsLorg_eclipse_swt_graphics_Point();
	else if (getName().equals("test_equalsLjava_lang_Object")) test_equalsLjava_lang_Object();
	else if (getName().equals("test_hashCode")) test_hashCode();
	else if (getName().equals("test_intersectionLorg_eclipse_swt_graphics_Rectangle")) test_intersectionLorg_eclipse_swt_graphics_Rectangle();
	else if (getName().equals("test_intersectsLorg_eclipse_swt_graphics_Rectangle")) test_intersectsLorg_eclipse_swt_graphics_Rectangle();
	else if (getName().equals("test_isEmpty")) test_isEmpty();
	else if (getName().equals("test_toString")) test_toString();
	else if (getName().equals("test_unionLorg_eclipse_swt_graphics_Rectangle")) test_unionLorg_eclipse_swt_graphics_Rectangle();
}
}
