/*******************************************************************************
 * Copyright (c) 2011 Laurent CARON
 * 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:
 *     Laurent CARON (laurent.caron at gmail dot com) - Initial implementation and API
 *******************************************************************************/
package org.mihalis.opal.launcher;

import org.eclipse.swt.SWT;
import org.eclipse.swt.SWTException;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.graphics.Font;
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.mihalis.opal.utils.SWTGraphicUtil;

/**
 * Instance of this class are a button with text, image and a nice animation
 * effect.
 */
class LauncherLabel extends Canvas {

	/** The text. */
	private String text;
	
	/** The image. */
	private Image image;
	
	/** The font. */
	private Font font;

	/** The Constant GAP. */
	private static final int GAP = 12;
	
	/** The draw flags. */
	private static int DRAW_FLAGS = SWT.DRAW_MNEMONIC | SWT.DRAW_TAB | SWT.DRAW_TRANSPARENT | SWT.DRAW_DELIMITER;
	
	/** The Constant DEFAULT_MARGIN. */
	private static final int DEFAULT_MARGIN = 5;
	
	/** The left margin. */
	private int leftMargin = DEFAULT_MARGIN;
	
	/** The top margin. */
	private int topMargin = DEFAULT_MARGIN;
	
	/** The right margin. */
	private int rightMargin = DEFAULT_MARGIN;
	
	/** The bottom margin. */
	private int bottomMargin = DEFAULT_MARGIN;
	
	/** The text size. */
	private Point textSize;

	/** The Constant MAX_NUMBER_OF_STEPS. */
	private static final int MAX_NUMBER_OF_STEPS = 10;
	
	/** The animation step. */
	private int animationStep = 0;

	/**
	 * Constructs a new instance of this class given its parent and a style
	 * value describing its behavior and appearance.
	 * <p>
	 * The style value is either one of the style constants defined in class
	 * <code>SWT</code> which is applicable to instances of this class, or must
	 * be built by <em>bitwise OR</em>'ing together (that is, using the
	 * <code>int</code> "|" operator) two or more of those <code>SWT</code>
	 * style constants. The class description lists the style constants that are
	 * applicable to the class. Style bits are also inherited from superclasses.
	 * </p>
	 * 
	 * @param parent a composite control which will be the parent of the new
	 *            instance (cannot be null)
	 * @param style the style of control to construct
	 * 
	 * @exception IllegalArgumentException <ul>
	 *                <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
	 *                </ul>
	 * @exception SWTException <ul>
	 *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
	 *                thread that created the parent</li>
	 *                </ul>
	 * 
	 */
	LauncherLabel(final Composite parent, final int style) {
		super(parent, style | SWT.BORDER | SWT.DOUBLE_BUFFERED);

		final Font original = super.getFont();

		final Font defaultFont = new Font(getDisplay(), original.getFontData()[0].getName(), 18, SWT.BOLD);
		this.font = defaultFont;
		SWTGraphicUtil.addDisposer(this, defaultFont);

		addPaintListener(new PaintListener() {
			@Override
			public void paintControl(final PaintEvent event) {
				onPaint(event);
			}
		});

	}

	/**
	 * Draw the content of the LLabel.
	 *
	 * @param event paintevent
	 */
	private void onPaint(final PaintEvent event) {
		final Rectangle rect = getClientArea();
		if (rect.width == 0 || rect.height == 0) {
			return;
		}

		final Image bufferImage = new Image(getDisplay(), Math.max(1, rect.width), Math.max(1, rect.height));

		final GC gc = new GC(bufferImage);
		gc.setForeground(getForeground());
		gc.setBackground(getBackground());

		gc.fillRectangle(rect);

		final Point extent = getTotalSize(this.image.getBounds().width, this.image.getBounds().height);
		final int xImage = (rect.width - this.image.getBounds().width) / 2;
		final int yImage = (rect.height - extent.y) / 2;
		gc.drawImage(this.image, xImage, yImage);

		gc.setFont(this.font);
		final int xText = (rect.width - this.textSize.x) / 2;
		final int yText = yImage + this.image.getBounds().height + GAP - this.textSize.y / 2;
		gc.drawString(this.text, xText, yText);

		if (this.animationStep != 0) {
			final float zoom = 1f + this.animationStep * (Math.max(extent.x, extent.y) - Math.max(this.image.getBounds().width, this.image.getBounds().height)) / MAX_NUMBER_OF_STEPS / 100f;

			final int newSizeX = (int) (this.image.getBounds().width * zoom);
			final int newSizeY = (int) (this.image.getBounds().height * zoom);

			gc.setAntialias(SWT.ON);
			gc.setInterpolation(SWT.HIGH);

			gc.setAlpha(255 - 255 / MAX_NUMBER_OF_STEPS * this.animationStep);

			final Point extentZoomedImage = getTotalSize(newSizeX, newSizeY);
			final int xZoomedImage = (rect.width - newSizeX) / 2;
			final int yZoomedImage = (rect.height - extentZoomedImage.y) / 2;
			gc.drawImage(this.image, 0, 0, this.image.getBounds().width, this.image.getBounds().height, xZoomedImage, yZoomedImage, (int) (this.image.getBounds().width * zoom), (int) (this.image.getBounds().height * zoom));

		}

		gc.dispose();

		event.gc.drawImage(bufferImage, 0, 0);

		bufferImage.dispose();

	}

	/**
	 * Compute size.
	 *
	 * @param wHint the w hint
	 * @param hHint the h hint
	 * @param changed the changed
	 * @return the point
	 * @see org.eclipse.swt.widgets.Composite#computeSize(int, int, boolean)
	 */
	@Override
	public Point computeSize(final int wHint, final int hHint, final boolean changed) {
		checkWidget();
		final Point e = getTotalSize(this.image.getBounds().width, this.image.getBounds().height);
		if (wHint == SWT.DEFAULT) {
			e.x += this.leftMargin + this.rightMargin;
		} else {
			e.x = wHint;
		}
		if (hHint == SWT.DEFAULT) {
			e.y += this.topMargin + this.bottomMargin;
		} else {
			e.y = hHint;
		}
		return e;
	}

	/**
	 * Compute the size of the content (image + text + gap).
	 *
	 * @param imgWidth image width
	 * @param imgHeight image height
	 * @return the size of the content
	 */
	private Point getTotalSize(final int imgWidth, final int imgHeight) {
		final Point size = new Point(0, 0);

		int textWidth = 0;
		int textHeight = 0;

		if (this.textSize == null) {
			final GC gc = new GC(this);
			gc.setFont(this.font);

			this.textSize = gc.textExtent(this.text, DRAW_FLAGS);
			gc.dispose();

		}
		textWidth = this.textSize.x;
		textHeight = this.textSize.y;

		size.x = Math.max(imgWidth, textWidth);
		size.y = imgHeight + GAP + textHeight;

		return size;
	}

	/**
	 * Gets the text.
	 *
	 * @return the text
	 */
	String getText() {
		return this.text;
	}

	/**
	 * Sets the text.
	 *
	 * @param text the text to set
	 */
	void setText(final String text) {
		this.text = text;
	}

	/**
	 * Gets the image.
	 *
	 * @return the image
	 */
	Image getImage() {
		return this.image;
	}

	/**
	 * Sets the image.
	 *
	 * @param image the image to set
	 */
	void setImage(final Image image) {
		this.image = image;
	}

	/**
	 * Gets the font.
	 *
	 * @return the font
	 */
	@Override
	public Font getFont() {
		return this.font;
	}

	/**
	 * Sets the font.
	 *
	 * @param font the font to set
	 */
	@Override
	public void setFont(final Font font) {
		this.font = font;
	}

	/**
	 * Increment the steps of the animation.
	 *
	 * @return true if animation keeps running, false otherwise
	 */
	boolean incrementAnimation() {
		this.animationStep++;
		final boolean stopAnimation = this.animationStep > MAX_NUMBER_OF_STEPS;

		if (stopAnimation) {
			this.animationStep = 0;
		}
		if (!isDisposed()) {
			redraw();
		}
		return !stopAnimation;
	}

	/**
	 * Gets the left margin.
	 *
	 * @return the left margin
	 */
	public int getLeftMargin() {
		return this.leftMargin;
	}

	/**
	 * Sets the left margin.
	 *
	 * @param leftMargin the left margin to set
	 */
	public void setLeftMargin(final int leftMargin) {
		this.leftMargin = leftMargin;
	}

	/**
	 * Gets the top margin.
	 *
	 * @return the top margin
	 */
	public int getTopMargin() {
		return this.topMargin;
	}

	/**
	 * Sets the top margin.
	 *
	 * @param topMargin the top margin to set
	 */
	public void setTopMargin(final int topMargin) {
		this.topMargin = topMargin;
	}

	/**
	 * Gets the right margin.
	 *
	 * @return the right margin
	 */
	public int getRightMargin() {
		return this.rightMargin;
	}

	/**
	 * Sets the right margin.
	 *
	 * @param rightMargin the right margin to set
	 */
	public void setRightMargin(final int rightMargin) {
		this.rightMargin = rightMargin;
	}

	/**
	 * Gets the bottom margin.
	 *
	 * @return the bottom margin
	 */
	public int getBottomMargin() {
		return this.bottomMargin;
	}

	/**
	 * Sets the bottom margin.
	 *
	 * @param bottomMargin the bottom margin to set
	 */
	public void setBottomMargin(final int bottomMargin) {
		this.bottomMargin = bottomMargin;
	}

}
