/*******************************************************************************
 * Copyright (c) 2012 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.obutton;

import org.eclipse.swt.SWT;
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.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.mihalis.opal.utils.AdvancedPath;
import org.mihalis.opal.utils.SWTGraphicUtil;

/**
 * This class is an abstract button renderer used for default, red, orange,
 * green and purple themes.
 */
public abstract class AbstractButtonRenderer implements ButtonRenderer {

	/** The Constant ARROW_RIGHT_IMAGE. */
	private static final String ARROW_RIGHT_IMAGE = "images/arrow_right.png";
	
	/** The Constant ARROW_LEFT_IMAGE. */
	private static final String ARROW_LEFT_IMAGE = "images/arrow_left.png";
	
	/** The Constant ARROW_DOWN_IMAGE. */
	private static final String ARROW_DOWN_IMAGE = "images/arrow_down.png";
	
	/** The Constant ARROW_UP_IMAGE. */
	private static final String ARROW_UP_IMAGE = "images/arrow_up.png";
	
	/** The Constant RADIUS_VALUE. */
	private static final int RADIUS_VALUE = 10;
	
	/** The Constant DISABLED_FONT_COLOR. */
	private static final Color DISABLED_FONT_COLOR = SWTGraphicUtil.getColorSafely(119, 119, 119);
	
	/** The Constant DISABLED_SECOND_BACKGROUND_COLOR. */
	private static final Color DISABLED_SECOND_BACKGROUND_COLOR = SWTGraphicUtil.getColorSafely(220, 220, 220);
	
	/** The Constant DISABLED_FIRST_BACKGROUND_COLOR. */
	private static final Color DISABLED_FIRST_BACKGROUND_COLOR = SWTGraphicUtil.getColorSafely(237, 237, 237);

	/** The onclick. */
	private ButtonConfiguration normal, hover, disabled, selected, onclick;
	
	/** The gc. */
	private GC gc;
	
	/** The configuration. */
	private ButtonConfiguration configuration;
	
	/** The gap on clic. */
	private int gapOnClic;
	
	/** The parent. */
	protected OButton parent;
	
	/** The image up. */
	private Image imageUp;
	
	/** The image down. */
	private Image imageDown;
	
	/** The image left. */
	private Image imageLeft;
	
	/** The image right. */
	private Image imageRight;
	
	/** The disabled image. */
	private Image disabledImage;
	
	/** The Constant MARGIN. */
	private static final int MARGIN = 5;
	
	/** The Constant GAP_ON_CLIC. */
	private static final int GAP_ON_CLIC = 2;

	/**
	 * Constructor.
	 */
	protected AbstractButtonRenderer() {
		initButtonConfiguration();
		createArrows();
		createDisabledImage();
	}

	/**
	 * Inits the button configuration.
	 */
	private void initButtonConfiguration() {
		normal = createNormalConfiguration();
		hover = createHoverConfiguration();
		disabled = createDisabledConfiguration();
		selected = createSelectedConfiguration();
		onclick = createOnClickConfiguration();
	}

	/**
	 * Creates the normal configuration.
	 *
	 * @return the configuration when the button is not clicked, enabled, not
	 *         selected, and the mouse is not hover
	 */
	protected ButtonConfiguration createNormalConfiguration() {
		final ButtonConfiguration configuration = new ButtonConfiguration();
		configuration.setCornerRadius(10);
		configuration.setFont(Display.getDefault().getSystemFont()).setFontColor(getFontColor());
		configuration.setGradientDirection(SWT.VERTICAL);
		configuration.setBackgroundColor(getFirstBackgroundColor());
		configuration.setSecondBackgroundColor(getSecondBackgroundColor());
		return configuration;
	}

	/**
	 * Gets the font color.
	 *
	 * @return the font color
	 */
	protected abstract Color getFontColor();

	/**
	 * Gets the first background color.
	 *
	 * @return the first background color
	 */
	protected abstract Color getFirstBackgroundColor();

	/**
	 * Gets the second background color.
	 *
	 * @return the second background color
	 */
	protected abstract Color getSecondBackgroundColor();

	/**
	 * Creates the hover configuration.
	 *
	 * @return the configuration when the mouse is hover
	 */
	protected ButtonConfiguration createHoverConfiguration() {
		final ButtonConfiguration configuration = new ButtonConfiguration();
		configuration.setCornerRadius(10);
		configuration.setFont(Display.getDefault().getSystemFont()).setFontColor(getFontColor());
		configuration.setGradientDirection(SWT.VERTICAL);
		configuration.setBackgroundColor(getSecondBackgroundColor());
		configuration.setSecondBackgroundColor(getFirstBackgroundColor());
		return configuration;
	}

	/**
	 * Creates the disabled configuration.
	 *
	 * @return the configuration when the button is disabled
	 */
	protected ButtonConfiguration createDisabledConfiguration() {
		final ButtonConfiguration configuration = new ButtonConfiguration();
		configuration.setCornerRadius(RADIUS_VALUE);
		configuration.setFont(Display.getDefault().getSystemFont()).setFontColor(DISABLED_FONT_COLOR);
		configuration.setGradientDirection(SWT.VERTICAL);
		configuration.setBackgroundColor(DISABLED_FIRST_BACKGROUND_COLOR);
		configuration.setSecondBackgroundColor(DISABLED_SECOND_BACKGROUND_COLOR);
		return configuration;
	}

	/**
	 * Creates the selected configuration.
	 *
	 * @return the configuration when the button is selected
	 */
	protected ButtonConfiguration createSelectedConfiguration() {
		return createHoverConfiguration();
	}

	/**
	 * Creates the on click configuration.
	 *
	 * @return the configuration when the button is clicked
	 */
	protected ButtonConfiguration createOnClickConfiguration() {
		return createHoverConfiguration();
	}

	/**
	 * Creates the arrows.
	 */
	private void createArrows() {
		final ClassLoader loader = org.mihalis.opal.obutton.AbstractButtonRenderer.class.getClassLoader();
		imageUp = new Image(Display.getCurrent(), loader.getResourceAsStream(ARROW_UP_IMAGE));
		imageDown = new Image(Display.getCurrent(), loader.getResourceAsStream(ARROW_DOWN_IMAGE));
		imageLeft = new Image(Display.getCurrent(), loader.getResourceAsStream(ARROW_LEFT_IMAGE));
		imageRight = new Image(Display.getCurrent(), loader.getResourceAsStream(ARROW_RIGHT_IMAGE));

		Display.getCurrent().addListener(SWT.Dispose, new Listener() {

			@Override
			public void handleEvent(final Event event) {
				imageUp.dispose();
				imageDown.dispose();
				imageLeft.dispose();
				imageRight.dispose();
			}
		});
	}

	/**
	 * Creates the disabled image.
	 *
	 * @see org.mihalis.opal.obutton.ButtonRenderer#createDisabledImage()
	 */
	@Override
	public void createDisabledImage() {
		if (disabledImage != null && !disabledImage.isDisposed()) {
			disabledImage.dispose();
		}
		if (parent == null || parent.getImage() == null) {
			disabledImage = null;
		} else {
			disabledImage = new Image(parent.getDisplay(), parent.getImage(), SWT.IMAGE_DISABLE);
			parent.addListener(SWT.Dispose, new Listener() {
				@Override
				public void handleEvent(final Event e) {
					if (!disabledImage.isDisposed()) {
						disabledImage.dispose();
					}
				}
			});
		}
	}

	/**
	 * Dispose.
	 *
	 * @see org.mihalis.opal.obutton.ButtonRenderer#dispose()
	 */
	@Override
	public void dispose() {
	}

	/**
	 * Draw button when mouse hover.
	 *
	 * @param gc the gc
	 * @param parent the parent
	 * @see org.mihalis.opal.obutton.ButtonRenderer#drawButtonWhenMouseHover(org.eclipse.swt.graphics.GC,
	 *      org.mihalis.opal.obutton.OButton)
	 */
	@Override
	public void drawButtonWhenMouseHover(final GC gc, final OButton parent) {
		this.gc = gc;
		configuration = hover;
		gapOnClic = 0;
		this.parent = parent;
		draw();
	}

	/**
	 * Draw.
	 */
	private void draw() {
		gc.setAdvanced(true);
		gc.setAntialias(SWT.ON);
		drawBackground();
		int xPosition = computeStartingPosition();
		xPosition += drawImage(xPosition);
		if (parent.getText() != null) {
			drawText(xPosition);
		}
	}

	/**
	 * Draw background.
	 */
	private void drawBackground() {
		final AdvancedPath path = createClipping();
		if (path.isDisposed()) {
			return;
		}
		gc.setClipping(path);
		gc.setForeground(configuration.getBackgroundColor());
		gc.setBackground(configuration.getSecondBackgroundColor());
		gc.fillGradientRectangle(0, gapOnClic, parent.getWidth(), parent.getHeight() - GAP_ON_CLIC, configuration.getGradientDirection() == SWT.VERTICAL);
		gc.setClipping((Rectangle) null);
		path.dispose();
	}

	/**
	 * Creates the clipping.
	 *
	 * @return the advanced path
	 */
	private AdvancedPath createClipping() {
		final AdvancedPath path = new AdvancedPath(parent.getDisplay());
		path.addRoundRectangle(0, gapOnClic, parent.getWidth(), parent.getHeight() - GAP_ON_CLIC, configuration.getCornerRadius(), configuration.getCornerRadius());
		return path;
	}

	/**
	 * Compute starting position.
	 *
	 * @return the int
	 */
	private int computeStartingPosition() {
		final int widthOfTextAndImage = computeSizeOfTextAndImages().x;
		switch (parent.alignment) {
		case SWT.CENTER:
			return (parent.getWidth() - widthOfTextAndImage) / 2;
		case SWT.RIGHT:
			return parent.getWidth() - widthOfTextAndImage - MARGIN;
		default:
			return MARGIN;
		}
	}

	/**
	 * Draw image.
	 *
	 * @param xPosition the x position
	 * @return the int
	 */
	private int drawImage(final int xPosition) {
		final Image image = extractImage();

		if (image == null) {
			return 0;
		}

		final int yPosition = (parent.getHeight() - image.getBounds().height - GAP_ON_CLIC) / 2;
		gc.drawImage(image, xPosition, yPosition + gapOnClic);
		return image.getBounds().width + MARGIN;
	}

	/**
	 * Extract image.
	 *
	 * @return the image
	 */
	private Image extractImage() {
		if ((parent.getStyle() & SWT.ARROW) != 0) {
			if ((parent.getStyle() & SWT.DOWN) != 0) {
				return imageDown;
			}
			if ((parent.getStyle() & SWT.UP) != 0) {
				return imageUp;
			}
			if ((parent.getStyle() & SWT.LEFT) != 0) {
				return imageLeft;
			}
			if ((parent.getStyle() & SWT.RIGHT) != 0) {
				return imageRight;
			}
		}

		if (parent.getImage() == null) {
			return null;
		}

		final Image image;
		if (!parent.isEnabled()) {
			image = disabledImage;
		} else {
			image = parent.getImage();
		}

		return image;
	}

	/**
	 * Draw text.
	 *
	 * @param xPosition the x position
	 */
	private void drawText(final int xPosition) {
		gc.setFont(configuration.getFont());
		gc.setForeground(configuration.getFontColor());

		final Point textSize = gc.stringExtent(parent.getText());
		final int yPosition = (parent.getHeight() - textSize.y - GAP_ON_CLIC) / 2;

		gc.drawText(parent.getText(), xPosition, yPosition + gapOnClic, true);
	}

	/**
	 * Draw button when disabled.
	 *
	 * @param gc the gc
	 * @param parent the parent
	 * @see org.mihalis.opal.obutton.ButtonRenderer#drawButtonWhenDisabled(org.eclipse.swt.graphics.GC,
	 *      org.mihalis.opal.obutton.OButton)
	 */
	@Override
	public void drawButtonWhenDisabled(final GC gc, final OButton parent) {
		this.gc = gc;
		configuration = disabled;
		gapOnClic = 0;
		this.parent = parent;
		draw();
	}

	/**
	 * Draw button when selected.
	 *
	 * @param gc the gc
	 * @param parent the parent
	 * @see org.mihalis.opal.obutton.ButtonRenderer#drawButtonWhenSelected(org.eclipse.swt.graphics.GC,
	 *      org.mihalis.opal.obutton.OButton)
	 */
	@Override
	public void drawButtonWhenSelected(final GC gc, final OButton parent) {
		this.gc = gc;
		configuration = selected;
		gapOnClic = 0;
		this.parent = parent;
		draw();
	}

	/**
	 * Draw button.
	 *
	 * @param gc the gc
	 * @param parent the parent
	 * @see org.mihalis.opal.obutton.ButtonRenderer#drawButton(org.eclipse.swt.graphics.GC,
	 *      org.mihalis.opal.obutton.OButton)
	 */
	@Override
	public void drawButton(final GC gc, final OButton parent) {
		this.gc = gc;
		configuration = normal;
		gapOnClic = 0;
		this.parent = parent;
		draw();
	}

	/**
	 * Draw button when clicked.
	 *
	 * @param gc the gc
	 * @param parent the parent
	 * @see org.mihalis.opal.obutton.ButtonRenderer#drawButtonWhenClicked(org.eclipse.swt.graphics.GC,
	 *      org.mihalis.opal.obutton.OButton)
	 */
	@Override
	public void drawButtonWhenClicked(final GC gc, final OButton parent) {
		this.gc = gc;
		configuration = onclick;
		gapOnClic = GAP_ON_CLIC;
		this.parent = parent;
		draw();
	}

	/**
	 * Compute size.
	 *
	 * @param button the button
	 * @param wHint the w hint
	 * @param hHint the h hint
	 * @param changed the changed
	 * @return the point
	 * @see org.mihalis.opal.obutton.ButtonRenderer#computeSize(org.mihalis.opal.obutton.OButton,
	 *      int, int, boolean)
	 */
	@Override
	public Point computeSize(final OButton button, final int wHint, final int hHint, final boolean changed) {
		parent = button;
		final Point sizeOfTextAndImages = computeSizeOfTextAndImages();
		return new Point(2 * MARGIN + sizeOfTextAndImages.x, 2 * MARGIN + sizeOfTextAndImages.y + GAP_ON_CLIC);
	}

	/**
	 * Compute size of text and images.
	 *
	 * @return the point
	 */
	private Point computeSizeOfTextAndImages() {
		int width = 0, height = 0;
		final boolean textNotEmpty = parent.getText() != null && !parent.getText().equals("");

		if (textNotEmpty) {
			final GC gc = new GC(parent);
			if (configuration == null) {
				gc.setFont(parent.getFont());
			} else {
				gc.setFont(configuration.getFont());
			}

			final Point extent = gc.stringExtent(parent.getText());
			gc.dispose();
			width += extent.x;
			height = extent.y;
		}

		final Point imageSize = new Point(-1, -1);
		computeImageSize(extractImage(), imageSize);

		if (imageSize.x != -1) {
			width += imageSize.x;
			height = Math.max(imageSize.y, height);
			if (textNotEmpty) {
				width += MARGIN;
			}
		}
		return new Point(width, height);
	}

	/**
	 * Compute image size.
	 *
	 * @param image the image
	 * @param imageSize the image size
	 */
	private void computeImageSize(final Image image, final Point imageSize) {
		if (image == null) {
			return;
		}
		final Rectangle imageBounds = image.getBounds();
		imageSize.x = Math.max(imageBounds.width, imageSize.x);
		imageSize.y = Math.max(imageBounds.height, imageSize.y);
	}

}
