package org.skyve.metadata.view.model.chart.colours;

import java.awt.Color;
import java.util.Arrays;

import org.skyve.metadata.view.model.chart.colours.rainbow.Rainbow;
import org.skyve.metadata.view.model.chart.colours.rainbow.RainbowException;

/**
 * Produce a gradient of colours between the default or a specified spectrum (min 2 colours).
 * 
 * @author ben
 */
public class RainbowColourSeries extends ColourSeries {

	private Rainbow rainbow;
	private int currentRainbowIndex = 1;
	private String[] spectrum = { "ff6385", "ffa040", "ffcc56", "4bc0c0", "36a3eb", "9966ff", "c9cbcf" };

	public RainbowColourSeries() {
		this.rainbow = new Rainbow();
		rainbow.setSpectrum(spectrum);
		rainbow.setNumberRange(0, size < spectrum.length ? spectrum.length : size);
		current = getColor(0);
	}

	public RainbowColourSeries(String... spectrum) {
		this();
		if (spectrum.length > 0) {
			this.spectrum = spectrum;
			rainbow.setSpectrum(spectrum);
			rainbow.setNumberRange(0, size < spectrum.length ? spectrum.length : size);
		}
		current = getColor(0);
	}

	@Override
	public Color next() {
		current = getColor(++currentRainbowIndex);
		return current;
	}

	@Override
	public void setSize(int size) {
		super.setSize(size);

		if (size <= 10) {
			// trim the spectrum if 10 or fewer
			rainbow.setSpectrum(Arrays.copyOf(spectrum, spectrum.length - 1));
		}

		rainbow.setNumberRange(0, size < spectrum.length ? spectrum.length : size);
	}

	/**
	 * Sets the spectrum of the Rainbow. By default, the spectrum is a rainbow between the
	 * default chartjs colours. You must have a minimum of two colours, but you can specify
	 * more than two colours.
	 * 
	 * Colours can be in the form "red", "ff0000", or "#ff0000".
	 * For example, <code>rainbowColourSeries.setSpectrum("red", "yellow", "white");</code>
	 * makes the "Rainbow" a colour gradient from red to yellow to white.
	 * 
	 * @param spectrum Two or more Strings representing HTML colours,
	 *        or pass in a whole String array of length 2 or greater
	 * @throws RainbowException if there is less than two arguments or if one of the arguments
	 *         is an invalid colour
	 */
	public void setSpectrum(String... spectrum) throws RainbowException {
		this.rainbow.setSpectrum(spectrum);
	}

	@SuppressWarnings("boxing")
	private Color getColor(int index) {
		String hex = rainbow.colorAt(index);
		return new Color(
				Integer.valueOf(hex.substring(0, 2), 16),
				Integer.valueOf(hex.substring(2, 4), 16),
				Integer.valueOf(hex.substring(4, 6), 16));
	}
}

@@ -518,78 +518,232 @@
  = %7B
- %22ff6385%22, %22ffa040%22, %22ffcc56%22, %224bc0c0%22, %2236a3eb%22, %229966ff%22, %22c9cbcf%22 
+%0A%09%09%09%2236a3eb%22, // light blue%0A%09%09%09%22257dbe%22, // blue%0A%09%09%09%224bc0c0%22, // cyan%0A%09%09%09%22248669%22, // teal%0A%09%09%09%229966ff%22, // purple%0A%09%09%09%22b172b2%22, // violet%0A%09%09%09%22ff6385%22, // red%0A%09%09%09%22ffa040%22, // orange%0A%09%09%09%22ffcc56%22, // yellow%0A%09%09%09%22c9cbcf%22 // grey%0A%09
 %7D;%0A%0A

Update default colour in RainbowColourSeries to be blue, add more seed colours to the gradient