/*
 * Copyright (c) 2014 Paul Scherrer Institute. All rights reserved.
 */
package ch.psi.plot.jfree;

import java.awt.Color;

/**
 * Utility class for applying a color map
 */
public class ColorManager {

    /**
     * Get color for a given value
     *
     * @param v	Value to get the color for
     * @param vmin	Lower end value mapped to the lower end of the color map
     * @param vmax	Upper end value mapped to the upper end of the color map
     * @return	Mapped color for the specified value
     */
    public static Color getColourForValue(double v, double vmin, double vmax) {
		// Standard algorithm for hot-cold color gradient (copied from 
        // http://local.wasp.uwa.edu.au/~pbourke/texture_colour/colourramp/)

        //Init color to white
        double r = 1.0;
        double g = 1.0;
        double b = 1.0;

        double dv;

        if (v < vmin) {
            v = vmin;
        }
        if (v > vmax) {
            v = vmax;
        }
        dv = vmax - vmin;

        if (v < (vmin + 0.25 * dv)) {
            r = 0.0;
            g = 4 * (v - vmin) / dv;
        } else if (v < (vmin + 0.5 * dv)) {
            r = 0.0;
            b = 1 + 4 * (vmin + 0.25 * dv - v) / dv;
        } else if (v < (vmin + 0.75 * dv)) {
            r = 4 * (v - vmin - 0.5 * dv) / dv;
            b = 0.0;
        } else {
            g = 1 + 4 * (vmin + 0.75 * dv - v) / dv;
            b = 0.0;
        }

        return new Color(new Double(255.0 * r).intValue(), new Double(255.0 * g).intValue(), new Double(255.0 * b).intValue());
    }

    /**
     * Get a gray value for a given value
     *
     * @param value the value (must be within the range specified by the lower
     * and upper bounds for the scale).
     *
     * @return a gray scale color.
     */
    public static Color getGrayForValue(double value, double vmin, double vmax) {
        double v = Math.max(value, vmin);
        v = Math.min(v, vmax);
        int g = (int) ((v - vmin) / (vmax - vmin) * 255.0);
        // FIXME:  it probably makes sense to allocate an array of 256 Colors
        // and lazily populate this array...
        return new Color(g, g, g);
    }
}
