/*******************************************************************************
 * Copyright (c) 2000, 2016 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     Red Hat Inc. - Bug 462631
 *******************************************************************************/
package org.eclipse.swt.tests.junit;

import static org.junit.Assert.fail;

import org.eclipse.swt.SWTException;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.graphics.Region;
import org.eclipse.swt.widgets.Display;
import org.junit.Before;
import org.junit.Test;

/**
 * Automated Test Suite for class org.eclipse.swt.graphics.Region
 *
 * @see org.eclipse.swt.graphics.Region
 */
public class Test_org_eclipse_swt_graphics_Region {

@Before
public void setUp() {
	display = Display.getDefault();
}

@Test
public void test_Constructor() {
	// test Region()
	Region reg = new Region();
	if (reg.isDisposed()) {
		fail("Constructor for Region didn't initialize");
	}
	reg.dispose();
}

@Test
public void test_ConstructorLorg_eclipse_swt_graphics_Device() {
	Region reg = new Region(display);
	if (reg.isDisposed()) {
		fail("Constructor for Region didn't initialize");
	}
	reg.dispose();
}

@Test
public void test_add$I() {
	Region reg = new Region(display);
	try {
		reg.add((int[])null);
		reg.dispose();
		fail("no exception thrown for adding a null rectangle");
	}
	catch (IllegalArgumentException e) {
	}
	reg.dispose();
	try {
		reg.add(new int[]{});
		reg.dispose();
		fail("no exception thrown on disposed region");
	}
	catch (SWTException e) {
	}
	reg.dispose();

	reg = new Region(display);
	reg.add(new int[] {0,0, 50,0, 50,25, 0,25});
	Rectangle box = reg.getBounds();
	reg.dispose();
	Rectangle expected = new Rectangle (0,0,50,25);
	if (!box.equals(expected)) {
		fail("add 1 failed - expected: "+expected+" actual: "+box);
	}

	reg = new Region(display);
	reg.add(new int[] {0,0, 50,0, 50,25, 0,25});
	reg.add(new int[] {0,25, 50,25, 50,40, 0,40});
	box = reg.getBounds();
	reg.dispose();
	expected = new Rectangle (0,0,50,40);
	if (!box.equals(expected)) {
		fail("add 2 failed - expected: "+expected+" actual: "+box);
	}

//	reg = new Region(display);
//	reg.add(new int[] {10,10, 40,30, 20,60, 5,55});
//	box = reg.getBounds();
//	reg.dispose();
//	expected = new Rectangle (5,10,35,50);
//	if (!box.equals(expected)) {
//		fail("add 3 failed - expected: "+expected+" actual: "+box);
//	}
}

@Test
public void test_addLorg_eclipse_swt_graphics_Rectangle() {
	Region reg = new Region(display);
	// add a rectangle
	reg.add(new Rectangle(0, 0, 100, 50));
	// add a second rectangle
	reg.add(new Rectangle(200, 200, 10,10));

	try {
		reg.add((Rectangle)null);
		fail("no exception thrown for adding a null rectangle");
	}
	catch (IllegalArgumentException e) {
	}

	reg.dispose();

	try {
		reg.add(new Rectangle(20,30,10,5));
		fail("no exception thrown for adding a rectangle after Region got disposed");
	}
	catch (SWTException e) {
	}
}

@Test
public void test_addLorg_eclipse_swt_graphics_Region() {
	Region reg1 = new Region(display);
	// make a second region and add it to the first one
	Region reg2 = new Region(display);
	reg2.add(new Rectangle(40, 50, 10, 20));
	reg1.add(reg2);
	reg2.dispose();

	try {
		reg1.add((Region)null);
		fail("no exception thrown for adding a null region");
	}
	catch (IllegalArgumentException e) {
	}

	try {
		reg2 = new Region(display);
		reg2.add(new Rectangle(1,1,100,200));
		reg2.dispose();
		reg1.add(reg2);
		fail("no exception thrown for adding to a Region a Region which got disposed");
	}
	catch (IllegalArgumentException e) {
	}

	reg1.dispose();

	try {
		reg2 = new Region(display);
		reg2.add(new Rectangle(1,1,100,200));
		reg1.add(reg2);
		fail("no exception thrown for adding a Region to a Region which got disposed");
	}
	catch (SWTException e) {
	} finally {
		if (reg2 != null) reg2.dispose();
	}
}

@Test
public void test_containsII() {
	Rectangle rect1 = new Rectangle(10,10,200,100);
	Point pointInRect1 = new Point(10,10);
	Rectangle rect2 = new Rectangle(50,50,1000,1000);
	Point pointInRect2 = new Point(1049,1009);
	Point pointNotInRect12 = new Point(49,110);

	Region reg = new Region(display);
	reg.dispose();
	try {
		reg.contains(pointInRect1.x, pointInRect1.y);
		fail("no exception thrown on disposed region");
	}
	catch (Exception e) {
	}

	reg = new Region(display);
	if (reg.contains(pointInRect1.x, pointInRect1.y)) {
		reg.dispose();
		fail("Empty region should not contain point");
	}
	reg.add(rect1);
	if (!reg.contains(pointInRect1.x, pointInRect1.y)) {
		reg.dispose();
		fail("Region should contain point");
	}
	reg.add(rect2);
	if (!reg.contains(pointInRect1.x, pointInRect1.y) ||
		!reg.contains(pointInRect2.x, pointInRect2.y)) {
		reg.dispose();
		fail("Region should contain point");
	}
	if (reg.contains(pointNotInRect12.x, pointNotInRect12.y)) {
		reg.dispose();
		fail("Region should not contain point");
	}
	reg.dispose();
}

@Test
public void test_containsLorg_eclipse_swt_graphics_Point() {
	Rectangle rect1 = new Rectangle(10,10,200,100);
	Point pointInRect1 = new Point(10,10);
	Rectangle rect2 = new Rectangle(50,50,1000,1000);
	Point pointInRect2 = new Point(1049,1009);
	Point pointNotInRect12 = new Point(49,110);

	Region reg = new Region(display);
	reg.dispose();
	try {
		reg.contains(pointInRect1);
		fail("no exception thrown on disposed region");
	}
	catch (Exception e) {
	}

	reg = new Region(display);
	if (reg.contains(pointInRect1)) {
		reg.dispose();
		fail("Empty region should not contain point");
	}
	reg.add(rect1);
	if (!reg.contains(pointInRect1)) {
		reg.dispose();
		fail("Region should contain point");
	}
	reg.add(rect2);
	if (!reg.contains(pointInRect1) ||
		!reg.contains(pointInRect2)) {
		reg.dispose();
		fail("Region should contain point");
	}
	if (reg.contains(pointNotInRect12)) {
		reg.dispose();
		fail("Region should not contain point");
	}
	reg.dispose();
}

@Test
public void test_dispose() {
	Region reg = new Region(display);
	reg.add(new Rectangle(1,1,50,100));
	if (reg.isDisposed()) {
		fail("Region should not be in the disposed state");
	}

	// dispose twice as this is allowed
	for (int i = 0; i < 2; i++) {
		reg.dispose();
		if (!reg.isDisposed()) {
			fail("Region should be in the disposed state");
		}
	}
}

@Test
public void test_equalsLjava_lang_Object() {
	Rectangle rect1 = new Rectangle(25, 100, 200, 780);
	Rectangle rect2 = new Rectangle(30, 105, 205, 785);

	Region reg1 = new Region(display);
	reg1.add(rect1);

	Region reg2 = reg1;

	if (!reg1.equals(reg2)) {
		reg1.dispose();
		reg2.dispose();
		fail("references to the same instance of Region should be considered equal");
	}

	reg2 = new Region(display);
	reg2.add(rect1);

// Currently, Regions are only "equal" if they have the same handle.
// This is so that identical objects are properly hashed.
// We are considering adding a new method that will compare Regions for the same area.
//	if (!reg1.equals(reg2)) {
//		reg1.dispose();
//		reg2.dispose();
//		fail("two instances of Region representing the same area should be considered equal");
//	}

	reg2.dispose();
	reg2 = new Region(display);
	if (reg1.equals(reg2)) {
		reg1.dispose();
		reg2.dispose();
		fail("Non empty region considered equal to empty one");
	}

	reg2.add(rect2);
	if (reg1.equals(reg2)) {
		reg1.dispose();
		reg2.dispose();
		fail("two different regions considered equal");
	}

	reg1.dispose();
	reg2.dispose();
}

@Test
public void test_getBounds() {
	Region reg = new Region(display);
	reg.dispose();

	try {
		reg.getBounds();
		fail("Region disposed should throw Exception");
	}
	catch (Exception e) {
	}

	Rectangle rect1 = new Rectangle(10,10,50,30);
	Rectangle rect2 = new Rectangle(100,100,10,10);
	// the rectangle enclosing the two preceding rectangles
	Rectangle rect12Bounds = new Rectangle(10,10,100,100);

	reg = new Region(display);
	reg.add(rect1);
	Rectangle rect1Bis = reg.getBounds();
	if (rect1Bis.x != rect1.x || rect1Bis.y != rect1.y ||
		rect1Bis.height != rect1.height || rect1Bis.width != rect1.width) {
		reg.dispose();
		fail("getBounds doesn't return the borders of the rectangle area which was set up");
	}

	reg.add(rect2);
	Rectangle rect12 = reg.getBounds();
	if (rect12.x != rect12Bounds.x || rect12.y != rect12Bounds.y ||
		rect12.height != rect12Bounds.height || rect12.width != rect12Bounds.width) {
		reg.dispose();
		fail("getBounds doesn't return the borders of the resulting rectangle area which was set up");
	}

	reg.dispose();
}

@Test
public void test_hashCode() {
	Region reg1 = new Region(display);
	Region reg2 = new Region(display);

	Rectangle rect1 = new Rectangle(25, 100, 200, 780);
	Rectangle rect2 = new Rectangle(30, 105, 205, 785);

	reg1.add(rect1);
	reg2.add(rect2);

	if (reg1.hashCode() == reg2.hashCode()) {
		reg1.dispose();
		reg2.dispose();
		fail("two different regions should have different hashCode");
	}
	reg2.dispose();

	reg2 = new Region(display);
	reg2.add(rect1);


// BUG: this should pass
//	if (reg1.hashCode() != reg2.hashCode()) {
//		reg1.dispose();
//		reg2.dispose();
//		fail("two regions representing same area should have same hashCode");
//	}

	reg1.dispose();
	reg2.dispose();
}

@Test
public void test_intersectLorg_eclipse_swt_graphics_Rectangle() {
	Rectangle rect1 = new Rectangle(0,0,48,24);
	Rectangle rect2 = new Rectangle(0,0,48,24);
	Rectangle rect3 = new Rectangle(10,10,10,10);
	Rectangle rect4 = new Rectangle(48,24,10,10);
	Rectangle rect5 = new Rectangle(24,20,24,10);

	Region reg = new Region(display);
	reg.dispose();
	try {
		reg.intersect(rect1);
		fail("no exception thrown on disposed region");
	}
	catch (SWTException e) {
	}

	reg = new Region(display);
	reg.intersect(rect1);
	if (!reg.isEmpty()) {
		reg.dispose();
		fail("intersect failed for empty region");
	}
	reg.add(rect1);
	reg.intersect(rect2);
	Rectangle box = reg.getBounds();
	if (!box.equals(rect1)) {
		reg.dispose();
		fail("intersect failed 1");
	}
	reg.intersect(rect3);
	box = reg.getBounds();
	if (!box.equals(rect3)) {
		reg.dispose();
		fail("intersect failed 2");
	}
	reg.intersect(rect4);
	if (!reg.isEmpty()) {
		reg.dispose();
		fail("intersect failed 3");
	}
	reg.add(rect1.union(rect4));
	reg.intersect(rect5);
	box = reg.getBounds();
	if (!box.equals(rect5)) {
		reg.dispose();
		fail("intersect failed 4");
	}
	reg.dispose();

	reg = new Region(display);
	reg.add(rect1);
	reg.add(rect4);
	reg.intersect(rect5);
	box = reg.getBounds();
	if (!box.equals(new Rectangle(24,20,24,4))) {
		reg.dispose();
		fail("intersect failed 5");
	}
	reg.dispose();
}

@Test
public void test_intersectLorg_eclipse_swt_graphics_Region() {
	Region reg = new Region(display);
	Region reg1 = new Region(display);
	reg1.add(new Rectangle(0,0,48,24));

	reg.dispose();
	try {
		reg.intersect(reg1);
		reg1.dispose();
		fail("no exception thrown on disposed region");
	}
	catch (SWTException e) {
	}

	reg = new Region(display);
	reg.intersect(reg1);
	if (!reg.isEmpty()) {
		reg.dispose();
		reg1.dispose();
		fail("intersect failed for empty region");
	}

	Region reg2 = new Region(display);
	reg2.add(new Rectangle(0,0,48,24));

	reg.add(reg1);
	reg.intersect(reg2);
	Rectangle box = reg.getBounds();
	if (!box.equals(reg1.getBounds())) {
		reg.dispose();
		reg1.dispose();
		reg2.dispose();
		fail("intersect failed 1");
	}
	reg2.dispose();

	Region reg3 = new Region(display);
	reg3.add(new Rectangle(10,10,10,10));

	reg.intersect(reg3);
	box = reg.getBounds();
	if (!box.equals(reg3.getBounds())) {
		reg.dispose();
		reg1.dispose();
		reg3.dispose();
		fail("intersect failed 2");
	}
	reg3.dispose();

	Region reg4 = new Region(display);
	reg4.add(new Rectangle(48,24,10,10));

	reg.intersect(reg4);
	if (!reg.isEmpty()) {
		reg.dispose();
		reg1.dispose();
		reg4.dispose();
		fail("intersect failed 3");
	}

	Region reg5 = new Region(display);
	reg5.add(new Rectangle(24,20,24,10));

	reg.add(reg1.getBounds().union(reg4.getBounds()));
	reg.intersect(reg5);
	box = reg.getBounds();
	if (!box.equals(reg5.getBounds())) {
		reg.dispose();
		reg1.dispose();
		reg4.dispose();
		fail("intersect failed 4");
	}
	reg.dispose();

	reg = new Region(display);
	reg.add(reg1);
	reg.add(reg4);
	reg.intersect(reg5);
	box = reg.getBounds();
	if (!box.equals(new Rectangle(24,20,24,4))) {
		reg.dispose();
		reg1.dispose();
		reg4.dispose();
		fail("intersect failed 5");
	}
	reg.dispose();
	reg1.dispose();
	reg4.dispose();
	reg5.dispose();
}

@Test
public void test_intersectsIIII() {
	Rectangle rect1 = new Rectangle(10,20,50,30);
	Rectangle rectInter1 = new Rectangle(59,49,10,20);
	Rectangle rectNotInter1 = new Rectangle(0,5,10,15);

	Rectangle rect2 = new Rectangle(30,40,10,100);
	Rectangle rectInter2 = new Rectangle(39,139,1,5);
	Rectangle rectNotInter12 = new Rectangle(40,50,5,15);


	Region reg = new Region(display);
	reg.dispose();
	try {
		reg.intersects(rectInter1.x, rectInter1.y, rectInter1.width, rectInter1.height);
		fail("no exception thrown on disposed region");
	}
	catch (Exception e) {
	}

	reg = new Region(display);
	if (reg.intersects(rect1.x, rect1.y, rect1.width, rect1.height)) {
		reg.dispose();
		fail("intersects can't return true on empty region");
	}
	reg.add(rect1);
	if (!reg.intersects(rect1.x, rect1.y, rect1.width, rect1.height)) {
		reg.dispose();
		fail("intersects didn't return true");
	}
	if (!reg.intersects(rectInter1.x, rectInter1.y, rectInter1.width, rectInter1.height)) {
		reg.dispose();
		fail("intersects didn't return true ");
	}
	if (reg.intersects(rectNotInter1.x, rectNotInter1.y, rectNotInter1.width, rectNotInter1.height)) {
		reg.dispose();
		fail("intersects return true on rectangle not intersecting with region");
	}

	reg.add(rect2);
	if (!reg.intersects(rect2.x, rect2.y, rect2.width, rect2.height)) {
		reg.dispose();
		fail("intersects didn't return true");
	}
	if (!reg.intersects(rectInter2.x, rectInter2.y, rectInter2.width, rectInter2.height)) {
		reg.dispose();
		fail("intersects didn't return true ");
	}
	if (reg.intersects(rectNotInter12.x, rectNotInter12.y, rectNotInter12.width, rectNotInter12.height)) {
		reg.dispose();
		fail("intersects return true on rectangle not intersecting with region");
	}
	reg.dispose();
}

@Test
public void test_intersectsLorg_eclipse_swt_graphics_Rectangle() {
	Rectangle rect1 = new Rectangle(10,20,50,30);
	Rectangle rectInter1 = new Rectangle(59,49,10,20);
	Rectangle rectNotInter1 = new Rectangle(0,5,10,15);

	Rectangle rect2 = new Rectangle(30,40,10,100);
	Rectangle rectInter2 = new Rectangle(39,139,1,5);
	Rectangle rectNotInter12 = new Rectangle(40,50,5,15);


	Region reg = new Region(display);
	reg.dispose();
	try {
		reg.intersects(rectInter1);
		fail("no exception thrown on disposed region");
	}
	catch (Exception e) {
	}

	reg = new Region(display);
	if (reg.intersects(rect1)) {
		reg.dispose();
		fail("intersects can't return true on empty region");
	}
	reg.add(rect1);
	if (!reg.intersects(rect1)) {
		reg.dispose();
		fail("intersects didn't return true");
	}
	if (!reg.intersects(rectInter1)) {
		reg.dispose();
		fail("intersects didn't return true ");
	}
	if (reg.intersects(rectNotInter1)) {
		reg.dispose();
		fail("intersects return true on rectangle not intersecting with region");
	}

	reg.add(rect2);
	if (!reg.intersects(rect2)) {
		reg.dispose();
		fail("intersects didn't return true");
	}
	if (!reg.intersects(rectInter2)) {
		reg.dispose();
		fail("intersects didn't return true ");
	}
	if (reg.intersects(rectNotInter12)) {
		reg.dispose();
		fail("intersects return true on rectangle not intersecting with region");
	}
	reg.dispose();
}

@Test
public void test_isEmpty() {
	Region reg = new Region(display);
	Rectangle emptyRect1 = new Rectangle(10,20,0,200);
	Rectangle emptyRect2 = new Rectangle(10,20,10,0);
	Rectangle rect = new Rectangle(10,20,50,100);

	if (!reg.isEmpty()) {
		reg.dispose();
		fail("isEmpty didn't return true on empty region");
	}

	reg.add(emptyRect1);
	if (!reg.isEmpty()) {
		reg.dispose();
		fail("isEmpty didn't return true on empty region");
	}

	reg.add(emptyRect2);
	if (!reg.isEmpty()) {
		reg.dispose();
		fail("isEmpty didn't return true on empty region");
	}

	reg.add(rect);
	if (reg.isEmpty()) {
		reg.dispose();
		fail("isEmpty returned true on non empty region");
	}

	reg.dispose();
}

@Test
public void test_subtract$I() {
	Region reg = new Region(display);
	try {
		reg.subtract((int[])null);
		reg.dispose();
		fail("no exception thrown for subtract a null array");
	}
	catch (IllegalArgumentException e) {
	}
	reg.dispose();
	try {
		reg.subtract(new int[]{});
		reg.dispose();
		fail("no exception thrown on disposed region");
	}
	catch (SWTException e) {
	}
	reg.dispose();

	reg = new Region(display);
	reg.add(new int[] {0,0, 50,0, 50,25, 0,25});
	reg.subtract(new int[] {0,0, 50,0, 50,20, 0,20});
	Rectangle box = reg.getBounds();
	reg.dispose();
	Rectangle expected = new Rectangle (0,20,50,5);
	if (!box.equals(expected)) {
		fail("subtract 1 failed - expected: "+expected+" actual: "+box);
	}


	reg = new Region(display);
	reg.add(new int[] {0,0, 50,0, 50,25, 0,25});
	reg.add(new int[] {0,25, 50,25, 50,40, 0,40});
	reg.subtract(new int[] {0,25, 50,25, 50,40, 0,40});
	box = reg.getBounds();
	reg.dispose();
	expected = new Rectangle (0,0,50,25);
	if (!box.equals(expected)) {
		fail("subtract 2 failed - expected: "+expected+" actual: "+box);
	}
}

@Test
public void test_subtractLorg_eclipse_swt_graphics_Rectangle() {
	Rectangle rect1 = new Rectangle(0,0,50,25);
	Rectangle rect2 = new Rectangle(0,0,50,25);
	Rectangle rect3 = new Rectangle(10,10,10,10);
	Rectangle rect4 = new Rectangle(50,25,10,10);
	Rectangle rect5 = new Rectangle(0,0,60,20);

	Region reg = new Region(display);
	reg.dispose();
	try {
		reg.subtract(rect1);
		fail("no exception thrown on disposed region");
	}
	catch (SWTException e) {
	}

	reg = new Region(display);
	reg.subtract(rect1);
	if (!reg.isEmpty()) {
		reg.dispose();
		fail("subtract failed for empty region");
	}
	reg.add(rect1);
	reg.subtract(rect2);
	if (!reg.isEmpty()) {
		reg.dispose();
		fail("subtract failed 1");
	}
	reg.add(rect1);
	reg.subtract(rect3);
	Rectangle box = reg.getBounds();
	if (!box.equals(rect1)) {
		reg.dispose();
		fail("subtract failed 2");
	}
	reg.subtract(rect4);
	box = reg.getBounds();
	if (!box.equals(rect1)) {
		reg.dispose();
		fail("subtract failed 3");
	}
	reg.add(rect1.union(rect4));
	reg.subtract(rect5);
	box = reg.getBounds();
	if (!box.equals(new Rectangle(0,20,60,15))) {
		reg.dispose();
		fail("subtract failed 4");
	}
	reg.dispose();

	reg = new Region(display);
	reg.add(rect1);
	reg.add(rect4);
	reg.subtract(rect5);
	box = reg.getBounds();
	if (!box.equals(new Rectangle(0,20,60,15))) {
		reg.dispose();
		fail("subtract failed 5");
	}
	reg.dispose();
}

@Test
public void test_subtractLorg_eclipse_swt_graphics_Region() {
	Region reg1 = new Region(display);
	reg1.add(new Rectangle(0,0,50,25));

	Region reg = new Region(display);
	reg.dispose();
	try {
		reg.subtract(reg1);
		reg1.dispose();
		fail("no exception thrown on disposed region");
	}
	catch (SWTException e) {
	}

	reg = new Region(display);
	reg.subtract(reg1);
	if (!reg.isEmpty()) {
		reg.dispose();
		reg1.dispose();
		fail("subtract failed for empty region");
	}

	Region reg2 = new Region(display);
	reg2.add(new Rectangle(0,0,50,25));

	reg.add(reg1);
	reg.subtract(reg2);
	if (!reg.isEmpty()) {
		reg.dispose();
		reg1.dispose();
		reg2.dispose();
		fail("subtract failed 1");
	}
	reg2.dispose();

	Region reg3 = new Region(display);
	reg3.add(new Rectangle(10,10,10,10));

	reg.add(reg1);
	reg.subtract(reg3);
	Rectangle box = reg.getBounds();
	if (!box.equals(reg1.getBounds())) {
		reg.dispose();
		reg1.dispose();
		reg3.dispose();
		fail("subtract failed 2");
	}
	reg3.dispose();

	Region reg4 = new Region(display);
	reg4.add(new Rectangle(50,25,10,10));

	reg.subtract(reg4);
	box = reg.getBounds();
	if (!box.equals(reg1.getBounds())) {
		reg.dispose();
		reg1.dispose();
		reg4.dispose();
		fail("subtract failed 3");
	}

	Region reg5 = new Region(display);
	reg5.add(new Rectangle(0,0,60,20));

	reg.add(reg1.getBounds().union(reg4.getBounds()));
	reg.subtract(reg5);
	box = reg.getBounds();
	if (!box.equals(new Rectangle(0,20,60,15))) {
		reg.dispose();
		reg1.dispose();
		reg4.dispose();
		reg5.dispose();
		fail("subtract failed 4");
	}
	reg.dispose();

	reg = new Region(display);
	reg.add(reg1);
	reg.add(reg4);
	reg.subtract(reg5);
	box = reg.getBounds();
	if (!box.equals(new Rectangle(0,20,60,15))) {
		reg.dispose();
		reg1.dispose();
		reg4.dispose();
		reg5.dispose();
		fail("subtract failed 5");
	}
	reg.dispose();
	reg1.dispose();
	reg4.dispose();
	reg5.dispose();
}

@Test
public void test_toString() {
	Region reg = new Region(display);

	String s = reg.toString();

	if (s == null || s.length() == 0) {
		fail("toString returns null or empty string");
	}

	reg.add(new Rectangle(1,1,10,20));
	s = reg.toString();

	if (s == null || s.length() == 0) {
		fail("toString returns null or empty string");
	}

	reg.dispose();
	s = reg.toString();

	if (s == null || s.length() == 0) {
		fail("toString returns null or empty string");
	}
}

@Test
public void test_add_intArray() {
	Region reg = new Region(display);
	int[] points = new int[] {1};
	reg.add(points);
	reg.dispose();

	Region reg2 = new Region(display);
	points = new int[] {1,2};
	reg2.add(points);
	reg2.dispose();

	Region reg3 = new Region(display);
	points = new int[] {1,2,3};
	reg3.add(points);
	reg3.dispose();

	Region reg4 = new Region(display);
	points = new int[] {1,2,3,4};
	reg4.add(points);
	reg4.dispose();

	Region reg5 = new Region(display);
	points = new int[] {1,2,3,4,5};
	reg5.add(points);
	reg5.dispose();

	Region reg6 = new Region(display);
	points = new int[] {1,2,3,4,5,6};
	reg6.add(points);
	reg6.dispose();
}

/* custom */
	Display display;
}
