/**
* A (conceptually cubical) color palette
* so far:
* 1. shows a preview of the color selected
* 999. a lot more, will document later
*/

function getColorTable(borders, spaces) {
	resp = document.createElement('table');
	resp.border = (borders ? 1 : 0);
	resp.cellPadding = (spaces ? 1 : 0);
	resp.cellSpacing = (spaces ? 1 : 0);
	resp.style.borderColor = 'black';

	return resp;
}
function getColorTBody() {
	resp = document.createElement('tbody');

	return resp;
}
function getColorRow() {
	resp = document.createElement('tr');

	return resp;
}
function getColorButton(palette, prvw, dest, w, h, color, onColorPick) {
	resp = document.createElement('td');
	resp.style.width = w;
	resp.style.height = h;
	resp.style.backgroundColor = color;
	
	ucolor = (prvw.style.backgroundColor ? prvw.style.backgroundColor : 'lightgray');
	prvw.style.backgroundColor = ucolor;

	//0-ini,out
	//1-over
	//2-down
	//3-sel
	butMouseTracker = 0;
	
	resp.onmouseover = function() {
		prvw.style.backgroundColor = color;
		if(prvw.value) prvw.value = color;
		butMouseTracker = 1;
	};
	//resp.onmousedown = function(event) {
	resp.onmousedown = function() {
		if(butMouseTracker == 1) {
			butMouseTracker = 2;
			//dont stop so it'll reach the table
		}
	}
	resp.onmouseout = function() {
		if(butMouseTracker != 3) {
			prvw.style.backgroundColor = ucolor;
			if(prvw.value) prvw.value = ucolor;
			butMouseTracker = 0;
		}
		//butMouseTracker = 0;
		//table doesnt handle it && browser behavior doesnt hurt
	};
	resp.onmouseup = function(event) {
		if(butMouseTracker == 2) {
			butMouseTracker = 3;

			//alert('color selected:'+color);
			//palette.style.visibility = 'hidden';
			togglePalette(event, palette.id);
			prvw.style.backgroundColor = color;
			if(prvw.value) prvw.value = color;
			dest.value = color;

			ucolor = color;

			//alert('event:'+event);
			//event.preventDefault();
			//event.stopPropagation();
			preventDefault(event);
			stopPropagation(event);

			//alert('evaling ' + onColorPick);
			eval(onColorPick);
		}
	}

	return resp;
}
function getColorHex(r, g, b) {
	rAux = r - 1;
	gAux = g - 1;
	bAux = b - 1;
	
	rAux = (rAux<0 ? 0 : rAux);
	gAux = (gAux<0 ? 0 : gAux);
	bAux = (bAux<0 ? 0 : bAux);

	rAux = (rAux>255 ? 255 : rAux);
	gAux = (gAux>255 ? 255 : gAux);
	bAux = (bAux>255 ? 255 : bAux);
	
	rAux = '00' + rAux.toString(16);
	gAux = '00' + gAux.toString(16);
	bAux = '00' + bAux.toString(16);

	rAux = rAux.substring(rAux.length - 2);
	gAux = gAux.substring(gAux.length - 2);
	bAux = bAux.substring(bAux.length - 2);

	resp = rAux + gAux + bAux;

	return resp.toUpperCase();
}

function initPalette(paletteId, prvwId, destId, totw, step, whitening, borders, spaces, order, opacity, onColorPick) {
	palette = document.getElementById(paletteId);
	//OK
	//palette.innerHTML = 'hola';
	//OK
	//palette.innerHTML = '<table><tr><td><span><table><tr><td style=\'background-color: blue; width: 40px; height: 50px;\'></td></tr></table></span></td></tr></table>';
	//OK
	//e1 = document.createElement('td');
	//e1.innerHTML = 'holaaaa';
	//e2 = document.createElement('tr');
	//e2.appendChild(e1);
	//e3 = document.createElement('tbody');
	//e3.appendChild(e2);
	//e4 = document.createElement('table');
	//e4.appendChild(e3);
	//palette.appendChild(e4);
	//return;
	prvw = document.getElementById(prvwId);
	dest = document.getElementById(destId);

	totspace = 256;

	discrets = parseInt(totspace / step) + 1;
	//l = parseInt(totw / (discrets * discrets));
	//plus 1 to include the grayscale
	//minus 20 to include the intertable space, borders, etc
	l = parseInt((totw - 10) / (discrets + 1));
	//toth = l * discrets;
	toth = totw;

	palette.style.width = totw;
	palette.style.height = toth;
	//palette.style.backgroundColor = 'lightgray';
	if(opacity < 1) {
		//only set this parameter if it's value differs from 1, because it makes everything slower
		setOpacity(palette, opacity);
	}
	levels = new Array();

	theTbl = document.createElement('table');
	//theTbl.border = 0;
	//theTbl.cellspacing = 0;
	//theTbl.cellpadding = 0;
	//theTbl.style.borderColor = 'blue';
	theTBody = document.createElement('tbody');
	theRow = document.createElement('tr');
	theTdGrayscale = document.createElement('td');
	theTdPlaceholder = document.createElement('td');
	theRow.appendChild(theTdGrayscale);
	theRow.appendChild(theTdPlaceholder);
	theTBody.appendChild(theRow);
	theTbl.appendChild(theTBody);

	placeholder = document.createElement('span');
	theTdPlaceholder.appendChild(placeholder);

	//alert(l+';'+discrets+';'+levels+';'+totspace+';'+step+';'+borders+';'+spaces+';'+whitening+';'+placeholder);
	grayscale = getGrayscale(l, discrets, levels, totspace, step, borders, spaces, whitening, placeholder);
	//grayscale = getGrayscale(l, discrets, totspace, step, borders, spaces, whitening);
	theTdGrayscale.appendChild(grayscale);

	palette.appendChild(theTbl);

	rIndex = order.toUpperCase().indexOf('R');
	rIndex = ((rIndex < 0 || rIndex > 2) ? 0 : rIndex);
	gIndex = order.toUpperCase().indexOf('G');
	gIndex = ((gIndex < 0 || gIndex > 2) ? 1 : gIndex);
	bIndex = order.toUpperCase().indexOf('B');
	bIndex = ((bIndex < 0 || bIndex > 2) ? 2 : bIndex);
	cValues = new Array();

	if(whitening) {
		ix = 0;
		for(cValues[0]=1;cValues[0]<=(totspace+1);cValues[0]+=step) {
			tblAux = getColorTable(borders, spaces);
			tBodyAux = getColorTBody();
			for(cValues[1]=1;cValues[1]<=(totspace+1);cValues[1]+=step) {
				rowAux = getColorRow();
				for(cValues[2]=1;cValues[2]<=(totspace+1);cValues[2]+=step) {
					rowAux.appendChild(getColorButton(palette, prvw, dest, l, l, getColorHex(cValues[rIndex], cValues[gIndex], cValues[bIndex]), onColorPick));
				}
				tBodyAux.appendChild(rowAux);
			}
			tblAux.appendChild(tBodyAux);
			levels[ix] = tblAux;
			ix++;
		}
	}
	else {
		ix = 0;
		for(cValues[0]=totspace;cValues[0]>=-1;cValues[0]-=step) {
			tblAux = getColorTable(borders, spaces);
			tBodyAux = getColorTBody();
			for(cValues[1]=totspace;cValues[1]>=-1;cValues[1]-=step) {
				rowAux = getColorRow();
				for(cValues[2]=totspace;cValues[2]>=-1;cValues[2]-=step) {
					rowAux.appendChild(getColorButton(palette, prvw, dest, l, l, getColorHex(cValues[rIndex], cValues[gIndex], cValues[bIndex]), onColorPick));
				}
				tBodyAux.appendChild(rowAux);
			}
			tblAux.appendChild(tBodyAux);
			levels[ix] = tblAux;
			ix++;
		}
	}

	if (!palette.style.zIndex) {
		palette.style.zIndex = 1000;
	}

}
function hideLevels(discrets, levels, placeholder) {
	nodes = placeholder.childNodes;
	for(i=0; i<nodes.length; i++) {
		placeholder.removeChild(nodes[i]);
	}
	
}
function showLevel(levels, ix, placeholder) {
	placeholder.appendChild(levels[ix]);
}

function xyMsg(x, y) {
	resp = '(' + x + ',' + y + ')'; 
	return resp;
}
function equisY(event) {
	msg = '';

msg += '; event.XY' + xyMsg(event.x, event.y);
msg += '; event.clientXY' + xyMsg(event.clientX, event.clientY);
msg += '; event.layerXY' + xyMsg(event.layerX, event.layerY);
msg += '; event.offsetXY' + xyMsg(event.offsetX, event.offsetY);
msg += '; event.pageXY' + xyMsg(event.pageX, event.pageY);
msg += '; event.screenXY' + xyMsg(event.screenX, event.screenY);
	
msg += '; window.innerWidthHeight' + xyMsg(window.innerWidth, window.innerHeight);
msg += '; window.outerWidthHeight' + xyMsg(window.outerWidth, window.outerHeight);
msg += '; window.pageXYOffset' + xyMsg(window.pageXOffset, window.pageYOffset);
msg += '; window.screenXY' + xyMsg(window.screenX, window.screenY);

	alert(msg);
}
function togglePalette(event, paletteId) {
	palette = document.getElementById(paletteId);
	closerId = paletteId + '_closer';
	closer = getCloser(palette, closerId);

	if (palette.style.visibility=='visible') {
		palette.style.visibility = 'hidden';
	}
	else {
		palette.style.left = calculatePaletteLeft(event, palette);
		palette.style.top = calculatePaletteTop(event, palette);
		palette.style.visibility = 'visible';
	}

	closer.style.visibility = palette.style.visibility;
	//alert('togglePalette:'+palette.style.visibility);
}
function calculatePaletteLeft(event, palette) {
	//function uses the event object, so get it in a browser-independent manner
	event = getEvent(event);
	resp = 0;
	
	mouseX = getMouseX(event);
	clientX = event.clientX;
	paletteW = parseInt(palette.style.width);
	innerW = getInnerWidth();
	//alert('mouseX:' + mouseX + '; clientX:' + clientX + '; paletteW:' + paletteW + '; innerW:' + innerW + ';');

	fitsRight = ((clientX + paletteW) <= innerW);
	fitsLeft = ((clientX - paletteW) >= 0);
	rightPos = mouseX;
	leftPos = mouseX - paletteW;

	//resp = ((clientX + paletteW) > innerW ? (mouseX - paletteW) : mouseX);
	resp = ((!fitsRight && fitsLeft) ? leftPos : rightPos);

	return resp;
}
function calculatePaletteTop(event, palette) {
	//function uses the event object, so get it in a browser-independent manner
	event = getEvent(event);
	resp = 0;
	
	mouseY = getMouseY(event);
	clientY = event.clientY;
	paletteH = parseInt(palette.style.height);
	innerH = getInnerHeight();

	fitsBelow = ((clientY + paletteH) <= innerH);
	fitsAbove = ((clientY - paletteH) >= 0);
	belowPos = mouseY;
	abovePos = mouseY - paletteH;

	//resp = ((clientY + paletteH) > innerH ? (mouseY - paletteH) : mouseY);
	resp = ((!fitsBelow && fitsAbove) ? abovePos : belowPos);

	return resp;
}

function getEvent(event) {
	if (!event) var event = window.event;
	return event;
}
function stopPropagation(event) {
	//function uses the event object, so get it in a browser-independent manner
	event = getEvent(event);

	if (event.stopPropagation) event.stopPropagation(); //DOM Level 2
	else event.cancelBubble = true; //IE
}
function preventDefault(event) {
	//function uses the event object, so get it in a browser-independent manner
	event = getEvent(event);

	if (event.preventDefault) event.preventDefault(); //DOM Level 2
	else event.returnValue = false; //IE
}
function getMouseX(event) {
	//function uses the event object, so get it in a browser-independent manner
	event = getEvent(event);
	var posx = 0;
	if (event.pageX) {
		posx = event.pageX;
	}
	else if (event.clientX) {
		posx = event.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
	}
	return posx;
}
function getMouseY(event) {
	//function uses the event object, so get it in a browser-independent manner
	event = getEvent(event);
	var posy = 0;
	if (event.pageY) {
		posy = event.pageY;
	}
	else if (event.clientY) {
		posy = event.clientY + document.body.scrollTop + document.documentElement.scrollTop;
	}
	return posy;
}
function getInnerWidth() {
	var innw = 0;
	if (window.innerWidth) {
		innw = window.innerWidth;
	}
	else if (document.body.clientWidth) {
		innw = document.body.clientWidth;
	}
	return innw;
}
function getInnerHeight() {
	var innh = 0;
	if (window.innerHeight) {
		innh = window.innerHeight;
	}
	else if (document.body.clientHeight) {
		innh = document.body.clientHeight;
	}
	return innh;
}
function getOpacityType(elem) {
	resp = 'none';

	if (typeof elem.style.opacity != 'undefined') {
		resp = 'w3c';
	}
	else if (typeof elem.style.MozOpacity != 'undefined') {
		resp = 'moz';
	}
	else if (typeof elem.style.KhtmlOpacity != 'undefined') {
		resp = 'khtml';
	}
	else if (typeof elem.filters == 'object') {
		resp = (
			elem.filters.length > 0
			&& typeof elem.filters.alpha == 'object'
			&& typeof elem.filters.alpha.opacity == 'number'
		) ? 'ie' : 'none';
	}
	else {
		resp = 'none';
	}

	return resp;
}
function setOpacity(elem, value) {
	otype = getOpacityType(elem);

	if(otype == 'w3c') {
		elem.style.opacity = (value == 1 ? 0.9999999 : value);
	}
	else if(otype == 'moz') {
		elem.style.MozOpacity = (value == 1 ? 0.9999999 : value);
	}
	else if(otype == 'khtml') {
		elem.style.KhtmlOpacity = value;
	}
	else if(otype == 'ie') {
		elem.filters.alpha.opacity = value * 100;
	}
	
}
function getGrayscaleButton(tblLevelGetter, tblLevelSetter, h, ix, color) {
//function getGrayscaleButton(h, color) {
	resp = document.createElement('td');
	resp.style.height = h;
	resp.style.width = h;
	resp.style.backgroundColor = color;

	resp.onmouseover = function() {
		tblLevelSetter(ix, false);
	};

	return resp;
}
function getGrayscale(h, discrets, levels, totspace, step, borders, spaces, whitening, placeholder) {
//function getGrayscale(h, discrets, totspace, step, borders, spaces, whitening) {
	s = document.createElement('span');
	t = document.createElement('table');
	t.border = (borders ? 3 : 0);
	t.cellPadding = (spaces ? 1 : 0);
	t.cellSpacing = (spaces ? 1 : 0);
	t.style.borderColor = 'black';
	tBody = document.createElement('tbody');

	tblLevelTracker = 0;
	tblLevelGetter = function() {
		return tblLevelTracker;
	}
	tblLevelSetter = function(value, previewing) {
		if(!previewing) {
			tblLevelTracker = value;
		}
		hideLevels(discrets, levels, placeholder);
		showLevel(levels, value, placeholder);
	}

	if(whitening) {
		g=1;
		for(i=0; i<discrets; i++) {//for(g=1;g<=(totspace+1);g+=step) {
			f = document.createElement('tr');
			f.appendChild(getGrayscaleButton(tblLevelGetter, tblLevelSetter, h, i, getColorHex(g, g, g)));
			tBody.appendChild(f);
			g+=step;
		}
	}
	else {
		g=totspace;
		for(i=0; i<discrets; i++) {//for(g=totspace;g>=-1;g-=step) {
			f = document.createElement('tr');
			f.appendChild(getGrayscaleButton(tblLevelGetter, tblLevelSetter, h, i, getColorHex(g, g, g)));
			tBody.appendChild(f);
			g-=step;
		}
	}

	//g=1;
	//for(i=0; i<discrets; i++) {
	//	f = document.createElement('tr');
	//	f.appendChild(getGrayscaleButton(h, getColorHex(g, g, g)));
	//	tBody.appendChild(f);
	//	g+=step;
	//}
	
	t.appendChild(tBody);
	s.appendChild(t);
	return s;
}
function createCloser(palette, closerId) {
	resp = document.createElement('span');

	resp.id = closerId;
	
	resp.onclick = function(event) {
		//alert('closer: onclick');
		togglePalette(event, palette.id);
	}

	//palette.parentNode.appendChild(resp);
	return resp;
}
function getCloser(palette, closerId) {
	resp = document.getElementById(closerId);
	if (!resp) {
		resp = createCloser(palette, closerId);
		palette.parentNode.appendChild(resp);
	}

	resp.style.position = 'absolute';
	resp.style.zIndex = palette.style.zIndex - 1;
	resp.style.left = 0;
	resp.style.top = 0;
	resp.style.width = document.body.scrollWidth;
	resp.style.height = document.body.scrollHeight;

	return resp;
}
