//http://www.webreference.com/programming/javascript/mk/column3/4.html

(function colorPickerNamespace(){
	var cp = null;

	var imgBase = 'images/';

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

	function mouseCoordinates(ev){
		ev = ev || window.event;
		if(ev.pageX || ev.pageY)
			return {x:ev.pageX, y:ev.pageY};
		return {x:ev.clientX + document.body.scrollLeft - document.body.clientLeft,
				  y:ev.clientY + document.body.scrollTop  - document.body.clientTop};
	}

	function getPosition(obj){
		var left = 0;
		var top  = 0;

		while (obj.offsetParent){
			left += obj.offsetLeft;
			top  += obj.offsetTop;
			obj   = obj.offsetParent;
		}
		left += obj.offsetLeft;
		top  += obj.offsetTop;

		return {x:left, y:top};
	}

	function $DOM(A){
		var aL = A.length, node, child, ref={}, bRef=false;
		if(aL>=1){
			node = cE(A[0]);
			if(aL>=2){
				for(var arg in A[1]){
					if(arg.indexOf('on')==0){
						node[arg] = A[1][arg];
					}else if(arg=='ref'){
						ref[A[1][arg]] = node;
						ref['DOM']     = node;
						bRef           = true;
					}else{
						if(arg=='style'){
							node.style.cssText   = A[1][arg];
						} else if(arg.toLowerCase()=='classname'){
							node.style.className = A[1][arg];
						} else {
							node.setAttribute(arg, A[1][arg]);
						}
					}
				}
			}
			for(var i=2; i<aL; i++){
				if(typeof(A[i])=='string'){
					node.appendChild(document.createTextNode(A[i]));
				} else {
					child = $DOM(A[i]);
					if(child.DOM){
						bRef = true;
						for(n in child){
							if(n=='DOM'){
								node.appendChild(child[n]);
							}else{
								ref[n] = child[n];
							}
						}
						ref['DOM'] = node;
					}else{
						node.appendChild(child);
					}
				}
			}
			return bRef?ref:node;
		}
		return null;
	}

	function cE(){
		var A = arguments;

		if(!cE.cache[A[0]]) cE.cache[A[0]]=document.createElement(A[0]);
		return cE.cache[A[0]].cloneNode(false);
	}
	cE.cache    = {};

	function createColorPicker(coords){
		if(cp) return;
		var cx = coords.x + 10;
		var cy = coords.y + 55;
		cp = $DOM(
			['DIV', {style:'top:' + cy + 'px;left:' + cx + 'px;position:absolute;font-family:tahoma,verdana,sans-serif;font-size:10px;', ref:'ColorPicker'},
				['DIV', {style:'background-color:#FFF;line-height:2px;width:402px;height:21px;border:1px solid #000;', ref:'hColorPicker'},
					['DIV', {style:'width:50px;height:21px;border-right:1px solid #FFF;float:left;', ref:'hColorDiv'}],
					['DIV', {style:'float:left;'},
						['IMG', {style:'cursor:crosshair;', src:imgBase+'cp_horizontal_picker.png', width:350, height:21, onmousemove:hColorPickerMouseMove, onmousedown:hColorPickerMouseDown, ref:'hColorImg'}]
					]
				]
			]);

		document.onmousemove         = cpMouseMove;
		cp.baseColor                 = {r:0, g:0, b:0};

		document.body.appendChild(cp.ColorPicker);
		cp.ColorPicker.style.display = 'none';
	}

	function getHorizColor(i, width, height){
		var sWidth = (width)/7;         // "section" width
		var C=i%width;                  // column
		var R=Math.floor(i/(sWidth*7)); // row
		var c=i%sWidth;                 // column in current group
		var r, g, b, h;

		var l=(255/sWidth)*c;           // color percentage

		if(C>=sWidth*6){
			r=g=b=255-l;
		} else {
			h=255-l;

			r=C<sWidth?255:C<sWidth*2?h:C<sWidth*4?0:C<sWidth*5?l:255;
			g=C<sWidth?l:C<sWidth*3?255:C<sWidth*4?h:0;
			b=C<sWidth*2?0:C<sWidth*3?l:C<sWidth*5?255:h;

			if(R<(height/2)){
				var base = 255-(255*2/height)*R;

				r=base+(r*R*2/height);
				g=base+(g*R*2/height);
				b=base+(b*R*2/height);
			}else if(R>(height/2)){
				var base = (height-R)/(height/2);

				r=r*base;
				g=g*base;
				b=b*base;
			}
		}

		return hex(r)+hex(g)+hex(b);
	}

	function getGradientColor(x, y, Base){
		x = x<0?0:x>255?255:x;
		y = y<0?0:y>255?255:y;

		var r = Math.round((1-(1-(Base.r/255))*(x/255))*(255-y));
		var g = Math.round((1-(1-(Base.g/255))*(x/255))*(255-y));
		var b = Math.round((1-(1-(Base.b/255))*(x/255))*(255-y));

		return {r:r, g:g, b:b};
	}

	function hColorPickerMouseMove(ev){
		ev            = ev || window.event;
		var hCPImg    = ev.target || ev.srcElement;

		var mousePos  = mouseCoordinates(ev);
		cp.colorPos   = getPosition(hCPImg);

		var x         = mousePos.x-cp.colorPos.x;
		var y         = mousePos.y-cp.colorPos.y;
		var width     = parseInt(hCPImg.offsetWidth);
		var height    = parseInt(hCPImg.offsetHeight);

		var color     = getHorizColor(y*width+x, width, height);

		try {
			cp.hColorDiv.style.backgroundColor = cp.cpColor = '#'+color;
		} catch(e) {
			//this code fails in explorer debugger but as usual i can't see what is wrong...
		}
	}

	function hColorPickerMouseDown(){
		if(cp.cpColor.r || (cp.cpColor.r===0)) cp.cpColor = '#'+hex(cp.cpColor.r)+hex(cp.cpColor.g)+hex(cp.cpColor.b);
		if(cp.cpInput.nodeName=='INPUT'){
			cp.cpInput.value = cp.cpColor;
		} else {
			cp.cpInput.style.backgroundColor = cp.cpColor;
			$('pencil').style.backgroundColor = cp.cpColor;
		}
		hideColorPicker();
	}

	function attachColorPicker(input, coords){
		createColorPicker(coords);
		input.onfocus = showColorPicker;
		input.onblur  = tryHideColorPicker;
		input.onclick = showColorPicker;
	}

	function showSmColorPicker(ev){
		cp.clicked = true;
		showColorPicker(ev);
	}
	function showColorPicker(ev){
		ev         = ev        || window.event;
		var input  = ev.target || ev.srcElement;
		
		cp.ColorPicker.style.display  = 'block';
		//if(input.nodeName=='INPUT'){
		cp.cpInput = input;
		//}
		
		var inpPos = getPosition(cp.cpInput);

		cp.ColorPicker.style.left = inpPos.x;
		cp.ColorPicker.style.top  = inpPos.y+parseInt(cp.cpInput.offsetHeight);

		cp.hColorPicker.style.display = 'block';
	}

	function tryHideColorPicker(){
		if(!cp.clicked) hideColorPicker();
	}

	function hideColorPicker(){
		cp.ColorPicker.style.display  = 'none';
	}

	function cpMouseDown(ev){
		cp.cpPos       = getPosition(cp.fColorImg);
		cp.cpMouseDown = true;

		return false;
	}

	function cpMouseUp(ev){
		cp.cpMouseDown = false;
	}


	function cpMouseClick(ev){
		ev           = ev || window.event;
		var mousePos = mouseCoordinates(ev);

		var x        = mousePos.x-cp.cpPos.x-1;
		var y        = mousePos.y-cp.cpPos.y-1;

		setCPColor(getGradientColor(x, y, cp.baseColor));
	}

	function cpMouseMove(ev){
		 // fired when mouse moves over the color picker
		if(cp.cpMouseDown){
			cpMouseClick(ev);
		}
		return false;
	}

	function setCPColor(color){
		if(color.srcElement || color.target) color=null;
		if(color && (!color.r && (color.r!=0))) color = parseColor(color);
		if(!color){
			color = {
				r:parseInt(cp.rInput.value),
				g:parseInt(cp.gInput.value),
				b:parseInt(cp.bInput.value)
			}
		}
		cp.rInput.value = color.r;
		cp.gInput.value = color.g;
		cp.bInput.value = color.b;

		cp.cpColor      = color;
		cp.curColorDiv.style.backgroundColor = '#'+hex(color.r)+hex(color.g)+hex(color.b);
	}

	function parseColor(text){
		if(colorNames[text.toLowerCase()]) text = colorNames[text.toLowerCase()];
		if(/^\#?[0-9A-F]{6}$/i.test(text)){
			return {
				r: eval('0x'+text.substr(text.length==6?0:1, 2)),
				g: eval('0x'+text.substr(text.length==6?2:3, 2)),
				b: eval('0x'+text.substr(text.length==6?4:5, 2))
			}
		}
		return {r:255, g:0, b:0};
	}

	function documentMouseDown(ev){
		ev         = ev            || window.event;
		var target = ev.srcElement || ev.target;

		while(target){
			if(target==cp.ColorPicker) return;
			target = target.parentNode;
		}
		cp.ColorPicker.style.display = 'none';
	}

	function documentMouseUp(ev){
		cpMouseUp(ev);
	}

	document.onmousedown     = documentMouseDown;
	document.onmouseup       = documentMouseUp;
	window.attachColorPicker = attachColorPicker;
})();
