/**
 * xforms.js
 *
 * Expanded form functionality using the Scriptaculous Prototype lib
 */


/**
 * Trim a string
 *
 * @param		string		strString	String to trim
 * @return		null
 */
function trim(strString) {
    return strString.replace(/^\s*|\s*$/g,"");
}

/**
 * Check if a string is a valid email address
 *
 * @param		string		strEmail	Email address to check
 * @return		null
 */
function isValidEmail(strEmail) {
   return (strEmail.indexOf(".")) && (strEmail.indexOf("@") > 0);
}

/**
 * Highlight a form field
 *
 * @param		event		e			Form event, use the keydown event for best results
 * @param		string		strElement	Form field ID name
 * @return		null
 */
function highlightFormField(e, strElement) {
	if (e.type == 'focus') {
		Element.removeClassName(strElement, 'textinput');
		Element.addClassName(strElement, 'textinputHighlight');
		//$(strField).className = 'textinputHighlight';
	}
	if (e.type == 'blur') {
		Element.removeClassName(strElement, 'textinputHighlight');
		Element.addClassName(strElement, 'textinput');		
		//$(strField).className = 'textinput';		
	}	
}


/**
 * Ensure that a text field only has numberic values
 *
 * @param		event		e					Form event, use the keydown event for best results
 * @param		object		objText				Form field object referance
 * @param		integer		[iLimit]			Optional number length limit
 * @param		string		[sNext]				Optional next field name to jump to when the limit is hit
 * @param		boolean		[bStopBeforeNext]	Optional, if true the event will be stoped before we jump to the next field if sNext is set and iLimit is true
 * @return		null
 */
function checkNumeric(e, objText, iLimit, strNext, bStopBeforeNext) {

	// Get the key code, first way is stupid IE, next is the test of the world
	if (window.event) {
		keyCode = e.keyCode;
	} else {
		keyCode = e.which;
	}
	
	// Allow navigation and tab keys
	if (keyCode == 8 || keyCode == 9 || keyCode == 13 || keyCode == 35 || keyCode == 36 || keyCode == 37 || keyCode == 38 || keyCode == 39 || keyCode == 40 ||keyCode == 46) { 
		return; 
	}

	// Stop the event if a number was not selected
	if( ! ((keyCode >= 48 && keyCode <=57) || (keyCode >= 96 && keyCode <=105)) ) {
		Event.stop(e);
		return;
	}

	// Check for already selected text and clear it
	// Internet exploder
	var appVer = navigator.appVersion.toLowerCase();
	if (appVer.indexOf('msie')!=-1) {
		var sel = Try.these( function() {return document.selection.createRange() } );
		if (sel) { 
			// We'll use this as a 'dummy'
			var stored_range = sel.duplicate();
			// Select all text
			stored_range.expand('textedit');
			// Now move 'dummy' end point to end point of original range
			stored_range.setEndPoint( 'EndToEnd', sel );
			// Now we can calculate start and end points
			objText.selectionStart = stored_range.text.length - sel.text.length;
			objText.selectionEnd = objText.selectionStart + sel.text.length;
			sel.text  = "";
			sel.select();
		}
	} else {
		// Firefox and Mozilla 
		if (Try.these( function() {return objText.selectionStart;} ) >= 0 ) {
				var iLength = objText.value.length;
				var sStart = objText.value.substr(0, objText.selectionStart);
				var sEnd = objText.value.substr( objText.selectionEnd, objText.value.length);
				iSelectedLen = objText.selectionEnd - objText.selectionStart;
				objText.value = sStart+sEnd;
		}	
	}
	
	// Stop the event if we have a limit and it has been reached
	if (iLimit != null) {
		if ((objText.value.length) >= iLimit) {
			
			// Jump to the next field if the param is passed
			// We will only stop the event if the option bStopBeforeNext is true, otherwise the field we jump to will get the value that was keyed
			if (strNext != null) {
				if (bStopBeforeNext != null && bStopBeforeNext) {
					Event.stop(e);		
				}
				$(strNext).focus();
			} else {
				// Else just stop the event because the limit is reached
				Event.stop(e);	
			}
			return;
		}
	}
	

	if (iLimit != null && strNext != null) {
		if ((objText.value.length + 1) == iLimit) {
			setTimeout("$('"+strNext+"').focus()",150);
		}
	}
	
} 


/**
 * As the $F function will return an objects value the $ST function will return the select objects text value
 *
 * @param		string		strSelect		Select box name
 * @return		null
 */
Form.Element.getSelectText = function (strSelect) {
	var objSelect = $(strSelect);
	if (objSelect.type == 'select-one') {
		for (var i=0;i<objSelect.options.length;i++) {
			if (objSelect.options[i].selected) { return objSelect.options[i].text; }
		}
	}
	return '';
}
var $ST = Form.Element.getSelectText;


/**
 * Search a select objects option list for an option whos text equals the given value
 *
 * @param		string		strSelect		Select box name
 * @param		string		strText			Text to find
 * @return		mixed						Index of the given text or false if not found
 */
function findSelectTextIndex(strSelect, strText) {
	if (! $(strSelect) ) { return false; } 
	strText = strText.toUpperCase()
	for (var i=0;i<$(strSelect).options.length;i++) {
		if ($(strSelect).options[i].text.toUpperCase() == strText) { return i; }
	}
	return false;
}

/**
 * Search a select objects option list for an option whos value equals the given value
 *
 * @param		string		strSelect		Select box name
 * @param		string		strValue		Value to find
 * @return		mixed						Index of the given value or false if not found
 */
function findSelectValueIndex(strSelect, strValue) {
	strValue += ''; // Force into a string
	if (! $(strSelect) ) { return false; } 
	strValue = strValue.toUpperCase()
	for (var i=0;i<$(strSelect).options.length;i++) {
		if ($(strSelect).options[i].text.toUpperCase() == strValue) { return i; }
	}
	return false;
}


/**
 * Highlight the parent row of a given error message <div> tag
 *
 * @param		string		strID		ID of the element of whos parent to highlight
 * @param		integer		iLimit		Maximum number of levels to traverse up
 * @return		boolean					True on success, false on error
 */
function highLightRow(strID, iLimit) {
	if ( ! $(strID) ) { return false; }
	var objDiv = $(strID);
	var objParent = objDiv.parentNode;
	var iControll = 0;
	if (iLimit == null) {
		iLimit = 5;
	}
	// Loop up until we find the parent <tr> or iControll goes over iLimit
	while( objParent.tagName != 'TR' || iControll >= iLimit) {
		objParent = objParent.parentNode;
		iControll++;
	}

	// Error highlight all the <td>s in this row
	for(var i=0;i<objParent.childNodes.length;++i) {
	    if (objParent.childNodes[i].tagName == 'TD' && 
			! Element.hasClassName(objParent.childNodes[i], 'error') ) {
			Element.addClassName(objParent.childNodes[i], 'error');			
		}
	}
}

/**
 * UnHighlight the parent row of a given error message <div> tag
 *
 * @param		string		strID		ID of the element of whos parent to be unhighlighted
 * @param		integer		iLimit		Maximum number of levels to traverse up
 * @return		boolean					True on success, false on error
 */
function unhighLightRow(strID, iLimit) {
	if ( ! $(strID) ) { return false; }
	var objDiv = $(strID);
	var objParent = objDiv.parentNode;
	var iControll = 0;
	if (iLimit == null) {
		iLimit = 5;
	}
	// Loop up until we find the parent <tr> or iControll goes over iLimit
	while( objParent.tagName != 'TR' || iControll >= iLimit) {
		objParent = objParent.parentNode;
		iControll++;
	}

	// Error highlight all the <td>s in this row
	for(var i=0;i<objParent.childNodes.length;++i) {
	    if (objParent.childNodes[i].tagName == 'TD' && 
			Element.hasClassName(objParent.childNodes[i], 'error') ) {
			Element.removeClassName(objParent.childNodes[i], 'error');			
		}
	}
}


/**
 * Custom check boxes using images with full support for the native check boxs, labels and onclick events
 */
var imgFalse = '/sites/main/img/template/checkbox_off_y.gif';
var imgTrue = '/sites/main/img/template/checkbox_on_y.gif';
var i_isOpera=navigator.appName.indexOf("Opera")!=-1;
var i_isIE=navigator.appName.indexOf("Internet Explorer")!=-1;
/** 
 * Replace all check boxes on the page with image based check boxes
 *
 * @return		null
 */
function replaceChecks() {
    // Get all the input fields on the page
    var chkBoxInputs = document.getElementsByTagName('input');
	// Get all the label fields on the page
	var labelTags = document.getElementsByTagName('label');
	var bPreloaded = false;
	// cycle through the labels
	for(var i=0; i < labelTags.length; i++) {
		var forID = labelTags[i].getAttribute('htmlfor') || labelTags[i].getAttribute('for');
		if ($(forID) && $(forID).getAttribute('type') == 'checkbox') {
			labelTags[i].onclick = new Function('checkChange(\''+forID+'\', true);');
		}
	}
    // cycle through the input fields
    for(var i=0; i < chkBoxInputs.length; i++) {
        //check if the input is a checkbox and its not already hidden
        if(chkBoxInputs[i].getAttribute('type') == 'checkbox' && chkBoxInputs[i].style.display != 'none') {
            //hide the checkbox
            chkBoxInputs[i].style.display='none';
            // Preload images if not done
			if ( ! bPreloaded) {
				var preImages = new Array();
				preImages[0] = new Image();
				preImages[0].src = imgFalse;
				preImages[1] = new Image();
				preImages[1].src = imgTrue;
				bPreloaded = true;	
			}
            //create a new image
            var img = document.createElement('img');
            //check if the checkbox is checked
            if(chkBoxInputs[i].checked) {
                img.src = imgTrue;
            } else {
                img.src = imgFalse;
            }
            //set image ID and onclick action
            img.id = 'checkImage_'+chkBoxInputs[i].id;
            //set image
            img.onclick = new Function('checkChange(\''+chkBoxInputs[i].id+'\', false);');
            //place image in front of the checkbox
            chkBoxInputs[i].parentNode.insertBefore(img, chkBoxInputs[i]);
        }
    }
	return;
}


/**
 * Change the checkbox status and the replacement image
 *
 * @param		id			string		ID of the check box being changed
 * @param		bIsLabel	boolean		True if click is triggered by a label
 * @return		null
 */
function checkChange(id, bIsLabel) {
	var objCheckBox = $(id);
    if(objCheckBox.checked) {
		if ( ! bIsLabel || i_isOpera || i_isIE) {
			objCheckBox.click();
			objCheckBox.checked = ''; 
		}
        $('checkImage_'+id).src=imgFalse;
    } else {
		if ( ! bIsLabel || i_isOpera || i_isIE) {
			objCheckBox.click();
			objCheckBox.checked = 'checked';
		}
        $('checkImage_'+id).src=imgTrue;
    }
	return;
}

/**
 * Perform a manual uncheck of a box
 *
 * @param		id			string		ID of the check box being changed
 * @return		null
 */
function doUncheck(id) {
	if ( $(id) ) {
		$(id).checked = false;
		$('checkImage_'+id).src=imgFalse;
	}
	return;
}

/**
 * Perform a manual check of a box
 *
 * @param		id			string		ID of the check box being changed
 * @return		null
 */
function doCheck(id) {
	if ( $(id) ) {
		$(id).checked = true;
		$('checkImage_'+id).src=imgTrue;
	}
	return;
}
