/*******************************************************************************
 * 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 API and implementation 
 *******************************************************************************/
package org.mihalis.opal.flatButton;

import java.util.ArrayList;
import java.util.List;

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.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Color;
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.Event;
import org.eclipse.swt.widgets.Listener;
import org.mihalis.opal.utils.SWTGraphicUtil;

/**
 * Instances of this class represent a flat button.
 * <dl>
 * <dt><b>Styles:</b></dt>
 * <dd>UP, DOWN, LEFT, RIGHT, CENTER</dd>
 * <dt><b>Events:</b></dt>
 * <dd>Selection</dd>
 * </dl>
 * <p>
 * Note: Only one of the styles LEFT, RIGHT, and CENTER may be specified.
 * </p>
 * 
 */
public class FlatButton extends Canvas {
	
	/** The Constant DEFAULT_PADDING. */
	private static final int DEFAULT_PADDING = 5;
	
	/** The image. */
	private Image image;
	
	/** The text. */
	private String text;
	
	/** The selection. */
	private boolean selection;
	
	/** The alignment. */
	private int alignment;
	
	/** The listeners. */
	private final List<SelectionListener> listeners;
	
	/** The mouse in. */
	private boolean mouseIn;
	
	/** The background color. */
	private Color backgroundColor;
	
	/** The selected color. */
	private Color selectedColor;
	
	/** The selected text color. */
	private Color selectedTextColor;
	
	/** The mouse over color. */
	private Color mouseOverColor;

	/**
	 * 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
	 * @see SWT#DOWN
	 * @see SWT#LEFT
	 * @see SWT#RIGHT
	 * @see SWT#CENTER
	 * @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>
	 *                <li>ERROR_INVALID_SUBCLASS - if this class is not an
	 *                allowed subclass</li>
	 *                </ul>
	 */
	public FlatButton(final Composite parent, final int style) {
		super(parent, style);
		this.listeners = new ArrayList<SelectionListener>();
		buildAlignmentFromStyle(style);
		addListeners();
		initializeDefaultColors();
	}

	/**
	 * Builds the alignment from style.
	 *
	 * @param style the style
	 */
	private void buildAlignmentFromStyle(final int style) {
		if ((style & SWT.LEFT) == SWT.LEFT) {
			this.alignment = SWT.LEFT;
		} else if ((style & SWT.RIGHT) == SWT.RIGHT) {
			this.alignment = SWT.RIGHT;
		} else {
			this.alignment = SWT.CENTER;

		}
	}

	/**
	 * Adds the listeners.
	 */
	private void addListeners() {
		addPaintListener(new PaintListener() {
			@Override
			public void paintControl(final PaintEvent e) {
				FlatButton.this.paintControl(e);
			}
		});

		addListener(SWT.MouseEnter, new Listener() {
			@Override
			public void handleEvent(final Event event) {
				FlatButton.this.mouseIn = true;
				redraw();
			}
		});

		addListener(SWT.MouseExit, new Listener() {
			@Override
			public void handleEvent(final Event event) {
				FlatButton.this.mouseIn = false;
				redraw();
			}
		});

		addListener(SWT.MouseUp, new Listener() {
			@Override
			public void handleEvent(final Event event) {
				boolean doIt = true;
				FlatButton.this.selection = !FlatButton.this.selection;
				for (final SelectionListener listener : FlatButton.this.listeners) {
					final SelectionEvent sEvent = new SelectionEvent(event);
					listener.widgetSelected(sEvent);
					doIt = doIt && sEvent.doit;
				}
				if (!doIt) {
					FlatButton.this.selection = !FlatButton.this.selection;
				}
			}

		});
	}

	/**
	 * Initialize default colors.
	 */
	private void initializeDefaultColors() {
		this.backgroundColor = getDisplay().getSystemColor(SWT.COLOR_WHITE);
		this.selectedColor = new Color(getDisplay(), 0, 112, 192);
		this.selectedTextColor = getDisplay().getSystemColor(SWT.COLOR_WHITE);
		this.mouseOverColor = new Color(getDisplay(), 235, 234, 226);

		SWTGraphicUtil.addDisposer(this, this.selectedColor);
		SWTGraphicUtil.addDisposer(this, this.mouseOverColor);
		SWTGraphicUtil.addDisposer(this, this.image);
	}

	/**
	 * Paint control.
	 *
	 * @param e the e
	 */
	private void paintControl(final PaintEvent e) {
		final GC gc = e.gc;
		drawBackground(gc);
		if (this.image != null) {
			drawImage(gc);
		}
		if (this.text != null) {
			drawText(gc);
		}
	}

	/**
	 * Draw background.
	 *
	 * @param gc the gc
	 */
	private void drawBackground(final GC gc) {
		Color color;
		if (this.selection) {
			color = this.selectedColor;
		} else if (this.mouseIn) {
			color = this.mouseOverColor;
		} else {
			color = this.backgroundColor;
		}
		gc.setBackground(color);
		gc.fillRectangle(getClientArea());

	}

	/**
	 * Draw image.
	 *
	 * @param gc the gc
	 */
	private void drawImage(final GC gc) {
		final Rectangle rect = getClientArea();
		final Point imageSize = new Point(this.image.getBounds().width, this.image.getBounds().height);

		int x;
		if (this.alignment == SWT.LEFT) {
			x = DEFAULT_PADDING;
		} else if (this.alignment == SWT.RIGHT) {
			x = rect.width - imageSize.x - DEFAULT_PADDING;
		} else {
			x = (rect.width - imageSize.x) / 2;
		}
		gc.drawImage(this.image, x, DEFAULT_PADDING);
	}

	/**
	 * Draw text.
	 *
	 * @param gc the gc
	 */
	private void drawText(final GC gc) {
		final Rectangle rect = getClientArea();

		if (this.selection) {
			gc.setForeground(this.selectedTextColor);
		} else {
			gc.setForeground(getForeground());
		}

		gc.setFont(getFont());
		final Point textSize = gc.stringExtent(this.text);
		int x, y;

		if (this.alignment == SWT.LEFT) {
			x = DEFAULT_PADDING;
		} else if (this.alignment == SWT.RIGHT) {
			x = rect.width - textSize.x - DEFAULT_PADDING;
		} else {
			x = (rect.width - textSize.x) / 2;
		}
		if (this.image == null) {
			y = DEFAULT_PADDING;
		} else {
			y = 2 * DEFAULT_PADDING + this.image.getBounds().height;
		}
		gc.drawString(this.text, x, y, true);
	}

	/**
	 * Adds the listener to the collection of listeners who will be notified
	 * when the control is selected by the user, by sending it one of the
	 * messages defined in the <code>SelectionListener</code> interface.
	 * <p>
	 * <code>widgetSelected</code> is called when the control is selected by the
	 * user. <code>widgetDefaultSelected</code> is not called.
	 * </p>
	 *
	 * @param listener the listener which should be notified
	 * @see SelectionListener
	 * @see #removeSelectionListener
	 * @see SelectionEvent
	 * @exception IllegalArgumentException <ul>
	 *                <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
	 *                </ul>
	 * @exception SWTException <ul>
	 *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been
	 *                disposed</li>
	 *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
	 *                thread that created the receiver</li>
	 *                </ul>
	 */
	public void addSelectionListener(final SelectionListener listener) {
		checkWidget();
		this.listeners.add(listener);
	}

	/**
	 * 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) {
		int width = 2 * DEFAULT_PADDING, height = 3 * DEFAULT_PADDING;
		if (this.image != null) {
			final Rectangle bounds = this.image.getBounds();
			width += bounds.width;
			height += bounds.height;
		}

		if (this.text != null) {
			final GC gc = new GC(this);
			final Point extent = gc.stringExtent(this.text);
			gc.dispose();
			width = Math.max(width, extent.x + 2 * DEFAULT_PADDING);
			height = height + extent.y;
		}

		return new Point(Math.max(width, wHint), Math.max(height, hHint));
	}

	/**
	 * Returns a value which describes the position of the text in the receiver.
	 * The value will be one of <code>LEFT</code>, <code>RIGHT</code> or
	 * <code>CENTER</code>.
	 * 
	 * @return the alignment
	 * 
	 * @exception SWTException <ul>
	 *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been
	 *                disposed</li>
	 *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
	 *                thread that created the receiver</li>
	 *                </ul>
	 */
	public int getAlignment() {
		checkWidget();
		return this.alignment;
	}

	/**
	 * Returns a value which describes the default background color.
	 *
	 * @return the default background color
	 * @exception SWTException <ul>
	 *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been
	 *                disposed</li>
	 *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
	 *                thread that created the receiver</li>
	 *                </ul>
	 */
	public Color getBackgroundColor() {
		checkWidget();
		return this.backgroundColor;
	}

	/**
	 * Returns the receiver's image if it has one, or null if it does not.
	 * 
	 * @return the receiver's image
	 * 
	 * @exception SWTException <ul>
	 *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been
	 *                disposed</li>
	 *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
	 *                thread that created the receiver</li>
	 *                </ul>
	 */
	public Image getImage() {
		checkWidget();
		return this.image;
	}

	/**
	 * Returns a value which describes the color when the mouse is over the
	 * button.
	 *
	 * @return the color when the mouse is over the button
	 * @exception SWTException <ul>
	 *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been
	 *                disposed</li>
	 *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
	 *                thread that created the receiver</li>
	 *                </ul>
	 */
	public Color getMouseOverColor() {
		checkWidget();
		return this.mouseOverColor;
	}

	/**
	 * Returns a value which describes the color when the button is selected.
	 *
	 * @return the color when the button is selected
	 * @exception SWTException <ul>
	 *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been
	 *                disposed</li>
	 *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
	 *                thread that created the receiver</li>
	 *                </ul>
	 */
	public Color getSelectedColor() {
		checkWidget();
		return this.selectedColor;
	}

	/**
	 * Returns a value which describes the color of the text when the button is
	 * selected.
	 *
	 * @return the color of the text when the button is selected
	 * @exception SWTException <ul>
	 *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been
	 *                disposed</li>
	 *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
	 *                thread that created the receiver</li>
	 *                </ul>
	 */

	public Color getSelectedTextColor() {
		return this.selectedTextColor;
	}

	/**
	 * Returns <code>true</code> if the receiver is selected, and false
	 * otherwise.
	 * <p>
	 * 
	 * @return the selection state
	 * 
	 * @exception SWTException <ul>
	 *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been
	 *                disposed</li> <li>ERROR_THREAD_INVALID_ACCESS - if not
	 *                called from the thread that created the receiver</li>
	 *                </ul>
	 */
	public boolean getSelection() {
		checkWidget();
		return this.selection;
	}

	/**
	 * Returns the receiver's text.
	 * 
	 * @return the receiver's text
	 * 
	 * @exception SWTException <ul>
	 *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
	 *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
	 *                thread that created the receiver</li>
	 *                </ul>
	 */
	public String getText() {
		checkWidget();
		return this.text;
	}

	/**
	 * Removes the listener from the collection of listeners who will be
	 * notified when the control is selected by the user.
	 *
	 * @param listener the listener which should no longer be notified
	 * @see SelectionListener
	 * @see #addSelectionListener
	 * @exception IllegalArgumentException <ul>
	 *                <li>ERROR_NULL_ARGUMENT - if the listener is null</li>
	 *                </ul>
	 * @exception SWTException <ul>
	 *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been
	 *                disposed</li>
	 *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
	 *                thread that created the receiver</li>
	 *                </ul>
	 */
	public void removeSelectionListener(final SelectionListener listener) {
		checkWidget();
		this.listeners.remove(listener);
	}

	/**
	 * Controls how text, images and arrows will be displayed in the receiver.
	 * The argument should be one of <code>LEFT</code>, <code>RIGHT</code> or
	 * <code>CENTER</code>.
	 * 
	 * @param alignment the new alignment
	 * 
	 * @exception SWTException <ul>
	 *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been
	 *                disposed</li>
	 *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
	 *                thread that created the receiver</li>
	 *                </ul>
	 */
	public void setAlignment(final int alignment) {
		checkWidget();
		if ((alignment & (SWT.LEFT | SWT.RIGHT | SWT.CENTER)) == 0) {
			return;
		}
		this.alignment = alignment;
		redraw();
	}

	/**
	 * Sets the receiver's background color to the color specified by the
	 * argument.
	 *
	 * @param backgroundColor the new background color
	 * @exception IllegalArgumentException <ul>
	 *                <li>ERROR_INVALID_ARGUMENT - if the argument has been
	 *                disposed</li>
	 *                </ul>
	 * @exception SWTException <ul>
	 *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been
	 *                disposed</li>
	 *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
	 *                thread that created the receiver</li>
	 *                </ul>
	 */
	public void setBackgroundColor(final Color backgroundColor) {
		checkWidget();
		this.backgroundColor = backgroundColor;
	}

	/**
	 * Sets the receiver's image to the argument, which may be <code>null</code>
	 * indicating that no image should be displayed.
	 * <p>
	 * Note that a Button can display an image and text simultaneously on
	 * Windows (starting with XP), GTK+ and OSX. On other platforms, a Button
	 * that has an image and text set into it will display the image or text
	 * that was set most recently.
	 * </p>
	 * 
	 * @param image the image to display on the receiver (may be
	 *            <code>null</code>)
	 * 
	 * @exception IllegalArgumentException <ul>
	 *                <li>ERROR_INVALID_ARGUMENT - if the image has been disposed</li>
	 *                </ul>
	 * @exception SWTException <ul>
	 *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
	 *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
	 *                thread that created the receiver</li>
	 *                </ul>
	 */
	public void setImage(final Image image) {
		checkWidget();
		this.image = image;
		redraw();
	}

	/**
	 * Sets the receiver's color when the mouse if over the button.
	 *
	 * @param mouseOverColor the new mouse over color
	 * @exception IllegalArgumentException <ul>
	 *                <li>ERROR_INVALID_ARGUMENT - if the argument has been
	 *                disposed</li>
	 *                </ul>
	 * @exception SWTException <ul>
	 *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been
	 *                disposed</li>
	 *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
	 *                thread that created the receiver</li>
	 *                </ul>
	 */
	public void setMouseOverColor(final Color mouseOverColor) {
		checkWidget();
		this.mouseOverColor = mouseOverColor;
	}

	/**
	 * Sets the receiver's color when the button is selected.
	 *
	 * @param selectedColor the new selected color
	 * @exception IllegalArgumentException <ul>
	 *                <li>ERROR_INVALID_ARGUMENT - if the argument has been
	 *                disposed</li>
	 *                </ul>
	 * @exception SWTException <ul>
	 *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been
	 *                disposed</li>
	 *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
	 *                thread that created the receiver</li>
	 *                </ul>
	 */
	public void setSelectedColor(final Color selectedColor) {
		checkWidget();
		this.selectedColor = selectedColor;
	}

	/**
	 * Sets the receiver's text color when the button is selected.
	 *
	 * @param selectedTextColor the new selected text color
	 * @exception IllegalArgumentException <ul>
	 *                <li>ERROR_INVALID_ARGUMENT - if the argument has been
	 *                disposed</li>
	 *                </ul>
	 * @exception SWTException <ul>
	 *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been
	 *                disposed</li>
	 *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
	 *                thread that created the receiver</li>
	 *                </ul>
	 */
	public void setSelectedTextColor(final Color selectedTextColor) {
		this.selectedTextColor = selectedTextColor;
	}

	/**
	 * Sets the selection state of the receiver.
	 * 
	 * @param selected the new selection state
	 * 
	 * @exception SWTException <ul>
	 *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
	 *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
	 *                thread that created the receiver</li>
	 *                </ul>
	 */
	public void setSelection(final boolean selected) {
		checkWidget();
		this.selection = selected;
		redraw();
	}

	/**
	 * Sets the receiver's text.
	 *
	 * @param text the new text
	 * @exception IllegalArgumentException <ul>
	 *                <li>ERROR_NULL_ARGUMENT - if the text is null</li>
	 *                </ul>
	 * @exception SWTException <ul>
	 *                <li>ERROR_WIDGET_DISPOSED - if the receiver has been
	 *                disposed</li>
	 *                <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
	 *                thread that created the receiver</li>
	 *                </ul>
	 */
	public void setText(final String text) {
		checkWidget();
		this.text = text;
		redraw();
	}

}
