// JavaScript Document
// Holds common functions
//--------------- GLOBALS -----------------------------------------------------
var d=new Date();
var monthname		= new Array("January",	"February",	"March",
								"April",	"May",		"June",
								"July",		"August",	"September",
								"October",	"November",	"December");
//Ensure correct for language. English is "January 1, 2007"
var TODAY 			= monthname[d.getMonth()] + " " + d.getDate() + ", " + d.getFullYear();
var gv_firstError	= null;
//-----------------------------------------------------------------------------


// --------------------closeWindowFF()-----------------------------------------
// Close this window, whatever browser you are in, whether you opened it or not
// Don't try to understand it! It just fools browser into believing it opened
// this window, whether it did or not, so it is happy to always close it down.
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
function closeWindowFF() 
{
	window.open('','_parent','');
	window.close();
}
// --------------------END closeWindowFF()-------------------------------------

// --------------------mm_displayStatusMsg()-----------------------------------
// Relates to text for mouse-over for buttons 
// from Dreamweaver version 3.
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
function mm_displayStatusMsg(msgStr) 
{
	status=msgStr;
	document.mm_returnValue = true;
}
// --------------------END mm_displayStatusMsg()--------------------------------

// --------------------gv_findCell()-----------------------==-------------------
// Find which table cell was clicked on
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
function gv_findCell(e)
{
	/* for most browsers, "e" is the event argument
	   but IE has a global "event" object, with different names for most properties
	   the easiest way to deal with this is to convert IE's references, so:
	   if e is not recognised, store event object to it
	   and then convert the event target reference	*/
	var evt;
	if (!e) { evt = window.event; }
	else { evt 	= e }
    if (evt.target) { mouseActionObj = evt.target }
	else
	{ 	// check if we have a srcElement for the event (InternetExplorer ONLY)
	    if (evt.srcElement) { mouseActionObj = evt.srcElement }
	}
    if (mouseActionObj.nodeType == 3) { mouseActionObj = mouseActionObj.parentNode } 	// defeat Safari bug
	var cell 		= mouseActionObj.parentNode;		// get the cell containing the element clicked
    var row 		= cell.parentNode;					// Get the row this cell belongs to
    var lineIndex 	= row.rowIndex;     				// find the index of this row
	return lineIndex;
}
// --------------------end gv_findCell()---------------------------------------


// --------------------Common Validation routines------------------------------

// --------------------validate_email()----------------------------------------
// email address must have one "@" and at least one ".", with a letter between them.
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
function validate_email(field,alerttxt)
{
	with (field)
	{
		apos=value.indexOf("@");
		dotpos=value.lastIndexOf(".");
		if (apos<1||dotpos-apos<2) 
		{
			gv_writeError(field, alerttxt);
			// field.focus();
			return false;
		}
		else { return true }
	}
}
// --------------------END validate_email()-------------------------------------

// --------------------gv_strip()--------------------------------------
// remove leading and trailing blanks from a field
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
function strltrim()
{
return this.replace(/^\s+/,'');
}

function strrtrim()
{
return this.replace(/\s+$/,'');
}

function strtrim()
{
return this.replace(/^\s+/,'').replace(/\s+$/,'');
}

String.prototype.ltrim 	= strltrim;
String.prototype.rtrim 	= strrtrim;
String.prototype.trim 	= strtrim;

// --------------------validate_required()--------------------------------------
// various fields are required, and must have some data entered
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
function validate_required(field,alerttxt)
{
	with (field)
	{
		if (value==null||value=="")
		{
			gv_writeError(field, alerttxt);
			return false;
		}
		var str	= value.trim();
		if(str==null||str=="")
		{
			gv_writeError(field, alerttxt);
			// alert(alerttxt);
			// field.focus();
			return false;
		}
		return true;
	}
}
// --------------------END validate_required()----------------------------------

// --------------------validate_match()-----------------------------------------
// The data in two field values must match
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
function validate_match(field1,field2,alerttxt)
{
	with (field1) { str1=value.rtrim(); }
	with (field2) { str2=value.rtrim(); }
	if (str1!=str2)
	{
		gv_writeError(field2, alerttxt);
		// field2.focus();
		return false;
	}
	else { return true }
}
// --------------------END validate_match()-------------------------------------

// --------------------validate_phone()-----------------------------------------
// The data in a field should be reformatted as a phone number, and obey certain 
// rules if it is a US number
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
function validate_phone(phoneField)
{
	var phoneNbr = phoneField.value.rtrim();
// 1. save the original number in case no changes are required. 
// 		- (saved still in phoneField.value)
// 2.  If it starts with a 1 or a +1, then remove them.
	if(phoneNbr.length > 2)
	{
		if (phoneNbr.substring(0,2) == "+1")
		{	
			prefix		= "+1";
			phoneNbr	= phoneNbr.substring(2);
		}
		else
		{
			if(phoneNbr.substring(0,1) == "1")
			{	
				prefix		= "+1";
				phoneNbr	= phoneNbr.substring(1);
			}
		}
	}
// 3. Remove their formatting, up to the 10th digit
	var fmtStr	= "";
	var sv		= "";
	for(i=0; i<phoneNbr.length; i++)
	{
	   var x = phoneNbr.charAt(i);
//	   
// following line WAS allowing their formatting to stay
//	   if (x=='/' || x=='(' || x==')' || x=='.' || x=='-')  { return true; }
// above line WAS allowing their formatting to stay
//
// 4. Close up any spaces or formatting characters within the first 10 characters.
// & any double-spaces after that
	   if ((fmtStr.length > 9 || (x!=" " && x!='/' && x!='(' && x!=')' && x!='.' && x!='-')) && !(sv == " " && x == " ")) 
	   {
		   fmtStr = fmtStr + x;
		   sv	= x;
	   }
	}
	phoneNbr	= fmtStr;
// 5. Get all the leading numbers (ending at non-numeric characters)
	nbrStr		= "";
	for(i=0; i<phoneNbr.length; i++)
	{
       if (isNaN(parseInt(phoneNbr.charAt(i))) || phoneNbr.charAt(i) == " ") { break; }
	   nbrStr	= nbrStr + phoneNbr.charAt(i);
	}
// 6. If 7 digits, then ask for area code, and declare it an error. Leave as is.
	if(nbrStr.length == 7)
	{
		gv_writeError(phoneField, 'Please enter an area code');
		return false;
	}
// 7. If not 10 digits then assume not a US number. Leave as is.
	if(nbrStr.length != 10) { return true; }
// 8. Format it nnn-nnn-nnnn
   	fmtStr = nbrStr.substring(0,3) + "-" + nbrStr.substring(3,6) + "-" + nbrStr.substring(6,10);
// 9. Get all the remaining characters from where we ended in step 5, and tack them on the end
// 		- after a one space gap 
//		- assuming that is the extension number.
	if(nbrStr.length<phoneNbr.length)
	{
		fmtStr = fmtStr + " " + phoneNbr.substring(nbrStr.length);
	}
	phoneField.value	=  fmtStr;
	return true;
}
// --------------------END validate_match()-------------------------------------
// --------------------gv_writeError()-----------------------------------------
// Write an error message next to the field in error. 
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
function gv_writeError(obj,	message) 
{
	validForm = false;
	if (obj.hasError) return;
	var W3CDOM = (document.getElementsByTagName && document.createElement);
	if (W3CDOM) 
	{
		obj.className 		+= ' errorfield';
		obj.onchange 		= gv_removeError;
		var sp 				= document.createElement('span');
		sp.className 		= 'errortext';
		sp.appendChild(document.createTextNode(message));
		obj.parentNode.appendChild(sp);
		obj.hasError 		= sp;
	}
	else 
	{
		alert(message);
		obj.hasError 		= true;
	}
	if (!gv_firstError)
	{
		gv_firstError 		= obj;
		gv_firstError.focus();
	}
}

function gv_removeError()
{
	this.className = this.className.substring(0,this.className.lastIndexOf(' '));
	this.parentNode.removeChild(this.hasError);
	this.hasError = null;
	this.onchange = null;
}
// --------------------END validate_match()-------------------------------------
// --------------------gv_clientWidth()-----------------------------------------
// Get the width of the window (or browser) in pixels. 
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
function gv_clientWidth() 		
{
	return gv_filterResults (
		window.innerWidth ? window.innerWidth : 0,
		document.documentElement ? document.documentElement.clientWidth : 0,
		document.body ? document.body.clientWidth : 0
	);
}
// --------------------END gv_clientWidth()-------------------------------------

// --------------------gv_clientHeight()----------------------------------------
// Get the height of the window (or browser) in pixels. 
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
function gv_clientHeight() 
{
	return gv_filterResults (
		window.innerHeight ? window.innerHeight : 0,
		document.documentElement ? document.documentElement.clientHeight : 0,
		document.body ? document.body.clientHeight : 0
	);
}
// --------------------END gv_clientHeight()------------------------------------

// --------------------gv_scrollLeft()------------------------------------------
// Get the horizontal scroll bar position in pixels. 
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
function gv_scrollLeft() 
{
	return gv_filterResults (
		window.pageXOffset ? window.pageXOffset : 0,
		document.documentElement ? document.documentElement.scrollLeft : 0,
		document.body ? document.body.scrollLeft : 0
	);
}
// --------------------END gv_scrollLeft()--------------------------------------

// --------------------gv_scrollTop()-------------------------------------------
// Get the vertical scroll bar position in pixels. 
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
function gv_scrollTop() 			// vertical scroll bar position
{
	return gv_filterResults (
		window.pageYOffset ? window.pageYOffset : 0,
		document.documentElement ? document.documentElement.scrollTop : 0,
		document.body ? document.body.scrollTop : 0
	);
}
// --------------------END gv_scrollTop()---------------------------------------

// --------------------gv_filterResults()---------------------------------------
// determine which value is valid - depends on browser implementation
// this is used by the above window size and scroll bar positiuon functions
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
function gv_filterResults(n_win, n_docel, n_body)   
{
	var n_result = n_win ? n_win : 0;
	if (n_docel && (!n_result || (n_result > n_docel)))
		n_result = n_docel;
	return n_body && (!n_result || (n_result > n_body)) ? n_body : n_result;
}
// --------------------END gv_filterResults()-----------------------------------

// --------------------gv_findPosX()--------------------------------------------
// determines the left-hand offset of the document object relative to the window.
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
function gv_findPosX(obj)
{
	var curleft = 0;
	if (obj.offsetParent)
	{
		while (obj.offsetParent)
		{
			curleft += obj.offsetLeft
			obj = obj.offsetParent;
		}
	}
	else if (obj.x)
		curleft += obj.x;
	return curleft;
}
// --------------------END gv_findPosX()----------------------------------------

// --------------------gv_findPosY()--------------------------------------------
// determines the top offset of the document object relative to the window.
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
function gv_findPosY(obj)
{
	var curtop = 0;
	if (obj.offsetParent)
	{
		while (obj.offsetParent)
		{
			curtop += obj.offsetTop
			obj = obj.offsetParent;
		}
	}
	else if (obj.y)
		curtop += obj.y;
	return curtop;
}
// --------------------END gv_findPosY()----------------------------------------

// --------------------gv_getObj()----------------------------------------------
// cross-browser code to get the document object from its id
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
function gv_getObj(divName)
{
  if (document.getElementById)
  { this.obj 	= document.getElementById(divName) }
  else if (document.all)
  { this.obj 	= document.all[divName] }
  else if (document.layers)
  { this.obj 	= document.layers[divName] }
}
// --------------------END gv_getObj()------------------------------------------

// --------------------gv_positionObj()-----------------------------------------
// reposition a pop-up window to be next to an existing object, like a button
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
function gv_positionObj(targetObj, movingObj, extraX, extraY)
{
	var oldLeft, oldTop;
	if (movingObj.offsetParent)
	{
		oldLeft	= movingObj.offsetLeft;
		oldTop	= movingObj.offsetTop;
	}
	else if (movingObj.y) 
	{
		oldLeft	= movingObj.x;
		oldTop	= movingObj.y;
	}
	var newLeft		= gv_findPosX(targetObj) - gv_findPosX(movingObj) + oldLeft + extraX;
	var newTop		= gv_findPosY(targetObj) - gv_findPosY(movingObj) + oldTop + extraY;
	movingObj.style.left 	= newLeft + 'px';
	movingObj.style.top 	= newTop + 'px';
}
// --------------------END gv_positionObj()-------------------------------------

// --------------------gv_ensureOnScreen()-------------------------------------
// Make sure that the adjustments to an object's start positions are not too large
// & haven't moved it off the screen. move to the edge off the screen if necessary
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
function gv_ensureOnScreen(div)
{
	var divY		= gv_findPosY(div);
	var cHeight		= gv_clientHeight();
	var dY			= div.style.top;
	var y 			= parseInt(dY.substring(0,dY.length-2));
	var dH			= div.style.height;
	var h 			= parseInt(dH.substring(0,dH.length-2));
	if (divY + h > cHeight)
	{
		var newY		= y + cHeight - divY - h - 1;
		if (newY < 0) { newY = 0 }
		div.style.top	= newY + 'px'; 
	}

	var divX		= gv_findPosX(div);
	var cWidth		= gv_clientWidth();
	var dX 			= div.style.left;
	var x			= parseInt(dX.substring(0,dX.length-2));  // strip off the "px"
	var dW			= div.style.width;
	var w			= parseInt(dW.substring(0,dW.length-2));  // strip off the "px"
	if (x + w > cWidth)
	{
		var newX		= x + cWidth - divX - w - 1;
		if (newX < 0) { newX = 0 }
		div.style.left	= newX + 'px'; 
	}
}
// --------------------END gv_ensureOnScreen()----------------------------------

// --------------------gv_drag_drop()-------------------------------------------
// Set up the functions to wait for mouse actions and move a visible DOM element
// Global variables used by the drag-drop functions
var gv_movingElement;				// the window element to be dragged and dropped
var gv_posX;						// x coordinate of mouse
var gv_posY;						// y coordinate of mouse
var	gv_wdwTop;						// y coordinate of element
var	gv_wdwLeft;						// x coordinate of element
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
function gv_drag_drop(divName)
{
	gv_movingElement				= new gv_getObj(divName).obj;
	gv_movingElement.onmousedown	= gv_mouse_Move;						// set up mouse listener functions
	gv_movingElement.onmouseup		= gv_stop_mouse_Move;
}
// --------------------END gv_drag_drop()---------------------------------------

// --------------------gv_mouse_Move()------------------------------------------
// onmousedown function to start drag-drop
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
function gv_mouse_Move(e)
{
	gv_movingElement.onmousemove	= gv_drag;								// start the drag function
	gv_getMouseXY(e);
	sWdwTop							= gv_movingElement.style.top;
	sWdwLeft						= gv_movingElement.style.left;
	gv_wdwTop						= sWdwTop.substring(0,sWdwTop.length-2);  // strip off the "px"
	gv_wdwLeft						= sWdwLeft.substring(0,sWdwLeft.length-2);
}
// --------------------END gv_drag_drop()---------------------------------

// --------------------gv_getMouseXY()------------------------------------------
// Get the starting position of the mouse
// The mouse position, relative to the document, is put into gv_posX and gv_posY
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
function gv_getMouseXY(e)
{
	var we;
	if (e) { we	= e }
	else { we 	= window.event }
	if (we.pageX || we.pageY)
	{
		gv_posX	= we.pageX;
		gv_posY	= we.pageY;
	}
	else if (we.clientX || we.clientY)
	{
		gv_posX	= we.clientX + document.body.scrollLeft
					 		 + document.documentElement.scrollLeft;
		gv_posY = we.clientY + document.body.scrollTop
							 + document.documentElement.scrollTop;
	}
}
// --------------------END gv_getMouseXY()--------------------------------------

// --------------------gv_drag()------------------------------------------------
// Drag the object by moving it the same amount as the mouse has moved
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
function gv_drag(e)
{
																	// find the mouse position
	var tX						= parseInt(gv_posX);
	var tY						= parseInt(gv_posY);
	gv_getMouseXY(e);
	gv_wdwLeft					= parseInt(gv_wdwLeft) + parseInt(gv_posX) - tX;
	gv_wdwTop					= parseInt(gv_wdwTop) + parseInt(gv_posY) - tY;
	var nX						= gv_wdwLeft + "px";
	var nY						= gv_wdwTop + "px";
	gv_movingElement.style.left	= nX;
	gv_movingElement.style.top	= nY;
//	moveBy(gv_posX-tX, gv_posY-tY); // <-- why didn't this work??
	return false;
}
// --------------------END gv_drag()--------------------------------------------


// --------------------gv_stop_mouse_Move()-------------------------------------
// onmouseup function to end the drag-drop process
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
function gv_stop_mouse_Move()
{
	gv_movingElement.onmousemove	= null;
}
// --------------------END gv_stop_mouse_Move()---------------------------------

// --------------------gv_createRequestObject()---------------------------------
/* AJAX (Asynchronous posting to the server).  */
/* The following function creates an XMLHttpRequest object.  */
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
function gv_createRequestObject()
{
	var request_o = false;
	try { request_o = new ActiveXObject("Microsoft.XMLHTTP") }
	catch(ex) {  } 		//either this is not IE, or it is a version of IE which does not support XMLHTTP
	if (!request_o)
	{
		try { request_o = new XMLHttpRequest() }
		catch(ex) { }	//we can't use AJAX because this browser is not compatible.
	}
	return request_o;
}

/* The variable http will hold our new XMLHttpRequest object. */
var http		= null;
var httpPosting	= false;
var httpnext	= null; 
// --------------------END gv_createRequestObject()------------------------------

// --------------------gv_ajaxForm()---------------------------------------------
// Function called to transmit a form to the server
//
// Function parameters:
//	formName    is the name of an html form
//	url			is the address of the server script to post to.
//	funk 		is the function that is sent the response (if any):  funk(response);
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
function gv_ajaxForm(formName, url, funk)
{
	thisForm = document[formName];
	var postdata		= new Object();
	for (var i in thisForm) 
	{
		try 
		{
			if (thisForm[i].value) { postdata[i]	= thisForm[i].value; }
		}
		catch(ex) { }
	}
	sent	= gv_ajaxPost(postdata, url, funk);
	if (!sent) { alert('not posted!'); }
}
// --------------------END gv_ajaxForm()-----------------------------------------

// --------------------gv_ajaxPost()---------------------------------------------
// Function called to transmit an associative array to the server
// Function parameters:
//	postdata	is an associative array, with named indexes, where the names are the POST field names
//	url			is the address of the server script to post to.
//	funk 		is the function that is sent the response (if any):  funk(response);
//	
//	this function returns true if it posted the postdata or false if it failed to post
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
function gv_ajaxPost(postdata, url, funk)
{
	if (http == null) 
	{	
		http	= gv_createRequestObject();
		if (!http) 
		{ 
			alert('Browser not AJAX-compatible - cannot post to server!');
			http	= 0;
		}
	}	
	/*  Create the request. The first argument to the open function is the method (POST/GET),
		and the second argument is the url... 	*/
	if(!httpPosting && http)
	{
		httpPosting	= true;
		/*	http.abort; */  
		http.open('post', url);
		http.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
		/* Define a function to call once a response has been received. */
		http.onreadystatechange = gv_waitAjaxResponse;
		httpnext				= null;
		if (funk) {	httpnext	= funk; }
		/* Send the data. We use something other than null when we are sending using the POST
			method: separate variables with &. To send no data use: 	http.send(null);	*/
		post = "";
		for (var i in postdata)
		{
//			alert('postdata[\''+i+'\'] is ' + postdata[i]);
			if (post) { post	+= '&'; }
			post	+= i + '=' + postdata[i].replace(/&/g,'%26');
		}
		if (post == "" )	{ http.send(null) }
		else				{ http.send(post) }
		return true;
	}
	return false;
}
// --------------------END gv_ajaxPost()----------------------------------------

// --------------------gv_waitAjaxResponse()------------------------------------
// Function called to handle whatever was returned from the internal_request.php file
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
function gv_waitAjaxResponse()
{
	/* Make sure that the transaction has finished. The XMLHttpRequest object 
		has a property called readyState with several states:
		0: Uninitialized
		1: Loading
		2: Loaded
		3: Interactive
		4: Finished */
	if(http.readyState == 4)
	{
		//Finished loading the response
		httpPosting		= false;
		var response	= http.responseText;
		if (httpnext) { httpnext(response) }
	}
}
// --------------------END gv_waitAjaxResponse()--------------------------------
