/*******************************************************************************
 * Copyright (c) 2000, 2017 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.performance;

import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.List;
import org.eclipse.swt.widgets.ProgressBar;
import org.eclipse.swt.widgets.Scale;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Slider;
import org.eclipse.swt.widgets.TabFolder;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.test.performance.Dimension;
import org.eclipse.test.performance.Performance;
import org.eclipse.test.performance.PerformanceMeter;

import junit.framework.Test;
import junit.framework.TestSuite;
import junit.textui.TestRunner;

/**
 * Automated Performance Test Suite for class org.eclipse.swt.graphics.Color
 *
 * @see org.eclipse.swt.graphics.Color
 */
public class Test_situational extends SwtPerformanceTestCase {

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

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

@Override
protected void setUp() throws Exception {
	super.setUp();
	display = Display.getDefault();
}


/**
 * Situations:
 *
 * - Widget creation
 * - syncExec/asyncExec performance
 * - Image creation
 * - Drawing operations
 * - String measuring
 * - String drawing
 * - Region operations
 * - Fonts
 * - Image loading
 * - Layouts
 */
public void test_createComposites() {
	PerformanceMeter meter = createMeter("Create composites");
	int samples;

    Performance.getDefault();

	// Warm up.
	for(samples = 0; samples < 2; samples++) {
		Shell shell = new Shell(display);
		for (int i = 0; i < 100; i++) {
			Composite c = new Composite(shell, SWT.NONE);
			for (int j = 0; j < 10; j++) {
				new Composite(c, SWT.NONE);
			}
		}
		shell.dispose();
		while(display.readAndDispatch()){/*empty*/}
	}

	for(samples = 0; samples < 100; samples++) {
		Shell shell = new Shell(display);
		meter.start();
		for (int i = 0; i < 100; i++) {
			Composite c = new Composite(shell, SWT.NONE);
			for (int j = 0; j < 50; j++) {
				new Composite(c, SWT.NONE);
			}
		}
		meter.stop();
		shell.dispose();
		while(display.readAndDispatch()){/*empty*/}
	}
	disposeMeter(meter);
}

public void test_createWidgets() {
	PerformanceMeter meter = createMeter("Create composites and widgets");
	int samples;

    Performance performance = Performance.getDefault();
    performance.tagAsGlobalSummary(meter, "Create composites and widgets", Dimension.ELAPSED_PROCESS);

	for(samples = 0; samples < 10; samples++) {
		Shell shell = new Shell(display);
		shell.setLayout(new FillLayout());
		meter.start();
		for (int i = 0; i < 50; i++) {
			Composite c = new Composite(shell, SWT.NONE);
			for (int j = 0; j < 10; j++) {
				new Button(c, SWT.PUSH);
				new Label(c, SWT.NONE);
				new Scale(c, SWT.NONE);
				new ProgressBar(c, SWT.NONE);
				new List(c, SWT.NONE);
				new Text(c, SWT.SINGLE);
				new Text(c, SWT.MULTI);
				new Slider(c, SWT.NONE);
				new Tree(c, SWT.NONE);
				new Table(c, SWT.NONE);
				new TabFolder(c, SWT.NONE);
				new Group(c, SWT.BORDER);
				new Composite(c, SWT.NONE);
			}
		}
		meter.stop();
		shell.dispose();
		while(display.readAndDispatch()){/*empty*/}
	}
	disposeMeter(meter);
}

public void test_layout() {
	PerformanceMeter meter = createMeter("Layout Composites");
	int samples;

	for(samples = 0; samples < 10; samples++) {
		Shell shell = new Shell(display);
		shell.setLayout(new GridLayout());
		String curText = "";
		Label changedLabel;
		Composite parent = shell;
		GridData data;

		for(int i = 0; i < 10; i++) {
			Composite c = new Composite(parent, SWT.BORDER);
			data = new GridData();
			data.horizontalAlignment = GridData.FILL;
			data.verticalAlignment = GridData.FILL;
			c.setLayoutData(data);
			c.setLayout(new GridLayout(2, false));

			Composite c1 = new Composite(c, SWT.BORDER);
			data = new GridData();
			data.horizontalAlignment = GridData.FILL;
			data.verticalAlignment = GridData.FILL;
			data.widthHint = data.heightHint = 2;
			c1.setLayoutData(data);

			Composite c2 = new Composite(c, SWT.BORDER);
			data = new GridData();
			data.horizontalAlignment = GridData.FILL;
			data.verticalAlignment = GridData.FILL;
			data.widthHint = data.heightHint = 2;
			c2.setLayoutData(data);

			Composite c3 = new Composite(c, SWT.BORDER);
			data = new GridData();
			data.horizontalAlignment = GridData.FILL;
			data.verticalAlignment = GridData.FILL;
			data.widthHint = data.heightHint = 2;
			c3.setLayoutData(data);

			Composite c4 = new Composite(c, SWT.BORDER);
			data = new GridData();
			data.horizontalAlignment = GridData.FILL;
			data.verticalAlignment = GridData.FILL;
			c4.setLayoutData(data);
			c4.setLayout(new GridLayout());
			parent = c4;
		}
		changedLabel = new Label(parent, SWT.NONE);
		data = new GridData();
		data.horizontalAlignment = GridData.FILL;
		data.verticalAlignment = GridData.FILL;
		data.grabExcessHorizontalSpace = true;
		data.grabExcessVerticalSpace = true;
		changedLabel.setLayoutData(data);

		shell.open();
		while(display.readAndDispatch()){/*empty*/}
		try { Thread.sleep(2000); } catch (Exception e) {}
		while(display.readAndDispatch()){/*empty*/}
		meter.start();
		for(int numlayouts = 0; numlayouts < 20; numlayouts++) {
			shell.layout(true);
			curText = "!!!" + curText + "!!!\n!";
			changedLabel.setText(curText);
			//while(display.readAndDispatch());
		}
		meter.stop();
		shell.dispose();
		while(display.readAndDispatch()){/*empty*/}
	}
	disposeMeter(meter);
}

public void test_imageDrawing() {
	PerformanceMeter meter = createMeter("Draw on an image");
	int samples;

	for(samples = 0; samples < 10; samples++) {
		int width = 640;
		int height = 480;
		Image image = new Image(display, width, height);
		Color color1 = new Color(display, 0xff, 0, 0xff);
		Color color2 = new Color(display, 0, 0xff, 0xff);
		int x1 = 0, y1 = height/2, x2 = width/2, y2 = 0;
		meter.start();
		GC gc = new GC(image);
		for(int i = 0; i < 10000; i++) {
			x1 = (x1 + 5) % width; y1 = (y1 + 5) % height; x2 = (x2 + 5) % width; y2 = (y2 + 5) % height;
			gc.setLineStyle(SWT.LINE_SOLID);
			gc.drawLine(x1, y1, x2, y2);
			gc.setForeground((i & 1) == 0 ? color1 : color2);
			gc.setBackground((i & 1) == 0 ? color1 : color2);
			gc.fillRectangle(x1, y1, 200, 200);
			gc.drawRoundRectangle(x2, y2, 200, 200, 50, 50);
			gc.setLineStyle(SWT.LINE_DASHDOT);
			gc.drawLine(x2, y1, x1, y2);
		}
		gc.dispose();
		meter.stop();
		image.dispose();
		color1.dispose();
		color2.dispose();
		while(display.readAndDispatch()){/*empty*/}
	}
	disposeMeter(meter);
}

public void test_windowDrawing() {
	PerformanceMeter meter = createMeter("Draw on a window");
	Performance performance= Performance.getDefault();
	performance.setComment(meter,
			Performance.EXPLAINS_DEGRADATION_COMMENT,
			"Regression due to a issue on the Releng test machine");

	int samples;

	for(samples = 0; samples < 10; samples++) {
		int width = 640;
		int height = 480;
		Shell shell = new Shell(display);
		shell.setLayout(new GridLayout());
		Canvas c = new Canvas(shell, SWT.NONE);
		GridData data = new GridData();
		data.widthHint = width;
		data.heightHint = height;
		c.setLayoutData(data);
		shell.pack();
		shell.open();
		while(display.readAndDispatch()){/*empty*/}
		try { Thread.sleep(2000); } catch (Exception e) {}
		while(display.readAndDispatch()){/*empty*/}
		Color color1 = new Color(display, 0xff, 0, 0xff);
		Color color2 = new Color(display, 0, 0xff, 0xff);
		int x1 = 0, y1 = height/2, x2 = width/2, y2 = 0;
		meter.start();
		GC gc = new GC(c);
		for(int i = 0; i < 6000; i++) {
			x1 = (x1 + 5) % width; y1 = (y1 + 5) % height; x2 = (x2 + 5) % width; y2 = (y2 + 5) % height;
			gc.setLineStyle(SWT.LINE_SOLID);
			gc.drawLine(x1, y1, x2, y2);
			gc.setForeground((i & 1) == 0 ? color1 : color2);
			gc.setBackground((i & 1) == 0 ? color1 : color2);
			gc.fillRectangle(x1, y1, 200, 200);
			gc.drawRoundRectangle(x2, y2, 200, 200, 50, 50);
			gc.setLineStyle(SWT.LINE_DASHDOT);
			gc.drawLine(x2, y1, x1, y2);
		}
		gc.dispose();
		meter.stop();
		shell.dispose();
		color1.dispose();
		color2.dispose();
		while(display.readAndDispatch()){/*empty*/}
	}
	disposeMeter(meter);
}

public void test_stringDrawing() {
	PerformanceMeter meter = createMeterWithoutSummary("Draw strings using GC.drawText");
	int samples;

	for(samples = 0; samples < 10; samples++) {
		int width = 640;
		int height = 480;
		Shell shell = new Shell(display);
		shell.setLayout(new GridLayout());
		Canvas c = new Canvas(shell, SWT.NONE);
		GridData data = new GridData();
		data.widthHint = width;
		data.heightHint = height;
		c.setLayoutData(data);
		shell.pack();
		shell.open();
		while(display.readAndDispatch()){/*empty*/}
		try { Thread.sleep(2000); } catch (Exception e) {}
		while(display.readAndDispatch()){/*empty*/}
		Color color1 = new Color(display, 0xff, 0, 0xff);
		Color color2 = new Color(display, 0, 0xff, 0xff);
		Font font1 = new Font(display, "Helvetica", 20, SWT.NONE);
		Font font2 = new Font(display, "Helvetica", 10, SWT.BOLD);
		String testString = "The quick \tbr&own SWT jum&ped foxily o\nver the lazy dog.";
		int x1 = 0, y1 = height/2, x2 = width/2, y2 = 0;
		meter.start();
		GC gc = new GC(c);
		for(int i = 0; i < 4000; i++) {
			x1 = (x1 + 5) % width; y1 = (y1 + 5) % height; x2 = (x2 + 5) % width; y2 = (y2 + 5) % height;
			gc.setFont((i & 1) == 0 ? font1 : font2);
			gc.setForeground((i & 1) == 0 ? color1 : color2);
			gc.textExtent(testString);
			gc.drawText(testString, x2, y1);
			gc.drawText(testString, x2, y1/2, SWT.DRAW_MNEMONIC | SWT.DRAW_TRANSPARENT);
			gc.drawText(testString, x2, y2, true);
		}
		gc.dispose();
		meter.stop();
		shell.dispose();
		color1.dispose();
		color2.dispose();
		font1.dispose();
		font2.dispose();
		while(display.readAndDispatch()){/*empty*/}
	}
	disposeMeter(meter);
}

public void test_fastStringDrawing() {
	PerformanceMeter meter = createMeterWithoutSummary("Draw strings using GC.drawString()");
	int samples;

	for(samples = 0; samples < 10; samples++) {
		int width = 640;
		int height = 480;
		Shell shell = new Shell(display);
		shell.setLayout(new GridLayout());
		Canvas c = new Canvas(shell, SWT.NONE);
		GridData data = new GridData();
		data.widthHint = width;
		data.heightHint = height;
		c.setLayoutData(data);
		shell.pack();
		shell.open();
		while(display.readAndDispatch()){/*empty*/}
		try { Thread.sleep(2000); } catch (Exception e) {}
		while(display.readAndDispatch()){/*empty*/}
		Color color1 = new Color(display, 0xff, 0, 0xff);
		Color color2 = new Color(display, 0, 0xff, 0xff);
		Font font1 = new Font(display, "Helvetica", 20, SWT.NONE);
		Font font2 = new Font(display, "Helvetica", 10, SWT.BOLD);
		String testString = "The quick brown SWT jumped foxily over the lazy dog.";
		int x1 = 0, y1 = height/2, x2 = width/2, y2 = 0;
		meter.start();
		GC gc = new GC(c);
		for(int i = 0; i < 2000; i++) {
			x1 = (x1 + 5) % width; y1 = (y1 + 5) % height; x2 = (x2 + 5) % width; y2 = (y2 + 5) % height;
			gc.setFont((i & 1) == 0 ? font1 : font2);
			gc.setForeground((i & 1) == 0 ? color1 : color2);
			gc.stringExtent(testString);
			gc.drawString(testString, x1, y2);
			gc.drawString(testString, x1, y1, true);
		}
		gc.dispose();
		meter.stop();
		shell.dispose();
		color1.dispose();
		color2.dispose();
		font1.dispose();
		font2.dispose();
		while(display.readAndDispatch()){/*empty*/}
	}
	disposeMeter(meter);
}

public static Test suite() {
	TestSuite suite = new TestSuite();
	java.util.List<String> methodNames = methodNames();
	for (String e : methodNames) {
		suite.addTest(new Test_situational(e));
	}
	return suite;
}
public static java.util.List<String> methodNames() {
	java.util.List<String> methodNames = new java.util.ArrayList<>();
	methodNames.add("test_createComposites");
	methodNames.add("test_createWidgets");
	methodNames.add("test_imageDrawing");
	methodNames.add("test_windowDrawing");
	methodNames.add("test_stringDrawing");
	methodNames.add("test_fastStringDrawing");
	methodNames.add("test_layout");
	return methodNames;
}
@Override
protected void runTest() {
	if (getName().equals("test_createComposites")) test_createComposites();
	else if (getName().equals("test_createWidgets")) test_createWidgets();
	else if (getName().equals("test_layout")) test_layout();
	else if (getName().equals("test_imageDrawing")) test_imageDrawing();
	else if (getName().equals("test_windowDrawing")) test_windowDrawing();
	else if (getName().equals("test_stringDrawing")) test_stringDrawing();
	else if (getName().equals("test_fastStringDrawing")) test_fastStringDrawing();
}

/* custom */
Display display;
}
