function clearHex(color_set) {
	document.getElementById(color_set+"_hex").value = "";	
}

function isNum(q_string) {
	if(q_string.match(/[^0123456789]/)) {
		//non numerics found
		return false;
	}
	else {
		return true;
	}
}

function isHex(q_string) {
	if(q_string.match(/[^0123456789abcdefABCDEF]/)) {
		//non hex found
		return false;
	}	
	else {
		return true;
	}
}

function decToHex(d) {
	//lazy me; gratuitously ripped from http://javascript.about.com/library/blh2d.htm
	var hD="0123456789ABCDEF";
	
	var h = hD.substr(d&15,1);
	while(d>15) {d>>=4;h=hD.substr(d&15,1)+h;}
	
	if(h.length==1) {
		h = "0"+h;
	}

	return h;
}

function hexToDec(h) {
	//lazy me; gratuitously ripped from http://javascript.about.com/library/blh2d.htm
	
	return parseInt(h,16);
}

function getColors(color_set) {
	var red_value = document.getElementById(color_set+"_red").value;
	var green_value = document.getElementById(color_set+"_green").value;
	var blue_value = document.getElementById(color_set+"_blue").value;
	var hex_value = document.getElementById(color_set+"_hex").value;

	return [red_value,green_value,blue_value,hex_value];

}

function validateFormInput(fg_color, bg_color) {
	
	//first, are we working with dec values, hex values, or (gulp!) both?

	var fg_dec_values = 0;
	var bg_dec_values = 0;
	var fg_hex_value = 0;
	var bg_hex_value = 0;

	if(	fg_color[0] &&
		fg_color[1] &&
		fg_color[2] ) {
		
		fg_dec_values=1;
	}

	if(	bg_color[0] &&
		bg_color[1] &&
		bg_color[2] ) {
		
		bg_dec_values=1;
	}
	
	if(fg_color[3]) {
		fg_hex_value=1;
	}

	if(bg_color[3]) {
		bg_hex_value=1;
	}

	//next, check to see if we have sufficient input to work:
	if( !fg_dec_values && !fg_hex_value) {
		alert("Foreground Color Error: Please enter three decimal values or one hex value.");
		return false;
	}

	if(	!bg_dec_values && !bg_hex_value) {
		alert("Background Color Error: Please enter three decimal values or one hex value.");
		return false;
	}

	//validate hex values, if any
	if(fg_hex_value) {
		if(fg_color[3].length != 6) {
			alert("Foreground Color Error: Hex values must have 6 characters.");
			return false;
		}
		else if(!isHex(fg_color[3])) {
			alert("Foreground Color Error: Hex values may only contain the character 0 - 9 and A - F.");
			return false;
		}
	}

	if(bg_hex_value) {
		if(bg_color[3].length != 6) {
			alert("Background Color Error: Hex values must have 6 characters.");
			return false;
		}
		else if(!isHex(bg_color[3])) {
			alert("Background Color Error: Hex values may only contain the character 0 - 9 and A - F.");
			return false;
		}
	}

	//if dec values, make sure they're numbers, and in range
	if(fg_dec_values) {
		if (isNum(fg_color[0]) && isNum(fg_color[1]) && isNum(fg_color[2])) {
			if(fg_color[0] > 255 || fg_color[1] > 255 || fg_color[2] > 255) {
				alert("Foreground Color Error: Decimal values must be within the range 0 to 255");
				return false;
			}
		}
		else {
			alert("Foreground Color Error: Decimal values may only contain numbers.");
			return false;
		}
	}

	if(bg_dec_values) {
		if (isNum(bg_color[0]) && isNum(bg_color[1]) && isNum(bg_color[2])) {
			if(bg_color[0] > 255 || bg_color[1] > 255 || bg_color[2] > 255) {
				alert("Background Color Error: Decimal values must be within the range 0 to 255");
				return false;
			}
		}
		else {
			alert("Background Color Error: Decimal values may only contain numbers.");
			return false;
		}
	}

	//if both, check to see if dec and hex are the same
	if(fg_dec_values && fg_hex_value) {
		var calculated_hex_value = decToHex(fg_color[0]) + decToHex(fg_color[1]) + decToHex(fg_color[2]);
		
		if(calculated_hex_value != fg_color[3].toUpperCase()) {
			alert("Foreground Color Error: You entered both Dec and Hex values, but they don't seem to match. Try entering only Decimal or Hex values.");
			return false;
		}
	}

	if(bg_dec_values && bg_hex_value) {
		var calculated_hex_value = decToHex(bg_color[0]) + decToHex(bg_color[1]) + decToHex(bg_color[2]);
		
		if(calculated_hex_value != bg_color[3].toUpperCase()) {
			alert("Background Color Error: You entered both Dec and Hex values, but they don't seem to match. Try entering only Decimal or Hex values.");
			return false;
		}
	}
	
	//now that everything is good, if there are dec and not hex values, we're going to calculate hex
	// and insert that into the field via the DOM
	
	if(fg_dec_values && !fg_hex_value) {
		var calculated_hex_value = decToHex(fg_color[0]) + decToHex(fg_color[1]) + decToHex(fg_color[2]);
		
		document.getElementById("fg_hex").value = calculated_hex_value;
		
	}

	if(bg_dec_values && !bg_hex_value) {
		var calculated_hex_value = decToHex(bg_color[0]) + decToHex(bg_color[1]) + decToHex(bg_color[2]);
		
		document.getElementById("bg_hex").value = calculated_hex_value;
		
	}
	
	return true;
}

function setExampleColors() {
	
	//i'm assuming that there's hex in the field because i set it when i validated the form
	// i'm re-grabbing data from the form because it may have changed when i validated
		
	fg_color_string = document.getElementById("fg_hex").value;
	bg_color_string = document.getElementById("bg_hex").value;
	
	// insert the values into the spans
	
	fg_text_span = document.getElementById("fg_hex_color");
	bg_text_span = document.getElementById("bg_hex_color");
	
	if(fg_text_span.firstChild) {
		fg_text_span.firstChild.data = "#" + fg_color_string;
	}
	else {
		var fg_color_text = document.createTextNode("#" + fg_color_string);
		fg_text_span.appendChild(fg_color_text);
	}

	if(bg_text_span.firstChild) {
		bg_text_span.firstChild.data = "#" + bg_color_string;
	}
	else {
		var bg_color_text = document.createTextNode("#" + bg_color_string);
		bg_text_span.appendChild(bg_color_text);
	}
	
	//now set the style properties of the demo area
	
	demo_para = document.getElementById("demo");
	demo_para.style.backgroundColor = "#" + bg_color_string;
	demo_para.style.color = "#" + fg_color_string;
}

function hexToRGB(hex_color) {
	//i'm assuming that this is 6 digits, with no leading # sign

	var RGB_result = new Array;
	
	RGB_result[0] = hexToDec(hex_color.substr(0,2));
	RGB_result[1] = hexToDec(hex_color.substr(2,2));
	RGB_result[2] = hexToDec(hex_color.substr(4,2));
	
	return RGB_result;
}

function bigger(i,j) {
	if (i >= j) {
		return i;
	}
	else {
		return j;
	}
}

function smaller(i,j) {
	if (i <= j) {
		return i;
	}	
	else {
		return j;
	}
}

function displayResults(fg_brightness,bg_brightness,color_contrast,deltas, color_difference) {
	var fg_bright_span = document.getElementById("fg_bright");
	var bg_bright_span = document.getElementById("bg_bright");
	var contrast_span = document.getElementById("contrast");
	var difference_span = document.getElementById("difference");
	var deltaR_span = document.getElementById("dR");
	var deltaG_span = document.getElementById("dG");
	var deltaB_span = document.getElementById("dB");
	
	

	if(fg_bright_span.firstChild) {
		fg_bright_span.firstChild.data = fg_brightness;
	}
	else {
		var fg_bright_text = document.createTextNode(fg_brightness);
		fg_bright_span.appendChild(fg_bright_text);
	}

	if(bg_bright_span.firstChild) {
		bg_bright_span.firstChild.data = bg_brightness;
	}
	else {
		var bg_bright_text = document.createTextNode(bg_brightness);
		bg_bright_span.appendChild(bg_bright_text);
	}

// ie5 mac throws an exception with toFixed, so we'll just work around that
// with parseInt, which i don't want to use here, but ug, stupid IE5 mac 


	if(color_contrast > 125) {
		try {
			var contrast_string = "Yes ("+color_contrast.toFixed(0)+")";
		}
		catch(e) {
			var contrast_string = "Yes ("+parseInt(color_contrast,10)+")";
		}
	}
	else {
		try {
			var contrast_string = "No ("+color_contrast.toFixed(0)+")";
		}
		catch(e) {
			var contrast_string = "No ("+parseInt(color_contrast,10)+")";
		}
	}

	if(contrast_span.firstChild) {
		contrast_span.firstChild.data = contrast_string;
	}
	else {
		var contrast_text = document.createTextNode(contrast_string);
		contrast_span.appendChild(contrast_text);
	}

	if(color_difference > 500) {
		try {
			var difference_string = "Yes ("+color_difference.toFixed(0)+")";
		}
		catch(e) {
			var difference_string = "Yes ("+parseInt(color_difference,10)+")";
		}
	}
	else {
		try {
			var difference_string = "No ("+color_difference.toFixed(0)+")";
		}
		catch(e) {
			var difference_string = "No ("+parseInt(color_difference,10)+")";
		}
	}
	
	if(deltaR_span.firstChild) {
		deltaR_span.firstChild.data = deltas[0];
	}
	else {
		var deltaR_text = document.createTextNode(deltas[0]);
		deltaR_span.appendChild(deltaR_text);
	}
	
	if(deltaG_span.firstChild) {
		deltaG_span.firstChild.data = deltas[1];
	}
	else {
		var deltaG_text = document.createTextNode(deltas[1]);
		deltaG_span.appendChild(deltaG_text);
	}
	
	if(deltaB_span.firstChild) {
		deltaB_span.firstChild.data = deltas[2];
	}
	else {
		var deltaB_text = document.createTextNode(deltas[2]);
		deltaB_span.appendChild(deltaB_text);
	}

	if(difference_span.firstChild) {
		difference_span.firstChild.data = difference_string;
	}
	else {
		var difference_text = document.createTextNode(difference_string);
		difference_span.appendChild(difference_text);
	}

	document.getElementById("results").style.display = "block";
}

function checkColors() {
	//first, get the colors from the form (they may have changed in validation)
	
	var fg_color = document.getElementById("fg_hex").value;
	var bg_color = document.getElementById("bg_hex").value;
	
	//convert to rgb, which we need for the math
	
	fg_color = hexToRGB(fg_color);
	bg_color = hexToRGB(bg_color);
	
	//calculate algorithms
	
	/* from https://www.visionaustralia.org.au/info.aspx?page=628
	Colour brightness is determined by the following formula:
	((Red value X 299) + (Green value X 587) + (Blue value X 114)) / 1000
	The difference between the background brightness, and the foreground brightness
	should be greater than 125.
	*/
	
	var fg_brightness = ( (fg_color[0]*299) + (fg_color[1]*587) + (fg_color[2]*114))/1000;
	var bg_brightness = ( (bg_color[0]*299) + (bg_color[1]*587) + (bg_color[2]*114))/1000;
	
	var color_contrast = Math.abs(fg_brightness - bg_brightness);
	
	/*
	Colour difference is determined by the following formula:
	(maximum (Red value 1, Red value 2) - minimum (Red value 1, Red value 2)) + 
	(maximum (Green value 1, Green value 2) - minimum (Green value 1, Green value 2)) + 
	(maximum (Blue value 1, Blue value 2) - minimum (Blue value 1, Blue value 2))
	*/
	
	var deltas = new Array;
	
	deltas[0] = ( bigger(fg_color[0],bg_color[0]) - smaller(fg_color[0],bg_color[0]) );
	deltas[1] = ( bigger(fg_color[1],bg_color[1]) - smaller(fg_color[1],bg_color[1]) );
	deltas[2] = ( bigger(fg_color[2],bg_color[2]) - smaller(fg_color[2],bg_color[2]) );
	var color_difference =  deltas[0] + deltas[1] + deltas[2];
	
	displayResults(fg_brightness,bg_brightness,color_contrast,deltas,color_difference);
}

function analyzeForm() {
	//get data; colors are in arrays of four values: 
	// [0] - dec/red	[1] dec/green	[2] dec/blue	[3] hex value
	var fg_color = getColors("fg");
	var bg_color = getColors("bg");

	//validate intput (this will also change dec values to hex values):
	if(!validateFormInput(fg_color, bg_color)) {
		return null;
	}
	
	//change example space
	setExampleColors();
	
	checkColors();

	//this shouldn't work but IE seems to like it :)
	document.getElementById("results").focus();	
	return true;
	
}

window.onload = function() {
	// we can use the onload function to check if all this dom jazz is supported;
	// originally i was defaulting to displain=none in the style sheet, and this
	// method grew out of debugging IE5 mac problems. 'sokay... this is better
	try {
		document.getElementById("results").style.display="none";
	}
	catch(e) {
		alert("Whoops. A javascript error occured. I don't think this tool will work in your browser. If you're interested, javascript threw the exception "+e+" when calling getElementById");
	}
}