(function colorPickerNamespace(){
	var cp = null;

	var imgBase = 'http://itp.nyu.edu/~acb363/postfort/colorpicker/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(){
		if(cp) return;
		cp = $DOM(
			['DIV', {style:'position:absolute;font-family:tahoma,verdana,sans-serif;font-size:10px;', ref:'ColorPicker'},
				['DIV', {style:'background-color:#FFF;line-height:2px;width:401px;_width:401px;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'}],
						
					]
				],
				['DIV', {style:'border:1px solid #000;width:397px;height:305px;position:relative;background-color:#E0DFE3;', ref:'fColorPicker'},
					['IMG', {src:imgBase+'cp_cur_color_background.png', width:62, height:70, style:'position:absolute;top:20px;left:315px;'}],
					['DIV', {style:'z-index:2;position:absolute;top:22px;left:317px;width:58px;height:33px;', ref:'curColorDiv'}],
					['DIV', {style:'position:absolute;top:103px;left:315px;'}, 'R:'],
					['DIV', {style:'position:absolute;top:128px;left:315px;'}, 'G:'],
					['DIV', {style:'position:absolute;top:153px;left:315px;'}, 'B:'],
					['INPUT', {style:'position:absolute;top:100px;left:330px;width:47px;', ref:'rInput', onchange:setCPColor}],
					['INPUT', {style:'position:absolute;top:125px;left:330px;width:47px;', ref:'gInput', onchange:setCPColor}],
					['INPUT', {style:'position:absolute;top:150px;left:330px;width:47px;', ref:'bInput', onchange:setCPColor}],
					['BUTTON', {style:'position:absolute;bottom:50px;left:315px;width:77px;', ref:'OK', onclick:hColorPickerMouseDown}, 'OK'],
					['BUTTON', {style:'position:absolute;bottom:25px;left:315px;width:77px;', ref:'Cancel', onclick:hideColorPicker}, 'Cancel'],
					['INPUT', {type:'checkbox', style:'position:absolute;top:280px;left:4px;', ref:'websafeCheckbox'}],
					['DIV', {style:'position:absolute;top:284px;left:25px;'}, 'Only Web Colors'],
					['IMG', {src:imgBase+'cp_mini_icon.png', height:21, width:21, style:'cursor:pointer;position:absolute;bottom:0px;right:0px;border:1px solid #000;border-width:1px 0px 0px 1px;', ref:'fColorIcon', onmousedown:showSmColorPicker}]
				]
			]);

		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 getVertColor(i, sZ){
		var n=sZ/6, j=sZ/n, C=i, c=C%n;

		r=C<n?255:C<n*2?255-c*j:C<n*4?0:C<n*5?c*j:255;
		g=C<n*2?0:C<n*3?c*j:C<n*5?255:255-c*j;
		b=C<n?c*j:C<n*3?255:C<n*4?255-c*j:0;

		return {r:r, g:g, b: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);

		cp.hColorDiv.style.backgroundColor = cp.cpColor = '#'+color;
		colorselect = color;
	}
	
	var spanid;
var colorselect;

	function hColorPickerMouseDown(){
		if(cp.cpColor.r || (cp.cpColor.r===0)) cp.cpColor = '#'+hex(cp.cpColor.r)+hex(cp.cpColor.g)+hex(cp.cpColor.b);
		cp.cpInput.value = cp.cpColor;
		
				cp.cpInput.style.backgroundColor = cp.cpColor;
		hideColorPicker();
		
	var ajaxRequest;  // The variable that makes Ajax possible!
	
	try{
		// Opera 8.0+, Firefox, Safari
		ajaxRequest = new XMLHttpRequest();
	} catch (e){
		// Internet Explorer Browsers
		try{
			ajaxRequest = new ActiveXObject("Msxml2.XMLHTTP");
		} catch (e) {
			try{
				ajaxRequest = new ActiveXObject("Microsoft.XMLHTTP");
			} catch (e){
				// Something went wrong
				alert("Your browser broke!");
				return false;
			}
		}
	}
	
var queryString = "?spancolor=" + colorselect + "&spanid=" + spanid;
	ajaxRequest.open("GET", "http://itp.nyu.edu/~acb363/postfort/color.php" + queryString, true);
	ajaxRequest.send(null); 
	}

	function attachColorPicker(input, noLg){
		createColorPicker();
		if(noLg) input.setAttribute('noLg', '1');
		input.onclick  = tryHideColorPicker;
		input.ondblclick = showSmColorPicker;
	}

	function showSmColorPicker(ev){
		cp.clicked = true;
		showColorPicker(ev, 's');
		spanid = this.id;
}


	function showColorPicker(ev, size){
		ev         = ev        || window.event;
		var input  = ev.target || ev.srcElement;
		size       = size      || (cp.fColorPicker.style.display=='block'?'l':'s');

		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 = cp.fColorPicker.style.display = 'none';
		(size=='s'?cp.hColorPicker:cp.fColorPicker)['style'].display = 'block';

		if(size!='s'){
			cp.baseColor = parseColor(cp.cpInput.value);
			setCPColor(cp.fColorImg.style.backgroundColor = cp.origColor = cp.OrigColorDiv.style.backgroundColor = '#'+hex(cp.baseColor.r)+hex(cp.baseColor.g)+hex(cp.baseColor.b));

			cp.sliderPos = getPosition(cp.colorSlider);
		}
	}

	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 cpSliderMouseDown(ev){
		cp.csPos           = getPosition(cp.colorSlider);
		cp.SliderMouseDown = true;
		return false;
	}

	function cpSliderMouseUp(ev){
		cp.SliderMouseDown = false;
	}

	function cpSliderClick(ev){
		ev           = ev || window.event;
		var mousePos = mouseCoordinates(ev);
		var y        = mousePos.y-cp.sliderPos.y-4;
		cpSliderSetColor(y);

	}

	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);
		}

		// fired when mouse moves over the color slider
		if(cp.SliderMouseDown){
			cpSliderClick(ev);
		}

		return false;
	}


	
	function resetColor(){
		setCPColor(cp.origColor);
	}

	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)
			}
		}
	
	}

	//generic mouse down listener
	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);
		cpSliderMouseUp(ev);
	}

	document.onmousedown     = documentMouseDown;
	document.onmouseup       = documentMouseUp;
	window.attachColorPicker = attachColorPicker;
})();