/*******************************************************************************
 * 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
 *     Chriss Gross (schtoo@schtoo.com) - fix for 61670
 *******************************************************************************/
package org.eclipse.ui.forms.widgets;

import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Event;

/**
 * This class extends hyperlink widget by adding the capability to render an
 * image relative to the text. If no text has been set, only image will be
 * shown. Images for hover and active states can be set in addition to the
 * normal state image.
 * <p>
 * When image is taller than the text, additional style can be provided to
 * control vertical alignment (supported values are SWT.TOP, SWT.BOTTOM and
 * SWT.CENTER).
 * <p>
 * The class does not need to be sublassed but it is allowed to do so if some
 * aspect of the image hyperlink needs to be modified.
 * 
 * @since 3.0
 */
public class ImageHyperlink extends Hyperlink {
	/**
	 * Amount of pixels between the image and the text (default is 5).
	 */
	public int textSpacing = 5;

	private Image image;

	private Image hoverImage;

	private Image activeImage;

	private int state;

	private static final int HOVER = 1 << 1;

	private static final int ACTIVE = 1 << 2;

	private int verticalAlignment = SWT.CENTER;

	private int horizontalAlignment = SWT.LEFT;

	/**
	 * Creates the image hyperlink instance.
	 * 
	 * @param parent
	 *            the control parent
	 * @param style
	 *            the control style (SWT.WRAP, BOTTOM, TOP, MIDDLE, LEFT, RIGHT)
	 */
	public ImageHyperlink(Composite parent, int style) {
		super(parent, removeAlignment(style));
		extractAlignment(style);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ui.forms.widgets.AbstractHyperlink#paintHyperlink(org.eclipse.swt.events.PaintEvent)
	 */
	protected void paintHyperlink(GC gc) {
		paintHyperlink(gc, getClientArea());
	}
	
	protected void paintHyperlink(GC gc, Rectangle bounds) {
		Image image = null;
		if ((state & ACTIVE) != 0)
			image = activeImage;
		else if ((state & HOVER) != 0)
			image = hoverImage;
		if (image == null)
			image = this.image;
		Rectangle ibounds = image != null ? image.getBounds() : new Rectangle(0, 0, 0, 0);
		Point maxsize = computeMaxImageSize();
		int spacing = image!=null?textSpacing:0;		
		int textWidth = bounds.width - maxsize.x - spacing
				- marginWidth - marginWidth;
		int y = bounds.y+marginHeight + maxsize.y / 2 - ibounds.height / 2;

		if (horizontalAlignment == SWT.LEFT) {
			int x = bounds.x+marginWidth + maxsize.x / 2 - ibounds.width / 2;
			int textX = bounds.x + marginWidth + maxsize.x + spacing;
			if (image != null)
				gc.drawImage(image, x, y);
			if (getText() != null)
				drawText(gc, bounds, textX, textWidth);
		} else if (horizontalAlignment == SWT.RIGHT) {
			int x = bounds.x+marginWidth;
			if (getText() != null) {
				x += drawText(gc, bounds, x, textWidth);
			}
			x += maxsize.x / 2 - ibounds.width / 2 + spacing;
			if (image != null)
				gc.drawImage(image, x, y);
		}
	}

	private int drawText(GC gc, Rectangle clientArea, int textX, int textWidth) {
		Point textSize = computeTextSize(textWidth, SWT.DEFAULT);
		int slotHeight = clientArea.height - marginHeight - marginHeight;
		int textY;
		textWidth = textSize.x;
		int textHeight = textSize.y;
		if (verticalAlignment == SWT.BOTTOM) {
			textY = marginHeight + slotHeight - textHeight;
		} else if (verticalAlignment == SWT.CENTER) {
			textY = marginHeight + slotHeight / 2 - textHeight / 2;
		} else {
			textY = marginHeight;
		}
		paintText(gc, new Rectangle(textX, textY, textWidth, textHeight));
		return textWidth;
	}

	/**
	 * Computes the control size by reserving space for images in addition to
	 * text.
	 * 
	 * @param wHint
	 *            width hint
	 * @param hHint
	 *            height hint
	 * @param changed
	 *            if <code>true</code>, any cached layout data should be
	 *            computed anew
	 */
	public Point computeSize(int wHint, int hHint, boolean changed) {
		checkWidget();
		Point isize = computeMaxImageSize();
		int spacing = isize.x>0?textSpacing:0;
		Point textSize = null;
		if (getText() != null) {
			int innerWHint = wHint;
			if (wHint != SWT.DEFAULT) {
				innerWHint = wHint - 2 * marginWidth - isize.x - spacing;
			}
			textSize = super.computeSize(innerWHint, hHint, changed);
		}
		int width = isize.x;
		int height = isize.y;
		if (textSize != null) {
			width += spacing;
			width += textSize.x;
			height = Math.max(height, textSize.y);
		}
		width += 2 * marginWidth;
		height += 2 * marginHeight;
		return new Point(width, height);
	}

	protected void handleEnter(Event e) {
		state = HOVER;
		super.handleEnter(e);
	}

	protected void handleExit(Event e) {
		state = 0;
		super.handleExit(e);
	}

	protected void handleActivate(Event e) {
		state &= ACTIVE;
		redraw();
		super.handleActivate(e);
		state &= ~ACTIVE;
		if (!isDisposed())
			redraw();
	}

	/**
	 * Returns active image.
	 * 
	 * @return active image or <code>null</code> if not set.
	 */
	public Image getActiveImage() {
		return activeImage;
	}

	/**
	 * Sets the image to show when link is activated.
	 * 
	 * @param activeImage
	 * 
	 */
	public void setActiveImage(Image activeImage) {
		this.activeImage = activeImage;
	}

	/**
	 * Returns the hover image.
	 * 
	 * @return hover image or <code>null</code> if not set.
	 */
	public Image getHoverImage() {
		return hoverImage;
	}

	/**
	 * Sets the image to show when link is hover state (on mouse over).
	 * 
	 * @param hoverImage
	 */
	public void setHoverImage(Image hoverImage) {
		this.hoverImage = hoverImage;
	}

	/**
	 * Returns the image to show in the normal state.
	 * 
	 * @return normal image or <code>null</code> if not set.
	 */
	public Image getImage() {
		return image;
	}

	/**
	 * Sets the image to show when link is in the normal state.
	 * 
	 * @param image
	 */
	public void setImage(Image image) {
		this.image = image;
	}

	private Point computeMaxImageSize() {
		int x = 0;
		int y = 0;
		if (image != null) {
			x = Math.max(image.getBounds().width, x);
			y = Math.max(image.getBounds().height, y);
		}
		if (hoverImage != null) {
			x = Math.max(hoverImage.getBounds().width, x);
			y = Math.max(hoverImage.getBounds().height, y);
		}
		if (activeImage != null) {
			x = Math.max(activeImage.getBounds().width, x);
			y = Math.max(activeImage.getBounds().height, y);
		}
		return new Point(x, y);
	}

	private static int removeAlignment(int style) {
		int resultStyle = style;
		if ((style & SWT.CENTER) != 0) {
			resultStyle &= (~SWT.CENTER);
		}
		if ((style & SWT.TOP) != 0) {
			resultStyle &= (~SWT.TOP);
		}
		if ((style & SWT.BOTTOM) != 0) {
			resultStyle &= (~SWT.BOTTOM);
		}
		if ((style & SWT.LEFT) != 0) {
			resultStyle &= (~SWT.LEFT);
		}
		if ((style & SWT.RIGHT) != 0) {
			resultStyle &= (~SWT.RIGHT);
		}
		return resultStyle;
	}

	private void extractAlignment(int style) {
		if ((style & SWT.CENTER) != 0) {
			verticalAlignment = SWT.CENTER;
		} else if ((style & SWT.TOP) != 0) {
			verticalAlignment = SWT.TOP;
		} else if ((style & SWT.BOTTOM) != 0) {
			verticalAlignment = SWT.BOTTOM;
		}
		if ((style & SWT.LEFT) != 0) {
			horizontalAlignment = SWT.LEFT;
		} else if ((style & SWT.RIGHT) != 0) {
			horizontalAlignment = SWT.RIGHT;
		}
	}
}
