/*******************************************************************************
 * Copyright (c) 2000, 2010 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.gef.internal.ui.palette.editparts;

import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.PaletteData;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.widgets.Display;

import org.eclipse.draw2d.Clickable;
import org.eclipse.draw2d.Graphics;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.Label;
import org.eclipse.draw2d.RangeModel;
import org.eclipse.draw2d.ScrollBar;
import org.eclipse.draw2d.ScrollBarLayout;
import org.eclipse.draw2d.Toggle;
import org.eclipse.draw2d.TreeSearch;
import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.Insets;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.draw2d.geometry.PointList;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.draw2d.rap.swt.SWT;

import org.eclipse.gef.internal.ui.palette.PaletteColorUtil;

public final class PaletteScrollBar extends ScrollBar {

	private static final PointList OUTER_DOWN_TRIANGLE = new PointList(3);
	private static final PointList INNER_DOWN_TRIANGLE = new PointList(3);
	private static final PointList OUTER_UP_TRIANGLE = new PointList(3);
	private static final PointList INNER_UP_TRIANGLE = new PointList(3);

	public static final int BUTTON_HEIGHT = 7;
	private static final int BUTTON_WIDTH = 76;
	private static final int SCROLL_TIME = 200;

	private static final Image TRANSPARENCY;

	static {
		Display display = Display.getCurrent();
		PaletteData pData = new PaletteData(0xFF, 0xFF00, 0xFF0000);
		RGB rgb = display.getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW)
				.getRGB();
		int fillColor = pData.getPixel(rgb);
		ImageData iData = new ImageData(1, 1, 24, pData);
		iData.setPixel(0, 0, fillColor);
		iData.setAlpha(0, 0, 200);
		TRANSPARENCY = new Image(display, iData);

		OUTER_DOWN_TRIANGLE.addPoint(new Point(34, 2));
		OUTER_DOWN_TRIANGLE.addPoint(new Point(38, 6));
		OUTER_DOWN_TRIANGLE.addPoint(new Point(42, 2));

		INNER_DOWN_TRIANGLE.addPoint(new Point(35, 2));
		INNER_DOWN_TRIANGLE.addPoint(new Point(37, 5));
		INNER_DOWN_TRIANGLE.addPoint(new Point(41, 2));

		OUTER_UP_TRIANGLE.addPoint(new Point(33, 5));
		OUTER_UP_TRIANGLE.addPoint(new Point(38, 0));
		OUTER_UP_TRIANGLE.addPoint(new Point(42, 5));

		INNER_UP_TRIANGLE.addPoint(new Point(34, 5));
		INNER_UP_TRIANGLE.addPoint(new Point(38, 1));
		INNER_UP_TRIANGLE.addPoint(new Point(42, 5));

	}

	protected Label downLabel;

	protected Label upLabel;

	public PaletteScrollBar() {
		super();
	}

	public boolean containsPoint(int x, int y) {
		return findDescendantAtExcluding(x, y, IdentitySearch.INSTANCE) != null;
	}

	protected Clickable createDefaultDownButton() {
		return createTransparentArrowButton(true);
	}

	protected Clickable createDefaultUpButton() {
		return createTransparentArrowButton(false);
	}

	/**
	 * Creates the figure used for the scrollbar button.
	 * 
	 * @param down
	 *            true if the arrow should be pointing down; false, if it should
	 *            be pointing up.
	 * @return a new <code>Toggle</code> figure for the scroll bar button
	 */
	private Toggle createTransparentArrowButton(final boolean down) {
		Toggle button = new Toggle() {
			protected void paintFigure(Graphics g) {
				// paint background
				if (!getModel().isMouseOver())
					g.drawImage(TRANSPARENCY, new Rectangle(0, 0, 1, 1),
							getBounds());
				else {
					g.setBackgroundColor(getModel().isArmed() ? PaletteColorUtil
							.getSelectedColor() : PaletteColorUtil
							.getHoverColor());
					g.fillRectangle(getBounds());
				}

				// paint triangle
				g.translate(getLocation());
				PointList outerPoints = transpose(down ? OUTER_DOWN_TRIANGLE
						: OUTER_UP_TRIANGLE);
				PointList innerPoints = transpose(down ? INNER_DOWN_TRIANGLE
						: INNER_UP_TRIANGLE);
				g.setBackgroundColor(PaletteColorUtil.WIDGET_LIST_BACKGROUND);
				g.fillPolygon(outerPoints);
				g.setBackgroundColor(PaletteColorUtil.WIDGET_DARK_SHADOW);
				g.fillPolygon(innerPoints);
				g.translate(getLocation().getNegated());
			}
		};
		button.setRolloverEnabled(true);
		button.setRequestFocusEnabled(false);
		return button;
	}

	/**
	 * Transposes a list of points using the <code>transposer</code>.
	 * 
	 * @param origPoints
	 *            the original list of points
	 * @return a new list of transposed points
	 */
	private PointList transpose(PointList origPoints) {
		PointList transposedPoints = new PointList(origPoints.size());
		for (int i = 0; i < origPoints.size(); i++) {
			transposedPoints.addPoint(transposer.t(origPoints.getPoint(i)));
		}
		return transposedPoints;
	}

	public IFigure findFigureAt(int x, int y, TreeSearch search) {
		IFigure result = super.findFigureAt(x, y, search);
		if (result != this)
			return result;
		return null;
	}

	public Dimension getPreferredSize(int wHint, int hHint) {
		return new Dimension(wHint, hHint);
	}

	protected void initialize() {
		super.initialize();
		setLayoutManager(new ScrollBarLayout(transposer) {
			protected Rectangle layoutButtons(ScrollBar scrollBar) {
				Rectangle bounds = transposer.t(scrollBar.getClientArea());
				Dimension buttonSize = new Dimension(BUTTON_WIDTH,
						BUTTON_HEIGHT);

				getButtonUp().setBounds(
						transposer.t(new Rectangle(bounds.getTop()
								.getTranslated(-(buttonSize.width / 2), 0),
								buttonSize)));
				Rectangle r = new Rectangle(bounds.getBottom().getTranslated(
						-(buttonSize.width / 2), -buttonSize.height),
						buttonSize);
				getButtonDown().setBounds(transposer.t(r));
				Rectangle trackBounds = bounds.getCropped(new Insets(
						buttonSize.height, 0, buttonSize.height, 0));
				RangeModel model = scrollBar.getRangeModel();
				getButtonUp()
						.setVisible(model.getValue() != model.getMinimum());
				getButtonDown().setVisible(
						model.getValue() != model.getMaximum()
								- model.getExtent());
				return trackBounds;
			}
		});
		setPageUp(null);
		setPageDown(null);
		setThumb(null);
		setOpaque(false);
	}

	protected void stepDown() {
		timedStep(false);
	}

	protected void stepUp() {
		timedStep(true);
	}

	protected void timedStep(boolean up) {
		int increment = Math.max(getExtent() * 1 / 2, getStepIncrement());
		int value = getValue();
		long startTime = System.currentTimeMillis();
		long elapsedTime = System.currentTimeMillis() - startTime;
		while (elapsedTime < SCROLL_TIME) {
			int step = (int) (increment * elapsedTime / SCROLL_TIME);
			step = up ? value - step : value + step;
			setValue(step);
			getUpdateManager().performUpdate();
			elapsedTime = System.currentTimeMillis() - startTime;
		}
	}

	protected void updateDownLabel() {
		getButtonDown().setVisible(getValue() < (getMaximum() - getExtent()));
	}

	protected void updateUpLabel() {
		getButtonUp().setVisible(getValue() > getMinimum());
	}

}
