/*
Copyright (c) 2007 John Dyer (http://johndyer.name)
MIT style license
*/

if (!window.Refresh) Refresh = {};
if (!Refresh.Web) Refresh.Web = {};

Refresh.Web.Color = function(init) {	
	var color = {
		r: 0,
		g: 0,
		b: 0,
		
		h: 0,
		s: 0,
		v: 0,
		
		hex: '',
		
		setRgb: function(r, g, b) {
			this.r = r;
			this.g = g;
			this.b = b;
						
			var newHsv = Refresh.Web.ColorMethods.rgbToHsv(this);
			this.h = newHsv.h;
			this.s = newHsv.s;
			this.v = newHsv.v;
			
			this.hex = Refresh.Web.ColorMethods.rgbToHex(this);					
		},
		
		setHsv: function(h, s, v) {
			this.h = h;
			this.s = s;
			this.v = v;
			
			var newRgb = Refresh.Web.ColorMethods.hsvToRgb(this);
			this.r = newRgb.r;
			this.g = newRgb.g;
			this.b = newRgb.b;	
			
			this.hex = Refresh.Web.ColorMethods.rgbToHex(newRgb);	
		},
		
		setHex: function(hex) {
			this.hex = hex;
			
			var newRgb = Refresh.Web.ColorMethods.hexToRgb(this.hex);
			this.r = newRgb.r;
			this.g = newRgb.g;
			this.b = newRgb.b;
			
			var newHsv = Refresh.Web.ColorMethods.rgbToHsv(newRgb);
			this.h = newHsv.h;
			this.s = newHsv.s;
			this.v = newHsv.v;			
		}
	};
	
	if (init) {
		if (init.hex)
			color.setHex(init.hex);
		else if (init.r)
			color.setRgb(init.r, init.g, init.b);
		else if (init.h)
			color.setHsv(init.h, init.s, init.v);			
	}
	
	return color;
};
Refresh.Web.ColorMethods = {
	hexToRgb: function(hex) {
		hex = this.validateHex(hex);

		var r='00', g='00', b='00';
		
		/*
		if (hex.length == 3) {
			r = hex.substring(0,1);
			g = hex.substring(1,2);
			b = hex.substring(2,3);
		} else if (hex.length == 6) {
			r = hex.substring(0,2);
			g = hex.substring(2,4);
			b = hex.substring(4,6);
		*/
		if (hex.length == 6) {
			r = hex.substring(0,2);
			g = hex.substring(2,4);
			b = hex.substring(4,6);	
		} else {
			if (hex.length > 4) {
				r = hex.substring(4, hex.length);
				hex = hex.substring(0,4);
			}
			if (hex.length > 2) {
				g = hex.substring(2,hex.length);
				hex = hex.substring(0,2);
			}
			if (hex.length > 0) {
				b = hex.substring(0,hex.length);
			}					
		}
		
		return { r:this.hexToInt(r), g:this.hexToInt(g), b:this.hexToInt(b) };
	},
	validateHex: function(hex) {
		hex = new String(hex).toUpperCase();
		hex = hex.replace(/[^A-F0-9]/g, '0');
		if (hex.length > 6) hex = hex.substring(0, 6);
		return hex;
	},
	webSafeDec: function (dec) {
		dec = Math.round(dec / 51);
		dec *= 51;
		return dec;
	},
	hexToWebSafe: function (hex) {
		var r, g, b;

		if (hex.length == 3) {
			r = hex.substring(0,1);
			g = hex.substring(1,1);
			b = hex.substring(2,1);
		} else {
			r = hex.substring(0,2);
			g = hex.substring(2,4);
			b = hex.substring(4,6);
		}
		return intToHex(this.webSafeDec(this.hexToInt(r))) + this.intToHex(this.webSafeDec(this.hexToInt(g))) + this.intToHex(this.webSafeDec(this.hexToInt(b)));
	},
	rgbToWebSafe: function(rgb) {
		return {r: this.webSafeDec(rgb.r), g: this.webSafeDec(rgb.g), b: this.webSafeDec(rgb.b) };
	},
	rgbToHex: function (rgb) {
		return this.intToHex(rgb.r) + this.intToHex(rgb.g) + this.intToHex(rgb.b);
	},
	intToHex: function (dec){
		var result = (parseInt(dec).toString(16));
		if (result.length == 1)
			result = ("0" + result);
		return result.toUpperCase();
	},
	hexToInt: function (hex){
		return(parseInt(hex,16));
	},
	rgbToHsv: function (rgb) {

		var r = rgb.r / 255;
		var g = rgb.g / 255;
		var b = rgb.b / 255;

		hsv = {h:0, s:0, v:0};

		var min = 0
		var max = 0;

		if (r >= g && r >= b) {
			max = r;
			min = (g > b) ? b : g;
		} else if (g >= b && g >= r) {
			max = g;
			min = (r > b) ? b : r;
		} else {
			max = b;
			min = (g > r) ? r : g;
		}

		hsv.v = max;
		hsv.s = (max) ? ((max - min) / max) : 0;

		if (!hsv.s) {
			hsv.h = 0;
		} else {
			delta = max - min;
			if (r == max) {
				hsv.h = (g - b) / delta;
			} else if (g == max) {
				hsv.h = 2 + (b - r) / delta;
			} else {
				hsv.h = 4 + (r - g) / delta;
			}

			hsv.h = parseInt(hsv.h * 60);
			if (hsv.h < 0) {
				hsv.h += 360;
			}
		}
		
		hsv.s = parseInt(hsv.s * 100);
		hsv.v = parseInt(hsv.v * 100);

		return hsv;
	},
	hsvToRgb: function (hsv) {

		rgb = {r:0, g:0, b:0};
		
		var h = hsv.h;
		var s = hsv.s;
		var v = hsv.v;

		if (s == 0) {
			if (v == 0) {
				rgb.r = rgb.g = rgb.b = 0;
			} else {
				rgb.r = rgb.g = rgb.b = parseInt(v * 255 / 100);
			}
		} else {
			if (h == 360) {
				h = 0;
			}
			h /= 60;

			// 100 scale
			s = s/100;
			v = v/100;

			var i = parseInt(h);
			var f = h - i;
			var p = v * (1 - s);
			var q = v * (1 - (s * f));
			var t = v * (1 - (s * (1 - f)));
			switch (i) {
				case 0:
					rgb.r = v;
					rgb.g = t;
					rgb.b = p;
					break;
				case 1:
					rgb.r = q;
					rgb.g = v;
					rgb.b = p;
					break;
				case 2:
					rgb.r = p;
					rgb.g = v;
					rgb.b = t;
					break;
				case 3:
					rgb.r = p;
					rgb.g = q;
					rgb.b = v;
					break;
				case 4:
					rgb.r = t;
					rgb.g = p;
					rgb.b = v;
					break;
				case 5:
					rgb.r = v;
					rgb.g = p;
					rgb.b = q;
					break;
			}

			rgb.r = parseInt(rgb.r * 255);
			rgb.g = parseInt(rgb.g * 255);
			rgb.b = parseInt(rgb.b * 255);
		}

		return rgb;
	}
};