// $Id: picker.js 4432 2006-09-14 07:45:55Z shacka $
/**
 *
 * Copyright (c) 2006 by SouthProjects
 * http://www.southprojects.com
 * Santiago, Chile,
 * Version 1.2 Dec 2006.
 * All rights reserved.
 */

ISIE = document.all ? true : false;
ISDOM = document.getElementById ? true : false;
ISNS4 = document.layers ? true : false;


// hides <select> and <applet> objects (for IE only)
function hideElement( elmID, overDiv ){
    if( !ISIE )
        return;
    
    for( i = 0; i < document.all.tags( elmID ).length; i++ ){
        obj = document.all.tags( elmID )[i];
        
        if( !obj || !obj.offsetParent )
            continue;
        
        objLeft   = obj.offsetLeft;
        objTop    = obj.offsetTop;
        objParent = obj.offsetParent;
        
        while(objParent != null && objParent.tagName.toUpperCase() != "BODY" ){
            objLeft  += objParent.offsetLeft;
            objTop   += objParent.offsetTop;
            objParent = objParent.offsetParent;
        }
        
        objHeight = obj.offsetHeight;
        objWidth = obj.offsetWidth;
        
        if(( overDiv.offsetLeft + overDiv.offsetWidth ) <= objLeft );
        else if(( overDiv.offsetTop + overDiv.offsetHeight ) <= objTop );
        else if( overDiv.offsetTop >= ( objTop + objHeight + obj.height ));
        else if( overDiv.offsetLeft >= ( objLeft + objWidth ));
        else {
            obj.style.visibility = "hidden";
            obj.setAttribute("cleared", 't');
        }
    }
}

// unhides <select> and <applet> objects (for IE only)
function showElement( elmID ){
    if( !ISIE )
        return;
 
    for( i = 0; i < document.all.tags( elmID ).length; i++ ){
        obj = document.all.tags( elmID )[i];
        
        if( !obj || !obj.offsetParent || obj.getAttribute("cleared") != 't')
            continue;

            
        obj.style.visibility = "";
        obj.setAttribute("cleared", null);
    }
}

// add class with name styleClass to element node
function addStyleClass(node, styleClass){
    if(node == null || styleClass == null || node.className.indexOf(styleClass) != -1)
        return;

    node.className += node.className == "" ? styleClass : " " + styleClass;
}

// shortcut for addStyleClass
function aSC(node, styleClass){
	return addStyleClass(node, styleClass);
}

// removing class with name styleClass from element node
function removeStyleClass(node, styleClass){
    if(node == null || styleClass == null)
        return;

    node.className = node.className.replace(styleClass, "").replace(" " + styleClass, "");
}

// shortcut for removeStyleClass
function rSC(node, styleClass){
	return removeStyleClass(node, styleClass);
}

// crossbrowser getting element by its ID
function getElement(styleId) {
    if (ISDOM) {
        return document.getElementById(styleId);
    } else if (ISIE) {
        return document.all[styleId];
    } else if (ISNS4) {
        return window[styleId];
    }

    return null;
}

// Available window width
function pageWidth(wnd){
    if(!wnd)
        wnd = window

    if (wnd.innerWidth) {
        return wnd.innerWidth;
    } else if (wnd.document.documentElement && wnd.document.documentElement.clientWidth) {
        return wnd.document.documentElement.clientWidth;
    } else if (wnd.document.body) {
        return wnd.document.body.clientWidth;
    }
}

// Available window height
function pageHeight(wnd){
    if(!wnd)
        wnd = window

    if (wnd.innerHeight) {
        return wnd.innerHeight;
    } else if (wnd.document.documentElement && wnd.document.documentElement.clientHeight) {
        return wnd.document.documentElement.clientHeight;
    } else if (wnd.document.body) {
        return document.body.clientHeight;
    }
}

function isDef(){
	for(var i=0; i<arguments.length; ++i){
		if(typeof(arguments[i])=='undefined')
			return false;
	}

	return true;
}

// calculates elements offset from the left
function elOffsetX(e){
	var x = 0;

	while (e) {
		if (isDef(e.offsetLeft))
			x += e.offsetLeft;
		e = isDef(e.offsetParent) ? e.offsetParent : null;
	}

	return x;
}

// calculates elements offset from the top
function elOffsetY(e){
	var y = 0;

	while (e) {
		if (isDef(e.offsetTop))
			y += e.offsetTop;

		e = isDef(e.offsetParent) ? e.offsetParent : null;
	}

	return y;
}

// get value of element
function getElementValue(element) {
    var tagName = element.tagName.toUpperCase();

    var value;
    
    switch (tagName) {
        case "SELECT":
            var option = element.options[element.selectedIndex];
            if(option != null)
                value = option.value;
            else
                value = '';
            break;
        case "INPUT":
            value = element.value;
            break;
        default:
            value = element.innerHTML;
            break;
    }

    return value;
}

// set element value
function setElementValue(element, value) {
    var tagName = element.tagName;

    switch (tagName) {
        case "INPUT":
            element.value = value;
            break;
        case "SELECT":
            for(var i = 0; i < element.options.length; i++){
                if (element.options[i].value == value){
                    element.selectedIndex = i;
                    break;
                }
            }

            break;
        default:
            element.innerHTML = value;
            break;
    }
}


var inputEl, displayEl, buttonEl, callFunc;
var pickerShow = false;
var defaultCells = 0;

// function for calling color picker without displayer
function showPickerWithoutDisplayer(_inputEl, _buttonEl, _callFunc){
	return showPicker(_inputEl, null, _buttonEl, _callFunc);
}

// main function for calling color picker
// parameters:
//	1) element, where to write selected value(required)(ID or node)
//	2) element, where to display selected value(ID or node)
//	3) button element(needed for correct positioning)(required)(ID or node)
//	4) function for calling after selectiong a color (ID or node)
function showPicker(_inputEl, _displayEl, _buttonEl, _callFunc){
	hidePicker();
	if(typeof(_inputEl) == "string")
		_inputEl = getElement(_inputEl);

	if(typeof(_displayEl) == "string")
		_displayEl = getElement(_displayEl);

	if(typeof(_buttonEl) == "string")
		_buttonEl = getElement(_buttonEl);
	
	if(_buttonEl == null)
		return;

	defaultCells = 0;

	inputEl = _inputEl;
	displayEl = _displayEl;
	buttonEl = _buttonEl;
	callFunc = _callFunc;

	putPickerContainer();
	positePickerContainer();
	pickerShow = true;
	hideElement( 'SELECT', getPickerContainer());
	hideElement( 'APPLET', getPickerContainer());
}

// get picker container element. Create it if it is not exists yet
function getPickerContainer(){
	var pickerContainer = getElement("colorPickerContainer");

	if(pickerContainer == null){
		pickerContainer = document.createElement("DIV");
		pickerContainer.id = "colorPickerContainer"
		document.body.appendChild(pickerContainer);
	}

	return pickerContainer;
}

// read value from inputEl
function getDefaultColor(){
	if(inputEl == null)
		return "";

	var val = getElementValue(inputEl);
	return (val != null && val.match(/#[\da-fA-F]/) ? val: null);
}

// dynamically create picker container
function putPickerContainer(){
	var container = getPickerContainer();

	var str = "";
	str += "<table border='0' cellspacing='0' onclick='pickerShow=true'>";
	var defColor = getDefaultColor(inputEl);
	str += "<tr><td colspan='2'><table cellspacing='0' border='0' width='100%'><tr>";
	str += "	<td width='45'><img src='../themes/picker/px.gif' alt='' id='colorViewer' style='background-color: " + (defColor != null ? defColor : "#FFFFFF") + "'></td>";
	str += "	<td><input id='colorValue' readonly type='text' size='7' value='" + (defColor != null ? defColor : "#FFFFFF") + "'></td>";
	str += "	<td align='right'><img src='../themes/picker/close.gif' style='cursor: pointer' onclick='hidePicker()' alt=''></td>"
	str += "</td></tr></table></td></tr>"
	str += "<tr><td width='40' align='center' bgcolor='black'>";
	str += "	<table cellpadding='0' cellspacing='0'>";

	// common colors. displayed into the left column. You can easily change them
	var commonColors = ["000000", "333333", "666666", "999999", "CCCCCC", "FFFFFF", "FF0000", "00FF00", "0000FF", "FFFF00", "00FFFF", "FF00FF"];

	for(var i = 0; i < commonColors.length; i++)
		str += "<tr height='10'>" + getTD(commonColors[i], defColor) + "</tr>";

	str += "	</table>";
	str += "</td><td bgcolor='black'><table cellpadding='0' cellspacing='0'>";

	// all colors. displayed into the right table. You can easily change them
	var allColors = [
		['000000', '003300', '006600', '009900', '00CC00', '00FF00', '330000', '333300', '336600', '339900', '33CC00', '33FF00', '660000', '663300', '666600', '669900', '66CC00', '66FF00'],
		['000033', '003333', '006633', '009933', '00CC33', '00FF33', '330033', '333333', '336633', '339933', '33CC33', '33FF33', '660033', '663333', '666633', '669933', '66CC33', '66FF33'],
		['000066', '003366', '006666', '009966', '00CC66', '00FF66', '330066', '333366', '336666', '339966', '33CC66', '33FF66', '660066', '663366', '666666', '669966', '66CC66', '66FF66'],
		['000099', '003399', '006699', '009999', '00CC99', '00FF99', '330099', '333399', '336699', '339999', '33CC99', '33FF99', '660099', '663399', '666699', '669999', '66CC99', '66FF99'],
		['0000CC', '0033CC', '0066CC', '0099CC', '00CCCC', '00FFCC', '3300CC', '3333CC', '3366CC', '3399CC', '33CCCC', '33FFCC', '6600CC', '6633CC', '6666CC', '6699CC', '66CCCC', '66FFCC'],
		['0000FF', '0033FF', '0066FF', '0099FF', '00CCFF', '00FFFF', '3300FF', '3333FF', '3366FF', '3399FF', '33CCFF', '33FFFF', '6600FF', '6633FF', '6666FF', '6699FF', '66CCFF', '66FFFF'],
		['990000', '993300', '996600', '999900', '99CC00', '99FF00', 'CC0000', 'CC3300', 'CC6600', 'CC9900', 'CCCC00', 'CCFF00', 'FF0000', 'FF3300', 'FF6600', 'FF9900', 'FFCC00', 'FFFF00'],
		['990033', '993333', '996633', '999933', '99CC33', '99FF33', 'CC0033', 'CC3333', 'CC6633', 'CC9933', 'CCCC33', 'CCFF33', 'FF0033', 'FF3333', 'FF6633', 'FF9933', 'FFCC33', 'FFFF33'],
		['990066', '993366', '996666', '999966', '99CC66', '99FF66', 'CC0066', 'CC3366', 'CC6666', 'CC9966', 'CCCC66', 'CCFF66', 'FF0066', 'FF3366', 'FF6666', 'FF9966', 'FFCC66', 'FFFF66'],
		['990099', '993399', '996699', '999999', '99CC99', '99FF99', 'CC0099', 'CC3399', 'CC6699', 'CC9999', 'CCCC99', 'CCFF99', 'FF0099', 'FF3399', 'FF6699', 'FF9999', 'FFCC99', 'FFFF99'],
		['9900CC', '9933CC', '9966CC', '9999CC', '99CCCC', '99FFCC', 'CC00CC', 'CC33CC', 'CC66CC', 'CC99CC', 'CCCCCC', 'CCFFCC', 'FF00CC', 'FF33CC', 'FF66CC', 'FF99CC', 'FFCCCC', 'FFFFCC'],
		['9900FF', '9933FF', '9966FF', '9999FF', '99CCFF', '99FFFF', 'CC00FF', 'CC33FF', 'CC66FF', 'CC99FF', 'CCCCFF', 'CCFFFF', 'FF00FF', 'FF33FF', 'FF66FF', 'FF99FF', 'FFCCFF', 'FFFFFF']
	];

	for(var i = 0; i < allColors.length; i++){
		str += "<tr height='10'>";

		for(var j = 0; j < allColors[i].length; j++)
			str += getTD(allColors[i][j], defColor);
		
		str += "</tr>";
	}
	str += "</table></td></tr></table>";

	container.innerHTML = str;
}

// create one TD with its contents
function getTD(color, defColor){
	color = "#" + color;
	return "<td><img src='../themes/picker/px.gif' onclick='selectColor(\"" + color + "\")' onmouseover='aSC(this, \"hl\"); viewColor(\"" + color + "\")' onmouseout='rSC(this, \"hl\")' style='background-color: " + color + "' class='cell'" + (color == defColor ? " id='defColor" + ++defaultCells + "'" : "") + "/></td>";
}

// put color under mouse into large element for previewing and into INPUT
function viewColor(color){
	var defEl = getElement("defColor1");

	if(defEl != null){
		removeStyleClass(defEl, "default");
		defEl.id = '';

		defEl = getElement("defColor2");

		if(defEl != null){
			removeStyleClass(defEl, "default");
			defEl.id = '';
		}
	}

	getElement("colorViewer").style.backgroundColor = color;
	setElementValue(getElement("colorValue"), color);
}

// put selected color into inputEl, displayer and close picker
function selectColor(color){
    if(inputEl != null)
		setElementValue(inputEl, color);
	
	if(displayEl != null)
		displayEl.style.backgroundColor = color;

	if(callFunc != null)
		callFunc(color);

	hidePicker();
}

// posite picker control on screen
function positePickerContainer(){
	var container = getPickerContainer();

	var w = buttonEl.clientWidth;

	if(w == null || w == "" || w == 0)
		w = buttonEl.scrollWidth;

	var h = buttonEl.clientHeight;

	if(h == null || h == "" || h == 0)
		w = buttonEl.scrollWidth;

	var left = elOffsetX(buttonEl) + w - 7;
	var top = elOffsetY(buttonEl) + h - 7;

	if(pageWidth() + document.body.scrollLeft < left + container.clientWidth)
		left = elOffsetX(buttonEl) - container.clientWidth + 7;

    if(pageHeight() + document.body.scrollTop < top + container.clientHeight)
		top = elOffsetY(buttonEl) - container.clientHeight;

    container.style.left = left + "px";
	container.style.top = top + "px";
}

// hide picker control from screen
function hidePicker(){
	var container = getPickerContainer();
	container.style.left = '-1000px';
	container.style.top = '-1000px';

	inputEl = null;
	displayEl = null;
	buttonEl = null;
	callFunc = null;
	pickerShow = false;

	showElement("SELECT");
	showElement("APPLET");
}

// processing ESCAPE button
document.onkeypress = function(e) {
	if (!e)
		e = window.event; 

	if (e.keyCode==27)
		hidePicker()
}

// processing click events outside picker control
document.onclick = function() { 		
	if(!pickerShow)
		hidePicker();

	pickerShow = false;
}
