/************************************************************
*                         FormHelper                        *
*                        Version 1.0                        *
*                          22/04/06                         *
*===========================================================*
*     Copyright Steven George 2006.  All rights reserved.   *
*                  DO NOT REMOVE THIS NOTICE                *
*                                                           *
*                   www.bx.com.au/formhelper                *
*                                                           *
* Use of this software is subject to the licence agreement  *
* which is available by visiting the above link.            *
*                                                           *
*   FREE FOR PRIVATE USE.  PUBLIC USE VIA SMALL DONATION    *
*                                                           *
*                      PLEASE DONATE!                       *
*      Your small cotribution is greatly appreciated!       *
*        Simply visit the form helper website above.        *
*                                                           *
*************************************************************/

// Global variables
var FH = new Object();
	FH.BgColor = "#ECE9D8";
	FH.TitleBgColor = "#0A78EE";
	FH.ArrowColor = "#AA0000";
	FH.Font = "Arial";
	FH.FontSize = "8pt";
	FH.TextColor = "#000000";
	FH.TitleText = "<b>&nbsp; FormHelper</b> <a href='http://www.bx.com.au/formhelper' style='color:#dddddd;font-size:7pt'> - By Steven George</a>";
	FH.TitleTextColor = "#FFFFFF";
	FH.FadeSpeed = 70;
    FH.SubmitButtonId = "submit";
    FH.SubmitButtonId2 = null;

var counterX = 0; 
var counterY = 0;
var arrowCounterX = 0; 
var arrowCounterY = 0;
var arrowHeadCounterX = 0; 
var arrowHeadCounterY = 0;
var myInterval;
var myFlasherInterval;
var inPosition1 = true;
var inPosition2 = true;
var lineOrder = 1;
var fadeStep = 0;
var currentElement;
var cuurentElementOrigColor;
var arrowArray = new Array(80);
var IE = (navigator.appName == "Microsoft Internet Explorer");
blend = new Array (12);

Number.prototype.numToHex = function() { return this.toString(16).toUpperCase(); }

String.prototype.hexToNum = function() { return parseInt(this, 16); }

////////////////////////////////////////////////
// COMMON FORM VALIDATION TOOLS               //
////////////////////////////////////////////////

// Function to check if a value is empty (null)
function IsNull(value){return !(value == "");}

// Function to check if a value is numeric
var numberString = "0123456789";
function IsNumeric(myString)
{
	for(var i=0 ; i < myString.length ; i++)
		if(numberString.indexOf(myString.substring(i,i+1)) == -1)
			return false;
	return true;
}

// Function to check if a value is not numeric
function IsNotNumeric(myString)
{
	for(var i=0 ; i < myString.length ; i++)
		if(!(numberString.indexOf(myString.substring(i,i+1)) == -1))
			return false;
	return true;
}

// Function to check if and quotations or apostrophes were entered
function IsValid(myString)
{
	if(myString.indexOf(unescape("%22")) != -1)
		return false;
	if(myString.indexOf(unescape("%27")) != -1)
		return false;
	return true;
}

// Function to automatically tab fields
function Advance(prevField, currentField, nextField, triggerSize)
{
	if(document.getElementById(currentField).value.length == triggerSize)
		document.getElementById(nextField).focus();
	else if(navigator.appName == "Microsoft Internet Explorer") 
	{
	  // Only IE supports capturing backspace keycode to advance to previous field
		if((document.getElementById(currentField).value.length == 0) && (event.keyCode == 8))
		{
			document.getElementById(prevField).focus();
			// Position cursor at the end of a text box
			document.getElementById(prevField).value = document.getElementById(prevField).value;
		}
	}
}

function colourBlend()
{
	var counter = 0;
	blend[counter++] = FH.BgColor;
	for(i=10;i>1;i--)
	{
		hex1R = FH.BgColor.substring(1,3).hexToNum();
		hex2R = FH.TextColor.substring(1,3).hexToNum();
		hex1G = FH.BgColor.substring(3,5).hexToNum();
		hex2G = FH.TextColor.substring(3,5).hexToNum();
		hex1B = FH.BgColor.substring(5,7).hexToNum();
		hex2B = FH.TextColor.substring(5,7).hexToNum();
		myRValue = Math.round((((hex1R-hex2R)/10)*i));
		myGValue = Math.round((((hex1G-hex2G)/10)*i));
		myBValue = Math.round((((hex1B-hex2B)/10)*i));
		blend[counter++] = "#" + myRValue.numToHex().substring(0,3) + myGValue.numToHex().substring(0,3) + myBValue.numToHex().substring(0,3);
	}
	blend[counter] = FH.TextColor;
}

// Functions to show and hide elements
function closeObject(someID){document.getElementById(someID).style.visibility = "hidden";}
function openObject(someID){document.getElementById(someID).style.visibility = "visible";}

// Closes and resets position of the form helper
function closeAndReset()
{
	// clear variables
	counterX = 0;
	counterY = 0;
	arrowCounterX = 0;
	arrowCounterY = 0;
	arrowHeadCounterX = 0; 
	arrowHeadCounterY = 0;
	inPosition = false;
	inPosition1 = true;
	inPosition2 = true;
	lineOrder = 1;
	currentElement.style.background = cuurentElementOrigColor;
	
	// Clear timers
	clearInterval(myInterval);
	clearInterval(myFlasherInterval);
	clearInterval(errorHeadInterval);
	clearInterval(errorTextInterval);
	clearInterval(myArrowInterval);
	clearInterval(myArrow2Interval);
	clearInterval(myArrow3Interval);
	
	// Reset form helper positions
	document.getElementById("helper").style.top = "-100px";
	document.getElementById("helper").style.left = "0px";
	closeObject("helper");
	document.getElementById("errorHead").style.color = FH.BgColor;
	document.getElementById("errorText").style.color = FH.BgColor;
	
	// Enable submit buttons
	document.getElementById(FH.SubmitButtonId).disabled = false;
    if(FH.SubmitButtonId2)
		document.getElementById(FH.SubmitButtonId2).disabled = false;
	//document.getElementById("reset").disabled = false;
	
	// Remove arrow	
	document.body.removeChild(document.getElementById("oHR"));
	document.body.removeChild(document.getElementById("oHR2"));
	document.body.removeChild(document.getElementById("arrowHeadDiv"));
}

function GetX(element)
{
	var x = 0;
	if(element.offsetParent)
	{
		while(element.offsetParent)
		{
			x += element.offsetLeft;
			element = element.offsetParent;
		}
	}
	else if(element.x) x += element.x;
	return x;
}

function GetY(element)
{
	var y = 0;
	if(element.offsetParent)
	{
		while(element.offsetParent)
		{
			y += element.offsetTop;
			element = element.offsetParent;
		}
	}
	else if(element.y) y += element.y;
	return y; 
}

// This function calls the form helper
function FormHelper(element, headingString, errorString)
{
	// Disable Submit button(s)
	document.getElementById(FH.SubmitButtonId).disabled = true;
    if(FH.SubmitButtonId2)
		document.getElementById(FH.SubmitButtonId2).disabled = true;

	createFormHelper();
	colourBlend();
	
	// Set form helper heading and text
	document.getElementById("errorHead").innerHTML = headingString;
    document.getElementById("errorText").innerHTML = errorString;	
	document.getElementById("errorHead").style.color = FH.BgColor;
	document.getElementById("errorText").style.color = FH.BgColor;
	
	// Fly in form helper to element position
	if(IE) flyIn("helper", (GetY(element) + 10), (GetX(element) + 20));
	else flyIn("helper", GetY(element), GetX(element));
	
	// Highlight form element if possible
	if(element.style != null)	
	{
		currentElement = element;
		cuurentElementOrigColor = element.style.background;
		element.style.background = "#ffff00";
	}
	
	// Scroll the window to the element's position
	if (IE)
		scroll(document.body.scrollLeft, GetY(element) - 80);
	else
		scroll(window.pageXOffset, GetY(element) - 80);

	return false;
}

function createFormHelper()
{
	formHelperDiv = document.createElement("div");
	formHelperDiv.id = "helper";
	with(formHelperDiv.style)
	{
		position = "absolute";
		height = "90px";
		width = "200px";
		top = "-200px";
		left = "0px";
		zIndex = "100";
	}
	
	formHelperTable = document.createElement("table");
	formHelperTable.cellPadding = "0";
	formHelperTable.cellSpacing = "0";
	with(formHelperTable.style)
	{
		border = "solid 1px " + FH.TitleBgColor;
		background = FH.BgColor;
		width = "200px";
	}
	
	newRow = formHelperTable.insertRow(0);
	titleCell = newRow.insertCell(0);
	titleCell.height = "15px";
	titleCell.innerHTML = FH.TitleText;
	with(titleCell.style)
	{
		background = FH.TitleBgColor;
		fontFamily = FH.Font;
		fontSize = FH.FontSize;
		borderBottom = "solid 1px";
		color = FH.TitleTextColor;
		fontWeight = "bold";
		height = "16px";
	}
	
	closeCell = newRow.insertCell(1);
	closeCell.innerHTML = "<div style='margin-right: 3px; text-align: center; border:solid 1px #ffffff; width: 8px; height: 10px; background-color: #E3552A;'><a style='font-family: Verdana; font-weight: bold; font-size: 6pt; text-decoration: none; color: #ffffff;' onClick='closeAndReset();' href='Javascript:void(0);'>X</a></div>";
	closeCell.align = "right";
	with(closeCell.style)
	{
		background = FH.TitleBgColor;
		fontFamily = FH.Font;
		fontSize = FH.FontSize;
		borderBottom = "solid 1px";
		color = FH.TitleTextColor;
	}
	
	newRow = formHelperTable.insertRow(1);	
	textCell = newRow.insertCell(0);
	textCell.align = "center";
	textCell.colSpan = "2";
	with(textCell.style)
	{
		background = FH.BgColor;
		fontFamily = FH.Font;
		fontSize = FH.FontSize;
		color = FH.BgColor;
		height = "60px";
		padding = "5px";
	}
	textCell.innerHTML = "<div style='margin: 5px; font-weight: bold;' align='center' id='errorHead'></div><div style='margin: 5px;' align='center' id='errorText'></div>";
	
	formHelperDiv.appendChild(formHelperTable);
	document.body.appendChild(formHelperDiv);	
}

// This function fades the form helper text in
function fadeText(element, order)
{
	if(lineOrder == order)
	{
		if(fadeStep < 12)
			document.getElementById(element).style.color = blend[fadeStep++];
		else
		{
			fadeStep = 0;
			lineOrder++;
		}
	}
}

// Function to calculate movement of element
function moveNextStep(myElement, Ypos, Xpos, order)
{
	if(lineOrder == order)
	{
		if(counterX < (Xpos - 100))
		{
			document.getElementById(myElement).style.left = counterX + "px";
			counterX += 6;
			inPosition1 = false;
		}
		else
			inPosition1 = true;

		if(counterY < (Ypos + 30))
		{
			document.getElementById(myElement).style.top = counterY + "px";
			counterY += 6;
			inPosition2 = false;
		}
		else
			inPosition2 = true;
			
		if(inPosition1 && inPosition2)
			lineOrder++;
	}
}

// Function to animate movement of form helper to specified positions
function flyIn(element, Ypos, Xpos)
{
    errorHeadInterval = setInterval("fadeText('errorHead', 5)", FH.FadeSpeed);
	errorTextInterval = setInterval("fadeText('errorText', 6)", FH.FadeSpeed);
	openObject(element);
	myInterval = setInterval("moveNextStep('" + element + "', " + Ypos + ", " + Xpos + ", 1)", 1);
	showArrow(Xpos, Ypos);
}

function showArrow(Xpos, Ypos)
{
	// Display arrow
	var oHR = document.createElement("HR");
	with(oHR.style)
        {
          position = "absolute";
          height = "0px";
          width = "10px";
          if(IE)
            color = FH.ArrowColor; // For IE
          else
            backgroundColor = FH.ArrowColor; // For Mozilla and Opera
          border: 0;
          
          top = Ypos + "px";          
          left = (Xpos - 90) + "px";
          display = "none";
        }
    oHR.noShade = true; 
    oHR.id = "oHR";
	document.body.appendChild(oHR);

	var oHR2 = document.createElement("HR");
	with(oHR2.style)
        {
          position = "absolute";
          height = "10px";
          width = "0px";
          if(IE)
            color = FH.ArrowColor; // For IE
          else
            backgroundColor = FH.ArrowColor; // For Mozilla and Opera
          border: 0;
          top = Ypos + "px";
          left = (Xpos - 90) + "px";
          display = "none";
        }
    oHR2.noShade = true; 
    oHR2.id = "oHR2";
	document.body.appendChild(oHR2);
	
	var arrowHead = document.createElement("div");
	arrowHead.id = "arrowHeadDiv";
	document.body.appendChild(arrowHead);
	
	myArrowInterval = setInterval("expandArrow('oHR',"  + 10 + ", " + 30 + "," + Xpos + "," + (Ypos + 30) + "," + 2 + ")", 1);
	myArrow2Interval = setInterval("expandArrow('oHR2',"  + 50 + ", " + 10 + "," + Xpos + "," + (Ypos + 5) + "," + 3 + ")", 1);
	myArrow3Interval = setInterval("expandArrowHead(" + 50 + ", " + 20 + "," + (Xpos - 43) + "," + (Ypos - 5) + "," + 4 + ")", 1);
}

function expandArrowHead(myWidth, myHeight, Xpos, Ypos, order)
{
	if(lineOrder == order)
	{
		if(arrowHeadCounterY < myHeight)
		{
			arrowArray[arrowHeadCounterX] = document.createElement("HR");
			arrowArray[arrowHeadCounterX].name = "FH_arrow_head";
			with(arrowArray[arrowHeadCounterX].style)
			{
				position = "absolute";
				height = (myHeight - arrowHeadCounterY) + "px";
				width = "3px";
                color = FH.ArrowColor; // For IE
                backgroundColor = FH.ArrowColor; // For Mozilla and Opera
				top = (Ypos + (arrowHeadCounterY / 2)) + "px";
				left = (Xpos + arrowHeadCounterX + 2) + "px";
			}
			//document.body.appendChild(arrowArray[arrowHeadCounterX]);
			document.getElementById("arrowHeadDiv").appendChild(arrowArray[arrowHeadCounterX]);
			arrowHeadCounterY += 2;
			arrowHeadCounterX += 2;
			inPosition = false;
		}
		else
			lineOrder++;			
	}
}

function expandArrow(anArrow, width, height, Xpos, Ypos, order)
{
	if(lineOrder == order)
	{
		document.getElementById(anArrow).style.display = "block";
		if(arrowCounterX < (width))
		{
			document.getElementById(anArrow).style.width = arrowCounterX + "px";
			arrowCounterX += 1;
			inPosition1 = false;
		}
		else
			inPosition1 = true;
		if(arrowCounterY < (height))
		{
			document.getElementById(anArrow).style.height = arrowCounterY + "px";
			document.getElementById(anArrow).style.top = (Ypos - arrowCounterY) + "px";
			arrowCounterY += 1;
			inPosition2 = false;
		}
		else
			inPosition2 = true;
			
		if(inPosition1 && inPosition2)
			lineOrder++;
	}
}

// Function to check if a value is even
function isEven(x) { return (x%2)?false:true; }
