/*******************************************************************************
 * Copyright (c) 2018 Red Hat and others. All rights reserved.
 * The contents of this file are made available under the terms
 * of the GNU Lesser General Public License (LGPL) Version 2.1 that
 * accompanies this distribution (lgpl-v21.txt).  The LGPL is also
 * available at http://www.gnu.org/licenses/lgpl.html.  If the version
 * of the LGPL at http://www.gnu.org is different to the version of
 * the LGPL accompanying this distribution and there is any conflict
 * between the two license versions, the terms of the LGPL accompanying
 * this distribution shall govern.
 *
 * Contributors:
 *     Red Hat - initial API and implementation
 *******************************************************************************/
package org.eclipse.swt.tests.gtk.snippets;

import static org.junit.Assert.assertTrue;

import java.util.concurrent.atomic.AtomicInteger;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.ControlListener;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;


/**
 * Title: Bug 465280 – [GTK3] OS.gtk_widget_get_allocation returns (0,0) for invisible controls
 * How to run: These are jUnits. Select the class and run as jUnits.
 * Bug description: getBounds is not working properly in combination with setVisible.
 * Expected results: All tests should pass, but on Gtk3.8+ the "fails_*" tests fail.
 * GTK version(s): GTK3.8+
 *
 * This is a snippet to validate upcomming bug submission. These will be used to make new jUnits later.
 */
public class Bug497705_setBoundsAfterSetVisible {

	boolean debugShowWidget = false; // true = see shell & widget.  False = tests run without interaction.

	Display display;
	Shell shell ;
	private StringBuilder log;
	private int x;
	private int y;
	private int height;
	private int width;
	private boolean passed;
	private Rectangle bounds;
	Control testControl;

	@Before
	public void setUp() {
		display = Display.getDefault();
		shell = new Shell(display);
		shell.setSize(400, 400);
		log = new StringBuilder("");
		x = 5;
		y = 10;
		height = 100;
		width = 200;
		passed = true;
		testControl = new Button(shell, SWT.PUSH);
	}

	@Test
	public void fails_test2_setBoundsAfterVisibility() { // Works on Gtk2, Fails on Gtk3.
		testControl.setVisible(false);
		testControl.setVisible(true);

		testControl.setBounds(x, y, width, height);

		bounds = testControl.getBounds();
		verifyBounds();
	}
	@Test
	public void fails_test2b_setBoundsInvisibleWidgets() { // Works on Gtk2, Fails on Gtk3.
		testControl.setVisible(false);

		testControl.setBounds(x, y, width, height);

		bounds = testControl.getBounds();
		verifyBounds();
	}


	@Test
	public void fails_test3_setBoundsBetweenVisibility() { // Works on Gtk2, Fails on Gtk3.
		testControl.setVisible(false);
		testControl.setBounds(x, y, width, height);
		testControl.setVisible(true);

		bounds = testControl.getBounds();
		verifyBounds();
	}

	@Test
	public void fails_moveInnvisibleControl() {
		testControl.setBounds(4, 4, 6, 6);

		shell.open(); for (int i = 0; i < 500; i++) display.readAndDispatch();
		testControl.setVisible(false);
		shell.open(); for (int i = 0; i < 500; i++) display.readAndDispatch();
		testControl.setBounds(x, y, width, height);
		shell.open(); for (int i = 0; i < 500; i++) display.readAndDispatch();
		testControl.setVisible(true);
		shell.open(); for (int i = 0; i < 500; i++) display.readAndDispatch();

		bounds = testControl.getBounds(); // Visually looks ok. (width/height), but programatically incorrect getBounds().
		verifyBounds();
	}

	@Test
	public void fails_unecessaryEvents() { // Breaks on Gtk3.8 & onwards
		testControl.setVisible(false);

		AtomicInteger resizeCount = new AtomicInteger(0);
		AtomicInteger moveCount = new AtomicInteger(0);

		testControl.addControlListener(new ControlListener() {
			@Override
			public void controlResized(ControlEvent e) {
				resizeCount.incrementAndGet();
			}
			@Override
			public void controlMoved(ControlEvent e) {
				moveCount.incrementAndGet();
			}
		});

		for (int i = 0; i < 10; i++) {
			testControl.setBounds(x, y, width, height); // Once bounds set, calling same bounds shouldn't trigger SWT.MOVE events.
		}
		if (resizeCount.get() != 1 || moveCount.get() != 1) {
			passed = false;
			log.append("\nERROR:\nExpected only one Resize and one Move event.\nActually received R/M:" + resizeCount.get() + "/" + moveCount.get());
		}
	}

	@Test
	public void works_test1_setBoundsBeforeVisibility () {
		// Note, here you can see that getBounds() does work for widgets that are set to be invisible, but
		// only if setBounds was called before setVisible(false).
		// The problem is inside setBounds, if it's called after setVisible(false), then getBounds() returns wrong output.
		testControl.setBounds(x, y, width, height);

		testControl.setVisible(false);
//		testControl.setVisible(true);   // commenting or uncommenting this doesn't change anything.

		bounds = testControl.getBounds();
		verifyBounds();
	}

	@Test
	public void works_zeroSize() { // There has to be a mechanism by which we set with and height to 0.
		testControl.setBounds(x, y, width, height);
		x = y = width = height = 0;
		testControl.setBounds(x, y, width, height);
		bounds = testControl.getBounds();
		verifyBounds();
	}

	@Test
	public void works_drainingQueue() {
		testControl.setVisible(false);
		testControl.setVisible(true);

		// doing readAndDispatch up *before* 'setBounds()' doesn't make a difference.
		testControl.setBounds(x, y, width, height);

		// doing readAndDispatch *After* setBounds *many times* gives gtk time to update it's cache, and getBounds() returns correct coordinates.
		shell.open();
		for (int i = 0; i < 1000; i++)
			display.readAndDispatch();

		bounds = testControl.getBounds();
		verifyBounds();
	}

	@After
	public void tearDown() {
		if (debugShowWidget) {
			if (!passed) System.err.println(log.toString());

			shell.open();
			while (!shell.isDisposed()) {
				if (!display.readAndDispatch())
					display.sleep();
			}
			display.dispose();
		}
		assertTrue(log.toString(), passed);
	}

	private void verifyBounds() {
		if (bounds.x != x | bounds.y != y) {
			passed = false;
			log.append("\nERROR: x,y do not match. Expected:" + x + "/" + y + " Actual:" + bounds.x + "/" + bounds.y);
		}
		if (bounds.height != height | bounds.width != width) {
			passed = false;
			log.append("\nERROR: width,height do not match. Expected:" + width + "/" + height + " Actual:"
					+ bounds.width + "/" + bounds.height);
		}
	}

}
