/**
 * @class ep.color
 * 
 */

/*
 * @copyright		© Copyright 2006-2010, epages GmbH, All Rights Reserved.
 *
 * @module			ep.color
 *
 * @revision		$Revision: 1.8 $
 */

define("ep/color", [
	"jquery",
	"ep"
], function ($, ep) {

	var nameMap = {
			'aliceblue':			'f0f8ff',
			'antiquewhite':			'faebd7',
			'aqua':					'00ffff',
			'aquamarine':			'7fffd4',
			'azure':				'f0ffff',
			'beige':				'f5f5dc',
			'bisque':				'ffe4c4',
			'black':				'000000',
			'blanchedalmond':		'ffebcd',
			'blue':					'0000ff',
			'blueviolet':			'8a2be2',
			'brown':				'a52a2a',
			'burlywood':			'deb887',
			'cadetblue':			'5f9ea0',
			'chartreuse':			'7fff00',
			'chocolate':			'd2691e',
			'coral':				'ff7f50',
			'cornflowerblue':		'6495ed',
			'cornsilk':				'fff8dc',
			'crimson':				'dc143c',
			'cyan':					'00ffff',
			'darkblue':				'00008b',
			'darkcyan':				'008b8b',
			'darkgoldenrod':		'b8860b',
			'darkgray':				'a9a9a9',
			'darkgrey':				'a9a9a9',
			'darkgreen':			'006400',
			'darkkhaki':			'bdb76b',
			'darkmagenta':			'8b008b',
			'darkolivegreen':		'556b2f',
			'darkorange':			'ff8c00',
			'darkorchid':			'9932cc',
			'darkred':				'8b0000',
			'darksalmon':			'e9967a',
			'darkseagreen':			'8fbc8f',
			'darkslateblue':		'483d8b',
			'darkslategray':		'2f4f4f',
			'darkslategrey':		'2f4f4f',
			'darkturquoise':		'00ced1',
			'darkviolet':			'9400d3',
			'deeppink':				'ff1493',
			'deepskyblue':			'00bfff',
			'dimgray':				'696969',
			'dimgrey':				'696969',
			'dodgerblue':			'1e90ff',
			'firebrick':			'b22222',
			'floralwhite':			'fffaf0',
			'forestgreen':			'228b22',
			'fuchsia':				'ff00ff',
			'gainsboro':			'dcdcdc',
			'ghostwhite':			'f8f8ff',
			'gold':					'ffd700',
			'goldenrod':			'daa520',
			'gray':					'808080',
			'grey':					'808080',
			'green':				'008000',
			'greenyellow':			'adff2f',
			'honeydew':				'f0fff0',
			'hotpink':				'ff69b4',
			'indianred':			'cd5c5c',
			'indigo':				'4b0082',
			'ivory':				'fffff0',
			'khaki':				'f0e68c',
			'lavender':				'e6e6fa',
			'lavenderblush':		'fff0f5',
			'lawngreen':			'7cfc00',
			'lemonchiffon':			'fffacd',
			'lightblue':			'add8e6',
			'lightcoral':			'f08080',
			'lightcyan':			'e0ffff',
			'lightgoldenrodyellow':	'fafad2',
			'lightgray':			'd3d3d3',
			'lightgrey':			'd3d3d3',
			'lightgreen':			'90ee90',
			'lightpink':			'ffb6c1',
			'lightsalmon':			'ffa07a',
			'lightseagreen':		'20b2aa',
			'lightskyblue':			'87cefa',
			'lightslategray':		'778899',
			'lightslategrey':		'778899',
			'lightsteelblue':		'b0c4de',
			'lightyellow':			'ffffe0',
			'lime':					'00ff00',
			'limegreen':			'32cd32',
			'linen':				'faf0e6',
			'magenta':				'ff00ff',
			'maroon':				'800000',
			'mediumaquamarine':		'66cdaa',
			'mediumblue':			'0000cd',
			'mediumorchid':			'ba55d3',
			'mediumpurple':			'9370d8',
			'mediumseagreen':		'3cb371',
			'mediumslateblue':		'7b68ee',
			'mediumspringgreen':	'00fa9a',
			'mediumturquoise':		'48d1cc',
			'mediumvioletred':		'c71585',
			'midnightblue':			'191970',
			'mintcream':			'f5fffa',
			'mistyrose':			'ffe4e1',
			'moccasin':				'ffe4b5',
			'navajowhite':			'ffdead',
			'navy':					'000080',
			'oldlace':				'fdf5e6',
			'olive':				'808000',
			'olivedrab':			'6b8e23',
			'orange':				'ffa500',
			'orangered':			'ff4500',
			'orchid':				'da70d6',
			'palegoldenrod':		'eee8aa',
			'palegreen':			'98fb98',
			'paleturquoise':		'afeeee',
			'palevioletred':		'd87093',
			'papayawhip':			'ffefd5',
			'peachpuff':			'ffdab9',
			'peru':					'cd853f',
			'pink':					'ffc0cb',
			'plum':					'dda0dd',
			'powderblue':			'b0e0e6',
			'purple':				'800080',
			'red':					'ff0000',
			'rosybrown':			'bc8f8f',
			'royalblue':			'4169e1',
			'saddlebrown':			'8b4513',
			'salmon':				'fa8072',
			'sandybrown':			'f4a460',
			'seagreen':				'2e8b57',
			'seashell':				'fff5ee',
			'sienna':				'a0522d',
			'silver':				'c0c0c0',
			'skyblue':				'87ceeb',
			'slateblue':			'6a5acd',
			'slategray':			'708090',
			'slategrey':			'708090',
			'snow':					'fffafa',
			'springgreen':			'00ff7f',
			'steelblue':			'4682b4',
			'tan':					'd2b48c',
			'teal':					'008080',
			'thistle':				'd8bfd8',
			'tomato':				'ff6347',
			'turquoise':			'40e0d0',
			'violet':				'ee82ee',
			'wheat':				'f5deb3',
			'white':				'ffffff',
			'whitesmoke':			'f5f5f5',
			'yellow':				'ffff00',
			'yellowgreen':			'9acd32'
		},

		hexMap = null,

		createHexMap = function(){
			hexMap = {};
			for( var i in nameMap ){
				hexMap[ nameMap[i] ] = i;
			}
		},

		toHex = function(c){
			c = parseInt( c, 10 ).toString(16);
			return c.length < 2 ? "0" + c : c;
		};

	$.extend(ep.color = {}, {

		/**
		 * Convert rgb color to hex color format.
		 * 
		 * Convert a rgb or rgba color object to hex color string.
		 * 
		 * ### Examples
		 * Convert rgb color to hex color format.
		 * 
		 * JavaScript:
		 * 
		 *     ep.color.rgbToHex({
		 *         r:255,
		 *         g:125,
		 *         b:44
		 *     });
		 * 
		 * Results:
		 * 
		 *     #ff7d2c
		 * 
		 * 
		 * @param {Object} rgb A rgb color object.
		 * 
		 * @method rgbToHex
		 * @static 
		 * @member ep.color
		 * 
		 * @since 6.12.0
		 */
		rgbToHex: function( rgb ){
			return rgb.a === 0 ? "transparent" : toHex(rgb.r) + toHex(rgb.g) + toHex(rgb.b);
		},

		/**
		 * Convert rgb color to hsb color format.
		 * 
		 * Convert a rgb or rgba color object to hsb color object.
		 * 
		 * ### Examples
		 * Convert rgb color to hsb color format.
		 * 
		 * JavaScript:
		 * 
		 *     ep.color.rgbToHsb({
		 *         r:255,
		 *         g:125,
		 *         b:44
		 *     });
		 * 
		 * Results:
		 * 
		 *     {
		 *         h:330,
		 *         s:67,
		 *         b:39
		 *     }
		 * 
		 * 
		 * @param {Object} rgb A rgb color object.
		 * 
		 * @method rgbToHsb
		 * @static 
		 * @member ep.color
		 * 
		 * @since 6.12.0
		 */
		rgbToHsb: function(rgb) {
			var min = Math.min( Math.min(rgb.r,rgb.g), rgb.b ),
				max = Math.max( Math.max(rgb.r,rgb.g), rgb.b ),
				delta = (max - min),
				sat = 0,
				lum = 0,
				hue = 0;

			if( max !== 0 ){
				sat = (delta / max) * 100;
				lum = (max / 255) * 100;
			}

			if( delta !== 0 ){
				if( rgb.r===max ){
					hue = (rgb.g - rgb.b) / delta;
				}
				else if( rgb.g===max ){
					hue = 2 + ( (rgb.b - rgb.r) / delta );
				}
				else{
					hue = 4 + ( (rgb.r - rgb.g) / delta );
				}
				hue = (hue * 60);
				hue = hue < 0 ? hue + 360 : hue;
			}

			return {
				h: Math.round(hue),
				s: Math.round(sat),
				b: Math.round(lum)
			};
		},

		/**
		 * Convert rgb color to color name.
		 * 
		 * Convert a rgb or rgba color object to color name string.
		 * Only the '''css color names''' are supported.
		 * 
		 * ### Examples
		 * Convert rgb color to color name.
		 * 
		 * JavaScript:
		 * 
		 *     ep.color.rgbToName({
		 *         r:0,
		 *         g:128,
		 *         b:0
		 *     });
		 * 
		 * Results:
		 * 
		 *     green
		 * 
		 * 
		 * @param {Object} rgb A rgb color object.
		 * 
		 * @method rgbToName
		 * @static 
		 * @member ep.color
		 * 
		 * @since 6.12.0
		 */
		rgbToName: function( rgb ){
			var hex = this.rgbToHex(rgb);
			return this.hexToName( hex );
		},

		/**
		 * Convert hex color to rgb color format.
		 * 
		 * Convert a hex color string to rgba color object.
		 * 
		 * ### Examples
		 * Convert hex color to rgb color format.
		 * 
		 * JavaScript:
		 * 
		 *     ep.color.hexToRgb('#ff7d2c');
		 * 
		 * Results:
		 * 
		 *     {
		 *         r:255,
		 *         g:125,
		 *         b:44,
		 *         a:1
		 *     }
		 * 
		 * 
		 * @param {String} hex A hex color string.
		 * 
		 * @method hexToRgb
		 * @static 
		 * @member ep.color
		 * 
		 * @since 6.12.0
		 */
		hexToRgb: function( hex ) {
			hex = hex.toUpperCase();

			var rgb;

			if( /^(transparent|none)$/.test(hex) ){
				return {
					r:255,
					g:255,
					b:255,
					a:0
				};
			}

			hex = hex.charAt(0) === "#" ? hex.substring(1,hex.length) : hex;

			if( hex.length === 6 ){
				rgb = {
					r: parseInt(hex.substring(0,2),16),
					g: parseInt(hex.substring(2,4),16),
					b: parseInt(hex.substring(4,6),16),
					a: 1
				};
			}
			else if( hex.length === 3){
				rgb = {
					r: parseInt(hex.substring(0,1) + hex.substring(0,1),16),
					g: parseInt(hex.substring(1,2) + hex.substring(1,2),16),
					b: parseInt(hex.substring(2,3) + hex.substring(2,3),16),
					a: 1
				};
			}
			else{
				//return white if no hex value was given
				rgb = {
					r: 255,
					g: 255,
					b: 255,
					a: 1
				};
			}

			rgb.r =  isNaN(rgb.r) ? 0 : Math.round(rgb.r);
			rgb.g =  isNaN(rgb.g) ? 0 : Math.round(rgb.g);
			rgb.b =  isNaN(rgb.b) ? 0 : Math.round(rgb.b);

			return rgb;
		},

		/**
		 * Convert hex color to hsb color format.
		 * 
		 * Convert a hex color string to hsb color object.
		 * 
		 * ### Examples
		 * Convert hex color to hsb color format.
		 * 
		 * JavaScript:
		 * 
		 *     ep.color.hexToHsb('#ff7d2c');
		 * 
		 * Results:
		 * 
		 *     {
		 *         h:23,
		 *         s:83,
		 *         b:100
		 *     }
		 * 
		 * 
		 * @param {String} hex A hex color string.
		 * 
		 * @method hexToHsb
		 * @static 
		 * @member ep.color
		 * 
		 * @since 6.12.0
		 */
		hexToHsb: function( hex ){
			return this.rgbToHsb( this.hexToRgb(hex) );
		},

		/**
		 * Convert hex color to color name.
		 * 
		 * Convert hex color to color name string.
		 * Only the '''css color names''' are supported.
		 * 
		 * ### Examples
		 * Convert hex color to hsb color format.
		 * 
		 * JavaScript:
		 * 
		 *     ep.color.hexToHsb('#008000');
		 * 
		 * Results:
		 * 
		 *     green
		 * 
		 * 
		 * @param {String} hex A hex color string.
		 * 
		 * @method hexToName
		 * @static 
		 * @member ep.color
		 * 
		 * @since 6.12.0
		 */
		hexToName: function( hex ){
			hex = hex.charAt(0) === "#" ? hex.substring(1,hex.length) : hex;

			if(!hexMap){
				createHexMap();
			}

			return hexMap[hex];
		},

		/**
		 * Convert hsb color to rgb color.
		 * 
		 * Convert hsb color object to rgb color object.
		 * 
		 * ### Examples
		 * Convert hsb color to rgb color.
		 * 
		 * JavaScript:
		 * 
		 *     ep.color.hsbToRgb({
		 *         h:23,
		 *         s:83,
		 *         b:100
		 *     });
		 * 
		 * Results:
		 * 
		 *     {
		 *         r:255,
		 *         g:124,
		 *         b:43,
		 *         a:1
		 *     }
		 * 
		 * 
		 * @param {Object} hsb A hsb color object.
		 * 
		 * @method hsbToRgb
		 * @static 
		 * @member ep.color
		 * 
		 * @since 6.12.0
		 */
		hsbToRgb: function(hsb) {
			var rgb = {},
				r = 0,
				g = 0,
				b = 0,
				hue = hsb.h/60,
				sat = hsb.s/100,
				lum = hsb.b/100;

			if( sat === 0 ) {
				r = g = b = lum;
			}
			else {
				var i = parseInt( hue, 10 ),
					p = lum * ( 1.0-sat ),
					q = lum * ( 1.0-sat * (hue-i) ),
					t = lum * ( 1.0-sat * ( 1 - (hue-i) ) );

				switch (i) {
					case 0: r = lum; g = t;   b = p;   break;
					case 1: r = q;   g = lum; b = p;   break;
					case 2: r = p;   g = lum; b = t;   break;
					case 3: r = p;   g = q;   b = lum; break;
					case 4: r = t;   g = p;   b = lum; break;
					case 5: r = lum; g = p;   b = q;   break;
					case 6: r = lum; g = t;   b = p;   break;
				}
			}

			return {
				r: Math.round( r * 255 ),
				g: Math.round( g * 255 ),
				b: Math.round( b * 255 ),
				a: 1
			};
		},

		/**
		 * Convert hsb color to hex color.
		 * 
		 * Convert hsb color object to hex color string.
		 * 
		 * ### Examples
		 * Convert hsb color to hex color.
		 * 
		 * JavaScript:
		 * 
		 *     ep.color.hsbToRgb({
		 *         h:23,
		 *         s:83,
		 *         b:100
		 *     });
		 * 
		 * Results:
		 * 
		 *     #ff7c2b
		 * 
		 * 
		 * @param {Object} hsb A hsb color object.
		 * 
		 * @method hsbToHex
		 * @static 
		 * @member ep.color
		 * 
		 * @since 6.12.0
		 */
		hsbToHex: function( hsb ){
			return this.rgbToHex( this.hsbToRgb(hsb) );
		},

		/**
		 * Convert hsb color to color name.
		 * 
		 * Convert hsb color object to color name.
		 * Only the '''css color names''' are supported.
		 * 
		 * ### Examples
		 * Convert hsb color to color name.
		 * 
		 * JavaScript:
		 * 
		 *     ep.color.hsbToRgb({
		 *         h:120,
		 *         s:100,
		 *         b:50
		 *     });
		 * 
		 * Results:
		 * 
		 *     green
		 * 
		 * 
		 * @param {Object} hsb A hsb color object.
		 * 
		 * @method hsbToName
		 * @static 
		 * @member ep.color
		 * 
		 * @since 6.12.0
		 */
		hsbToName: function( hsb ){
			return this.hexToName( this.hsbToHex(hsb) );
		},

		/**
		 * Convert color name to hex color.
		 * 
		 * Convert a color name string to hex color string.
		 * Only the '''css color names''' are supported.
		 * 
		 * ### Examples
		 * Convert color name to hex color.
		 * 
		 * JavaScript:
		 * 
		 *     ep.color.nameToHex('green');
		 * 
		 * Results:
		 * 
		 *     #008000
		 * 
		 * 
		 * @param {String} color A color name string.
		 * 
		 * @method nameToHex
		 * @static 
		 * @member ep.color
		 * 
		 * @since 6.12.0
		 */
		nameToHex: function( name ){
			name = $.trim( name.toLowerCase() );
			return (/^(transparent|none)$/).test(name) ? 'transparent' : nameMap[name];
		},

		/**
		 * Convert color name to rgb color.
		 * 
		 * Convert a color name string to rgb color object.
		 * Only the '''css color names''' are supported.
		 * 
		 * ### Examples
		 * Convert color name to rgb color.
		 * 
		 * JavaScript:
		 * 
		 *     ep.color.nameToRgb('green');
		 * 
		 * Results:
		 * 
		 *     {
		 *         r:0,
		 *         g:128,
		 *         b:0,
		 *         a:1
		 *     }
		 * 
		 * 
		 * @param {String} color A color name string.
		 * 
		 * @method nameToRgb
		 * @static 
		 * @member ep.color
		 * 
		 * @since 6.12.0
		 */
		nameToRgb: function( name ){
			var hex = this.nameToHex(name);
			return hex ? this.hexToRgb( hex ) : hex;
		},

		/**
		 * Convert color name to hsb color.
		 * 
		 * Convert a color name string to hsb color object.
		 * Only the '''css color names''' are supported.
		 * 
		 * ### Examples
		 * Convert color name to hsb color.
		 * 
		 * JavaScript:
		 * 
		 *     ep.color.nameToHsb('green');
		 * 
		 * Results:
		 * 
		 *     {
		 *         h:120,
		 *         s:100,
		 *         b:50
		 *     }
		 * 
		 * 
		 * @param {String} color A color name string.
		 * 
		 * @method nameToHsb
		 * @static 
		 * @member ep.color
		 * 
		 * @since 6.12.0
		 */
		nameToHsb: function( name ){
			var rgb = this.nameToRgb(name);
			return rgb ? this.rgbToHsb(rgb) : rgb;
		},

		/**
		 * Convert css color string to hex color.
		 * 
		 * Convert a css color string to hex color string.
		 * 
		 * ### Examples
		 * Convert css color string to hex color.
		 * 
		 * JavaScript:
		 * 
		 *     ep.color.stringToHex('green');
		 * 
		 * Results:
		 * 
		 *     #008000
		 * 
		 * Convert css color string to hex color.
		 * 
		 * JavaScript:
		 * 
		 *     ep.color.stringToHex('rgb(0,128,0)');
		 * 
		 * Results:
		 * 
		 *     #008000
		 * 
		 * Convert css color string to hex color.
		 * 
		 * JavaScript:
		 * 
		 *     ep.color.stringToHex('rgba(0,128,0,1)');
		 * 
		 * Results:
		 * 
		 *     #008000
		 * 
		 * 
		 * @param {String} string A css color string.
		 * 
		 * @method stringToHex
		 * @static 
		 * @member ep.color
		 * 
		 * @since 6.12.0
		 */
		stringToHex: function( string, /* internal */ strict ){
			string = $.trim( string.toLowerCase() );

			var result,
				found;

			if( (/^(transparent|none)$/).test(string) ){
				result = "transparent";
			}
			else if( found = (/^#?([0-9a-f]{6})$/).exec(string) ){
				result = found[1];
			}
			else if( found = (/^#?([0-9a-f])([0-9a-f])([0-9a-f])$/).exec(string) ) {
				result = found[1] + found[1] + found[2] + found[2] + found[3] + found[3];
			}
			else if( found = (/^rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)$/).exec(string) ){
				result = this.rgbToHex( {r: found[1], g: found[2], b: found[3]} );
			}
			else if( found = (/^rgba\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-1]{1}(:?\.?[0-9]{1})?)\s*\)$/).exec(string) ){
				result = this.rgbToHex( {r: found[1], g: found[2], b: found[3], a: found[4]} );
			}
			else{
				result = this.nameToHex( string );
			}

			return result===undefined && !strict ? "ffffff" : result;
		},

		/**
		 * Convert css color string to rgb color.
		 * 
		 * Convert a css color string to hex color string.
		 * 
		 * ### Examples
		 * Convert css color string to hex color.
		 * 
		 * JavaScript:
		 * 
		 *     ep.color.stringToRgb('green');
		 * 
		 * Results:
		 * 
		 *     {
		 *         r:0,
		 *         g:128,
		 *         b:0,
		 *         a:1
		 *     }
		 * 
		 * Convert css color string to hex color.
		 * 
		 * JavaScript:
		 * 
		 *     ep.color.stringToRgb('rgb(0,128,0)');
		 * 
		 * Results:
		 * 
		 *     {
		 *         r:0,
		 *         g:128,
		 *         b:0,
		 *         a:1
		 *     }
		 * 
		 * Convert css color string to hex color.
		 * 
		 * JavaScript:
		 * 
		 *     ep.color.stringToRgb('rgba(0,128,0,0.5)');
		 * 
		 * Results:
		 * 
		 *     {
		 *         r:0,
		 *         g:128,
		 *         b:0,
		 *         a:0.5
		 *     }
		 * 
		 * 
		 * @param {String} string A css color string.
		 * 
		 * @method stringToRgb
		 * @static 
		 * @member ep.color
		 * 
		 * @since 6.12.0
		 */
		stringToRgb: function( string ){
			var hex = this.stringToHex(string);
			return hex ? this.hexToRgb(hex) : hex;
		},

		/**
		 * Convert css color string to hsb color.
		 * 
		 * Convert a css color string to hex color string.
		 * 
		 * ### Examples
		 * Convert css color string to hsb color.
		 * 
		 * JavaScript:
		 * 
		 *     ep.color.stringToHsb('green');
		 * 
		 * Results:
		 * 
		 *     {
		 *         h:120,
		 *         s:100,
		 *         b:50
		 *     }
		 * 
		 * Convert css color string to hsb color.
		 * 
		 * JavaScript:
		 * 
		 *     ep.color.stringToHsb('rgb(0,128,0)');
		 * 
		 * Results:
		 * 
		 *     {
		 *         h:120,
		 *         s:100,
		 *         b:50
		 *     }
		 * 
		 * Convert css color string to hsb color.
		 * 
		 * JavaScript:
		 * 
		 *     ep.color.stringToHsb('rgba(0,128,0,0.5)');
		 * 
		 * Results:
		 * 
		 *     {
		 *         h:120,
		 *         s:100,
		 *         b:50
		 *     }
		 * 
		 * 
		 * @param {String} string A css color string.
		 * 
		 * @method stringToHsb
		 * @static 
		 * @member ep.color
		 * 
		 * @since 6.12.0
		 */
		stringToHsb: function( string ){
			var hex = this.stringToHex(string);
			return hex ? this.hexToHsb(hex) : hex;
		},

		/**
		 * Convert css color string to color name.
		 * 
		 * Convert a css color string to color name string.
		 * Only the '''css color names''' are supported.
		 * 
		 * ### Examples
		 * Convert css color string to color name.
		 * 
		 * JavaScript:
		 * 
		 *     ep.color.stringToName('#008000');
		 * 
		 * Results:
		 * 
		 *     green
		 * 
		 * Convert css color string to color name.
		 * 
		 * JavaScript:
		 * 
		 *     ep.color.stringToHsb('rgb(0,128,0)');
		 * 
		 * Results:
		 * 
		 *     green
		 * 
		 * Convert css color string to color name.
		 * 
		 * JavaScript:
		 * 
		 *     ep.color.stringToHsb('rgba(0,128,0,0.5)');
		 * 
		 * Results:
		 * 
		 *     green
		 * 
		 * 
		 * @param {String} string A css color string.
		 * 
		 * @method stringToName
		 * @static 
		 * @member ep.color
		 * 
		 * @since 6.12.0
		 */
		stringToName: function( string ){
			var hex = this.stringToHex(string);
			return hex ? this.hexToName(hex) : hex;
		}
	});

	return ep;

});