/*******************************************************************************
 * 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.brushedMetalComposite;

import java.util.Random;

import org.eclipse.swt.SWT;
import org.eclipse.swt.SWTException;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.PaletteData;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Widget;
import org.mihalis.opal.utils.SWTGraphicUtil;

/**
 * Instances of this class are controls which background's texture is brushed
 * metal "a la Mac"
 * This work is inspired by the article "Creating a brushed metal texture" by Jerry Huxtable (http://www.jhlabs.com/ip/brushed_metal.html)
 */
public class BrushedMetalComposite extends Composite {

	/** The old image. */
	private Image oldImage;
	
	/** The radius. */
	private int radius = 10;
	
	/** The amount. */
	private float amount = 0.1f;
	
	/** The color. */
	private int color = 0xff888888;
	
	/** The shine. */
	private float shine = 0.1f;
	
	/** The monochrome. */
	private boolean monochrome = true;
	
	/** The random numbers. */
	private Random randomNumbers;
	
	/** The palette. */
	private final PaletteData palette = new PaletteData(0xFF0000, 0x00FF00, 0x0000FF);
	
	/** The image data. */
	private ImageData imageData;

	/**
	 * 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 widget which will be the parent of the new instance
	 *            (cannot be null)
	 * @param style the style of widget to construct
	 * @see Composite#Composite(Composite, int)
	 * @see SWT#NO_BACKGROUND
	 * @see SWT#NO_FOCUS
	 * @see SWT#NO_MERGE_PAINTS
	 * @see SWT#NO_REDRAW_RESIZE
	 * @see SWT#NO_RADIO_GROUP
	 * @see SWT#EMBEDDED
	 * @see SWT#DOUBLE_BUFFERED
	 * @see Widget#getStyle
	 * @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>
	 */
	public BrushedMetalComposite(final Composite parent, final int style) {
		super(parent, style);
		addListeners(parent);
	}

	/**
	 * Adds the listeners.
	 *
	 * @param parent the parent
	 */
	private void addListeners(final Composite parent) {
		this.addListener(SWT.Resize, new Listener() {
			@Override
			public void handleEvent(final Event event) {
				createBrushedMetalBackground();
				paintControl();
			}
		});

		parent.addDisposeListener(new DisposeListener() {
			@Override
			public void widgetDisposed(final DisposeEvent e) {
				SWTGraphicUtil.safeDispose(BrushedMetalComposite.this.oldImage);
			}
		});
	}

	/**
	 * Paint the component.
	 */
	private void paintControl() {
		final Display display = getDisplay();
		final Image newImage = new Image(display, this.imageData);

		setBackgroundImage(newImage);
		SWTGraphicUtil.safeDispose(this.oldImage);
		this.oldImage = newImage;
	}

	/**
	 * Create a brushed metal background.
	 *
	 * @return an image data that contains the background
	 */
	private void createBrushedMetalBackground() {

		final Rectangle rect = getClientArea();
		final int width = Math.max(1, rect.width);
		final int height = Math.max(1, rect.width);

		final int[] inPixels = new int[width];

		this.imageData = new ImageData(width, height, 0x20, this.palette);

		this.randomNumbers = new Random(0);
		final int a = this.color & 0xff000000;
		final int r = this.color >> 16 & 0xff;
		final int g = this.color >> 8 & 0xff;
		final int b = this.color & 0xff;
		for (int y = 0; y < height; y++) {
			for (int x = 0; x < width; x++) {
				int tr = r;
				int tg = g;
				int tb = b;
				if	( Float.compare( this.shine, (float) 0.0 ) != 0 ) {
					final int f = (int) (255 * this.shine * Math.sin((double) x / width * Math.PI));
					tr += f;
					tg += f;
					tb += f;
				}
				if (this.monochrome) {
					final int n = (int) (255 * (2 * this.randomNumbers.nextFloat() - 1) * this.amount);
					inPixels[x] = a | this.clamp(tr + n) << 16 | this.clamp(tg + n) << 8 | this.clamp(tb + n);
				} else {
					inPixels[x] = a | this.random(tr) << 16 | this.random(tg) << 8 | this.random(tb);
				}
			}

			if (this.radius != 0) {
				setDataElements(0, y, width, 1, this.blur(inPixels, width, this.radius));
			} else {
				setDataElements(0, y, width, 1, inPixels);
			}
		}

	}

	/**
	 * Sets the data for a rectangle of pixels from a primitive array.
	 *
	 * @param posX The X coordinate of the upper left pixel location.
	 * @param posY The Y coordinate of the upper left pixel location.
	 * @param width Width of the pixel rectangle.
	 * @param height Height of the pixel rectangle
	 * @param pixels An array containing the pixel data to place between x,y and
	 *            x+w-1, y+h-1.
	 */
	private void setDataElements(final int posX, final int posY, final int width, final int height, final int[] pixels) {
		int cpt = 0;
		for (int y = posY; y < posY + height; y++) {
			for (int x = posX; x < posX + width; x++) {
				final int rgb = pixels[cpt++];
				final int pixel = this.palette.getPixel(new RGB(rgb >> 16 & 0xFF, rgb >> 8 & 0xFF, rgb & 0xFF));
				this.imageData.setPixel(x, y, pixel);
				this.imageData.setAlpha(x, y, rgb >> 24 & 0xFF);
			}
		}
	}

	/**
	 * Add a random number to the value. The result is between 0 and 255
	 *
	 * @param x the initial value
	 * @return the int
	 */
	private int random(int x) {
		x += (int) (255 * (2 * this.randomNumbers.nextFloat() - 1) * this.amount);
		if (x < 0) {
			x = 0;
		} else if (x > 0xff) {
			x = 0xff;
		}
		return x;
	}

	/**
	 * Clamp a number between 0 and 255.
	 *
	 * @param c the number to clamp
	 * @return the number. If c is negative, returns 0. If c is greater than
	 *         255, returns 255.
	 */
	private int clamp(final int c) {
		if (c < 0) {
			return 0;
		}

		if (c > 255) {
			return 255;
		}

		return c;
	}

	/**
	 * Apply a blur filter to an array of int that represents and image which
	 * size is width columns * 1 row.
	 *
	 * @param in the array of int that represents the image
	 * @param width the width of the image
	 * @param radius the "radius" blur parameter
	 * @return the int[]
	 */
	private int[] blur(final int[] in, final int width, final int radius) {
		final int[] out = new int[width];
		final int widthMinus1 = width - 1;
		final int r2 = 2 * radius + 1;
		int tr = 0, tg = 0, tb = 0;

		for (int i = -radius; i <= radius; i++) {
			final int rgb = in[this.mod(i, width)];
			tr += rgb >> 16 & 0xff;
			tg += rgb >> 8 & 0xff;
			tb += rgb & 0xff;
		}

		for (int x = 0; x < width; x++) {
			out[x] = 0xff000000 | tr / r2 << 16 | tg / r2 << 8 | tb / r2;

			int i1 = x + radius + 1;
			if (i1 > widthMinus1) {
				i1 = this.mod(i1, width);
			}
			int i2 = x - radius;
			if (i2 < 0) {
				i2 = this.mod(i2, width);
			}
			final int rgb1 = in[i1];
			final int rgb2 = in[i2];

			tr += (rgb1 & 0xff0000) - (rgb2 & 0xff0000) >> 16;
			tg += (rgb1 & 0xff00) - (rgb2 & 0xff00) >> 8;
			tb += (rgb1 & 0xff) - (rgb2 & 0xff);
		}
		return out;
	}

	/**
	 * Return a mod b. This differs from the % operator with respect to negative
	 * numbers.
	 * 
	 * @param a the dividend
	 * @param b the divisor
	 * @return a mod b
	 */
	private int mod(int a, final int b) {
		final int n = a / b;

		a -= n * b;
		if (a < 0) {
			return a + b;
		}
		return a;
	}

	// ------------------------------------ Getters and Setters

	/**
	 * Gets the radius.
	 *
	 * @return the "radius" of the blur
	 */
	public int getRadius() {
		return this.radius;
	}

	/**
	 * Sets the radius.
	 *
	 * @param radius the "radius" of the blur
	 */
	public void setRadius(final int radius) {
		this.radius = radius;
		createBrushedMetalBackground();
		paintControl();
	}

	/**
	 * Gets the amount.
	 *
	 * @return the amount of noise to add
	 */
	public float getAmount() {
		return this.amount;
	}

	/**
	 * Sets the amount.
	 *
	 * @param amount the amount of noise to add
	 * @exception IllegalArgumentException <ul>
	 *                <li>ERROR_INVALID_ARGUMENT - if the value is not between 0
	 *                and 1 inclusive</li>
	 *                </ul>
	 */
	public void setAmount(final float amount) {
		if (amount < 0f || amount > 1f) {
			SWT.error(SWT.ERROR_INVALID_ARGUMENT);
		}
		this.amount = amount;
		createBrushedMetalBackground();
		paintControl();
	}

	/**
	 * Gets the color.
	 *
	 * @return the color of the metal. Please notice that this color is a new
	 *         SWT object, so it has to be disposed !
	 */
	public Color getColor() {
		return new Color(this.getDisplay(), this.color >> 16 & 0xFF, this.color >> 8 & 0xFF, this.color & 0xFF);
	}

	/**
	 * Sets the color.
	 *
	 * @param color the color to set
	 * @exception IllegalArgumentException <ul>
	 *                <li>ERROR_NULL_ARGUMENT - if the value is null</li>
	 *                </ul>
	 */
	public void setColor(final Color color) {
		if (color == null) {
			SWT.error(SWT.ERROR_NULL_ARGUMENT);
			return;	// to satisfy SONAR
		}
		this.color = 0xFF << 24 | color.getRed() << 16 | color.getGreen() << 8 | color.getBlue();
		createBrushedMetalBackground();
		;
		paintControl();
	}

	/**
	 * Gets the shine.
	 *
	 * @return the shine to add
	 */
	public float getShine() {
		return this.shine;
	}

	/**
	 * Sets the shine.
	 *
	 * @param shine the shine to set
	 * @exception IllegalArgumentException <ul>
	 *                <li>ERROR_INVALID_ARGUMENT - if the value is not between 0
	 *                and 1 inclusive</li>
	 *                </ul>
	 */
	public void setShine(final float shine) {
		if (this.amount < 0f || this.amount > 1f) {
			SWT.error(SWT.ERROR_INVALID_ARGUMENT);
		}
		this.shine = shine;
		createBrushedMetalBackground();
		paintControl();
	}

	/**
	 * Checks if is monochrome.
	 *
	 * @return the monochrome
	 */
	public boolean isMonochrome() {
		return this.monochrome;
	}

	/**
	 * Sets the monochrome.
	 *
	 * @param monochrome the monochrome to set
	 */
	public void setMonochrome(final boolean monochrome) {
		this.monochrome = monochrome;
		createBrushedMetalBackground();
		paintControl();
	}

}
