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

import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;

import org.eclipse.draw2d.Animation;
import org.eclipse.draw2d.Border;
import org.eclipse.draw2d.BorderLayout;
import org.eclipse.draw2d.ButtonModel;
import org.eclipse.draw2d.ChangeEvent;
import org.eclipse.draw2d.ChangeListener;
import org.eclipse.draw2d.Clickable;
import org.eclipse.draw2d.ColorConstants;
import org.eclipse.draw2d.CompoundBorder;
import org.eclipse.draw2d.Figure;
import org.eclipse.draw2d.FigureUtilities;
import org.eclipse.draw2d.Graphics;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.Label;
import org.eclipse.draw2d.LayoutManager;
import org.eclipse.draw2d.MarginBorder;
import org.eclipse.draw2d.MouseEvent;
import org.eclipse.draw2d.MouseListener;
import org.eclipse.draw2d.MouseMotionListener;
import org.eclipse.draw2d.SchemeBorder;
import org.eclipse.draw2d.ScrollPane;
import org.eclipse.draw2d.Toggle;
import org.eclipse.draw2d.ToolbarLayout;
import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.Insets;
import org.eclipse.draw2d.geometry.Rectangle;

import org.eclipse.gef.internal.ui.palette.PaletteColorUtil;
import org.eclipse.gef.ui.palette.PaletteViewerPreferences;
import org.eclipse.gef.ui.palette.editparts.PaletteToolbarLayout;

/**
 * @author Pratik Shah
 */
public class DrawerFigure extends Figure {

	/** Foreground color constant **/
	protected static final Color FG_COLOR = FigureUtilities.mixColors(
			PaletteColorUtil.WIDGET_NORMAL_SHADOW,
			PaletteColorUtil.WIDGET_BACKGROUND);

	/** Scrollpane border constant for icon and column layout mode **/
	protected static final Border SCROLL_PANE_BORDER = new MarginBorder(2, 2,
			2, 2);
	/** Scrollpane border constant for list and details layout mode **/
	protected static final Border SCROLL_PANE_LIST_BORDER = new MarginBorder(2,
			0, 2, 0);
	/** Title margin border constant **/
	protected static final Border TITLE_MARGIN_BORDER = new MarginBorder(4, 2,
			2, 2);
	/** Toggle button border constant **/
	protected static final Border TOGGLE_BUTTON_BORDER = new RaisedBorder();
	/** Tooltip border constant **/
	protected static final Border TOOLTIP_BORDER = new CompoundBorder(
			new SchemeBorder(SchemeBorder.SCHEMES.RAISED()),
			new MarginBorder(1));
	private Toggle collapseToggle;
	private Label drawerLabel, tipLabel;

	private boolean addedScrollpane = false;
	private int layoutMode = -1;
	private PinFigure pinFigure;
	private ScrollPane scrollpane;
	private boolean showPin = true, skipNextEvent;
	private EditPartTipHelper tipHelper;

	/**
	 * This is the figure for the entire drawer label button.
	 */
	private class CollapseToggle extends Toggle {

		public CollapseToggle(IFigure contents) {
			super(contents);
			setSelected(true);
			setRequestFocusEnabled(true);
			addChangeListener(new ChangeListener() {

				public void handleStateChanged(ChangeEvent e) {
					if (e.getPropertyName().equals(
							ButtonModel.SELECTED_PROPERTY)) {
						Animation.markBegin();
						handleExpandStateChanged();
						Animation.run(150);
					}
					// RAP [am] no mouse over
					// } else if (e.getPropertyName().equals(
					// ButtonModel.MOUSEOVER_PROPERTY)) {
					// repaint();
					// }
					// RAPEND: [am]
				}
			});
		}

		public IFigure getToolTip() {
			return buildTooltip();
		}

		protected void paintFigure(Graphics g) {
			super.paintFigure(g);
			Rectangle r = Rectangle.getSINGLETON();
			r.setBounds(getBounds());

			// draw top border of drawer figure
			g.setForegroundColor(PaletteColorUtil.WIDGET_NORMAL_SHADOW);
			g.drawLine(r.getTopLeft(), r.getTopRight());
			g.setForegroundColor(ColorConstants.white());
			g.drawLine(r.getTopLeft().getTranslated(0, 1), r.getTopRight()
					.getTranslated(0, 1));
			r.crop(new Insets(2, 0, 0, 0));
			if (isExpanded()) {
				g.setForegroundColor(PaletteColorUtil.WIDGET_BACKGROUND_NORMAL_SHADOW_65);
				g.drawLine(r.getLocation(), r.getTopRight());
				r.crop(new Insets(1, 0, 0, 0));
			}

			// draw bottom border of drawer figure
			if (!isExpanded()) {
				g.setForegroundColor(ColorConstants.white());
				g.drawLine(r.getBottomLeft().getTranslated(0, -1), r
						.getBottomRight().getTranslated(0, -1));
				r.crop(new Insets(0, 0, 1, 0));
			}

			paintToggleGradient(g, r);

		}
	}

	/**
	 * Constructor
	 * 
	 * @param control
	 *            The Control of the LWS to which this Figure belongs (it is
	 *            used to display the drawer header with an EditPartTipHelper,
	 *            if the header is not completely visible). It can be
	 *            <code>null</code> (the tip won't be displayed).
	 */
	public DrawerFigure(final Control control) {
		/*
		 * A PaletteToolbarLayout is being used here instead of a ToolbarLayout
		 * so that the ScrollPane can be stretched to take up vertical space.
		 * This affects selection and appearance (background color).
		 */
		setLayoutManager(new PaletteToolbarLayout() {
			protected boolean isChildGrowing(IFigure child) {
				int wHint = child.getBounds().width;
				return child.getPreferredSize(wHint, -1).height != child
						.getMinimumSize(wHint, -1).height;
			}
		});

		Figure title = new Figure();
		title.setBorder(TITLE_MARGIN_BORDER);
		BorderLayout borderLayout = new BorderLayout();
		borderLayout.setHorizontalSpacing(2);
		title.setLayoutManager(borderLayout);

		drawerLabel = new Label();
		drawerLabel.setLabelAlignment(Label.LEFT);

		pinFigure = new PinFigure();

		title.add(pinFigure, BorderLayout.RIGHT);
		title.add(drawerLabel, BorderLayout.CENTER);

		collapseToggle = new CollapseToggle(title);

		/*
		 * @TODO:Pratik
		 * 
		 * There is a bug here. Right-click on the name pop-up for the header of
		 * a drawer figure in the palette. This will hide the pop-up.
		 * Right-click again, this time on the collapse toggle, to bring up the
		 * drawer's context menu. Now, left-click on the collapse toggle. The
		 * context menu will disappear, the name pop-up will re-appear, and the
		 * drawer will collapse/expand. If the drawer was in such a position,
		 * that collapsing/expanding it will cause its header to move, the name
		 * pop-up will now be floating over where the collapse toggle used to
		 * be, but is not anymore. To fix this, you can detect the left mouse
		 * click on the collapse toggle and hide the name pop-up then. The
		 * problem is that when you click on the collapseToggle after the
		 * context menu has been brought up, it does not fire a mouse pressed
		 * event. The listener below, that is commented out for now, is never
		 * notified.
		 */
		// collapseToggle.addMouseListener(new MouseListener.Stub(){
		// public void mousePressed(MouseEvent me) {
		// System.out.println("AAA");
		// }
		// });

		add(collapseToggle);
		createScrollpane();
		createHoverHelp(control);
	}

	/**
	 * Paints the background gradient on the drawer toggle figure.
	 * 
	 * @param g
	 *            the graphics object
	 * @param rect
	 *            the rectangle which the background gradient should cover
	 */
	private void paintToggleGradient(Graphics g, Rectangle rect) {
		if (isExpanded()) {
			g.setBackgroundColor(PaletteColorUtil.WIDGET_BACKGROUND_LIST_BACKGROUND_85);
			g.fillRectangle(rect);
		} else if (collapseToggle.getModel().isMouseOver()) {
			Color color1 = PaletteColorUtil.WIDGET_BACKGROUND_LIST_BACKGROUND_60;
			Color color2 = PaletteColorUtil.WIDGET_BACKGROUND_NORMAL_SHADOW_90;
			Color color3 = PaletteColorUtil.WIDGET_BACKGROUND_NORMAL_SHADOW_95;
			Color color4 = PaletteColorUtil.WIDGET_BACKGROUND_LIST_BACKGROUND_90;

			g.setForegroundColor(color1);
			g.setBackgroundColor(color2);
			g.fillGradient(rect.x, rect.y, rect.width, rect.height - 4, true);

			g.setForegroundColor(color2);
			g.setBackgroundColor(color3);
			g.fillGradient(rect.x, rect.bottom() - 4, rect.width, 2, true);

			g.setForegroundColor(color3);
			g.setBackgroundColor(color4);
			g.fillGradient(rect.x, rect.bottom() - 2, rect.width, 2, true);
		} else {
			g.setForegroundColor(PaletteColorUtil.WIDGET_BACKGROUND_LIST_BACKGROUND_85);
			g.setBackgroundColor(PaletteColorUtil.WIDGET_BACKGROUND_NORMAL_SHADOW_45);
			g.fillGradient(rect, true);
		}
	}

	private void createHoverHelp(final Control control) {
		if (control == null) {
			return;
		}
		// If a control was provided, create the tipLabel -- if the text in the
		// header is
		// truncated, it will display it as a tooltip.
		tipLabel = new Label() {
			/**
			 * @see org.eclipse.draw2d.Figure#getToolTip()
			 */
			public IFigure getToolTip() {
				return buildTooltip();
			}

			protected void paintFigure(Graphics graphics) {
				Rectangle r = Rectangle.getSINGLETON();
				r.setBounds(getBounds());
				graphics.pushState();
				paintToggleGradient(graphics, getBounds());
				graphics.popState();
				super.paintFigure(graphics);
			}
		};
		tipLabel.setOpaque(false);
		tipLabel.setBorder(TOOLTIP_BORDER);
		collapseToggle.addMouseMotionListener(new MouseMotionListener.Stub() {
			public void mouseMoved(MouseEvent e) {
				if (!drawerLabel.getBounds().contains(e.getLocation()))
					return;
				if (skipNextEvent) {
					skipNextEvent = false;
					return;
				}
				if (drawerLabel.isTextTruncated()
						&& !EditPartTipHelper.isCurrent(tipHelper)) {
					tipLabel.setText(drawerLabel.getText());
					tipLabel.setIcon(drawerLabel.getIcon());
					tipLabel.setFont(drawerLabel.getFont());
					tipHelper = new EditPartTipHelper(control);
					Rectangle bounds = drawerLabel.getBounds()
							.getExpanded(2, 2);
					drawerLabel.translateToAbsolute(bounds);
					org.eclipse.swt.graphics.Rectangle loc = new org.eclipse.swt.graphics.Rectangle(
							bounds.x, bounds.y, bounds.width, bounds.height);
					loc = Display.getCurrent().map(control, null, loc);
					tipHelper.displayToolTipAt(tipLabel, loc.x, loc.y);
				}
			}
		});
		tipLabel.addMouseListener(new MouseListener.Stub() {
			public void mousePressed(MouseEvent e) {
				if (e.button == 1) {
					Rectangle original = getCollapseToggle().getBounds()
							.getCopy();
					getCollapseToggle().requestFocus();
					setExpanded(!isExpanded());
					// Hide the tip if expanding the drawer causes the collapse
					// toggle to move
					if (!original.equals(getCollapseToggle().getBounds())) {
						tipHelper.hide();
					}
				} else {
					tipHelper.hide();
					if (e.button == 3) {
						skipNextEvent = true;
					}
				}
			}
		});
	}

	private void createScrollpane() {
		scrollpane = new ScrollPane();
		scrollpane.getViewport().setContentsTracksWidth(true);
		scrollpane.setMinimumSize(new Dimension(0, 0));
		scrollpane.setHorizontalScrollBarVisibility(ScrollPane.NEVER);
		scrollpane.setVerticalScrollBar(new PaletteScrollBar());
		scrollpane.getVerticalScrollBar().setStepIncrement(20);
		scrollpane.setLayoutManager(new OverlayScrollPaneLayout());
		scrollpane.setContents(new Figure());
		scrollpane.getContents().setOpaque(true);
		scrollpane.getContents().setBackgroundColor(
				PaletteColorUtil.WIDGET_LIST_BACKGROUND);
	}

	IFigure buildTooltip() {
		return null;
	}

	/**
	 * @return The Clickable that is used to expand/collapse the drawer.
	 */
	public Clickable getCollapseToggle() {
		return collapseToggle;
	}

	/**
	 * @return The content pane for this figure, i.e. the Figure to which
	 *         children can be added.
	 */
	public IFigure getContentPane() {
		return scrollpane.getContents();
	}

	/**
	 * @see Figure#getMinimumSize(int, int)
	 */
	public Dimension getMinimumSize(int wHint, int hHint) {
		/*
		 * Fix related to Bug #35176 The figure returns a minimum size that is
		 * of at least a certain height, so as to prevent each drawer from
		 * getting too small (in which case, the scrollbars cover up the entire
		 * available space).
		 */
		if (isExpanded()) {
			List children = getContentPane().getChildren();
			if (!children.isEmpty()) {
				Dimension result = collapseToggle
						.getPreferredSize(wHint, hHint).getCopy();
				result.height += getContentPane().getInsets().getHeight();
				IFigure child = (IFigure) children.get(0);
				result.height += Math.min(80,
						child.getPreferredSize(wHint, -1).height + 9);
				return result.intersect(getPreferredSize(wHint, hHint));
			}
		}

		return super.getMinimumSize(wHint, hHint);
	}

	/**
	 * Returns the ScrollPane associated with this DrawerFigure
	 * 
	 * @return the ScrollPane
	 */
	public ScrollPane getScrollpane() {
		return scrollpane;
	}

	protected void handleExpandStateChanged() {
		if (isExpanded()) {
			if (scrollpane.getParent() != this)
				add(scrollpane);
		} else {
			if (scrollpane.getParent() == this)
				remove(scrollpane);

			// collapse all pinnable palette stack children that aren't pinned
			for (Iterator iterator = getContentPane().getChildren().iterator(); iterator
					.hasNext();) {
				Object child = iterator.next();
				if (child instanceof PinnablePaletteStackFigure
						&& !((PinnablePaletteStackFigure) child).isPinnedOpen()) {
					((PinnablePaletteStackFigure) child).setExpanded(false);
				}
			}

		}

		if (pinFigure != null) {
			pinFigure.setVisible(isExpanded() && showPin);
		}
	}

	/**
	 * @return <code>true</code> if the drawer is expanded
	 */
	public boolean isExpanded() {
		return collapseToggle.isSelected();
	}

	/**
	 * @return <code>true</code> if the drawer is expanded and is pinned (i.e.,
	 *         it can't be automatically collapsed)
	 */
	public boolean isPinnedOpen() {
		return isExpanded() && pinFigure.isVisible() && pinFigure.isSelected();
	}

	/**
	 * @return <code>true</code> if the drawer is expanded and its pin is
	 *         showing
	 */
	public boolean isPinShowing() {
		return isExpanded() && showPin;
	}

	public void setAnimating(boolean isAnimating) {
		if (isAnimating) {
			if (scrollpane.getParent() != this) {
				addedScrollpane = true;
				add(scrollpane);
			}
			scrollpane.setVerticalScrollBarVisibility(ScrollPane.NEVER);
		} else {
			scrollpane.setVerticalScrollBarVisibility(ScrollPane.AUTOMATIC);
			if (addedScrollpane) {
				remove(scrollpane);
				addedScrollpane = false;
			}
		}
	}

	public void setExpanded(boolean value) {
		collapseToggle.setSelected(value);
	}

	public void setLayoutMode(int layoutMode) {
		if (this.layoutMode == layoutMode) {
			return;
		}

		this.layoutMode = layoutMode;

		LayoutManager manager;
		if (layoutMode == PaletteViewerPreferences.LAYOUT_COLUMNS) {
			manager = new ColumnsLayout();
			getContentPane().setBorder(SCROLL_PANE_BORDER);
		} else if (layoutMode == PaletteViewerPreferences.LAYOUT_ICONS) {
			PaletteContainerFlowLayout fl = new PaletteContainerFlowLayout();
			fl.setMinorSpacing(0);
			fl.setMajorSpacing(0);
			manager = fl;
			getContentPane().setBorder(SCROLL_PANE_BORDER);
		} else {
			manager = new ToolbarLayout();
			getContentPane().setBorder(SCROLL_PANE_LIST_BORDER);
		}
		getContentPane().setLayoutManager(manager);
	}

	/**
	 * Pins or unpins the drawer. The drawer can be pinned open only when it is
	 * expanded. Attempts to pin it when it is collapsed will do nothing.
	 * 
	 * @param pinned
	 *            <code>true</code> if the drawer is to be pinned
	 */
	public void setPinned(boolean pinned) {
		if (!isExpanded() || !showPin) {
			return;
		}

		pinFigure.setSelected(pinned);
	}

	/**
	 * Displays the given text in the drawer's header as its title.
	 * 
	 * @param s
	 *            The title of the drawer
	 */
	public void setTitle(String s) {
		drawerLabel.setText(s);
	}

	/**
	 * Displays the given image in the header as the drawer's icon.
	 * 
	 * @param icon
	 *            The icon for this drawer.
	 */
	public void setTitleIcon(Image icon) {
		drawerLabel.setIcon(icon);
	}

	public void showPin(boolean show) {
		showPin = show;
		handleExpandStateChanged();
	}

}
