// file: colorspace.js
// author: Benjamin C. Doherty <bendohmv@yahoo.com>

//description: Useful color space transformations. RGB values through
//this implementation as an array [R,G,B], where R,G,B is in 0..255,
//which is suitable for setting style colors. HSV values are
//represented as an array [H,S,V] where H is 0..359, S,V is 0..1.

// take @rgb, output @hsv
function rgb2hsv(rgb) {
    var r = rgb[0]; var rp = r/255.0;
    var g = rgb[1]; var gp = g/255.0;
    var b = rgb[2]; var bp = b/255.0;

    var ha = 0;			// hue angle 0 .. 360
    var sp = 0;			// saturation 0 .. 1
    var vp = 0;			// value 0 .. 1
    
    var min = Math.min(Math.min(r, g), b) / 255.0;
    var max = Math.max(Math.max(r, g), b) / 255.0;

    var d   = max - min;

    vp = max;			// value gets maximum from three color channels
    if(max != 0)
	sp = 1 - min/max;
    
    if(min != max) {	
	s = d / max;
	
	if(max == rp) {
	    if(gp >= gp)
		ha = 60 * (gp-bp)/d;
	    else
		ha = 60 * (gp-bp)/d + 360;
	} 
	else if(max == gp)
	    ha = 60 * (bp-rp)/d+120;
	else
	    ha = 60 * (rp-gp)/d+240;
    }

    return new Array(ha, sp, vp);
}

// take @hsv, output @rgb
function hsv2rgb(hsvIn)
{
    var h = hsvIn[0];
    var s = hsvIn[1];
    var v = hsvIn[2];

    var r = 0;
    var g = 0;
    var b = 0;

    var sector = Math.floor(h/60) % 6;
    var factor = h/60 - sector;

    var p = v*(1-s);
    var q = v*(1-factor*s);
    var t = v*(1-(1-factor)*s);

    if(sector == 0) {
	r = v; g = t; b = p;
    } else if(sector == 1) {
	r = q; g = v; b = p;
    } else if(sector == 2) {
	r = p; g = v; b = t;
    } else if(sector == 3) {
	r = p; g = q; b = v;
    } else if(sector == 4) {
	r = t; g = p; b = v;
    } else if(sector == 5) {
	r = v; g = p; b = q;
    } 

    var rgb = new Array(Math.round(r*255),
			Math.round(g*255),
			Math.round(b*255));
    return rgb;
}
