/*******************************************************************************
 * Copyright (c) 2000, 2005 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
 *******************************************************************************/
package org.eclipse.swt.examples.graphics;

import java.util.HashSet;
import java.util.Iterator;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
import java.util.Vector;

import org.eclipse.swt.*;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.layout.*;
import org.eclipse.swt.widgets.*;

public class GraphicsExample {
	
	Composite parent;
	GraphicsTab[] tabs;
	GraphicsTab tab;
	Object[] tabBackground;
	
	boolean animate;
	
	Listener redrawListener;
	
	ToolBar toolBar;
	Tree tabList;
	Canvas canvas;
	Composite controlPanel, tabPanel;
	ToolItem playItem, pauseItem, backItem, dbItem;
	Spinner timerSpinner;
	
	Menu backMenu;
	MenuItem customMI;
	Image customImage;
	Color customColor;
	
	Vector images;
	
	static boolean advanceGraphics, advanceGraphicsInit;
	
	static final int TIMER = 30;
	static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle.getBundle("examples_graphics"); //$NON-NLS-1$

public GraphicsExample(final Composite parent) {
	this.parent = parent;
	redrawListener = new Listener() {
		public void handleEvent(Event e) {
			redraw();
		}
	};
	GridData data;
	GridLayout layout = new GridLayout(3, false);
	layout.horizontalSpacing = 1;
	parent.setLayout(layout);
	tabs = createTabs();	
	images = new Vector();	
	createToolBar(parent);
	createTabList(parent);
	final Sash sash = new Sash(parent, SWT.VERTICAL);
	createTabPanel(parent);
	data = new GridData(SWT.FILL, SWT.CENTER, true, false);
	data.horizontalSpan = 3;
	toolBar.setLayoutData(data);	
	data = new GridData(SWT.CENTER, SWT.FILL, false, true);
	data.widthHint = tabList.computeSize(SWT.DEFAULT, SWT.DEFAULT).x + 50;
	tabList.setLayoutData(data);
	data = new GridData(SWT.CENTER, SWT.FILL, false, true);
	sash.setLayoutData(data);
	data = new GridData(SWT.FILL, SWT.FILL, true, true);
	tabPanel.setLayoutData(data);
	sash.addListener(SWT.Selection, new Listener() {
		public void handleEvent(Event event) {
			if (event.detail != SWT.DRAG) {
				GridData data = (GridData)tabList.getLayoutData();				
				data.widthHint = event.x - tabList.computeTrim(0, 0, 0, 0).width;
				parent.layout(true);
				animate = pauseItem.getEnabled();
			} else {
				animate = false;
			}
		}
	});	
	setTab(tab);
	startAnimationTimer();
}

boolean checkAdvancedGraphics() {
	if (advanceGraphicsInit) return advanceGraphics;
	advanceGraphicsInit = true;
	Display display = Display.getCurrent();
	try {
		Path path = new Path(display);
		path.dispose();
	} catch (SWTException e) {
		Shell shell = display.getActiveShell(), newShell = null;
		if (shell == null) shell = newShell = new Shell(display);
		MessageBox dialog = new MessageBox(shell, SWT.ICON_WARNING | SWT.OK);
		dialog.setText(RESOURCE_BUNDLE.getString("Warning")); //$NON-NLS-1$
		dialog.setMessage(RESOURCE_BUNDLE.getString("LibNotFound")); //$NON-NLS-1$
		dialog.open();
		if (newShell != null) newShell.dispose();
		return false;
	}
	return advanceGraphics = true;
}

void createCanvas(Composite parent) {
	canvas = new Canvas(parent, SWT.NO_BACKGROUND);
	canvas.addListener(SWT.Paint, new Listener() {
		public void handleEvent(Event event) {
			GC gc;
			Rectangle rect = canvas.getClientArea();
			Image buffer = null;
			if (dbItem.getSelection()) {
				buffer = new Image(canvas.getDisplay(), rect);
				gc = new GC(buffer);
			} else {
				gc = event.gc;
			}
			paintBackground(gc, rect);
			GraphicsTab tab = getTab();
			if (tab != null) tab.paint(gc, rect.width, rect.height);
			if (gc != event.gc) gc.dispose();
			if (buffer != null) {
				event.gc.drawImage(buffer, 0, 0);
				buffer.dispose();
			}
		}
	});
}

void createControlPanel(Composite parent) {
	Group group;
	controlPanel = group = new Group(parent, SWT.NONE);
	group.setText(getResourceString("Settings")); //$NON-NLS-1$
	controlPanel.setLayout(new RowLayout());
}

void createTabPanel(Composite parent) {
	tabPanel = new Composite(parent, SWT.NONE);
	GridData data;
	GridLayout layout = new GridLayout(1, false);
	layout.marginHeight = layout.marginWidth = 0;
	tabPanel.setLayout(layout);
	createCanvas(tabPanel);
	createControlPanel(tabPanel);
	data = new GridData(SWT.FILL, SWT.FILL, true, true);
	canvas.setLayoutData(data);	
	data = new GridData(SWT.FILL, SWT.CENTER, true, false);
	controlPanel.setLayoutData(data);
}

void createToolBar(final Composite parent) {
	final Display display = parent.getDisplay();
	
	toolBar = new ToolBar(parent, SWT.FLAT);
	Listener toolBarListener = new Listener() {
		public void handleEvent(Event event) {
			switch (event.type) {
				case SWT.Selection: {
					if (event.widget == playItem) {
						animate = true;
						playItem.setEnabled(!animate);
						pauseItem.setEnabled(animate);
					} else if (event.widget == pauseItem) {
						animate = false;
						playItem.setEnabled(!animate);
						pauseItem.setEnabled(animate);
					} else if (event.widget == backItem) {
						final ToolItem toolItem = (ToolItem) event.widget;
						final ToolBar  toolBar = toolItem.getParent();			
						Rectangle toolItemBounds = toolItem.getBounds();
						Point point = toolBar.toDisplay(new Point(toolItemBounds.x, toolItemBounds.y));
						backMenu.setLocation(point.x, point.y + toolItemBounds.height);
						backMenu.setVisible(true);
					}
				}
				break;
			}
		}
	};
	
	playItem = new ToolItem(toolBar, SWT.PUSH);
	playItem.setText(getResourceString("Play")); //$NON-NLS-1$
	playItem.setImage(loadImage(display, "play.gif")); //$NON-NLS-1$
	playItem.addListener(SWT.Selection, toolBarListener);
	
	pauseItem = new ToolItem(toolBar, SWT.PUSH);
	pauseItem.setText(getResourceString("Pause")); //$NON-NLS-1$
	pauseItem.setImage(loadImage(display, "pause.gif")); //$NON-NLS-1$
	pauseItem.addListener(SWT.Selection, toolBarListener);
	
	backItem = new ToolItem(toolBar, SWT.PUSH);
	backItem.setText(getResourceString("Background")); //$NON-NLS-1$
	backItem.addListener(SWT.Selection, toolBarListener);
	String[] names = new String[]{
		getResourceString("White"), //$NON-NLS-1$
		getResourceString("Black"), //$NON-NLS-1$
		getResourceString("Red"), //$NON-NLS-1$
		getResourceString("Green"), //$NON-NLS-1$
		getResourceString("Blue"), //$NON-NLS-1$
		getResourceString("CustomColor"), //$NON-NLS-1$
	};
	Color[] colors = new Color[]{
		display.getSystemColor(SWT.COLOR_WHITE),	
		display.getSystemColor(SWT.COLOR_BLACK),	
		display.getSystemColor(SWT.COLOR_RED),	
		display.getSystemColor(SWT.COLOR_GREEN),	
		display.getSystemColor(SWT.COLOR_BLUE),
		null,
	};	
	backMenu = new Menu(parent);
	Listener listener = new Listener() {
		public void handleEvent(Event event) {
			MenuItem item = (MenuItem)event.widget;
			if (customMI == item) {
				ColorDialog dialog = new ColorDialog(parent.getShell());
				RGB rgb = dialog.open();
				if (rgb == null) return;
				if (customColor != null) customColor.dispose();
				customColor = new Color(display, rgb);
				if (customImage != null) customImage.dispose();
				customImage = createImage(display, customColor);
				item.setData(new Object[]{customColor, customImage});
				item.setImage(customImage);
			}
			tabBackground = (Object[])item.getData();
			backItem.setImage((Image)tabBackground[1]);
			canvas.redraw();
		}
	};
	for (int i = 0; i < names.length; i++) {
		MenuItem item = new MenuItem(backMenu, SWT.NONE);
		item.setText(names[i]);
		item.addListener(SWT.Selection, listener);
		Image image = null;
		if (colors[i] != null) {
			image = createImage(display, colors[i]);
			images.addElement(image);
			item.setImage(image);
		} else {
			// custom menu item
			customMI = item;
		}
		item.setData(new Object[]{colors[i], image});
		if (tabBackground == null) {
			tabBackground = (Object[])item.getData();
			backItem.setImage((Image)tabBackground[1]);
		}
	}
	
	dbItem = new ToolItem(toolBar, SWT.CHECK);
	dbItem.setText(getResourceString("DoubleBuffer")); //$NON-NLS-1$
	dbItem.setImage(loadImage(display, "db.gif")); //$NON-NLS-1$

	ToolItem separator = new ToolItem(toolBar, SWT.SEPARATOR);
	Composite comp = new Composite(toolBar, SWT.NONE);
	GridData data;
	GridLayout layout = new GridLayout(1, false);
	layout.verticalSpacing = 0;
	layout.marginWidth = layout.marginHeight = 3;
	comp.setLayout(layout);
	timerSpinner = new Spinner(comp, SWT.BORDER | SWT.WRAP);
	data = new GridData(SWT.CENTER, SWT.CENTER, false, false);
	timerSpinner.setLayoutData(data);
	Label label = new Label(comp, SWT.NONE);
	label.setText(getResourceString("Animation")); //$NON-NLS-1$
	data = new GridData(SWT.CENTER, SWT.CENTER, false, false);
	label.setLayoutData(data);
	timerSpinner.setMaximum(1000);
	timerSpinner.setSelection(TIMER);
	timerSpinner.setSelection(TIMER);
	separator.setControl(comp);
	separator.setWidth(comp.computeSize(SWT.DEFAULT, SWT.DEFAULT).x);
}

Image createImage(Display display, Color color) {
	Image image = new Image(display, 16, 16);
	GC gc = new GC(image);
	gc.setBackground(color);
	Rectangle rect = image.getBounds();
	gc.fillRectangle(rect);
	if (color.equals(display.getSystemColor(SWT.COLOR_BLACK))) {
		gc.setForeground(display.getSystemColor(SWT.COLOR_WHITE));
	}
	gc.drawRectangle(rect.x, rect.y, rect.width - 1, rect.height - 1);
	gc.dispose();
	return image;
}

void createTabList(Composite parent) {
	tabList = new Tree(parent, SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER);
	HashSet set = new HashSet();
	for (int i = 0; i < tabs.length; i++) {
		GraphicsTab tab = tabs[i];
		set.add(tab.getCategory());
	}
	for (Iterator iter = set.iterator(); iter.hasNext();) {
		String text = (String) iter.next();
		TreeItem item = new TreeItem(tabList, SWT.NONE);
		item.setText(text);
	}
	TreeItem[] items = tabList.getItems();
	for (int i = 0; i < items.length; i++) {
		TreeItem item = items[i];
		for (int j = 0; j < tabs.length; j++) {
			GraphicsTab tab = tabs[j];
			if (item.getText().equals(tab.getCategory())) {
				TreeItem item1 = new TreeItem(item, SWT.NONE);
				item1.setText(tab.getText());
				item1.setData(tab);
			}
		}
	}
	tabList.addListener(SWT.Selection, new Listener() {
		public void handleEvent(Event event) {
			TreeItem item = (TreeItem)event.item;
			if (item != null) {
				setTab((GraphicsTab)item.getData());
			}
		}
	});
}

GraphicsTab[] createTabs() {
	return new GraphicsTab[] {
		new LineTab(this),
		new StarPolyTab(this),
		tab = new IntroTab(this),
		new BlackWholeTab(this),
	};
}

/**
 * Disposes all resources created by the receiver.
 */
public void dispose() {
	if (tabs != null) {
		for (int i = 0; i < tabs.length; i++) {
			GraphicsTab tab = tabs[i];
			tab.dispose();
		}
	}
	tabs = null;
	if (images != null) {
		for (int i = 0; i < images.size(); i++) {
			((Image)images.elementAt(i)).dispose();
		}
	}
	images = null;
	if (customColor != null) customColor.dispose();
	customColor = null;
	if (customImage != null) customImage.dispose();
	customImage = null;
}

TreeItem findItemByData(TreeItem[] items, Object data) {
	for (int i = 0; i < items.length; i++) {
		TreeItem item = items[i];
		if (item.getData() == data) return item;
		item = findItemByData(item.getItems(), data);
		if (item != null) return item;
	}
	return null;
}

/**
 * Gets the current tab.
 */
public GraphicsTab getTab() {
	return tab;
}

Listener getRedrawListener() {
	return redrawListener;
}

/**
 * Gets a string from the resource bundle.
 * We don't want to crash because of a missing String.
 * Returns the key if not found.
 */
static String getResourceString(String key) {
	try {
		return RESOURCE_BUNDLE.getString(key);
	} catch (MissingResourceException e) {
		return key;
	} catch (NullPointerException e) {
		return "!" + key + "!"; //$NON-NLS-1$ //$NON-NLS-2$
	}			
}

Image loadImage(Display display, String name) {
	Image image = new Image(display, GraphicsExample.class.getResourceAsStream(name));
	images.addElement(image);
	return image;
}

void paintBackground(GC gc, Rectangle rect) {
	gc.setBackground((Color)tabBackground[0]);
	gc.fillRectangle(rect);
}

/**
 * Redraws the current tab.
 */
public void redraw() {
	canvas.redraw();
}

/**
 * Grabs input focus.
 */
public void setFocus() {
	tabList.setFocus();
}

/**
 * Sets the current tab.
 */
public void setTab(GraphicsTab tab) {
	this.tab = tab;
	Control[] children = controlPanel.getChildren();
	for (int i = 0; i < children.length; i++) {
		Control control = children[i];
		control.dispose();
	}
	if (tab != null) {
		tab.createControlPanel(controlPanel);
		animate = tab.isAnimated();
	}
	playItem.setEnabled(!animate);
	pauseItem.setEnabled(animate);
	GridData data = (GridData)controlPanel.getLayoutData();
	children = controlPanel.getChildren();
	data.exclude = children.length == 0;
	controlPanel.setVisible(!data.exclude);
	if (data.exclude) {
		tabPanel.layout();
	} else {
		tabPanel.layout(children);
	}
	if (tab != null) {
		TreeItem[] selection = tabList.getSelection();
		if (selection.length == 0 || selection[0].getData() != tab) {
			TreeItem item = findItemByData(tabList.getItems(), tab);
			if (item != null) tabList.setSelection(new TreeItem[]{item});
		}
	}
	canvas.redraw();
}

void startAnimationTimer() {
	final Display display = Display.getCurrent();
	display.timerExec(timerSpinner.getSelection(), new Runnable() {
		public void run() {
			if (canvas.isDisposed()) return;
			if (animate) {
				GraphicsTab tab = getTab();
				if (tab != null && tab.isAnimated()) {
					Rectangle rect = canvas.getClientArea();
					tab.next(rect.width, rect.height);
					canvas.redraw();
					canvas.update();
				}
			}
			display.timerExec(timerSpinner.getSelection(), this);
		}
	});
}

public static void main(String[] args) {
	Display display = new Display();
	Shell shell = new Shell(display);
	shell.setText(getResourceString("SWTGraphics")); //$NON-NLS-1$
	final GraphicsExample example = new GraphicsExample(shell);
	shell.addListener(SWT.Close, new Listener() {
		public void handleEvent(Event event) {
			example.dispose();
		}
	});	
	shell.open();
	while (!shell.isDisposed()) {
		if (!display.readAndDispatch()) display.sleep();
	}
}
}
