/*******************************************************************************
 * Copyright (c) 2008 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.draw2d.examples.swt;

import org.eclipse.draw2d.ColorConstants;
import org.eclipse.draw2d.Ellipse;
import org.eclipse.draw2d.FigureCanvas;
import org.eclipse.draw2d.Polyline;
import org.eclipse.draw2d.RectangleFigure;
import org.eclipse.draw2d.RoundedRectangle;
import org.eclipse.draw2d.Shape;
import org.eclipse.draw2d.Triangle;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.draw2d.rap.swt.SWT;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;

public class ShapeStylesExample {

	static StyleAxis[] styleAxes = new StyleAxis[] {
		new StyleAxis(
			"Line Width",
			new StyleItem[] {
				new StyleItem(0.0f),
				new StyleItem(0.25f),
				new StyleItem(0.5f),
				new StyleItem(1.0f),
				new StyleItem(2.5f),
				new StyleItem(5.0f),
				new StyleItem(10.0f),
			}) {
				public void applyTo(Shape shape, int i) {
					shape.setLineWidthFloat(elements[i].getValue());					
				}
			},
			
		new StyleAxis(
			"Line Style",
			new StyleItem[] {
				new StyleItem("SWT.LINE_SOLID", SWT.LINE_SOLID),
				new StyleItem("SWT.LINE_DASH", SWT.LINE_DASH),
				new StyleItem("SWT.LINE_DASHDOT", SWT.LINE_DASHDOT),
				new StyleItem("SWT.LINE_DASHDOTDOT", SWT.LINE_DASHDOTDOT),
				new StyleItem("SWT.LINE_DOT", SWT.LINE_DOT),
			}) {
				public void applyTo(Shape shape, int i) {
					shape.setLineStyle((int)elements[i].getValue());					
				}
			},
			
		new StyleAxis(
			"Line Cap",
			new StyleItem[] {
				new StyleItem("SWT.CAP_FLAT", SWT.CAP_FLAT),
				new StyleItem("SWT.CAP_ROUND", SWT.CAP_ROUND),
				new StyleItem("SWT.CAP_SQUARE", SWT.CAP_SQUARE),
			}) {
				public void applyTo(Shape shape, int i) {
					shape.setLineCap((int)elements[i].getValue());					
				}
			},
			
		new StyleAxis(
			"Line Miter Limit",
			new StyleItem[] {
				new StyleItem(0.0f),
				new StyleItem(0.5f),
				new StyleItem(1.0f),
				new StyleItem(2.0f),
				new StyleItem(5.0f),
				new StyleItem(10.0f),
				new StyleItem(50.0f),
			}) {
				public void applyTo(Shape shape, int i) {
					shape.setLineMiterLimit(elements[i].getValue());					
				}
			},
		
		new StyleAxis(
			"Line Dash Offset",
			new StyleItem[] {
				new StyleItem(0.0f),
				new StyleItem(0.25f),
				new StyleItem(0.5f),
				new StyleItem(1.0f),
				new StyleItem(2.0f),
				new StyleItem(2.5f),
				new StyleItem(5.0f),
				new StyleItem(10.0f),
			}) {
				public void applyTo(Shape shape, int i) {
					shape.setLineDashOffset(elements[i].getValue());					
				}
			},	
			
		new StyleAxis(
			"Anti-Aliasing",
			new StyleItem[] {
				new StyleItem("SWT.ON", SWT.ON),
				new StyleItem("SWT.OFF", SWT.OFF),
				new StyleItem("SWT.DEFAULT", SWT.DEFAULT),
			}) {
				public void applyTo(Shape shape, int i) {
					shape.setAntialias((int)elements[i].getValue());					
				}
			},

		new StyleAxis(
			"Alpha",
			new StyleItem[] {
				new StyleItem(0),
				new StyleItem(10),
				new StyleItem(50),
				new StyleItem(100),
				new StyleItem(150),
				new StyleItem(200),
				new StyleItem(255),
			}) {
				public void applyTo(Shape shape, int i) {
					shape.setAlpha((int)elements[i].getValue());
				}
			},

		new StyleAxis(
			"Enabled",
			new StyleItem[] {
				new StyleItem("true", 1),
				new StyleItem("false", 0),
			}) {
				public void applyTo(Shape shape, int i) {
					int setting = (int)elements[i].getValue();
					if(setting == 1) {
						shape.setEnabled(true);
					} else {
						shape.setEnabled(false);
					}
				}
			},
	};
	
	static final String[] sampleShapeClasses = new String[] {
			Ellipse.class.getName(), RectangleFigure.class.getName(),
			RoundedRectangle.class.getName(), Triangle.class.getName(),
			Polyline.class.getName()};

	static final String[] defaultLineWidths = new String[] { "0", "0.5", "1",
			"2.5", "5", "10", "30" };
	
	private static Shell shell;
	private static Group styleGrid;

	private static StyleAxis xAxis;
	private static StyleAxis yAxis;
	private static float defaultLineWidth;
	private static Class sampleShape;
	
	
	public static void main(String[] args) {
		
		// create outer shell/window
		Display display = Display.getDefault();
		shell = new Shell(display, SWT.SHELL_TRIM);
		shell.setText("Shape Style Example");
		shell.setLayout(new GridLayout(2, false));
		
		// create control pane
		Group controlPane = new Group(shell, SWT.NONE);
		controlPane.setText("Style Axis Settings");
		controlPane.setLayout(new GridLayout(2, false));
		controlPane.setLayoutData(new GridData(SWT.CENTER, SWT.TOP, true, true, 1, 1));
		
		// x-axis selection
		Label xAxisSelectionLabel = new Label(controlPane, SWT.NONE);
		xAxisSelectionLabel.setText("X Axis");
		final Combo xAxisSelection = new Combo(controlPane, SWT.READ_ONLY);
		for(int i=0; i < styleAxes.length; i++) {
			xAxisSelection.add(styleAxes[i].getName());
		}
		xAxisSelection.addSelectionListener(new SelectionListener() {
			public void widgetSelected(SelectionEvent e) {
				xAxis = styleAxes[xAxisSelection.getSelectionIndex()];
				refreshGrid();
			}
			public void widgetDefaultSelected(SelectionEvent e) {
				widgetSelected(e);
			}
		});
	
		// y-axis selection
		Label yAxisSelectionLabel = new Label(controlPane, SWT.NONE);
		yAxisSelectionLabel.setText("Y Axis");
		final Combo yAxisSelection = new Combo(controlPane, SWT.READ_ONLY);
		for(int i=0; i < styleAxes.length; i++) {
			yAxisSelection.add(styleAxes[i].getName());
		}
		yAxisSelection.addSelectionListener(new SelectionListener() {
			public void widgetSelected(SelectionEvent e) {
				yAxis = styleAxes[yAxisSelection.getSelectionIndex()];
				refreshGrid();
			}
			public void widgetDefaultSelected(SelectionEvent e) {
				widgetSelected(e);
			}
		});		
		
		// shape selection
		Label shapeSelectionLabel = new Label(controlPane, SWT.NONE);
		shapeSelectionLabel.setText("Shape");
		final Combo shapeSelection = new Combo(controlPane, SWT.NONE);
		shapeSelection.setItems(sampleShapeClasses);
		shapeSelection.addSelectionListener(new SelectionListener() {
			public void widgetSelected(SelectionEvent e) {
				try {
					sampleShape = Class.forName(shapeSelection.getText());
				} catch (ClassNotFoundException e1) {
					e1.printStackTrace();
				}
				refreshGrid();
			}
			public void widgetDefaultSelected(SelectionEvent e) {
				widgetSelected(e);
			}
		});				
		
		// default line width selection
		Label lineWidthSelectionLabel = new Label(controlPane, SWT.NONE);
		lineWidthSelectionLabel.setText("Line Width");
		final Combo lineWidthSelection = new Combo(controlPane, SWT.NONE);
		lineWidthSelection.setItems(defaultLineWidths);
		lineWidthSelection.addSelectionListener(new SelectionListener() {
			public void widgetSelected(SelectionEvent e) {
				defaultLineWidth = Float.parseFloat(lineWidthSelection.getText());
				refreshGrid();
			}
			public void widgetDefaultSelected(SelectionEvent e) {
				widgetSelected(e);
			}
		});				
		
		// set defaults		
		xAxis = styleAxes[0];
		yAxis = styleAxes[1];
		defaultLineWidth = Float.parseFloat(defaultLineWidths[4]);
		try {
			sampleShape = Class.forName(sampleShapeClasses[0]);
		} catch (ClassNotFoundException e1) {
			e1.printStackTrace();
		}
		xAxisSelection.select(0);
		yAxisSelection.select(1);
		lineWidthSelection.select(4);
		shapeSelection.select(0);

		// display grid
		refreshGrid();

		shell.open();
		while (!shell.isDisposed()) {
			while (!display.readAndDispatch()) {
				display.sleep();
			}
		}
	}
	
	static void refreshGrid() {
		if(styleGrid != null) {
			styleGrid.dispose();
			shell.pack();
		}
		
		styleGrid = new Group(shell, SWT.NONE);
		styleGrid.setText(xAxis.getName() + " vs. " + yAxis.getName());
		styleGrid.setLayout(new GridLayout(xAxis.getCount() + 1, false));
		styleGrid.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, true, true, 1, 1));

		// put blank label in top left corner
		Label label = new Label(styleGrid, SWT.NONE);

		// add x-axis labels
		for(int x=0; x < xAxis.getCount(); x++) {
			label = new Label(styleGrid, SWT.NONE);
			label.setText(xAxis.getName() + " =\n" + xAxis.getAt(x).getName());
		}
		
		// iterate over the y-axis style settings
		for(int y=1; y < yAxis.getCount() + 1; y++) {
			
			// add y-axis label for this row
			label = new Label(styleGrid, SWT.NONE);
			label.setText(yAxis.getName() + " =\n" + yAxis.getAt(y - 1).getName());
			
			// iterate over the x-axis style settings
			for(int x=1; x < xAxis.getCount() + 1; x++) {
				
				// create a sample shape instance
				Shape shape;
				if(sampleShape == Polyline.class) {
					Polyline poly = new Polyline();
					poly.addPoint(new Point(20, 20));
					poly.addPoint(new Point(50, 80));
					poly.addPoint(new Point(10, 50));
					shape = poly;
				} else {
					try {
						shape = (Shape)sampleShape.getConstructor(null).newInstance(null);
					} catch (Exception e) {
						throw new RuntimeException("Could not find a no args constructor for " + sampleShape.getName());
					}
					shape.setBounds(new Rectangle(0, 0, 100, 75));
				}
				
				// apply default style
				shape.setBackgroundColor(ColorConstants.orange);
				shape.setLineWidthFloat(defaultLineWidth);
				shape.setAntialias(SWT.ON);
				
				// apply styles imposed by each axis
				xAxis.applyTo(shape, x - 1);
				yAxis.applyTo(shape, y - 1);

				FigureCanvas figureBox = new FigureCanvas(styleGrid);
				figureBox.setContents(shape);
			}
		}
		shell.pack();
	}
	
	static abstract class StyleAxis {
		private String name;
		protected StyleItem[] elements;
		
		public StyleAxis(String name, StyleItem[] elements) {
			this.name = name;
			this.elements = elements;
		}

		public int getCount() {
			return elements.length;
		}
		
		public StyleItem getAt(int i) {
			return elements[i];
		}
		
		public String getName() {
			return name;
		}
		
		public abstract void applyTo(Shape shape, int i);
	}
	
	static class StyleItem {
		private String name;
		private float value;
		
		public StyleItem(float value) {
			this.name = Float.toString(value);
			this.value = value;
		}
		
		public StyleItem(String name, float value) {
			this.name = name;
			this.value = value;
		}
		
		public String getName() {
			return name;
		}
		
		public float getValue() {
			return value;
		}
	}
}
