/*******************************************************************************
 * Copyright (c) 2000, 2003 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials 
 * are made available under the terms of the Common Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.swt.examples.paint;


import org.eclipse.jface.action.*;
import org.eclipse.jface.resource.*;
import org.eclipse.swt.*;
import org.eclipse.swt.events.*;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.layout.*;
import org.eclipse.swt.widgets.*;
import org.eclipse.ui.*;
import org.eclipse.ui.part.*;

import java.net.*;
import java.util.*;

/**
 * The view for the paint application.
 * All rendering happens inside the area created by createPartControl().
 * 
 * @see ViewPart
 */
public class PaintView extends ViewPart {
	private Display workbenchDisplay;

	// current active settings
	private ToolSettings toolSettings;

	// paint surface for drawing
	private PaintSurface paintSurface;

	// map action ids to useful data
	private HashMap /* of String to PaintTool */ paintToolMap;
	private HashMap /* of String to Integer */ paintFillTypeMap;
	private HashMap /* of String to Integer */ paintLineStyleMap;
	
	/** UI data **/
	// handle of currently active tool IAction on the UI
	private IAction activeToolAction;
	// handle of currently active filltype IAction on the UI
	private IAction activeFillTypeAction;
	// handle of currently active linetype IAction on the UI
	private IAction activeLineStyleAction;

	// handle of active foreground color box Canvas widget
	private Canvas activeForegroundColorCanvas;
	// handle of active background color box Canvas widget
	private Canvas activeBackgroundColorCanvas;
	
	private static final int numPaletteRows = 3;
	private static final int numPaletteCols = 50;

	// shared data	
	private Color paintColorBlack, paintColorWhite; // alias for paintColors[0] and [1]
	private Color[] paintColors;
	private Font paintDefaultFont; // do not free

	/**
	 * Constructs a Paint view.
	 */
	public PaintView() {
	}

	/**
	 * Cleanup
	 */
	public void dispose() {
		if (paintSurface != null) paintSurface.dispose();		
		if (paintColors != null) {
			for (int i = 0; i < paintColors.length; ++i) {
				final Color color = paintColors[i];
				if (color != null) color.dispose();
			}
		}
		paintDefaultFont = null;
		paintColors = null;
		paintSurface = null;
		super.dispose();
	}
	
	/**
	 * Called when we must grab focus.
	 * 
	 * @see org.eclipse.ui.part.ViewPart#setFocus
	 */
	public void setFocus() {
		paintSurface.setFocus();
	}

	/**
	 * Creates the example.
	 * 
	 * @see ViewPart#createPartControl
	 */
	public void createPartControl(Composite parent) {
		/*** Initialize shared data ***/
		workbenchDisplay = parent.getDisplay();
		
		paintColorWhite = new Color(workbenchDisplay, 255, 255, 255);
		paintColorBlack = new Color(workbenchDisplay, 0, 0, 0);
		
		paintDefaultFont = workbenchDisplay.getSystemFont();

		paintColors = new Color[numPaletteCols * numPaletteRows];
		paintColors[0] = paintColorBlack;
		paintColors[1] = paintColorWhite;
		for (int i = 2; i < paintColors.length; i++) {
			paintColors[i] = new Color(workbenchDisplay,
				((i*7)%255),((i*23)%255), ((i*51)%255));
		}

		toolSettings = new ToolSettings();
		toolSettings.commonForegroundColor = paintColorBlack;
		toolSettings.commonBackgroundColor = paintColorWhite;
		toolSettings.commonFont = paintDefaultFont;

		/*** Add toolbar contributions ***/
		final IActionBars actionBars = getViewSite().getActionBars();
		IToolBarManager toolbarManager = actionBars.getToolBarManager();

		toolbarManager.add(new GroupMarker("group.tools"));
		toolbarManager.appendToGroup("group.tools", new SelectPaintToolAction("tool.Pencil"));
		toolbarManager.appendToGroup("group.tools", new SelectPaintToolAction("tool.Airbrush"));
		toolbarManager.appendToGroup("group.tools", new SelectPaintToolAction("tool.Line"));
		toolbarManager.appendToGroup("group.tools", new SelectPaintToolAction("tool.PolyLine"));
		toolbarManager.appendToGroup("group.tools", new SelectPaintToolAction("tool.Rectangle"));
		toolbarManager.appendToGroup("group.tools", new SelectPaintToolAction("tool.RoundedRectangle"));
		toolbarManager.appendToGroup("group.tools", new SelectPaintToolAction("tool.Ellipse"));
		toolbarManager.appendToGroup("group.tools", new SelectPaintToolAction("tool.Text"));
		toolbarManager.add(new Separator());
		toolbarManager.add(new GroupMarker("group.options.fill"));
		toolbarManager.appendToGroup("group.options.fill", new SelectFillTypeAction("fill.None"));
		toolbarManager.appendToGroup("group.options.fill", new SelectFillTypeAction("fill.Outline"));
		toolbarManager.appendToGroup("group.options.fill", new SelectFillTypeAction("fill.Solid"));
		toolbarManager.add(new Separator());
		toolbarManager.add(new GroupMarker("group.options.linestyle"));
		toolbarManager.appendToGroup("group.options.linestyle", new SelectLineStyleAction("linestyle.Solid"));
		toolbarManager.appendToGroup("group.options.linestyle", new SelectLineStyleAction("linestyle.Dash"));
		toolbarManager.appendToGroup("group.options.linestyle", new SelectLineStyleAction("linestyle.Dot"));
		toolbarManager.appendToGroup("group.options.linestyle", new SelectLineStyleAction("linestyle.DashDot"));
		toolbarManager.add(new Separator());
		toolbarManager.add(new GroupMarker("group.options"));
		toolbarManager.appendToGroup("group.options", new SelectFontAction("options.Font"));
		actionBars.updateActionBars();

		/*** Build GUI ***/
		createGUI(parent);

		/*** Set defaults ***/
		setPaintToolByID("tool.Pencil");
		setFillTypeByID("fill.None");
		setLineStyleByID("linestyle.Solid");
		setForegroundColor(paintColorBlack);
		setBackgroundColor(paintColorWhite);
	}

	/**
	 * Creates the GUI.
	 */
	private void createGUI(Composite parent) {
		GridLayout gridLayout;
		GridData gridData;

		/*** Create principal GUI layout elements ***/		
		Composite displayArea = new Composite(parent, SWT.NONE);
		gridLayout = new GridLayout();
		gridLayout.numColumns = 1;
		displayArea.setLayout(gridLayout);

		// Creating these elements here avoids the need to instantiate the GUI elements
		// in strict layout order.  The natural layout ordering is an artifact of using
		// SWT layouts, but unfortunately it is not the same order as that required to
		// instantiate all of the non-GUI application elements to satisfy referential
		// dependencies.  It is possible to reorder the initialization to some extent, but
		// this can be very tedious.
		
		// paint canvas
		final Canvas paintCanvas = new Canvas(displayArea, SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL |
			SWT.NO_REDRAW_RESIZE | SWT.NO_BACKGROUND);
		gridData = new GridData(GridData.FILL_HORIZONTAL | GridData.FILL_VERTICAL);
		paintCanvas.setLayoutData(gridData);
		paintCanvas.setBackground(paintColorWhite);
		
		// color selector frame
		final Composite colorFrame = new Composite(displayArea, SWT.NONE);
		gridData = new GridData(GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_FILL);
		colorFrame.setLayoutData(gridData);

		// tool settings frame
		final Composite toolSettingsFrame = new Composite(displayArea, SWT.NONE);
		gridData = new GridData(GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_FILL);
		toolSettingsFrame.setLayoutData(gridData);

		// status text
		final Text statusText = new Text(displayArea, SWT.BORDER | SWT.SINGLE | SWT.READ_ONLY);
		gridData = new GridData(GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_FILL);
		statusText.setLayoutData(gridData);

		/*** Create the remaining application elements inside the principal GUI layout elements ***/	
		// paintSurface
		paintSurface = new PaintSurface(paintCanvas, statusText, paintColorWhite);

		// paintToolMap
		paintToolMap = new HashMap();
		paintToolMap.put("tool.Pencil", new PencilTool(toolSettings, paintSurface));
		paintToolMap.put("tool.Airbrush", new AirbrushTool(toolSettings, paintSurface));
		paintToolMap.put("tool.Line", new LineTool(toolSettings, paintSurface));
		paintToolMap.put("tool.PolyLine", new PolyLineTool(toolSettings, paintSurface));
		paintToolMap.put("tool.Rectangle", new RectangleTool(toolSettings, paintSurface));
		paintToolMap.put("tool.RoundedRectangle", new RoundedRectangleTool(toolSettings, paintSurface));
		paintToolMap.put("tool.Ellipse", new EllipseTool(toolSettings, paintSurface));
		paintToolMap.put("tool.Text", new TextTool(toolSettings, paintSurface));
		paintToolMap.put("tool.Null", null);

		// paintFillTypeMap
		paintFillTypeMap = new HashMap();
		paintFillTypeMap.put("fill.None", new Integer(ToolSettings.ftNone));
		paintFillTypeMap.put("fill.Outline", new Integer(ToolSettings.ftOutline));
		paintFillTypeMap.put("fill.Solid", new Integer(ToolSettings.ftSolid));

		// paintLineStyleMap
		paintLineStyleMap = new HashMap();
		paintLineStyleMap.put("linestyle.Solid", new Integer(SWT.LINE_SOLID));
		paintLineStyleMap.put("linestyle.Dash", new Integer(SWT.LINE_DASH));
		paintLineStyleMap.put("linestyle.Dot", new Integer(SWT.LINE_DOT));
		paintLineStyleMap.put("linestyle.DashDot", new Integer(SWT.LINE_DASHDOT));

		// colorFrame		
		gridLayout = new GridLayout();
		gridLayout.numColumns = 3;
		gridLayout.marginHeight = 0;
		gridLayout.marginWidth = 0;
		colorFrame.setLayout(gridLayout);

		// activeForegroundColorCanvas, activeBackgroundColorCanvas
		activeForegroundColorCanvas = new Canvas(colorFrame, SWT.BORDER);
		gridData = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
		gridData.heightHint = 24;
		gridData.widthHint = 24;
		activeForegroundColorCanvas.setLayoutData(gridData);

		activeBackgroundColorCanvas = new Canvas(colorFrame, SWT.BORDER);
		gridData = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
		gridData.heightHint = 24;
		gridData.widthHint = 24;
		activeBackgroundColorCanvas.setLayoutData(gridData);

		// paletteCanvas
		final Canvas paletteCanvas = new Canvas(colorFrame, SWT.BORDER | SWT.NO_BACKGROUND);
		gridData = new GridData(GridData.FILL_HORIZONTAL);
		gridData.heightHint = 24;
		paletteCanvas.setLayoutData(gridData);
		paletteCanvas.addListener(SWT.MouseDown, new Listener() {
			public void handleEvent(Event e) {
				Rectangle bounds = paletteCanvas.getClientArea();
				Color color = getColorAt(bounds, e.x, e.y);				
					
				if (e.button == 1) setForegroundColor(color);
				else setBackgroundColor(color);
			}
			private Color getColorAt(Rectangle bounds, int x, int y) {
				if (bounds.height <= 1 && bounds.width <= 1) return paintColorWhite;
				final int row = (y - bounds.y) * numPaletteRows / bounds.height;
				final int col = (x - bounds.x) * numPaletteCols / bounds.width;
				return paintColors[Math.min(Math.max(row * numPaletteCols + col, 0), paintColors.length - 1)];
			}
		});
		Listener refreshListener = new Listener() {
			public void handleEvent(Event e) {
				if (e.gc == null) return;
				Rectangle bounds = paletteCanvas.getClientArea();
				for (int row = 0; row < numPaletteRows; ++row) {
					for (int col = 0; col < numPaletteCols; ++col) {
						final int x = bounds.width * col / numPaletteCols;
						final int y = bounds.height * row / numPaletteRows;
						final int width = Math.max(bounds.width * (col + 1) / numPaletteCols - x, 1);
						final int height = Math.max(bounds.height * (row + 1) / numPaletteRows - y, 1);
						e.gc.setBackground(paintColors[row * numPaletteCols + col]);
						e.gc.fillRectangle(bounds.x + x, bounds.y + y, width, height);
					}
				}
			}
		};
		paletteCanvas.addListener(SWT.Resize, refreshListener);
		paletteCanvas.addListener(SWT.Paint, refreshListener);
		//paletteCanvas.redraw();
		
		// toolSettingsFrame
		gridLayout = new GridLayout();
		gridLayout.numColumns = 4;
		gridLayout.marginHeight = 0;
		gridLayout.marginWidth = 0;
		toolSettingsFrame.setLayout(gridLayout);

		Label label = new Label(toolSettingsFrame, SWT.NONE);
		label.setText(PaintPlugin.getResourceString("settings.AirbrushRadius.text"));

		final Scale airbrushRadiusScale = new Scale(toolSettingsFrame, SWT.HORIZONTAL);
		airbrushRadiusScale.setMinimum(5);
		airbrushRadiusScale.setMaximum(50);
		airbrushRadiusScale.setSelection(toolSettings.airbrushRadius);
		airbrushRadiusScale.setLayoutData(new GridData(GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_FILL));
		airbrushRadiusScale.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				toolSettings.airbrushRadius = airbrushRadiusScale.getSelection();
				updateToolSettings();
			}
		});

		label = new Label(toolSettingsFrame, SWT.NONE);
		label.setText(PaintPlugin.getResourceString("settings.AirbrushIntensity.text"));

		final Scale airbrushIntensityScale = new Scale(toolSettingsFrame, SWT.HORIZONTAL);
		airbrushIntensityScale.setMinimum(1);
		airbrushIntensityScale.setMaximum(100);
		airbrushIntensityScale.setSelection(toolSettings.airbrushIntensity);
		airbrushIntensityScale.setLayoutData(new GridData(GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_FILL));
		airbrushIntensityScale.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				toolSettings.airbrushIntensity = airbrushIntensityScale.getSelection();
				updateToolSettings();
			}
		});
	}
		
	/**
	 * Notifies the tool that its settings have changed.
	 */
	private void updateToolSettings() {
		final PaintTool activePaintTool = paintSurface.getPaintTool();
		if (activePaintTool == null) return;
		
		activePaintTool.endSession();
		activePaintTool.set(toolSettings);
		activePaintTool.beginSession();
	}

	/**
	 * Sets the tool foreground color.
	 * 
	 * @param color the new color to use
	 */
	public void setForegroundColor(Color color) {
		if (activeForegroundColorCanvas != null)
			activeForegroundColorCanvas.setBackground(color);
		toolSettings.commonForegroundColor = color;
		updateToolSettings();
	}

	/**
	 * Set the tool background color.
	 * 
	 * @param color the new color to use
	 */
	public void setBackgroundColor(Color color) {
		if (activeBackgroundColorCanvas != null)
			activeBackgroundColorCanvas.setBackground(color);
		toolSettings.commonBackgroundColor = color;
		updateToolSettings();
	}

	/**
	 * Selects a tool given its ID.
	 */
	public void setPaintToolByID(String id) {
		activeToolAction = handleRadioAction(activeToolAction, id);
		
		final PaintTool paintTool = (PaintTool) paintToolMap.get(id);
		paintSurface.setPaintSession(paintTool);
		updateToolSettings();
	}
	
	/**
	 * Selects a filltype given its ID.
	 */
	public void setFillTypeByID(String id) {
		activeFillTypeAction = handleRadioAction(activeFillTypeAction, id);
		
		final Integer fillType = (Integer) paintFillTypeMap.get(id);
		toolSettings.commonFillType = fillType.intValue();
		updateToolSettings();		
	}

	/**
	 * Selects line type given its ID.
	 */
	public void setLineStyleByID(String id) {
		activeLineStyleAction = handleRadioAction(activeLineStyleAction, id);
		
		final Integer lineType = (Integer) paintLineStyleMap.get(id);
		toolSettings.commonLineStyle = lineType.intValue();
		updateToolSettings();		
	}

	/**
	 * Gets the IAction for an ID belonging to a set of mutually exclusive actions, and
	 * toggles the old action off if necessary.
	 */
	private IAction handleRadioAction(IAction oldAction, String id) {
		IAction action = getActionByID(id);
		if (action != null) {
			if (oldAction != null) oldAction.setChecked(false);
			if (! action.isChecked()) action.setChecked(true);
			return action;
		}
		return oldAction;
	}

	/**
	 * Gets the IAction representing the UI toolbar button with the specified ID.
	 */
	private IAction getActionByID(String id) {
		final IActionBars actionBars = getViewSite().getActionBars();
		IToolBarManager toolbarManager = actionBars.getToolBarManager();
		ActionContributionItem contributionItem = (ActionContributionItem) toolbarManager.find(id);
		if (contributionItem == null) return null;
		return contributionItem.getAction();
	}

	/**
	 * Returns the Display.
	 * 
	 * @return the display we're using
	 */
	public Display getDisplay() {
		return workbenchDisplay;
	}
	
	/**
	 * Action set glue.
	 */
	abstract class PaintAction extends Action {
		public PaintAction(String id) {
			super();
			setId(id);

			try {
				final URL installUrl = PaintPlugin.getDefault().getDescriptor().getInstallURL();
				final URL imageUrl = new URL(installUrl, PaintPlugin.getResourceString(id + ".image"));
				setImageDescriptor(ImageDescriptor.createFromURL(imageUrl));
			} catch (MalformedURLException e) {
				PaintPlugin.logError("", e);	
			}

			setText(PaintPlugin.getResourceString(id + ".label"));
			setToolTipText(PaintPlugin.getResourceString(id + ".tooltip"));
			setDescription(PaintPlugin.getResourceString(id + ".description"));
		}
	}
	class SelectPaintToolAction extends PaintAction {
		public SelectPaintToolAction(String id) { super(id); }
		public int getStyle() { return IAction.AS_CHECK_BOX; }
		public void run() { setPaintToolByID(getId()); }
		
	}
	class SelectFillTypeAction extends PaintAction {
		public SelectFillTypeAction(String id) { super(id); }
		public int getStyle() { return IAction.AS_CHECK_BOX; }
		public void run() { setFillTypeByID(getId()); }
	}
	class SelectLineStyleAction extends PaintAction {
		public SelectLineStyleAction(String id) { super(id); }
		public int getStyle() { return IAction.AS_CHECK_BOX; }
		public void run() { setLineStyleByID(getId()); }
	}
	class SelectFontAction extends PaintAction {
		public SelectFontAction(String id) { super(id); }
		public int getStyle() { return IAction.AS_PUSH_BUTTON; }
		public void run() {
			FontDialog fontDialog = new FontDialog(paintSurface.getShell(), SWT.PRIMARY_MODAL);
			FontData[] fontDatum = toolSettings.commonFont.getFontData();
			if (fontDatum != null && fontDatum.length > 0) {
				fontDialog.setFontList(fontDatum);
			}
			fontDialog.setText(PaintPlugin.getResourceString("options.Font.dialog.title"));

			paintSurface.hideRubberband();
			FontData fontData = fontDialog.open();
			paintSurface.showRubberband();
			if (fontData != null) {
				try {
					Font font = new Font(workbenchDisplay, fontData);
					toolSettings.commonFont = font;
					updateToolSettings();
				} catch (SWTException e) {
				}
			}
		}
	}
}
