/*******************************************************************************
 * 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.io.*;
import java.util.*;

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

/**
 * This class is the main class of the graphics application. Various "tabs" are
 * created and made visible by this class.
 */
public class GraphicsExample {
		
	Composite parent;
	GraphicsTab[] tabs;				// tabs to be found in the application
	GraphicsTab tab;				// the current tab
	GraphicsBackground background;	// used to store information about the background
	
	ToolBar toolBar;				// toolbar that contains backItem and dbItem
	Tree tabList;					// tree structure of tabs
	Text tabDesc;					// multi-line text widget that displays a tab description
	Sash hSash, vSash;
	Canvas canvas;
	Composite tabControlPanel;
	ToolItem backItem, dbItem;		// background, double buffer items
	Menu backMenu;					// background menu item
	
	ArrayList resources;			// stores resources that will be disposed
	ArrayList tabs_in_order;		// stores GraphicsTabs in the order that they appear in the tree
	boolean animate = true;			// whether animation should happen

	static boolean advanceGraphics, advanceGraphicsInit;
	
	static final int MARGIN = 5;
	static final int SASH_SPACING = 1;
	static final int TIMER = 30;
	static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle.getBundle("examples_graphics"); //$NON-NLS-1$

/*
 * Default constructor is needed so that example launcher can create an instance. 
 */
public GraphicsExample() {
	super();
}

public GraphicsExample(final Composite parent) {
	this.parent = parent;
	resources = new ArrayList();
	createControls(parent);
	setTab(tab);
	startAnimationTimer();
}

boolean checkAdvancedGraphics() {
	if (advanceGraphicsInit) return advanceGraphics;
	advanceGraphicsInit = true;
	Display display = parent.getDisplay();
	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 createControls(final Composite parent) {
	tabs = createTabs();
	createToolBar(parent);
	createTabList(parent);
	hSash = new Sash(parent, SWT.HORIZONTAL);
	createTabDesc(parent);	
	vSash = new Sash(parent, SWT.VERTICAL);
	createCanvas(parent);
	createControlPanel(parent);
	
	FormData data;
	FormLayout layout = new FormLayout();
	parent.setLayout(layout);
	
	data = new FormData();
	data.left = new FormAttachment(0, MARGIN);
	data.top = new FormAttachment(0, MARGIN);
	data.right = new FormAttachment(100, -MARGIN);
	toolBar.setLayoutData(data);

	data = new FormData();
	data.left = new FormAttachment(0, MARGIN);
	data.top = new FormAttachment(toolBar, MARGIN);
	data.right = new FormAttachment(vSash, -SASH_SPACING);
	data.bottom = new FormAttachment(hSash, -SASH_SPACING);
	tabList.setLayoutData(data);

	data = new FormData();
	data.left = new FormAttachment(0, MARGIN);
	int offset = parent.getBounds().height - tabDesc.computeSize(SWT.DEFAULT, tabDesc.getLineHeight() * 10).y;
	data.top = new FormAttachment(null, offset);
	data.right = new FormAttachment(vSash, -SASH_SPACING);
	hSash.setLayoutData(data);

	data = new FormData();
	data.left = new FormAttachment(0, MARGIN);
	data.top = new FormAttachment(hSash, SASH_SPACING);
	data.right = new FormAttachment(vSash, -SASH_SPACING);
	data.bottom = new FormAttachment(100, -MARGIN);
	tabDesc.setLayoutData(data);
	
	data = new FormData();
	data.left = new FormAttachment(null, tabList.computeSize(SWT.DEFAULT, SWT.DEFAULT).x + 50);
	data.top = new FormAttachment(toolBar, MARGIN);
	data.bottom = new FormAttachment(100, -MARGIN);
	vSash.setLayoutData(data);

	data = new FormData();
	data.left = new FormAttachment(vSash, SASH_SPACING);
	data.top = new FormAttachment(toolBar, MARGIN);
	data.right = new FormAttachment(100, -MARGIN);
	data.bottom = new FormAttachment(tabControlPanel);
	canvas.setLayoutData(data);

	data = new FormData();
	data.left = new FormAttachment(vSash, SASH_SPACING);
	data.right = new FormAttachment(100, -MARGIN);
	data.bottom = new FormAttachment(100, -MARGIN);
	tabControlPanel.setLayoutData(data);
	
	vSash.addListener(SWT.Selection, new Listener() {
		public void handleEvent(Event event) {
			Rectangle rect = hSash.getParent().getClientArea();
			event.x = Math.min (Math.max (event.x, 60), rect.width - 60);
			System.out.println(event.x);
			if (event.detail != SWT.DRAG) {
				FormData data = (FormData)vSash.getLayoutData();
				data.left.offset = event.x;
				parent.layout(true);
				animate = true;
			} else {
				animate = false;
			}
		}
	});
	hSash.addListener (SWT.Selection, new Listener () {
		public void handleEvent (Event event) {
			Rectangle rect = vSash.getParent().getClientArea();
			event.y = Math.min (Math.max (event.y, tabList.getLocation().y + 60), rect.height - 60);
			if (event.detail != SWT.DRAG) {
				FormData data = (FormData)hSash.getLayoutData();
				data.top.offset = event.y;
				parent.layout(true);
			}
		}
	});
}

void createCanvas(Composite parent) {
	int style = SWT.NO_BACKGROUND;
	if (dbItem.getSelection()) style |= SWT.DOUBLE_BUFFERED;
	canvas = new Canvas(parent, style);
	canvas.addListener(SWT.Paint, new Listener() {
		public void handleEvent(Event event) {
			GC gc = event.gc;
			Rectangle rect = canvas.getClientArea();			
			Device device = gc.getDevice();
			Pattern pattern = null;
			if (background.getBgColor1() != null) {
				if (background.getBgColor2() != null) { // gradient
					pattern = new Pattern(device, 0, 0, rect.width, 
							rect.height,
							background.getBgColor1(),
							background.getBgColor2());
					gc.setBackgroundPattern(pattern);
				} else {	// solid color
					gc.setBackground(background.getBgColor1());
				}
			} else if (background.getBgImage() != null) {		// image
				pattern = new Pattern(device, background.getBgImage());
				gc.setBackgroundPattern(pattern);
			}
			gc.fillRectangle(rect);
			GraphicsTab tab = getTab();
			if (tab != null) tab.paint(gc, rect.width, rect.height);
			if (pattern != null) pattern.dispose();
		}
	});
}

void recreateCanvas() {
	if (dbItem.getSelection() == ((canvas.getStyle() & SWT.DOUBLE_BUFFERED) != 0)) return;
	Object data = canvas.getLayoutData();
	if (canvas != null) canvas.dispose();
	createCanvas(parent);
	canvas.setLayoutData(data);
	parent.layout(true, true);
}

/**
 * Creates the control panel 
 * @param parent
 */
void createControlPanel(Composite parent) {
	Group group;
	tabControlPanel = group = new Group(parent, SWT.NONE);
	group.setText(getResourceString("Settings")); //$NON-NLS-1$
	tabControlPanel.setLayout(new RowLayout());
}

void createToolBar(final Composite parent) {
	final Display display = parent.getDisplay();
	
	toolBar = new ToolBar(parent, SWT.FLAT);
	
	ToolItem  back = new ToolItem(toolBar, SWT.PUSH);
	back.setText(getResourceString("Back")); //$NON-NLS-1$
	back.setImage(loadImage(display, "back.gif")); //$NON-NLS-1$
	
	back.addListener(SWT.Selection, new Listener() {
		public void handleEvent(Event event) {
			int index = tabs_in_order.indexOf(tab) - 1;
			if (index < 0)
				index = tabs_in_order.size() - 1;
			setTab((GraphicsTab)tabs_in_order.get(index));
		}
	});
	
	ToolItem  next = new ToolItem(toolBar, SWT.PUSH);
	next.setText(getResourceString("Next")); //$NON-NLS-1$
	next.setImage(loadImage(display, "next.gif")); //$NON-NLS-1$
	next.addListener(SWT.Selection, new Listener() {
		public void handleEvent(Event event) {
			int index = (tabs_in_order.indexOf(tab) + 1)%tabs_in_order.size();
			setTab((GraphicsTab)tabs_in_order.get(index));
		}
	});
	
	ColorMenu colorMenu = new ColorMenu();
	
	// setup items to be contained in the background menu
	colorMenu.setColorItems(true);
	colorMenu.setPatternItems(checkAdvancedGraphics());
	colorMenu.setGradientItems(checkAdvancedGraphics());
	
	// create the background menu
	backMenu = colorMenu.createMenu(parent, new ColorListener() {
		public void setColor(GraphicsBackground gb) {
			background = gb;
			backItem.setImage(gb.getThumbNail());
			if (canvas != null) canvas.redraw();
		}
	});
	
	// initialize the background to the first item in the menu
	background = (GraphicsBackground)backMenu.getItem(0).getData();
	
	// background tool item
	backItem = new ToolItem(toolBar, SWT.PUSH);
	backItem.setText(getResourceString("Background")); //$NON-NLS-1$
	backItem.setImage(background.getThumbNail());
	backItem.addListener(SWT.Selection, new Listener() {
		public void handleEvent(Event event) {
			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);
			}
		}
	});
	
	// double buffer tool item
	dbItem = new ToolItem(toolBar, SWT.CHECK);
	dbItem.setText(getResourceString("DoubleBuffer")); //$NON-NLS-1$
	dbItem.setImage(loadImage(display, "db.gif")); //$NON-NLS-1$
	dbItem.addListener(SWT.Selection, new Listener() {
		public void handleEvent(Event event) {
			setDoubleBuffered(dbItem.getSelection());
		}
	});
}

/**
 * Creates and returns a thumbnail image.
 * 
 * @param device
 * 			a device
 * @param name
 * 			filename of the image
 */
static Image createThumbnail(Device device, String name) {
	Image image = new Image(device, name);
	Rectangle src = image.getBounds();
	Image result = null;
	if (src.width != 16 || src.height != 16) {
		result = new Image(device, 16, 16);
		GC gc = new GC(result);
		Rectangle dest = result.getBounds();
		gc.drawImage(image, src.x, src.y, src.width, src.height, dest.x, dest.y, dest.width, dest.height);
		gc.dispose();				
	}
	if (result != null) {
		image.dispose();
		return result;
	}
	return image;
}

/**
 * Creates an image based on a gradient pattern made up of two colors.
 * 
 * @param device - The Device
 * @param color1 - The first color used to create the image
 * @param color2 - The second color used to create the image
 * 
 * */
static Image createImage(Device device, Color color1, Color color2, int width, int height) {
	Image image = new Image(device, width, height);
	GC gc = new GC(image);
	Rectangle rect = image.getBounds();
	Pattern pattern = new Pattern(device, rect.x, rect.y, rect.width - 1,
				rect.height - 1, color1, color2);
	gc.setBackgroundPattern(pattern);
	gc.fillRectangle(rect);
	gc.drawRectangle(rect.x, rect.y, rect.width - 1, rect.height - 1);
	gc.dispose();
	pattern.dispose();
	return image;
}

/**
 * Creates an image based on the color provided and returns it.
 * 
 * @param device - The Device
 * @param color - The color used to create the image
 * 
 * */
static Image createImage(Device device, Color color) {
	Image image = new Image(device, 16, 16);
	GC gc = new GC(image);
	gc.setBackground(color);
	Rectangle rect = image.getBounds();
	gc.fillRectangle(rect);
	if (color.equals(device.getSystemColor(SWT.COLOR_BLACK))) {
		gc.setForeground(device.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);
	Arrays.sort(tabs, new Comparator() {
		public int compare(Object tab0, Object tab1) {
			return ((GraphicsTab)tab0).getText().compareTo(((GraphicsTab)tab1).getText());
		}
	});
	HashSet set = new HashSet();
	for (int i = 0; i < tabs.length; i++) {
		GraphicsTab tab = tabs[i];
		set.add(tab.getCategory());
	}
	String[] categories = new String[set.size()];
	set.toArray(categories);
	Arrays.sort(categories);
	for (int i = 0; i < categories.length; i++) {
		String text = categories[i];
		TreeItem item = new TreeItem(tabList, SWT.NONE);
		item.setText(text);
	}
	tabs_in_order = new ArrayList();
	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);
				tabs_in_order.add(tab);
			}
		}
	}
	tabList.addListener(SWT.Selection, new Listener() {
		public void handleEvent(Event event) {
			TreeItem item = (TreeItem)event.item;
			if (item != null) {
				GraphicsTab gt = (GraphicsTab)item.getData();
				if (gt == tab) return;
				setTab((GraphicsTab)item.getData());
			}
		}
	});
}

/**
 * Creates the multi-line text widget that will contain the tab description. 
 * */
void createTabDesc(Composite parent) {
	tabDesc = new Text(parent, SWT.MULTI | SWT.V_SCROLL | SWT.H_SCROLL | SWT.WRAP | SWT.BORDER);
	tabDesc.setEditable(false);
	tabDesc.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE));
}

/**
 * Initializes the GraphicsTab instances that will be contained in GraphicsExample.
 * */
GraphicsTab[] createTabs() {
	return new GraphicsTab[] {
		new LineTab(this),
		new StarPolyTab(this),
		tab = new IntroTab(this),
		new BlackHoleTab(this),
		new AlphaTab(this),
		new BallTab(this),
		new CountDownTab(this),
		new CurvesSWTTab(this),
		new CurvesTab(this),
		new CustomFontTab(this),
		new FontBounceTab(this),
		new GradientTab(this),
		new ImageTransformTab(this),
		new ShapesTab(this),
		new MazeTab(this),
		new RGBTab(this),
		new SpiralTab(this),
		new CardsTab(this),
		new LineCapTab(this),
		new InterpolationTab(this),
		new PathClippingTab(this),
		new PathClippingAnimTab(this),
		new LineStyleTab(this),
		new LineJoinTab(this),
		new RegionClippingTab(this),
		new CustomAlphaTab(this),
		new TextAntialiasTab(this),
		new GraphicAntialiasTab(this),
		new ImageFlipTab(this),
		new PathTab(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 (resources != null) {
		for (int i = 0; i < resources.size(); i++) {
			if (resources.get(i) instanceof Resource) {
				((Resource)resources.get(i)).dispose();
			}
		}
	}
	resources = null;
	
	if (backMenu != null) {
		backMenu.dispose();
		backMenu = 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;
}

/**
 * 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$
	}			
}

static Image loadImage (Device device, Class clazz, String string) {
	InputStream stream = clazz.getResourceAsStream (string);
	if (stream == null) return null;
	Image image = null;
	try {
		image = new Image (device, stream);
	} catch (SWTException ex) {
	} finally {
		try {
			stream.close ();
		} catch (IOException ex) {}
	}
	return image;
}

Image loadImage(Device device, String name) {
	Image image = loadImage(device, GraphicsExample.class, name);
	if (image != null) resources.add(image);
	return image;
}

public Shell open(final Display display) {
	Shell shell = new Shell(display);
	shell.setText(getResourceString("AdvancedGraphics")); //$NON-NLS-1$
	final GraphicsExample example = new GraphicsExample(shell);
	shell.addListener(SWT.Close, new Listener() {
		public void handleEvent(Event event) {
			example.dispose();
		}
	});	
	shell.open();
	return shell;
}

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

/**
 * Sets wheter the canvas is double buffered or not.
 */
public void setDoubleBuffered(boolean doubleBuffered) {
	dbItem.setSelection(doubleBuffered);
	recreateCanvas();
}

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

/**
 * Sets the current tab.
 */
public void setTab(GraphicsTab tab) {
	Control[] children = tabControlPanel.getChildren();
	for (int i = 0; i < children.length; i++) {
		Control control = children[i];
		control.dispose();
	}
	if (this.tab != null) this.tab.dispose();
	this.tab = tab;
	if (tab != null) {
		setDoubleBuffered(tab.getDoubleBuffered());
		tab.createControlPanel(tabControlPanel);
		tabDesc.setText(tab.getDescription());
	} else {
		tabDesc.setText("");
	}
	FormData data = (FormData)tabControlPanel.getLayoutData();
	children = tabControlPanel.getChildren();
	if (children.length != 0) {
		data.top = null;
	} else {
		data.top = new FormAttachment(100, -MARGIN);
	}
	parent.layout(true, true);
	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();
}

/**
 * Starts the animation if the animate flag is set.
 */
void startAnimationTimer() {
	final Display display = parent.getDisplay();
	display.timerExec(TIMER, new Runnable() {
		public void run() {
			if (canvas.isDisposed()) return;
			int timeout = TIMER;
			GraphicsTab tab = getTab();
			if (tab instanceof AnimatedGraphicsTab) {
				AnimatedGraphicsTab animTab = (AnimatedGraphicsTab) tab;	
				if (animate && animTab.getAnimation()) {
					Rectangle rect = canvas.getClientArea();
					animTab.next(rect.width, rect.height);
					canvas.redraw();
					canvas.update();
				}
				timeout =  animTab.getAnimationTime();
			}
			display.timerExec(timeout, this);
		}
	});
}

public static void main(String[] args) {
	Display display = new Display();
	Shell shell = new GraphicsExample().open(display);
	while (shell != null && !shell.isDisposed()) {
		if (!display.readAndDispatch())
			display.sleep();
	}
	display.dispose();
}
}
