/*-------------------------------------
 * Global configuration variables
 ------------------------------------*/

var xmlRequestObj = false; // The current XMLHttpRequest object.
var strJQueryElementID = ''; // Global variable that holds the current form element's ID for jQuery.
var blnIsFormValid = true; // if false and blnIsFormValidation equals true then halt form submission.  
var objForm; // array container for the document form element.

var iconInfo  = 'includes/media/images/gui/icon-info.gif';
var iconValid = 'includes/media/images/gui/icon-validated.gif';
var iconError = 'includes/media/images/gui/icon-invalid.gif';

var arrFormValidationEvents = new Array(); // array that holds the form element validation methods

/*-------------------------------------
 * Public methods
 ------------------------------------*/

/**
* Controls the process flow to validate
* a single form element.
**/
function validateElement( strAJAXURL, objElement, strFriendlyName, lstValidationRules )
{
	// setup the request param string
	var params = 'AJAX_REQUEST=true&method=validateElement&friendlyName=' + escape( strFriendlyName ) + '&value=' + escape( objElement.value ).replace( '+','%2B' ).replace( "'", '%27' ) + '&validationRules=' + escape( lstValidationRules ) + '&';
	
	// set the value for the current elements ID
	strJQueryElementID = objElement.id;
	strJQueryElementID = strJQueryElementID.replace( /:/g, "\\:" ).replace( /\./g, "\\." ); // trim leading and trailing spaces from ID.
	
	/** 
	* If the element's value is null then reset the 
	* elements class back to it's base class and 
	* return. no need to validate an empty field.
	**/
	if ( objElement.value == "" && lstValidationRules != "" ) 
	{
		changeElementStyle( $('#' + strJQueryElementID).attr( 'restoreClass') ); 
		return; 
	}
	
	/** 
	* If this is an optional field and the
	* element doesn't have a value then return.
	* no need to validate an empty optional field.
	**/
	rxOptional = /optional/;
	if( rxOptional.test( lstValidationRules ) && objElement.value == "" ) { return; }
	
	/** 
	* instantiate the AJAX call to validate an element.
	**/
	getXMLResults( strAJAXURL, params );
	
	return;
}


function validateForm()
{
	/**
	* arrFormValidationEvents array contents.
	* -----------------------------------------------------------------------------
	* Elements:         arrFormValidationEvents.length
	* URL:              arrFormValidationEvents[0][0] (AJAX validation url to call)
	* Current elmID:    arrFormValidationEvents[0][1]
	* Validation Event: arrFormValidationEvents[0][2] (blur or change)
	* Friendly Name:    arrFormValidationEvents[0][3]
	* Validation Rules: arrFormValidationEvents[0][4]
	**/
	
	/**
	* If we have form elements that
	* contain validation rules.
	* rules were defined in elem-gen.cfm
	**/
	if ( arrFormValidationEvents.length > 0 )
	{ 
		/**
		* Loop thru all form elements validating each one.
		* Each loop will make an AJAX call to the validating CFM.
		* any element deemed invalid will return 
		* false that in turn will invalidate the form
		**/
		for ( var el=0; el < arrFormValidationEvents.length; el++ )
		{
			// typecast the current Element
			objElement = document.getElementById( arrFormValidationEvents[el][1] );
			
			// set the value for the current elements ID
			strJQueryElementID = objElement.id;
			strJQueryElementID = strJQueryElementID.replace( /:/g, "\\:" ).replace( /\./g, "\\." ); // trim leading and trailing spaces from ID.
			
			/** 
			* If this is an optional field and the
			* element doesn't have a value then return.
			* no need to validate an empty optional field.
			**/
			//rxOptional = /optional\|/;
			//if( rxOptional.test( arrFormValidationEvents[el][4] ) && objElement.value == "" ) { return; }
			
			// setup the request param string
			var params = 'AJAX_REQUEST=true&method=validateElement&friendlyName=' + escape( arrFormValidationEvents[el][3] ) + '&value=' + escape( objElement.value ).replace( '+','%2B' ).replace( "'",'%27' ) + '&validationRules=' + escape( arrFormValidationEvents[el][4] ) + '&';
			
			/** 
			* instantiate the AJAX call to validate this element
			* using the provided rules. the results are returned as XML
			* and evaluated by the processValidationContainer() method.
			**/
			getXMLResults( arrFormValidationEvents[el][0], params );
		}

		// if all elements were returned as valid then submit the form.
		if( blnIsFormValid == true )
		{
			$( '.xhtml' ).css( 'display', 'block' );
			
			$( '.xhtml' ).each( function(){
				newVal = $(this).val().replace( /[']/g, '&#39;' );
				$( this	).val( newVal );
			});
			
			document.forms[0].submit();	
		}
	}
	// erase the current results XML values.
	//resultXML = false;
}

/*-------------------------------------
 * Private Utility methods
 ------------------------------------*/


/**
* function getXMLResults( {url_to_cfm}, params )
* Makes an AJAX call to the url argument. the xml object returned is
* set to the global xmlRequestObj.responseXML object variable
**/
function getXMLResults( url, params ) 
{
	xmlRequestObj = window.XMLHttpRequest?new XMLHttpRequest():new ActiveXObject( "Microsoft.XMLHTTP" );
	xmlRequestObj.open( "GET", url + '?' + params, false );
	xmlRequestObj.send( null );
	xmlRequestObj.onreadystatechange = processValidationContainer( xmlRequestObj.responseXML );
	
}


/** 
* process the returned XML result container
**/
function processValidationContainer()
{	
	if ( xmlRequestObj.readyState == 4 && xmlRequestObj.status == 200 ) 
	{ 
		//if( !xmlRequestObj.responseXML )
		//	return
			
		// verify the XML object and parse it's nodes
		root = xmlRequestObj.responseXML.getElementsByTagName( 'results' ).item(0);
		
		results = root.getElementsByTagName( 'result' );
	
		// Process the result XML container
		for( var x = 0; x < results.length; x++ )
		{
			// Get <Valid> element. The form elements valid status ( concidered boolean ) 
			var blnIsValid = results[x].getElementsByTagName( "Valid" )[0].childNodes[0].nodeValue;
			// Get <Message> element. any returned message such as error or information.
			if( results[x].getElementsByTagName( "Message" )[0].childNodes[0] != null )
				var strMessage = results[x].getElementsByTagName( "Message" )[0].childNodes[0].nodeValue;
			else
				var strMessage = "";
			// Get <Value> element. the returned masked value if the form element is valid.
			if( results[x].getElementsByTagName( "Value" )[0].childNodes[0] != null )
				var strValue = results[x].getElementsByTagName( "Value" )[0].childNodes[0].nodeValue;
			else
				var strValue = "";
			
			// Process the results

			// if processing a form and blnIsValid = false return false to stop further processing
			if( blnIsValid == 'false' )
			{
				// change style to invalid
				changeElementStyle( 'error' );
				// populate the message div with the returned error message.
				populateErrorDiv( '#tt-' + strJQueryElementID + '-message', strMessage );
					
				// if this run is a form validation check then set the isFormValid variable to false(Failed!)
				blnIsFormValid = false;
			}
			else if( blnIsValid == 'true' )
			{
				// change style to valid
				changeElementStyle( 'valid' );
				// insert the masked post value into the element
				//strValue = strValue.replace( '&lt;', '<' ).replace( '&gt;', '>' );
				jQuery( '#' + strJQueryElementID ).val( strValue );
			}
		} // end for loop
	} // end if
} // end processResultContainer


// sets the current elements class to the correct state
function changeElementStyle( strClassName )
{ 
	// remove error and valid classes
	jQuery( '#' + strJQueryElementID ).removeClass( 'valid' );
	jQuery( '#' + strJQueryElementID ).removeClass( 'error' );
	jQuery( '#' + strJQueryElementID ).removeClass( 'required' );
	
	// change tooltip icon to reflect valid/failed results
	if ( strClassName == 'valid' || strClassName == 'error' )
	{
		// append the requested validation className
		jQuery( '#' + strJQueryElementID ).addClass( strClassName );
		
		jQuery( 'div#tt-' + strJQueryElementID + '-info' ).hide();

		// change the image within the container
		if ( strClassName == 'error' ) {
			jQuery( '#tt-' + strJQueryElementID ).attr( 'src', iconError );
		}
		
		if ( strClassName == 'valid' ) {
			// hide tooltip info
			jQuery( '#tt-' + strJQueryElementID ).attr( 'src', iconValid );
			// hide error message
			jQuery( 'div#tt-' + strJQueryElementID + '-message' ).hide();
		}
	}
	else
	{
		jQuery( 'div#tt-' + strJQueryElementID + '-info' ).hide();
		jQuery( 'div#tt-' + strJQueryElementID + '-message' ).hide();
		jQuery( '#' + strJQueryElementID ).attr( 'class', strClassName );
		jQuery( '#tt-' + strJQueryElementID ).attr( 'src', iconInfo );
	}
}


// This method will populate the error div with the returned message.
function populateErrorDiv( strDivID, strErrorMessage )
{
	// alert( strDivID );
	jQuery( strDivID ).html( '<span>error</span><br />' + strErrorMessage.replace( '&lt;', '<' ).replace( '&gt;', '>' ) );
	jQuery( strDivID ).show( 'clip', 500 );
}


// on window load. for some reason $(document).ready() doesn't work as expected here.
jQuery( window ).load( function(){ 
	if ( arrFormValidationEvents.length > 0 )
	{
		/**
		* Loop thru all form elements extracting
		* their default base classes.
		**/
		for ( var el=0; el < arrFormValidationEvents.length; el++ )
		{
			$( '#' + arrFormValidationEvents[el][1] ).attr( 'restoreClass', jQuery( '#' + arrFormValidationEvents[el][1] ).attr( 'class' ) );
		}
	}
});
