
function HsvType(h, s, v) {
	var me = this;
	this.h = h;
	this.s = s;
	this.v = v;
	
	this.toString = function() {
		return 'h:' + me.h + ' s:' + me.s + ' v:' + me.v;
	}

	this.toRgb = function(isRyb) {
		var h = me.h, s = me.s, v = me.v, m, n, f, i;  
		if(h == null) return new RgbType(v, v, v);  
		h *= 6;
		if (isRyb) h = hsv2ryb(h);
		i = Math.floor(h);  
		f = h - i;  
		if(!(i % 2)) {
			// if i is even  
			f = 1 - f; 
		}
		m = v * (1 - s);  
		n = v * (1 - s * f);  
		switch (i) {  
			case 6:  
			case 0: return new RgbType(v, n, m);  
			case 1: return new RgbType(n, v, m);  
			case 2: return new RgbType(m, v, n)  
			case 3: return new RgbType(m, n, v);  
			case 4: return new RgbType(n, m, v);  
			case 5: return new RgbType(v, m, n);  
		}  
	} 
	
	this.applyDelta = function(dHsv, mHsv) {
		me.h = me.getDelta(dHsv.h, me.h, mHsv.h);
		me.s = me.getDelta(dHsv.s, me.s, mHsv.s);
		me.v = me.getDelta(dHsv.v, me.v, mHsv.v);
	}
	
	this.getDelta = function (d, v, m) {
//		if(debug) logger.dump('hsv.getDelta(d='+d+', v='+v+', m='+m+')');
		if (d != null)	{
			v = m + d;
			if (v > 1) v --;
			if (v < 0) v ++;
		}
		return v;
	}

	this.set = function (val, valueType) {
//		if(debug) logger.dump('hsv set setting type: ['+valueType+'] value: ['+val+']');
		switch(valueType) {
			case HUE:
				if (me.h == val) {
					return false;
				}
				me.h = val;
				return true;
				break;
			case SAT:
				if (me.s == val) {
					return false;
				}
				me.s = val;
				return true;
				break;
			case VAL:
				if (me.v == val) {
					return false;
				}
				me.v = val;
				return true;
				break;
			default:
				if(debug) logger.dump('hsv set failed. type: ['+valueType+'] not found');
				break;
		}
	}

	this.toStandardHue = function(h) {
		return hsv2ryb(h * 6) / 6;
	}		

	this.toRybHue = function(h) {
		return ryb2hsv(h * 6) / 6;
		return h;
	}		

	this.get = function (valueType) {
		var ret;
		switch(valueType) {
			case HUE:
				ret = me.h;
				break;
			case SAT:
				ret = me.s;
				break;
			case VAL:
				ret = me.v;
				break;
		}
//		if(debug) logger.dump('hsv get returning type: ['+valueType+'] value: ['+ret+']');
		return ret;
	}

}

function ryb2hsv (h) {
	if (h < 1) {
		h *= 2;
	} else if (h < 2 ) {
		h ++;			
	} else if (h < 4) {
		h -= 2;	
		h /= 2;
		h += 3;
	}
	return h;
}
/*
	tweaks hsv curve a bit to make thing like complimemtary
	color work.
		    HSV     MINE
		0 000-060     000-120  1-1 red 0-1 green
		1 060-120     120-180  1-0 red 1-1 green
		2 120-180     180-210          1-1 green 0-1 blue
		3 180-240     210-240          1-0 green 1-1 blue
		4 240-300     240-300  0-1 red           1-1 blue
		5 300-360     300-360  1-1 red           1-0 blue
*/
function hsv2ryb (h) {
	if (h < 2) { 			
		h /= 2;
	} else if (h < 3 ) {
		h --;
	} else if (h < 4 ) {	
		h -= 3;
		h *= 2;
		h += 2;
	}
	return h;
}

function RgbType(r, g, b) {
	var me = this;
	this.r = r;
	this.b = b;
	this.g = g;

	this.set = function (val, valueType) {
		switch(valueType) {
			case RED:
				if (me.r == val) {
					return false;
				}
				me.r = val;
				return true;
				break;
			case GREEN:
				if (me.g == val) {
					return false;
				}
				me.g = val;
				break;
				return true;
			case BLUE:
				if (me.b == val) {
					return false;
				}
				me.b = val;
				return true;
				break;
			default:
				if(debug) logger.dump('rgb set failed. type: ['+valueType+'] not found');
				break;
		}
	}
	
	this.get = function (valueType) {
		switch(valueType) {
			case RED:
				return me.r;
			case GREEN:
				return me.g;
			case BLUE:
				return me.b;
			default:
				if(debug) logger.dump('rgb get failed. type: ['+valueType+'] not found');
				break;
		}
	}
	
	this.toString = function() {
		return 'r:' + me.r + ' g:' + me.g + ' b:' + me.b;
	}

	this.getHex = function () {
		var hr = utils.decToBase(Math.round(me.r * 255), 16);
		if (hr.length == 1) hr = '0' + hr;
		var hg = utils.decToBase(Math.round(me.g * 255), 16);
		if (hg.length == 1) hg = '0' + hg;
		var hb = utils.decToBase(Math.round(me.b * 255), 16);
		if (hb.length == 1) hb = '0' + hb;
		return hr + hg + hb;
	}

	this.toHsv = function(isRyb) {
		var r = me.r, g = me.g, b = me.b, v, x, f, i;
		x = Math.min(r, Math.min(g, b));  
		v = Math.max(r, Math.max(g, b));  
		if (v == x) {
			return new HsvType(null, 0, v);  
		}
		f = (r == x? g - b : (g == x? b - r : r - g));  
		i = (r == x? 3 : (g == x? 5 : 1));  
		var h = (i - f /(v - x));
		if (isRyb) h = hsv2ryb(h);
		return new HsvType(h / 6, (v - x)/v, v);  
	} 
}

