/*******************************************************************************
 * Copyright (c) 2000, 2007 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.ui.internal.forms.widgets;

import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.swt.SWT;
import org.eclipse.swt.dnd.DragSource;
import org.eclipse.swt.dnd.DragSourceEffect;
import org.eclipse.swt.dnd.DragSourceEvent;
import org.eclipse.swt.dnd.DragSourceListener;
import org.eclipse.swt.dnd.DropTarget;
import org.eclipse.swt.dnd.DropTargetListener;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseMoveListener;
import org.eclipse.swt.events.MouseTrackListener;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontMetrics;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Layout;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.ui.forms.IFormColors;
import org.eclipse.ui.forms.widgets.ILayoutExtension;
import org.eclipse.ui.forms.widgets.SizeCache;
import org.eclipse.ui.forms.widgets.Twistie;
import org.eclipse.ui.internal.forms.IMessageToolTipManager;

/**
 * Form heading title.
 */
public class TitleRegion extends Canvas {
	public static final int STATE_NORMAL = 0;
	public static final int STATE_HOVER_LIGHT = 1;
	public static final int STATE_HOVER_FULL = 2;
	private int hoverState;
	private static final int HMARGIN = 1;
	private static final int VMARGIN = 5;
	private static final int SPACING = 5;
	private static final int ARC_WIDTH = 20;
	private static final int ARC_HEIGHT = 20;
	private Image image;
	private BusyIndicator busyLabel;
	private Label titleLabel;
	private SizeCache titleCache;
	private int fontHeight = -1;
	private int fontBaselineHeight = -1;
	private MenuHyperlink menuHyperlink;
	private MenuManager menuManager;
	private boolean dragSupport;
	private int dragOperations;
	private Transfer[] dragTransferTypes;
	private DragSourceListener dragListener;
	private DragSource dragSource;
	private Image dragImage;

	private class HoverListener implements MouseTrackListener,
			MouseMoveListener {

		public void mouseEnter(MouseEvent e) {
			setHoverState(STATE_HOVER_FULL);
		}

		public void mouseExit(MouseEvent e) {
			setHoverState(STATE_NORMAL);
		}

		public void mouseHover(MouseEvent e) {
		}

		public void mouseMove(MouseEvent e) {
			if (e.button > 0)
				setHoverState(STATE_NORMAL);
			else
				setHoverState(STATE_HOVER_FULL);
		}
	}

	private class MenuHyperlink extends Twistie {
		private boolean firstTime = true;

		public MenuHyperlink(Composite parent, int style) {
			super(parent, style);
			setExpanded(true);
		}

		public void setExpanded(boolean expanded) {
			if (firstTime) {
				super.setExpanded(expanded);
				firstTime = false;
			} else {
				Menu menu = menuManager.createContextMenu(menuHyperlink);
				menu.setVisible(true);
			}
		}
	}

	private class TitleRegionLayout extends Layout implements ILayoutExtension {

		protected Point computeSize(Composite composite, int wHint, int hHint,
				boolean flushCache) {
			return layout(composite, false, 0, 0, wHint, hHint, flushCache);
		}

		protected void layout(Composite composite, boolean flushCache) {
			Rectangle carea = composite.getClientArea();
			layout(composite, true, carea.x, carea.y, carea.width,
					carea.height, flushCache);
		}

		private Point layout(Composite composite, boolean move, int x, int y,
				int width, int height, boolean flushCache) {
			int iwidth = width == SWT.DEFAULT ? SWT.DEFAULT : width - HMARGIN
					* 2;
			Point bsize = null;
			Point tsize = null;
			Point msize = null;

			if (busyLabel != null) {
				bsize = busyLabel.computeSize(SWT.DEFAULT, SWT.DEFAULT);
			}
			if (menuManager != null) {
				menuHyperlink.setVisible(!menuManager.isEmpty()
						&& titleLabel.getVisible());
				if (menuHyperlink.getVisible())
					msize = menuHyperlink.computeSize(SWT.DEFAULT, SWT.DEFAULT);
			}
			if (flushCache)
				titleCache.flush();
			titleCache.setControl(titleLabel);
			int twidth = iwidth == SWT.DEFAULT ? iwidth : iwidth - SPACING * 2;
			if (bsize != null && twidth != SWT.DEFAULT)
				twidth -= bsize.x + SPACING;
			if (msize != null && twidth != SWT.DEFAULT)
				twidth -= msize.x + SPACING;
			if (titleLabel.getVisible()) {
				tsize = titleCache.computeSize(twidth, SWT.DEFAULT);
				if (twidth != SWT.DEFAULT) {
					// correct for the case when width hint is larger
					// than the maximum width - this is when the text
					// can be rendered on one line with width to spare
					int maxWidth = titleCache.computeSize(SWT.DEFAULT,
							SWT.DEFAULT).x;
					tsize.x = Math.min(tsize.x, maxWidth);
					// System.out.println("twidth="+twidth+",
					// tsize.x="+tsize.x); //$NON-NLS-1$//$NON-NLS-2$
				}
			} else
				tsize = new Point(0, 0);
			Point size = new Point(width, height);
			if (!move) {
				// compute size
				size.x = tsize.x > 0 ? HMARGIN * 2 + SPACING * 2 + tsize.x : 0;
				size.y = tsize.y;
				if (bsize != null) {
					size.x += bsize.x + SPACING;
					size.y = Math.max(size.y, bsize.y);
				}
				if (msize != null) {
					size.x += msize.x + SPACING;
					size.y = Math.max(size.y, msize.y);
				}
				if (size.y > 0)
					size.y += VMARGIN * 2;
				// System.out.println("Compute size: width="+width+",
				// size.x="+size.x); //$NON-NLS-1$ //$NON-NLS-2$
			} else {
				// position controls
				int xloc = x + HMARGIN + SPACING;
				int yloc = y + VMARGIN;
				if (bsize != null) {
					busyLabel.setBounds(xloc,
							// yloc + height / 2 - bsize.y / 2,
							yloc + (getFontHeight() >= bsize.y ? getFontHeight() : bsize.y) - 1 - bsize.y,
							bsize.x, bsize.y);
					xloc += bsize.x + SPACING;
				}
				if (titleLabel.getVisible()) {
					int tw = width - HMARGIN * 2 - SPACING * 2;
					if (bsize != null)
						tw -= bsize.x + SPACING;
					if (msize != null)
						tw -= msize.x + SPACING;
					titleLabel.setBounds(xloc,
					// yloc + height / 2 - tsize.y / 2,
							yloc, tw, tsize.y);
					// System.out.println("tw="+tw); //$NON-NLS-1$
					xloc += tw + SPACING;
				}
				if (msize != null) {
					menuHyperlink.setBounds(xloc, yloc
							+ getFontHeight() / 2 - msize.y / 2,
							msize.x, msize.y);
				}
			}
			return size;
		}

		public int computeMaximumWidth(Composite parent, boolean changed) {
			return computeSize(parent, SWT.DEFAULT, SWT.DEFAULT, changed).x;
		}

		public int computeMinimumWidth(Composite parent, boolean changed) {
			return computeSize(parent, 0, SWT.DEFAULT, changed).x;
		}
	}

	public TitleRegion(Composite parent) {
		super(parent, SWT.NULL);
		titleLabel = new Label(this, SWT.WRAP);
		titleLabel.setVisible(false);
		titleCache = new SizeCache();
		super.setLayout(new TitleRegionLayout());
		hookHoverListeners();
		addListener(SWT.Dispose, new Listener() {
			public void handleEvent(Event e) {
				if (dragImage != null) {
					dragImage.dispose();
					dragImage = null;
				}
			}
		});
	}

	/* (non-Javadoc)
	 * @see org.eclipse.swt.widgets.Control#forceFocus()
	 */
	public boolean forceFocus() {
		return false;
	}

	private Color getColor(String key) {
		return (Color) ((FormHeading) getParent()).colors.get(key);
	}

	private void hookHoverListeners() {
		HoverListener listener = new HoverListener();
		addMouseTrackListener(listener);
		addMouseMoveListener(listener);
		titleLabel.addMouseTrackListener(listener);
		titleLabel.addMouseMoveListener(listener);
		addPaintListener(new PaintListener() {
			public void paintControl(PaintEvent e) {
				onPaint(e);
			}
		});
	}

	private void onPaint(PaintEvent e) {
		if (hoverState == STATE_NORMAL)
			return;
		GC gc = e.gc;
		Rectangle carea = getClientArea();
		gc.setBackground(getHoverBackground());
		int savedAntialias = gc.getAntialias();
		FormUtil.setAntialias(gc, SWT.ON);
		gc.fillRoundRectangle(carea.x + HMARGIN, carea.y + 2, carea.width
				- HMARGIN * 2, carea.height - 4, ARC_WIDTH, ARC_HEIGHT);
		FormUtil.setAntialias(gc, savedAntialias);
	}

	private Color getHoverBackground() {
		if (hoverState == STATE_NORMAL)
			return null;
		Color color = getColor(hoverState == STATE_HOVER_FULL ? IFormColors.H_HOVER_FULL
				: IFormColors.H_HOVER_LIGHT);
		if (color == null)
			color = getDisplay()
					.getSystemColor(
							hoverState == STATE_HOVER_FULL ? SWT.COLOR_WIDGET_BACKGROUND
									: SWT.COLOR_WIDGET_LIGHT_SHADOW);
		return color;
	}

	public void setHoverState(int state) {
		if (dragSource == null || this.hoverState == state)
			return;
		this.hoverState = state;
		Color color = getHoverBackground();
		titleLabel.setBackground(color != null ? color
				: getColor(FormHeading.COLOR_BASE_BG));
		if (busyLabel != null)
			busyLabel.setBackground(color != null ? color
					: getColor(FormHeading.COLOR_BASE_BG));
		if (menuHyperlink != null)
			menuHyperlink.setBackground(color != null ? color
					: getColor(FormHeading.COLOR_BASE_BG));
		redraw();
	}

	/**
	 * Fully delegates the size computation to the internal layout manager.
	 */
	public final Point computeSize(int wHint, int hHint, boolean changed) {
		return ((TitleRegionLayout) getLayout()).computeSize(this, wHint,
				hHint, changed);
	}

	public final void setLayout(Layout layout) {
		// do nothing
	}

	public Image getImage() {
		return image;
	}

	public void setImage(Image image) {
		this.image = image;
	}

	public void updateImage(Image newImage, boolean doLayout) {
		Image theImage = newImage != null ? newImage : this.image;

		if (theImage != null) {
			ensureBusyLabelExists();
		} else if (busyLabel != null) {
			if (!busyLabel.isBusy()) {
				busyLabel.dispose();
				busyLabel = null;
			}
		}
		if (busyLabel != null) {
			busyLabel.setImage(theImage);
		}
		if (doLayout)
			layout();
	}

	public void updateToolTip(String toolTip) {
		if (busyLabel != null)
			busyLabel.setToolTipText(toolTip);
	}

	public void setBackground(Color bg) {
		super.setBackground(bg);
		titleLabel.setBackground(bg);
		if (busyLabel != null)
			busyLabel.setBackground(bg);
		if (menuHyperlink != null)
			menuHyperlink.setBackground(bg);
	}

	public void setForeground(Color fg) {
		super.setForeground(fg);
		titleLabel.setForeground(fg);
		if (menuHyperlink != null)
			menuHyperlink.setForeground(fg);
	}

	public void setText(String text) {
		if (text != null)
			titleLabel.setText(text);
		titleLabel.setVisible(text != null);
		layout();
		redraw();
	}

	public String getText() {
		return titleLabel.getText();
	}

	public void setFont(Font font) {
		super.setFont(font);
		titleLabel.setFont(font);
		fontHeight = -1;
		fontBaselineHeight = -1;
		layout();
	}

	private void ensureBusyLabelExists() {
		if (busyLabel == null) {
			busyLabel = new BusyIndicator(this, SWT.NULL);
			busyLabel.setBackground(getColor(FormHeading.COLOR_BASE_BG));
			HoverListener listener = new HoverListener();
			busyLabel.addMouseTrackListener(listener);
			busyLabel.addMouseMoveListener(listener);
			if (menuManager != null)
				busyLabel.setMenu(menuManager.createContextMenu(this));
			if (dragSupport)
				addDragSupport(busyLabel, dragOperations, dragTransferTypes, dragListener);
			IMessageToolTipManager mng = ((FormHeading) getParent())
					.getMessageToolTipManager();
			if (mng != null)
				mng.createToolTip(busyLabel, true);
		}
	}

	private void createMenuHyperlink() {
		menuHyperlink = new MenuHyperlink(this, SWT.NULL);
		menuHyperlink.setBackground(getColor(FormHeading.COLOR_BASE_BG));
		menuHyperlink.setDecorationColor(getForeground());
		menuHyperlink.setHoverDecorationColor(getDisplay().getSystemColor(SWT.COLOR_LIST_FOREGROUND));
		HoverListener listener = new HoverListener();
		menuHyperlink.addMouseTrackListener(listener);
		menuHyperlink.addMouseMoveListener(listener);
		if (dragSupport)
			addDragSupport(menuHyperlink, dragOperations, dragTransferTypes, dragListener);
	}

	/**
	 * Sets the form's busy state. Busy form will display 'busy' animation in
	 * the area of the title image.
	 * 
	 * @param busy
	 *            the form's busy state
	 */

	public boolean setBusy(boolean busy) {
		if (busy)
			ensureBusyLabelExists();
		else if (busyLabel == null)
			return false;
		if (busy == busyLabel.isBusy())
			return false;
		busyLabel.setBusy(busy);
		if (busyLabel.getImage() == null) {
			layout();
			return true;
		}
		return false;
	}

	public boolean isBusy() {
		return busyLabel != null && busyLabel.isBusy();
	}

	/*
	 * Returns the complete height of the font.
	 */
	public int getFontHeight() {
		if (fontHeight == -1) {
			Font font = getFont();
			GC gc = new GC(getDisplay());
			gc.setFont(font);
			FontMetrics fm = gc.getFontMetrics();
			fontHeight = fm.getHeight();
			gc.dispose();
		}
		return fontHeight;
	}

	/*
	 * Returns the height of the font starting at the baseline,
	 * i.e. without the descent.
	 */
	public int getFontBaselineHeight() {
		if (fontBaselineHeight == -1) {
			Font font = getFont();
			GC gc = new GC(getDisplay());
			gc.setFont(font);
			FontMetrics fm = gc.getFontMetrics();
			fontBaselineHeight = fm.getHeight() - fm.getDescent();
			gc.dispose();
		}
		return fontBaselineHeight;
	}

	public IMenuManager getMenuManager() {
		if (menuManager == null) {
			menuManager = new MenuManager();
			Menu menu = menuManager.createContextMenu(this);
			setMenu(menu);
			titleLabel.setMenu(menu);
			if (busyLabel != null)
				busyLabel.setMenu(menu);
			createMenuHyperlink();
		}
		return menuManager;
	}

	public void addDragSupport(int operations, Transfer[] transferTypes,
			DragSourceListener listener) {
		dragSupport = true;
		dragOperations = operations;
		dragTransferTypes = transferTypes;
		dragListener = listener;
		dragSource = addDragSupport(titleLabel, operations, transferTypes,
				listener);
		addDragSupport(this, operations, transferTypes, listener);
		if (busyLabel != null)
			addDragSupport(busyLabel, operations, transferTypes, listener);
		if (menuHyperlink != null)
			addDragSupport(menuHyperlink, operations, transferTypes, listener);
	}

	private DragSource addDragSupport(Control control, int operations,
			Transfer[] transferTypes, DragSourceListener listener) {
		DragSource source = new DragSource(control, operations);
		source.setTransfer(transferTypes);
		source.addDragListener(listener);
		source.setDragSourceEffect(new DragSourceEffect(control) {
			public void dragStart(DragSourceEvent event) {
				event.image = createDragEffectImage();
			}
		});
		return source;
	}

	private Image createDragEffectImage() {
		/*
		 * if (dragImage != null) { dragImage.dispose(); } GC gc = new GC(this);
		 * Point size = getSize(); dragImage = new Image(getDisplay(), size.x,
		 * size.y); gc.copyArea(dragImage, 0, 0); gc.dispose(); return
		 * dragImage;
		 */
		return null;
	}

	public void addDropSupport(int operations, Transfer[] transferTypes,
			DropTargetListener listener) {
		final DropTarget target = new DropTarget(this, operations);
		target.setTransfer(transferTypes);
		target.addDropListener(listener);
	}
}