/*
 * Colorpicker Functions
 * Custom functions for colorpicker.htm.
 * Copyright (c) 2003-2004 Mackley F. Pexton.  All rights reserved.
 * Send correspondence and feedback to: mack_pexton[at]acmebase[dot]com.
 */

/*****************************************************************************

These functions set the web page background color and text color according to
the color swatch the mouse points to on a color table image.

A <div> element with white borders is used as a highlighter element that is
moved around the color table image to highlight the color swatch used to set
the page colors.

Color values manually entered into an input field cause the highlight element
to be moved to the corresponding color.

Changes:
	v3.0 - added slider controls
	v3.2 - added switchColorTarget()

*****************************************************************************/

// The document body colors should be set to the following codes.
// This version assumes the intial colors is white text on black background.
var ColorVals = { 'background':'#666666', 'text': '#FFFFFF' };

var ColorTarget;		// "text" or "background" color style settings
var CurrentTarget;		// element of color swatch pointed to by mouse
var FrozenTarget;		// element frozen where mouse was clicked

function showColorVal(val) {

	// Find color swatch corresponding to color.

	if (val == '') val = '000000';		// set empty values to black

	// Remove # character.
	val = val.replace(/#/,'');

	// Change short hex notation into #000000 notation.
	if (val.match(/^[\dabcdef]{3}$/i)) val = val.replace(/(.)(.)(.)/,"$1$1$2$2$3$3");

	// Show color swatch.
	var e = document.getElementById("x"+val.toUpperCase());
	if (e) {
		showColorHighlight(e);
	}
	else {
		// Uncomment next to issue error if entered value is not a web safe color.
		//alert("Enter a 'web safe' color using three combinations of\n" +
		//  "'00','33','66','99','CC', or 'FF' like #FFCC33 or #66CCFF.");

		// Show color code entered by user.
		if (val.match(/^[\dabcdef]+$/i)) val = '#' + val;
		setColorTarget(val);
		document.color_form.hexval.value = val;
		document.getElementById('hilite').style.visibility = 'hidden';

		// Uncomment next to keep color swatches active when slider buttons are used.
		//FrozenTarget = null;	// unfreeze
	}
}

function showColor(evt) {
        evt = evt ? evt : window.event ? window.event : null;
	var target = evt.target ? evt.target : evt.srcElement ? evt.srcElement : null;

	CurrentTarget = target;		// track element mouse was last over
	if (FrozenTarget) return;

	showColorHighlight(CurrentTarget);
}

function showColorHighlight(e) {
	if (e.coords) {
		// Highlight a color swatch.
		var arr = e.coords.split(",");
		var hilite = document.getElementById('hilite');
		var border_width = 2;
		hilite.style.left = (arr[0] - border_width) + "px";
		hilite.style.top  = (arr[1] - border_width) + "px";
		hilite.style.visibility = 'visible';
	}

	CurrentTarget = e;	// track the element of color swatch

	// Set background color and form input value to color code.
	var val = e.id.replace(/x/,'#');
	document.color_form.hexval.value = val;
	setColorTarget(val);
}

function show(colorval) {

	// This is a dummy routine. It is used in the href attribute of
	// the color table's <area> tags so that the color value shows up
	// on the browser's status bar. The real work is done in the event
	// handler freeze().
}

function freeze(evt) {
        evt = evt ? evt : window.event ? window.event : null;
	var target = evt.target ? evt.target : evt.srcElement ? evt.srcElement : null;

	if (FrozenTarget && (
	   (FrozenTarget == target) ||			// IE
	   (target.id && target.id == 'hilite')		// W3C
	)) {
		// Unfreeze if frozen swatch is clicked again.
		FrozenTarget = null;	
	}
	else {
		// Note: use CurrentTarget instead of this click event's target
		// element because CurrentTarget gets set on mouseover events
		// before the hilite element gets placed below the mouse cursor
		// and causes it to become the target for clicks.

		showColorHighlight(CurrentTarget);
		FrozenTarget = CurrentTarget;
	}

	evt.cancelBubble = true;
	if (evt.stopPropagation) evt.stopPropagation();
}

function unfreeze(evt) {
        evt = evt ? evt : window.event ? window.event : null;
	var target = evt.target ? evt.target : evt.srcElement ? evt.srcElement : null;

	// Unfreeze only if the mouse was clicked outside the color table.
	while (target) {
		if (target.nodeName == 'INPUT') return;
		if (target.nodeName == 'A') return;
		target = target.parentNode;
	}
	FrozenTarget = null;
}

function setColorTarget(val) {
	if (ColorTarget == 'text') {
		document.body.style.color = val;
		document.getElementById('examplebox').style.borderColor = val;
	}
	else {
		document.body.style.backgroundColor = val;
	}
	ColorVals[ColorTarget] = val;		// save current setting

	// Change slider settings.
	if (val.match(/^#?[\dabcdef]+$/i)) setSliderColor(val);
	else			           setSliderColor('#000000');	// reset
}

function selectColorTarget(target) {
	ColorTarget = target;
	showColorVal(ColorVals[ColorTarget]);
	FrozenTarget = null;			// unfreeze
}

function switchColorTarget() {
	var f = document.color_form;
	if (ColorTarget == 'text') {
		var saved_color = ColorVals['text'];
		setColorTarget(ColorVals['background']);
		ColorTarget = 'background';
		showColorVal(saved_color);
		f.color_target[0].checked = true;
	}
	else {
		var saved_color = ColorVals['background'];
		setColorTarget(ColorVals['text']);
		ColorTarget = 'text';
		showColorVal(saved_color);
		f.color_target[1].checked = true;
	}
	FrozenTarget = null;			// unfreeze
}

function setupEvents() {
	if (document.getElementById) {
		var e = document.getElementById('colormap');
		if (e) {
			e.onmouseover = showColor;
			e.onclick = freeze;	// for IE
		}

		e = document.getElementById('hilite');
		if (e) e.onclick = freeze;	// for Netscape
	}

	// Uncomment following if clicking outside of image unfreezes the highlighter.
	document.body.parentNode.onclick = unfreeze;
}

function setup() {
	setupEvents();
	selectColorTarget('background');
}

window.onload = setup;

/*
 * Interface to Slider controls for fine tuning colors.
 */

function showSliderColor() {

	// This is the callback function invoked when a slider is moved.

	if (showSliderColor.skip) return;

	// Freeze color table from changing when mouse hovers over it.
	FrozenTarget = CurrentTarget;

	// Show color of the sliders.
	showColorVal(sliderColor());
}

function setSliderColor(hex) {

	// Set color sliders to specified color
	// Note: first character here is a #

	// Parse hex color code into RGB decimal numbers.
	var r = parseInt(hex.substr(1,2),16);
	var g = parseInt(hex.substr(3,2),16);
	var b = parseInt(hex.substr(5,2),16);

	// Set flag to stop recursion of showColorVal() calling this
	// function which calls the slider move() method which has an
	// assigned callback function of showColorVal().
	showSliderColor.skip = true;

	red_slider.move(r);
	green_slider.move(g);
	blue_slider.move(b);

	// Reset recursion busting flag
	showSliderColor.skip = false;
}

function sliderColor() {

	// Return hex value of color sliders.

	var f = document.slider_form;
	var s = '';
	s += DecToHex(f.red_val.value);
	s += DecToHex(f.green_val.value);
	s += DecToHex(f.blue_val.value);
	return s;
}

// Simple function to convert decimal color codes 0-255 to Hex codes 00 to FF.
DecToHex.HexDigits = [ '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' ];
function DecToHex(d) {
	return    (d > 255) ? 'FF'
		: (d < 0)   ? '00'
		: ('' + DecToHex.HexDigits[ Math.floor(d / 16) ] + DecToHex.HexDigits[ d % 16 ]);
}

