/******************************************************************************
 * Copyright (c) 2002, 2009 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.gmf.runtime.draw2d.ui.figures;

import org.eclipse.draw2d.Border;
import org.eclipse.draw2d.ChangeEvent;
import org.eclipse.draw2d.ChangeListener;
import org.eclipse.draw2d.Clickable;
import org.eclipse.draw2d.ColorConstants;
import org.eclipse.draw2d.Figure;
import org.eclipse.draw2d.Graphics;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.MarginBorder;
import org.eclipse.draw2d.MouseEvent;
import org.eclipse.draw2d.Panel;
import org.eclipse.draw2d.ScrollBar;
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.gmf.runtime.draw2d.ui.mapmode.IMapMode;
import org.eclipse.gmf.runtime.draw2d.ui.mapmode.MapModeUtil;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.RGB;


/**
 * Customizes the look of GEF's ScrollBar
 * 
 * @author sshaw
 * @author lgrahek
 */
public class ListScrollBar extends ScrollBar {

	/**
	 * @since 1.4
	 */
	protected ArrowButton downButtonFigure;
	/**
	 * @since 1.4
	 */
	protected ArrowButton upButtonFigure;
	ThumbFigure thumb;
	
	/**
	 * @since 1.4
	 */
	protected static Color fillLightGrey = new Color(null, new RGB(240, 240, 240));
	/**
	 * @since 1.4
	 */
	protected static Color outlineLightGrey = new Color(null, new RGB(185, 185, 185));
	/**
	 * @since 1.4
	 */
	protected static Color fillDarkGrey = new Color(null, new RGB(84, 84, 84));
	/**
	 * @since 1.4
	 */
	protected static Color outlineDarkGrey = new Color(null, new RGB(109, 109, 109));
	/**
	 * @since 1.4
	 */
	protected static Color arrowFill = new Color(null, new RGB(187, 187, 187));
	
	/**
	 * @since 1.4
	 */
	protected int mm_1;
	/**
	 * @since 1.4
	 */
	protected int mm_2;

	/**
	 * Constructor
	 * 
	 * @param orientation int that is a define from <code>Orientable</code>
	 * @param insets the <code>Insets> that represents the white space buffer around the scroll bar in 
	 * logical coordinates.
	 * @param size the <code>Dimension</code> that is the size of the scroll bar end boxes in 
	 * logical coordinates
	 * @param stepInc the <code>int</code> space to jump when incrementing the scroll bar one step in
	 * logical coordinates
	 * @param pageInc the <code>int</code> space to jump when paging the scroll bar up or down in
	 * logical coordinates.
	 */
	public ListScrollBar(int orientation, Insets insets, Dimension size, int stepInc, int pageInc) {
		setOrientation(orientation);
		
		Border margin = new MarginBorder(insets.top, insets.left, insets.bottom, insets.right);		
		setBorder(margin);
		setPreferredSize(size.width, size.height);
		setStepIncrement(stepInc);
		setPageIncrement(pageInc);
		if (isHorizontal()) {
			downButtonFigure.setDirection(EAST);
			upButtonFigure.setDirection(WEST);
		} else {
			downButtonFigure.setDirection(SOUTH);
			upButtonFigure.setDirection(NORTH);
		}
		
        IMapMode mm= MapModeUtil.getMapMode();
        mm_1 = mm.DPtoLP(1);
        mm_2 = mm.DPtoLP(2);
	}


	/* (non-Javadoc)
	 * @see org.eclipse.draw2d.ScrollBar#createDefaultDownButton()
	 */
	protected Clickable createDefaultDownButton() {
		downButtonFigure = new ArrowButton();
		downButtonFigure.setBorder(new MarginBorder(new Insets(mm_1)));
		Clickable button = new Clickable(downButtonFigure) {
			@Override
			public boolean hasFocus() {
				return false;
			}		
		};
		button.getModel().addChangeListener(new ChangeListener() {
			public void handleStateChanged(ChangeEvent event) {
				updateDownColors();
			}
		});

		button.setFiringMethod(Clickable.REPEAT_FIRING);
		button.setRolloverEnabled(true);
		return button;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.draw2d.ScrollBar#createDefaultUpButton()
	 */
	protected Clickable createDefaultUpButton() {
		upButtonFigure = new ArrowButton();
		upButtonFigure.setBorder(new MarginBorder(new Insets(mm_1)));
		Clickable button = new Clickable(upButtonFigure) {
			@Override
			public boolean hasFocus() {
				return false;
			}		
		};
		button.getModel().addChangeListener(new ChangeListener() {
			public void handleStateChanged(ChangeEvent event) {
				updateUpColors();
			}
		});

		button.setFiringMethod(Clickable.REPEAT_FIRING);
		button.setRolloverEnabled(true);
		return button;		
	}

	/* (non-Javadoc)
	 * @see org.eclipse.draw2d.ScrollBar#initialize()
	 */
	protected void initialize() {
		super.initialize();
		setPageUp(null);
		setPageDown(null);
		setOpaque(true);
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.draw2d.ScrollBar#createDefaultThumb()
	 */
	protected IFigure createDefaultThumb() {
		thumbDragger = new ThumbDraggerColors();
		
		thumb = new ThumbFigure();
		thumb.setMinimumSize(new Dimension(6, 6));
		return thumb;
	}

	/**
	 * Updates colors of down button depending on its state (highlighted,
	 * pressed, or neither)
	 * @since 1.4
	 */
	protected void updateDownColors() {
		boolean pressed = false;
		boolean highlighted = false;
		if (getValue() < (getMaximum() - getExtent())) {
			// Arrow is scrollable
			if (((Clickable) getButtonDown()).getModel().isPressed()) {
				pressed = true;
			} else if (((Clickable) getButtonDown()).getModel().isMouseOver()) {
				highlighted = true;
			}
		}
		boolean doRepaint = false;
		if (downButtonFigure.isHighlighted() != highlighted) {
			downButtonFigure.setHighlighted(highlighted);
			doRepaint = true;
		}
		if (downButtonFigure.isPressed() != pressed) {
			doRepaint = true;
			downButtonFigure.setPressed(pressed);
		}
		if (doRepaint) {
			// Just changing color, no recalculation of arrow position needed
			downButtonFigure.setRecalculate(false);			
			downButtonFigure.repaint();
		}
	}

	/**
	 * Updates colors of up button depending on its state (highlighted,
	 * pressed, or neither)
	 * @since 1.4
	 */	
	protected void updateUpColors() {
		boolean pressed = false;
		boolean highlighted = false;
		if (getValue() > getMinimum()) {
			// Arrow is scrollable			
			if (((Clickable) getButtonUp()).getModel().isPressed()) {
				pressed = true;
			} else if (((Clickable) getButtonUp()).getModel().isMouseOver()) {
				highlighted = true;
			}
		}
		boolean doRepaint = false;
		if (upButtonFigure.isHighlighted() != highlighted) {
			upButtonFigure.setHighlighted(highlighted);
			doRepaint = true;
		}
		if (upButtonFigure.isPressed() != pressed) {
			doRepaint = true;
			upButtonFigure.setPressed(pressed);
		}
		if (doRepaint) {
			// Just changing color, no recalculation of arrow position needed
			upButtonFigure.setRecalculate(false);
			upButtonFigure.repaint();
		}
	}

	/**
	 * Figure that defines the content for up and down buttons
	 * 
	 * @author lgrahek
	 * 
	 * @since 1.4
	 */
	protected class ArrowButton extends Figure 
	{
		private PointList arrow = new PointList();
		private boolean recalculate;
		private int direction;
		private boolean highlighted;
		private boolean pressed;		

		@Override
		protected void paintFigure(Graphics g) {
			Rectangle r = getBounds();
			// If not pressed, fill with white, so later there will be 1px of
			// white left around outline.
			g.setAlpha(130);
			if (!pressed) {
				g.setBackgroundColor(ColorConstants.white);
				g.fillRectangle(r);
			}						
			// Draw the outline (none when button is pressed)
			if (!pressed) {
				g.setLineWidth(mm_1);
				if (highlighted) {
					g.setForegroundColor(outlineDarkGrey);
				} else {
					g.setForegroundColor(outlineLightGrey);
				}
				g.drawRectangle(r);
			}
						
			// Fill the interior. If not pressed, leave 1px white between outline and filled area.
			if (pressed) {
				g.setBackgroundColor(fillDarkGrey);
			} else {
				g.setBackgroundColor(fillLightGrey);
				r = r.getCopy().shrink(mm_2, mm_2);
			}
			g.fillRectangle(r);		
			
			// Draw the arrow
			if (pressed) {
				r = r.getCopy().shrink(mm_2, mm_2);
			}
			if (recalculate || arrow.size() == 0) {
				int size;
				switch (direction) {
					case EAST:
					case WEST:
						size = Math.min(r.height / 2, r.width);
						r.x += (r.width - size) / 2;
						break;
					default: //North or south
						size = Math.min(r.height, r.width / 2);
						r.y += (r.height - size) / 2;
						break;
				}
				size = Math.max(size, 1); //Size cannot be negative		
				Point head, p2, p3;
				switch (direction) {
					case NORTH:
						head = new Point(r.x + r.width / 2, r.y);
						p2   = new Point (head.x - size, head.y + size);
						p3   = new Point (head.x + size, head.y + size);
						break;
					case SOUTH:
						head = new Point (r.x + r.width / 2, r.y + size);
						p2   = new Point (head.x - size, head.y - size);
						p3   = new Point (head.x + size, head.y - size);
						break;
					case WEST:
						head = new Point (r.x, r.y + r.height / 2);
						p2   = new Point (head.x + size, head.y - size);
						p3   = new Point (head.x + size, head.y + size);
						break;
					default:
						head = new Point(r.x + size, r.y + r.height / 2);
						p2   = new Point(head.x - size, head.y - size);
						p3   = new Point(head.x - size, head.y + size);
		
				}
				arrow.removeAllPoints();
				arrow.addPoint(p2);
				arrow.addPoint(head);
				arrow.addPoint(p3);
			} else {
				// Recalculating with every paint unless explicitly told not too
				recalculate = true;
			}
			if (highlighted) {
				g.setForegroundColor(fillDarkGrey);
			} else if (pressed) {
				g.setAlpha(255);
				g.setForegroundColor(ColorConstants.white);
			} else {
				g.setForegroundColor(arrowFill);
			}
			g.setLineWidth(mm_2);
			g.drawPolyline(arrow);			
		}

		/**
		 * @param value
		 *            one of PositionConstants: EAST, WEST, NORTH, SOUTH that
		 *            determine the arrow direction
		 */
		public void setDirection(int value) {
			direction = value;
		}

		/**
		 * @param value
		 *            false if arrow points do no have to be recalculated (e.g.
		 *            when just changing color)
		 */
		public void setRecalculate(boolean value) {
			recalculate = value;
		}
		
		/**
		 * @param value true if highlighted, false if not
		 */
		public void setHighlighted(boolean value) {
			highlighted = value;
		}
		
		/**
		 * @return true if highlighted, false if not
		 */
		public boolean isHighlighted() {
			return highlighted;
		}		
		
		/**
		 * @param value true if pressed, false if not
		 */
		public void setPressed(boolean value) {
			pressed = value;
		}

		/**
		 * @return true if pressed
		 */
		public boolean isPressed() {
			return pressed;
		}	
	}
	
	/**
	 * Figure that defines scroll bar thumb.
	 * 
	 * @author lgrahek
	 * 
	 * @since 1.4
	 */
	protected class ThumbFigure extends Panel {		
		boolean highlighted;
		boolean pressed;

		@Override
		protected void paintFigure(Graphics g) {
			g.setAlpha(130);
			
			Rectangle r = getBounds().getCopy();
			// Fill with white, so later there will be 1px of
			// white left around outline.
			g.setBackgroundColor(ColorConstants.white);
			g.fillRectangle(getBounds());
			// Draw the outline (none when button is pressed)
			g.setLineWidth(mm_1);
			if (highlighted || pressed) {
				g.setForegroundColor(outlineDarkGrey);
			} else {
				g.setForegroundColor(outlineLightGrey);
			}
			g.drawRectangle(r);
									
			// Fill the interior, while leaving 1px white between outline and filled area.
			r = r.getCopy().shrink(mm_2, mm_2);
			if (pressed) {
				g.setBackgroundColor(fillDarkGrey);
			} else {
				g.setBackgroundColor(fillLightGrey);				
			}
			g.fillRectangle(r);		
		}	

		/**
		 * @param value true if highlighted, false if not
		 */
		public void setHighlighted(boolean value) {
			highlighted = value;
		}
		
		/**
		 * @return true if highlighted, false if not
		 */		
		public boolean isHighlighted() {
			return highlighted;
		}		
		
		/**
		 * @param value true if pressed, false if not
		 */		
		public void setPressed(boolean value) {
			pressed = value;
		}

		/**
		 * @return true if pressed
		 */		
		public boolean isPressed() {
			return pressed;
		}			
	}
	
	/**
	 * Customizes ThumbDragger to set different colors to thumb depending on its
	 * state.
	 * 
	 * @author lgrahek
	 * 
	 * @since 1.4
	 */
	protected class ThumbDraggerColors extends ThumbDragger {
		
		/* (non-Javadoc)
		 * @see org.eclipse.draw2d.MouseMotionListener.Stub#mouseEntered(org.eclipse.draw2d.MouseEvent)
		 */
		@Override
		public void mouseEntered(MouseEvent me) {
			// Set up highlight colors
			thumb.setHighlighted(true);
			thumb.setPressed(false);
			thumb.repaint();
			super.mouseEntered(me);
		}
		
		/* (non-Javadoc)
		 * @see org.eclipse.draw2d.MouseMotionListener.Stub#mouseExited(org.eclipse.draw2d.MouseEvent)
		 */
		@Override
		public void mouseExited(MouseEvent me) {
			// Set up colors: back to no-hover, no-drag colors
			thumb.setHighlighted(false);
			thumb.setPressed(false);
			thumb.repaint();
			super.mouseExited(me);
		}

		/* (non-Javadoc)
		 * @see org.eclipse.draw2d.ScrollBar.ThumbDragger#mousePressed(org.eclipse.draw2d.MouseEvent)
		 */
		@Override
		public void mousePressed(MouseEvent me) {
			// Set up pressed colors
			thumb.setHighlighted(false);
			thumb.setPressed(true);
			thumb.repaint();
			super.mousePressed(me);
		}
	
		/* (non-Javadoc)
		 * @see org.eclipse.draw2d.ScrollBar.ThumbDragger#mouseReleased(org.eclipse.draw2d.MouseEvent)
		 */
		@Override
		public void mouseReleased(MouseEvent me) {
			// Set up colors: back to hover
			thumb.setHighlighted(true);
			thumb.setPressed(false);
			thumb.repaint();
			super.mouseReleased(me);
		}		
	}	
}
