/*******************************************************************************
 * Copyright (c) 2000, 2019 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.swt.tests.junit;

import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.ShellEvent;
import org.eclipse.swt.events.ShellListener;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.graphics.Region;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Shell;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

/**
 * Automated Test Suite for class org.eclipse.swt.widgets.Shell
 *
 * @see org.eclipse.swt.widgets.Shell
 */
public class Test_org_eclipse_swt_widgets_Shell extends Test_org_eclipse_swt_widgets_Decorations {

private static final boolean IS_GTK_BUG_445900 = SwtTestUtil.isGTK;

@Override
@Before
public void setUp() {
	super.setUp();
	testShell = new Shell(shell, SWT.NULL);
	setWidget(shell);
	assertTrue(testShell.getParent() == shell);
}

@Test
public void test_Constructor() {
	Shell newShell = new Shell();
	assertNotNull("a: ", newShell.getDisplay());
	newShell.dispose();
}

@Test
public void test_ConstructorI() {
	/* this should test various combinations of STYLE bits, for now just test individual bits */
	int[] cases = {SWT.NO_TRIM, SWT.RESIZE, SWT.TITLE, SWT.CLOSE, SWT.MENU, SWT.MIN, SWT.BORDER,
				   SWT.CLIP_CHILDREN, SWT.CLIP_SIBLINGS, SWT.ON_TOP, SWT.FLAT, SWT.SMOOTH};
	Shell newShell;
	for (int i = 0; i < cases.length; i++) {
		newShell = new Shell(cases[i]);
		assertTrue("a " +i, newShell.getDisplay() == shell.getDisplay());
		assertNotEquals(0, newShell.getStyle() & cases[i]);
		newShell.dispose();
	}
}

@Test
public void test_ConstructorLorg_eclipse_swt_widgets_Display() {
	Display display = shell.getDisplay();
	Shell newShell = new Shell(display);
	assertTrue("a: ", newShell.getDisplay() == display);
	newShell.dispose();
}

@Test
public void test_ConstructorLorg_eclipse_swt_widgets_DisplayI() {
	int[] cases = {SWT.NO_TRIM, SWT.RESIZE, SWT.TITLE, SWT.CLOSE, SWT.MENU, SWT.MIN, SWT.BORDER,
				   SWT.CLIP_CHILDREN, SWT.CLIP_SIBLINGS, SWT.ON_TOP, SWT.FLAT, SWT.SMOOTH};
	Shell newShell;
	Display display = shell.getDisplay();
	for (int i = 0; i < cases.length; i++) {
		newShell = new Shell(display, cases[i]);
		assertTrue("a " +i, newShell.getDisplay() == shell.getDisplay());
		newShell.dispose();
	}
}

@Test
public void test_ConstructorLorg_eclipse_swt_widgets_Shell() {
	Shell newShell = new Shell(shell);
	assertTrue("a: ", newShell.getParent() == shell);
	newShell.dispose();
}

@Test
public void test_ConstructorLorg_eclipse_swt_widgets_ShellI() {
	/* this should test various combinations of STYLE bits, for now just test individual bits */
	int[] cases = {SWT.NO_TRIM, SWT.RESIZE, SWT.TITLE, SWT.CLOSE, SWT.MENU, SWT.MIN, SWT.BORDER,
				   SWT.CLIP_CHILDREN, SWT.CLIP_SIBLINGS, SWT.ON_TOP, SWT.FLAT, SWT.SMOOTH};
	Shell newShell;
	for (int i = 0; i < cases.length; i++) {
		newShell = new Shell(shell, cases[i]);
		assertTrue("a " +i, newShell.getParent() == shell);
		newShell.dispose();
	}
}

@Test
public void test_addShellListenerLorg_eclipse_swt_events_ShellListener() {
	listenerCalled = false;
	boolean exceptionThrown = false;
	ShellListener listener = new ShellListener() {
		@Override
		public void shellActivated(ShellEvent e) {
			listenerCalled = true;
		}
		@Override
		public void shellClosed(ShellEvent e) {
		}
		@Override
		public void shellDeactivated(ShellEvent e) {
		}
		@Override
		public void shellDeiconified(ShellEvent e) {
		}
		@Override
		public void shellIconified(ShellEvent e) {
		}
	};
	try {
		shell.addShellListener(null);
	}
	catch (IllegalArgumentException e) {
		exceptionThrown = true;
	}
	assertTrue("Expected exception not thrown", exceptionThrown);
	exceptionThrown = false;
	shell.addShellListener(listener);
	shell.forceActive();
	/* can't assume listener is synchronously called when forceActive returned */
	/* assertTrue(":a:", listenerCalled == true); */

	listenerCalled = false;
	shell.removeShellListener(listener);
	shell.forceActive();
	/* can't assume listener is synchronously called when forceActive returned */
	/* assertTrue(":b:", listenerCalled == false); */
	try {
		shell.removeShellListener(null);
	}
	catch (IllegalArgumentException e) {
		exceptionThrown = true;
	}
	assertTrue("Expected exception not thrown", exceptionThrown);
}

@Test
public void test_addShellListenerShellActivatedAdapterLorg_eclipse_swt_events_ShellListener() {
	ShellListener listener = ShellListener.shellActivatedAdapter(e -> eventOccurred = true);
	shell.addShellListener(listener);
	eventOccurred = false;

	shell.notifyListeners(SWT.Activate, new Event());
	assertTrue(eventOccurred);

	eventOccurred = false;

	shell.notifyListeners(SWT.Deactivate, new Event());
	assertFalse(eventOccurred);

	eventOccurred = false;

	shell.notifyListeners(SWT.Deiconify, new Event());
	assertFalse(eventOccurred);

	eventOccurred = false;

	shell.notifyListeners(SWT.Iconify, new Event());
	assertFalse(eventOccurred);

	eventOccurred = false;

	shell.notifyListeners(SWT.Close, new Event());
	assertFalse(eventOccurred);

	shell.removeShellListener(listener);
	eventOccurred = false;

	shell.notifyListeners(SWT.Activate, new Event());
	assertFalse(eventOccurred);

	shell.notifyListeners(SWT.Deactivate, new Event());
	assertFalse(eventOccurred);

	shell.notifyListeners(SWT.Deiconify, new Event());
	assertFalse(eventOccurred);

	shell.notifyListeners(SWT.Iconify, new Event());
	assertFalse(eventOccurred);

	shell.notifyListeners(SWT.Close, new Event());
	assertFalse(eventOccurred);
}

@Test
public void test_addShellListenerShellDeactivatedAdapterLorg_eclipse_swt_events_ShellListener() {
	ShellListener listener = ShellListener.shellDeactivatedAdapter(e -> eventOccurred = true);
	shell.addShellListener(listener);
	eventOccurred = false;

	shell.notifyListeners(SWT.Deactivate, new Event());
	assertTrue(eventOccurred);

	eventOccurred = false;

	shell.notifyListeners(SWT.Activate, new Event());
	assertFalse(eventOccurred);

	eventOccurred = false;

	shell.notifyListeners(SWT.Deiconify, new Event());
	assertFalse(eventOccurred);

	eventOccurred = false;

	shell.notifyListeners(SWT.Iconify, new Event());
	assertFalse(eventOccurred);

	eventOccurred = false;

	shell.notifyListeners(SWT.Close, new Event());
	assertFalse(eventOccurred);

	shell.removeShellListener(listener);
	eventOccurred = false;

	shell.notifyListeners(SWT.Activate, new Event());
	assertFalse(eventOccurred);

	shell.notifyListeners(SWT.Deactivate, new Event());
	assertFalse(eventOccurred);

	shell.notifyListeners(SWT.Deiconify, new Event());
	assertFalse(eventOccurred);

	shell.notifyListeners(SWT.Iconify, new Event());
	assertFalse(eventOccurred);

	shell.notifyListeners(SWT.Close, new Event());
	assertFalse(eventOccurred);
}

@Test
public void test_addShellListenerShellDeiconifiedAdapterLorg_eclipse_swt_events_ShellListener() {
	ShellListener listener = ShellListener.shellDeiconifiedAdapter(e -> eventOccurred = true);
	shell.addShellListener(listener);
	eventOccurred = false;

	shell.notifyListeners(SWT.Deiconify, new Event());
	assertTrue(eventOccurred);

	eventOccurred = false;

	shell.notifyListeners(SWT.Deactivate, new Event());
	assertFalse(eventOccurred);

	eventOccurred = false;

	shell.notifyListeners(SWT.Activate, new Event());
	assertFalse(eventOccurred);

	eventOccurred = false;

	shell.notifyListeners(SWT.Iconify, new Event());
	assertFalse(eventOccurred);

	eventOccurred = false;

	shell.notifyListeners(SWT.Close, new Event());
	assertFalse(eventOccurred);

	shell.removeShellListener(listener);
	eventOccurred = false;

	shell.notifyListeners(SWT.Activate, new Event());
	assertFalse(eventOccurred);

	shell.notifyListeners(SWT.Deactivate, new Event());
	assertFalse(eventOccurred);

	shell.notifyListeners(SWT.Deiconify, new Event());
	assertFalse(eventOccurred);

	shell.notifyListeners(SWT.Iconify, new Event());
	assertFalse(eventOccurred);

	shell.notifyListeners(SWT.Close, new Event());
	assertFalse(eventOccurred);
}

@Test
public void test_addShellListenerShellIconifiedAdapterLorg_eclipse_swt_events_ShellListener() {
	ShellListener listener = ShellListener.shellIconifiedAdapter(e -> eventOccurred = true);
	shell.addShellListener(listener);
	eventOccurred = false;

	shell.notifyListeners(SWT.Iconify, new Event());
	assertTrue(eventOccurred);

	eventOccurred = false;

	shell.notifyListeners(SWT.Deactivate, new Event());
	assertFalse(eventOccurred);

	eventOccurred = false;

	shell.notifyListeners(SWT.Deiconify, new Event());
	assertFalse(eventOccurred);

	eventOccurred = false;

	shell.notifyListeners(SWT.Activate, new Event());
	assertFalse(eventOccurred);

	eventOccurred = false;

	shell.notifyListeners(SWT.Close, new Event());
	assertFalse(eventOccurred);

	shell.removeShellListener(listener);
	eventOccurred = false;

	shell.notifyListeners(SWT.Activate, new Event());
	assertFalse(eventOccurred);

	shell.notifyListeners(SWT.Deactivate, new Event());
	assertFalse(eventOccurred);

	shell.notifyListeners(SWT.Deiconify, new Event());
	assertFalse(eventOccurred);

	shell.notifyListeners(SWT.Iconify, new Event());
	assertFalse(eventOccurred);

	shell.notifyListeners(SWT.Close, new Event());
	assertFalse(eventOccurred);
}

@Test
public void test_addShellListenerShellClosedAdapterLorg_eclipse_swt_events_ShellListener() {
	ShellListener listener = ShellListener.shellClosedAdapter(e -> eventOccurred = true);
	shell.addShellListener(listener);
	eventOccurred = false;

	shell.notifyListeners(SWT.Close, new Event());
	assertTrue(eventOccurred);

	eventOccurred = false;

	shell.notifyListeners(SWT.Deactivate, new Event());
	assertFalse(eventOccurred);

	eventOccurred = false;

	shell.notifyListeners(SWT.Deiconify, new Event());
	assertFalse(eventOccurred);

	eventOccurred = false;

	shell.notifyListeners(SWT.Iconify, new Event());
	assertFalse(eventOccurred);

	eventOccurred = false;

	shell.notifyListeners(SWT.Activate, new Event());
	assertFalse(eventOccurred);

	shell.removeShellListener(listener);
	eventOccurred = false;

	shell.notifyListeners(SWT.Activate, new Event());
	assertFalse(eventOccurred);

	shell.notifyListeners(SWT.Deactivate, new Event());
	assertFalse(eventOccurred);

	shell.notifyListeners(SWT.Deiconify, new Event());
	assertFalse(eventOccurred);

	shell.notifyListeners(SWT.Iconify, new Event());
	assertFalse(eventOccurred);

	shell.notifyListeners(SWT.Close, new Event());
	assertFalse(eventOccurred);
}

@Test
public void test_close() {

	// bogus line that 'enabled' gpfs
	//	Shell newShell = new Shell();
	testShell.setBounds(20,30,200, 200);
	testShell.open();
	testShell.close();
	shell.setBounds(20,30,200, 200);
	shell.open();
}

@Test
public void test_dispose() {
	Shell newShell = new Shell();
	newShell.dispose();
}

@Test
public void test_forceActive() {
	shell.forceActive();
	/* can't assume listener is synchronously called when forceActive returned */
	/* assertTrue(":a:", shell.getDisplay().getActiveShell() == shell); */
}

@Test
public void test_getEnabled() {
	assertTrue(":a0:", shell.getEnabled());
	shell.setEnabled(false);
	assertTrue(":a:", !shell.getEnabled());
	shell.setEnabled(true);
	assertTrue(":b:", shell.getEnabled());
}

@Test
public void test_getImeInputMode() {
	int mode = shell.getImeInputMode();
	assertTrue(":a:", mode >= 0);
}

@Override
@Test
public void test_getLocation() {
	shell.setLocation(10,15);
	assertTrue(":a:", shell.getLocation().x == 10);
	assertTrue(":b:", shell.getLocation().y == 15);
}

@Override
@Test
public void test_getShell() {
	assertTrue(":a:", shell.getShell()==shell);
	Shell shell_1 = new Shell(shell);
	assertTrue(":b:", shell_1.getShell()== shell_1);
	shell_1.dispose();
}

@Test
public void test_getShells() {
	int num = shell.getShells().length;
	assertTrue(":a:", num == 1);
	Shell shell_1 = new Shell(shell);
	num = shell.getShells().length;
	assertTrue(":a:", num == 2);
	shell_1.dispose();
}

@Override
@Test
public void test_isEnabled() {
	assertTrue(":a:", shell.isEnabled());
	shell.setEnabled(false);
	assertTrue(":b:", !shell.isEnabled());
	if (SwtTestUtil.fCheckBogusTestCases)
		assertTrue(":b1:", !testShell.isEnabled());
	shell.setEnabled(true);
	assertTrue(":c:", shell.isEnabled());
	assertTrue(":a:", testShell.isEnabled());
	testShell.setEnabled(false);
	assertTrue(":b:", !testShell.isEnabled());
	testShell.setEnabled(true);
	assertTrue(":c:", testShell.isEnabled());
}

@Test
public void test_open() {
	shell.open();
}

@Test
public void test_setActive() {
	if (SwtTestUtil.isGTK) {
		//TODO Fix GTK failure.
		if (SwtTestUtil.verbose) {
			System.out.println("Excluded test_setActive(org.eclipse.swt.tests.junit.Test_org_eclipse_swt_widgets_Shell))");
		}
		return;
	}
	/* Create shell2 and make it active. */
	Shell shell2 = new Shell();
	shell2.setText("Shell2");
	shell2.open();

	/* Test setActive for visible shell. */
	shell.setVisible(true);
	shell.setActive();
	if (SwtTestUtil.isCocoa) { //workaround for Bug 536564
		drainEventQueue(shell.getDisplay(), 5000);
	}
	assertTrue("visible shell was not made active", shell.getDisplay().getActiveShell() == shell);

	/* Test setActive for visible dialog shell. */
	shell2.setActive();
	testShell.setBounds(shell.getBounds());
	testShell.setVisible(true);
	testShell.setActive();
	if (SwtTestUtil.isCocoa) { //workaround for Bug 536564
		drainEventQueue(shell.getDisplay(), 2000);
	}
	assertTrue("visible dialog shell was not made active", testShell.getDisplay().getActiveShell() == testShell);

	/* Test setActive for non-visible shell. */
	shell2.setActive();
	shell.setVisible(false);
	shell.setActive();
	shell2.setText("Shell2: Not active");
	if (SwtTestUtil.isCocoa) { //workaround for Bug 536564
		drainEventQueue(shell.getDisplay(), 2000);
	}
	assertTrue("non-visible shell was made active", shell.getDisplay().getActiveShell() != shell);

	/* Test setActive for non-visible dialog shell. */
	shell2.setActive();
	testShell.setVisible(false);
	testShell.setActive();
	shell2.setText("Shell2: Not active");
	if (SwtTestUtil.isCocoa) { //workaround for Bug 536564
		drainEventQueue(shell.getDisplay(), 2000);
	}
	assertTrue("non-visible dialog shell was made active", testShell.getDisplay().getActiveShell() != testShell);

	shell2.dispose();
}

private static void drainEventQueue(Display display, int millis) {
	if (millis == 0) {
		while (!display.isDisposed() && display.readAndDispatch()) {
		}
		return;
	}
	long end = System.currentTimeMillis() + millis;
	while (!display.isDisposed() && System.currentTimeMillis() < end) {
		if (!display.readAndDispatch ()) {
			try {
				Thread.sleep(10);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}

@Override
@Test
public void test_setEnabledZ() {
	// tested in getEnabled method
}

@Test
public void test_setImeInputModeI() {
	shell.setImeInputMode(SWT.NONE);
	assertTrue(":a:", shell.getImeInputMode() == SWT.NONE);
}

@Override
@Test
public void test_setVisibleZ() {
	shell.setVisible(false);
	assertTrue(":a:", !shell.isVisible());
	shell.setVisible(true);
	assertTrue(":b:", shell.isVisible());
}


/* custom */
@Override
@Test
public void test_getParent () {
	// overriding Control.test_getParent
	assertNull(shell.getParent());
	assertTrue(testShell.getParent() == shell);
}

@Test
public void test_getStyle() {
	// overriding Widget.test_getStyle
	assertTrue("testShell not modeless", (testShell.getStyle () & SWT.MODELESS) == SWT.MODELESS);
	int[] cases = {SWT.MODELESS, SWT.PRIMARY_MODAL, SWT.APPLICATION_MODAL, SWT.SYSTEM_MODAL};
	for (int i = 0; i < cases.length; i++) {
		Shell testShell2 = new Shell(shell, cases[i]);
		assertTrue("shell " + i, (testShell2.getStyle () & cases[i]) == cases[i]);
		testShell2.dispose();
	}
}

@Override
@Test
public void test_isVisible() {
	// overriding Control.test_isVisible
	testShell.setVisible(true);
	assertTrue(testShell.isVisible());
	shell.setVisible(true);
	assertTrue(shell.isVisible());

	testShell.setVisible(true);
	shell.setVisible(true);
	assertTrue("shell.isVisible() a:", shell.isVisible());
	shell.setVisible(false);
	assertTrue("shell.isVisible() b:", !shell.isVisible());
	if (SwtTestUtil.fCheckBogusTestCases)
		assertTrue("testShell.isVisible() c:", !testShell.isVisible());
}

@Override
@Test
public void test_setBoundsIIII() {
	// overridden from Control because Shells have a minimum size
}

@Override
@Test
public void test_setBoundsLorg_eclipse_swt_graphics_Rectangle() {
	// overridden from Control because Shells have a minimum size
//	/* windows */
//	/* note that there is a minimum size for a shell, this test will fail if p1.x < 112 or p1.y < 27 */
//	/* note that there is a maximum size for a shell, this test will fail if p1.x > 1292 or p1.y > 1036 */
//	if (SwtTestUtil.isWindows) {
//		Point p1 = new Point(112, 27);
//		Rectangle r1 = new Rectangle(20, 30, p1.x, p1.y);
//		Rectangle r2;
//		for (int i = 0; i < 11; i++) {
//			testShell.setBounds(r1);
//			r2 = testShell.getBounds();
//			assert("child shell iteration " + i + " set=" + r1 + " get=" + r2, r1.equals(r2));
//			r1.width += 100;
//			r1.height += 100;
//		}
//		r1 = new Rectangle(20, 30, p1.x, p1.y);
//		for (int i = 0; i < 11; i++) {
//			shell.setBounds(r1);
//			r2 = shell.getBounds();
//			assert("parent shell iteration " + i + " set=" + r1 + " get=" + r2, r1.equals(r2));
//			r1.width += 100;
//			r1.height += 100;
//		}
//	}
}

/**
 * Regression test for Bug 436841 - [GTK3] FocusOut/In and Activate/Deactivate
 * events when opening context menu. Only applicable on GTK x11.
 */
@Test
public void test_activateEventSend() {
	if (SwtTestUtil.isGTK && SwtTestUtil.isX11) {
		Shell testShell = new Shell(shell, SWT.SHELL_TRIM);
		testShell.addListener(SWT.Activate, e -> {
			listenerCalled = true;
			});
		testShell.open();
		int[] styles = {SWT.ON_TOP, SWT.APPLICATION_MODAL, SWT.PRIMARY_MODAL, SWT.SYSTEM_MODAL, SWT.NO_TRIM, SWT.BORDER, SWT.SHELL_TRIM};
		for (int i = 0; i < styles.length; i++) {
			Shell childShell = new Shell(testShell, styles[i]);
			listenerCalled = false;
			childShell.open();
			childShell.dispose();
			assertTrue(listenerCalled);
		}
	}
}

/**
 * Regression test for Bug 445900: [GTK] Shell#computeTrim(..) wrong for
 * first invisible shell (editor hovers jump when enriched).
 *
 * Disabled on Wayland as there is no absolute positioning.
 */
@Test
public void test_setBounds() throws Exception {
	if (SwtTestUtil.isX11) {
		Rectangle bounds = new Rectangle(100, 200, 200, 200);
		Rectangle bounds2 = new Rectangle(150, 250, 250, 250);

		StringBuilder log = new StringBuilder();
		int[] styles = { SWT.NO_TRIM, SWT.BORDER, SWT.RESIZE, SWT.TITLE | SWT.BORDER, SWT.TITLE | SWT.RESIZE, SWT.TITLE };
		for (int i = 0; i < styles.length; i++) {
			Shell testShell = new Shell(shell, styles[i]);
			try {
				testShell.setBounds(bounds);
				logUnlessEquals(log, i + ".1: style 0x" + Integer.toHexString(styles[i]), bounds, testShell.getBounds());

				testShell.open();
				logUnlessEquals(IS_GTK_BUG_445900 ? System.out : log, i + ".2: style 0x" + Integer.toHexString(styles[i]), bounds, testShell.getBounds());

				testShell.setBounds(bounds);
				logUnlessEquals(log, i + ".3: style 0x" + Integer.toHexString(styles[i]), bounds, testShell.getBounds());

				testShell.setBounds(bounds2);
				logUnlessEquals(log, i + ".4: style 0x" + Integer.toHexString(styles[i]), bounds2, testShell.getBounds());
			} finally {
				testShell.dispose();
			}
		}
		if (log.length() > 0) {
			Assert.fail(log.toString());
		}
	}
}

private void logUnlessEquals(Appendable log, String message, Rectangle expected, Rectangle actual) throws IOException {
	if (!expected.equals(actual)) {
			log.append(message).append("; expected: ").append(expected.toString())
					.append(", but was: ").append(actual.toString()).append("\n");
	}
}

//TODO This test was not hooked for running with the runTest override. It fails on GTK/Cocoa. Investigate.
public void a_test_setRegion() {
	Region region = new Region();
	region.add(new Rectangle(10, 20, 100, 200));
	// test shell without style SWT.NO_TRIM
	assertNull(":a:", shell.getRegion());
	shell.setRegion(region);
	assertNull(":b:", shell.getRegion());
	shell.setRegion(null);
	assertNull(":c:", shell.getRegion());
	// test shell with style SWT.NO_TRIM
	Display display = shell.getDisplay();
	Shell shell2 = new Shell(display, SWT.NO_TRIM);
	assertNull(":d:", shell2.getRegion());
	shell2.setRegion(region);
	assertTrue(":e:", shell2.getRegion().handle == region.handle);
	region.dispose();
	assertTrue(":f:", shell2.getRegion().isDisposed());
	shell2.setRegion(null);
	assertNull(":g:", shell2.getRegion());
}
@Override
@Test
public void test_setSizeII() {
	/* windows */
	/* note that there is a minimum size for a shell, this test will fail if p1.x < 112 or p1.y < 27 */
	/* note that there is a maximum size for a shell, this test will fail if p1.x > 1292 or p1.y > 1036 */
	if (SwtTestUtil.isWindows) {
		Point newSize = new Point(112, 27);
		for (int i = 0; i < 10; i++) {
			testShell.setSize(newSize.x, newSize.y);
			assertEquals(newSize, testShell.getSize());
			newSize.x += 100;
			newSize.y += 100;
		}
		newSize = new Point(1292, 1036);
		for (int i = 0; i < 10; i++) {
			testShell.setSize(newSize.x, newSize.y);
			assertEquals(newSize, testShell.getSize());
			newSize.x -= 100;
			newSize.y -= 100;
		}
	}

}

@Test
public void test_setSizeCustomResize() {
	/*
	 * Bug 319612: test the case where Shells with SWT.RESIZE and SWT.ON_TOP
	 * were shrinking in size. Only applicable to GTK (both GTK2 and GTK3).
	 */
	if (SwtTestUtil.isGTK) {
		Shell testShell = new Shell (shell, SWT.RESIZE | SWT.ON_TOP);
		Point size = new Point (200, 200);
		testShell.setSize(size);
		testShell.open();
		assertEquals(size, testShell.getSize());
		testShell.dispose();
	}
}

@Override
@Test
public void test_setSizeLorg_eclipse_swt_graphics_Point() {
	/* windows */
	/* note that there is a minimum size for a shell, this test will fail if p1.x < 112 or p1.y < 27 */
	/* note that there is a maximum size for a shell, this test will fail if p1.x > 1292 or p1.y > 1036 */
	if (SwtTestUtil.isWindows) {
		Point newSize = new Point(112, 27);
		for (int i = 0; i < 10; i++) {
			testShell.setSize(newSize);
			assertEquals(newSize, testShell.getSize());
			newSize.x += 100;
			newSize.y += 100;
		}
		newSize = new Point(1292, 1036);
		for (int i = 0; i < 10; i++) {
			testShell.setSize(newSize);
			assertEquals(newSize, testShell.getSize());
			newSize.x -= 100;
			newSize.y -= 100;
		}
	}
}

Shell testShell;

private void createShell() {
	tearDown();
	shell = new Shell();
	testShell = new Shell(shell, SWT.DIALOG_TRIM | SWT.MIN);
	testShell.setSize(100,300);
	testShell.setText("Shell");
	testShell.setLayout(new FillLayout());
	setWidget(testShell);

}

@Test
public void test_consistency_Open() {
	if (SwtTestUtil.fTestConsistency) {
		createShell();
		final Display display = shell.getDisplay();
		List<String> events = new ArrayList<>();
		String[] temp = hookExpectedEvents(testShell, getTestName(), events);
		shell.pack();
		shell.open();
		testShell.pack();
		testShell.open();
		new Thread() {
			@Override
			public void run() {
				display.asyncExec(new Thread() {
					@Override
					public void run() {
						shell.dispose();
					}
				});
		}}.start();

		while(!shell.isDisposed()) {
			if(!display.readAndDispatch()) display.sleep();
		}
		setUp();
		String[] results = events.toArray(new String[events.size()]);
		assertArrayEquals(getTestName() + " event ordering", temp, results);
	}
}

@Test
public void test_consistency_Iconify() {
	createShell();
	consistencyEvent(1, 0, 0, 0, ConsistencyUtility.SHELL_ICONIFY, null, false);
}

@Test
public void test_consistency_Close() {
	createShell();
	consistencyPrePackShell();
	consistencyEvent(0, SWT.ALT, 0, SWT.F4, ConsistencyUtility.DOUBLE_KEY_PRESS);
	createShell();
}

@Test
public void test_consistency_Dispose() {
	createShell();

	final Button button = new Button(testShell, SWT.PUSH);
	button.setText("dispose");
	button.addSelectionListener( new SelectionAdapter() {
		@Override
		public void widgetSelected(SelectionEvent se) {
			button.dispose();
			testShell.dispose();
		}
	});
	List<String> events = new ArrayList<>();
	consistencyPrePackShell(testShell);
	Point pt = button.getLocation();
	consistencyEvent(pt.x, pt.y, 1, 0, ConsistencyUtility.MOUSE_CLICK, events);
	createShell();
}

@Test
public void test_setAlpha() {
	createShell();
	testShell.setAlpha(128);
	int alpha = testShell.getAlpha();
	if (SwtTestUtil.isGTK && alpha == 255) {
		System.out.println("Test_org_eclipse_swt_widgets_Shell.test_setAlpha(): expected 128, but was 255. "
				+ "Probably missing window manager functionality, see bug 498208.");
	} else {
		assertEquals(128, alpha);
	}
	testShell.setAlpha(255);
	assertEquals(255, testShell.getAlpha());
}

@Test // see bug#520488
public void test_childDisposesParent () {
	createShell();
	Shell root = new Shell(testShell, SWT.SHELL_TRIM);
	Shell child = new Shell(root, SWT.SHELL_TRIM);
	child.addListener(SWT.Dispose, e -> root.dispose());
	root.dispose();
}
}
