/*
 * GODEDIT FORM VALIDATION
 * Joseph Blythe <joseph@plastyk.com.au>
 * (c) 2007 Plastyk Studios
 *
 * Uses Prototype for browser detections
 */

var gErrors = 0; //number of errors is set to none to begin with
window.onload = attachFormHandlers; // init validation

function attachFormHandlers()
{
  // Make sure we're on a newer browser
	if (document.getElementsByTagName && document.getElementById('GOEDITFORM'))
    { 
		var objInput = document.getElementsByTagName('input'); // get all input tags
		var objSelect = document.getElementsByTagName('select'); // get all input tags
		var objTextArea = document.getElementsByTagName('textarea'); // get all input tags
		
		var form = document.getElementById('GOEDITFORM'); // get the form
		
			// INPUTS
			for (var iCounter=0; iCounter<objInput.length; iCounter++)
			{
				switch(objInput[iCounter].type) {
					case 'text':
					case 'radio':
					case 'file':
						// Add Reuired Messages
						createMessageSpan(objInput[iCounter]);
						// attach the onchange event to each input tag
						if(objInput[iCounter].getAttribute('required') == 'true' || objInput[iCounter].getAttribute('validate')) {
							objInput[iCounter].onchange = function(){return attach(this);}
						}
						break;
					case 'checkbox':
						createMessageSpan(objInput[iCounter]);
						// IE doesnt like onchange event for checkboxes so onclick is used instead
						if(objInput[iCounter].getAttribute('required') == 'true' || objInput[iCounter].getAttribute('validate')) {
							objInput[iCounter].onclick = function(){return attach(this);}
						}
						break
					case 'image':
						break;
				}
			}
			
			// TEXTAREAS
			for (var iCounter=0; iCounter<objTextArea.length; iCounter++)
			{
				createMessageSpan(objTextArea[iCounter]);
				if(objTextArea[iCounter].getAttribute('required') == 'true' || objTextArea[iCounter].getAttribute('validate')) {
					objTextArea[iCounter].onchange = function(){return attach(this);}
				}
			}
			
			// SELECTS
			for (var iCounter=0; iCounter<objSelect.length; iCounter++)
			{
				createMessageSpan(objSelect[iCounter]);
				// attach the onchange event to each input tag
				// TODO: Inputs may already have a onchange event especially selects
				if(objSelect[iCounter].getAttribute('required') == 'true' || objSelect[iCounter].getAttribute('validate')) {
					if(objSelect[iCounter].getAttribute('onchange') == "") {
						objSelect[iCounter].onchange = function(){return attach(this);}
					}
				}
			}
			
	form.onsubmit = function(){return validate();} // atttach the onsubmit to the form 
	}
}

// Used by attachFormHandlers() attches to the onChange event of each input
function attach(objInput)
{
	sVal = objInput.value; //sVal is the value of the input field being validated
    var sFeedback; //feedback message sent back to the user
    var sValidateMethod = objInput.getAttribute('validate');
	
	if (objInput.getAttribute('required') == "true") {
		
		// for checkboxes they suck yes
		if (objInput.type == 'checkbox' || objInput.type == 'radio') {
			
			if(objInput.checked != true) {
				if(!Prototype.Browser.IE) {
					sVal = false;
				} else {
					sVal = '';
				}
			}
		}
		
		sFeedback = validateRequired(sVal);//validateRequired() checks if it is invalid and sends back feedback
	} else {
		sFeedback = "";
	}
	
	// if the value is blank we don't need to validate.  If it is required, the word
	// "Required"  will already be the feedback message from the validateRequired() function		
	if (sVal != "")  { 
		// check the different validation cases (ie: email, phone, etc.)
		switch (sValidateMethod) {
			case "date":
				sFeedback = validateDate(sVal);
				break;
			case "email":
				sFeedback = validateEmail(sVal);
				break;
			case "phone":
				sFeedback = validatePhone(sVal);
				break;
			case "zip":
				sFeedback = validateZip(sVal);
				break;
			case "password":
				sFeedback = validatePassword(sVal);
				break;
			case "name":
				sFeedback = validateName(sVal);
				break;
			case "numeric":
				sFeedback = validateNumeric(sVal);
				break;
			case "limit":
				sFeedback = validateLimit(sVal);
				break;
			case "min":
				sFeedback = validateMin(sVal);
				break;
			case "custom":
				alert('You can\'t call custom rules this way you must use custom=functionName syntax');
				break;
			default:
				// Handles mutiple rules and rules with key value pairs
				var methods = new Array();
				// Field has validation
				if(sValidateMethod != null) {
					// Is a list of validation methods
					if(sValidateMethod.match(new RegExp(',', "i"))) {
						//(?:[^",]|(?:"(?:\\{2}|\\"|[^"])*?"))*)
						methods = sValidateMethod.split(',');
						for(i=0; i<methods.length; i++) {
							// Has a method with a parameter
							if(methods[i].match(new RegExp("=", "i"))) {
								// build function name is always validate<Rulename>()
								// rules with key value pairs take second parameter
								var keyval = methods[i].split('=');
								// Support for userdefined validation rules
								// TODO: implement allowing of function parameters
								// ATM: only the field value is passed to function
								if(keyval[0] == 'custom') {
									var vFunction = keyval[1]+'(sVal)';
								} else {
									var vFunction = 'validate'+keyval[0].charAt(0).toUpperCase()+keyval[0].substr(1, keyval[0].length)+'('+'sVal,'+keyval[1]+')';
								}
							} else {
								var vFunction = 'validate'+methods[i].charAt(0).toUpperCase()+methods[i].substr(1, methods[i].length)+"(sVal)";
							}
							// Chain messages together
							if (sFeedback != '') {
								sFeedback = sFeedback +', '+ eval(vFunction);
								// Remove trailing comma and space if any
								if(sFeedback.charAt(sFeedback.length-2) == ',') {
									sFeedback = sFeedback.substr(0, sFeedback.length-2);
								}
							} else {
								// Only one message
								sFeedback = eval(vFunction);
							}
						}
					}
					// Match single custom rules
					// BROKEN FIXME
					if(sValidateMethod.match(new RegExp("=", "i")) && !sValidateMethod.match(new RegExp(",", "i"))) {
						var keyval = sValidateMethod.split('=');
						// Support for userdefined validation rules
						// TODO: implement allowing of function parameters
						// ATM: only the field value is passed to function
						if(keyval[0] == 'custom') {
							var vFunction = keyval[1]+'(sVal)';
						} else {
							var vFunction = 'validate'+keyval[0].charAt(0).toUpperCase()+keyval[0].substr(1, keyval[0].length)+'('+'sVal,'+keyval[1]+')';
						}
						sFeedback = eval(vFunction);
					} 
				}
		} // endif sVal
	} // end switch
	
	// Set border style on error and recovery
/*	if(objInput.type != 'checkbox' && objInput.type != 'radio' && objInput.type != 'file') {
	
		if(sFeedback != '') {
			objInput.style.border = '1px dashed #cc0000';
			if(objInput.type != 'select-one' && objInput.type != 'select-multiple') {
				// IE wont set events via DOM either
				if(!Prototype.Browser.IE) {
					objInput.setAttribute('onfocus',"this.className='errorrollover'");
				} else {
					objInput.onfocus = function(){return objInput.className='errorrollover';}
				}
			}
		} else {
			objInput.style.border = '1px solid #DDDDDD';
			if(objInput.type != 'select-one'&& objInput.type != 'select-multiple') {
				// IE wont set events via DOM either
				if(!Prototype.Browser.IE) {
					objInput.setAttribute('onfocus',"this.className='formrollover'");
				} else {
					objInput.onfocus = function(){return objInput.className='formrollover';}
				}
			}
		}
	}
*/	
	// after validation is complete return the feedback
	// see if message span already exists if so remove the message
	var sID = objInput.getAttribute('id').toLowerCase()+'_msg';
	
	if(!document.getElementById(sID)) {
		var eSpan = document.createElement('span');
		eSpan.setAttribute('id', sID);
		
		// IE6 has weird setAttribute uses different property names
		if(!Prototype.Browser.IE) {
			eSpan.setAttribute('class', 'rules');
		} else {
			eSpan.setAttribute('className', 'rules');
		}
		
		objInput.parentNode.appendChild(eSpan);
		var eMessage = document.createTextNode(sFeedback);
		eSpan.parentNode.appendChild(eMessage);
		
		// FIXME: strange behavior when using single rules with key value pairs 
		// seems to only add start of the span tag and then appends text so firstChild 
		// fails when updating or removing in this case we remove the node as it 
		// was added incorrectly and we will use innerHTML to add the text 
		// instead of createTextNode
		if(document.getElementById(sID).hasChildNodes() == false) {
			document.getElementById(sID).parentNode.removeChild(eMessage);
			document.getElementById(sID).parentNode.removeChild(eSpan);
			var eSpan = document.createElement('span');
			eSpan.setAttribute('id', sID);
			// IE6 has weird setAttribute uses different property names
			if(!Prototype.Browser.IE) {
				eSpan.setAttribute('class', 'rules');
			} else {
				eSpan.setAttribute('className', 'rules');
			}
			objInput.parentNode.appendChild(eSpan);
			document.getElementById(sID).innerHTML = sFeedback;
		}
		
	} else {
		//var eMessage = document.createTextNode(sFeedback);
		//document.getElementById(sID).removeChild(document.getElementById(sID).firstChild);
		//document.getElementById(sID).appendChild(eMessage);
		if(document.getElementById(sID).hasChildNodes()) {
			document.getElementById(sID).firstChild.data = sFeedback;
		} else {
			var eMessage = document.createTextNode(sFeedback);
			//document.getElementById(sID).removeChild(document.getElementById(sID).firstChild);
			document.getElementById(sID).appendChild(eMessage);
		}
	}
}

// Called on submit validates the form
function validate()
{
	if(window.myOnSubmitEventHandler) {
		myOnSubmitEventHandler();
	}
	if (document.getElementById('STARTDATE_Day') && document.getElementById('ENDDATE_Day')) {
		validateEvent();
	}
	var spans; //variable which will become an array holding all elements with the span tagname
	
	// store all <spans> elements in the tables array
	spans = document.getElementsByTagName('span')
	
	//loop through all the <spans> elements 
	for (i=0; i<spans.length; i++) {
	// if the class name of that span element is rules check to see if there are error warnings
		if (spans[i].className == "rules") {
			//if there is a thank you or its blank then it passes
			if (spans[i].innerHTML == '' || spans[i].innerHTML == '&nbsp;' ) {
				//spans[i].style.color = '#000000';//the color is changed to blank or stays black
			} else {
				gErrors = gErrors + 1; //the error count increases by 1
				// Add red dashed borders to errors on submit
				/*var sName = spans[i].getAttribute('id').split('_');
				var objInput = document.getElementById(sName[0]);
				if(objInput) {
					if(objInput.type != 'checkbox' && objInput.type != 'select-single' && objInput.type != 'select-multiple' && objInput.type != 'radio' && objInput.type != 'file' ) {
						objInput.style.border = '1px dashed #cc0000';
						if(!Prototype.Browser.IE) {
							objInput.setAttribute('onfocus',"this.className='errorrollover'");
						} else {
							objInput.onfocus = function(){return objInput.className='errorrollover';}
						}
					}
				}*/
			}
		}
	}
	
	if (gErrors > 0) {
		//if there are any errors give a message
		alert ("Please make sure all fields are properly completed.  Errors are marked in red!");
		gErrors = 0;// reset errors to 0
		return false;
	} else {
		//alert("The Form Is Valid!");
		return true;//set this to true in practice to allow the form to submit
	}
}

function createMessageSpan(ele) 
{
	//var class = (class == null) ? "rules" : class;
	if(ele.getAttribute('required') == 'true' && ele.value == "") {
		var eSpan = document.createElement('span');
		var sID = ele.getAttribute('id').toLowerCase()+'_msg';
		
		if(!document.getElementById(sID)) {
			eSpan.setAttribute('id', sID);
			// IE6 has weird setAttribute uses different property names
			if(!Prototype.Browser.IE) {
				eSpan.setAttribute('class', 'rules');
			} else {
				eSpan.setAttribute('className', 'rules');
			}
			//eSpan.setAttribute('style', 'padding-left:5px;color:#CC0000;');
			ele.parentNode.appendChild(eSpan);
			var eMessage = document.createTextNode(' * ');
			eSpan.appendChild(eMessage);
		}
	}
}

function setMessage(ele, message) 
{
	//var class = (class == null) ? "rules" : class;
	var eSpan = document.createElement('span');
	var sID = ele.getAttribute('id').toLowerCase()+'_msg';
	
	if(!document.getElementById(sID)) {
		eSpan.setAttribute('id', sID);
		// IE6 has weird setAttribute uses different property names
		if(!Prototype.Browser.IE) {
			eSpan.setAttribute('class', 'rules');
		} else {
			eSpan.setAttribute('className', 'rules');
		}
		//eSpan.setAttribute('style', 'padding-left:5px;color:#CC0000;');
		ele.parentNode.appendChild(eSpan);
		var eMessage = document.createTextNode(message);
		eSpan.appendChild(eMessage);
	}
	return sID;
}


/*
 * VALIDATION RULES
 */
 
// Validates required fields
function validateRequired(sVal)
{
		// if it is required and blank or false then it is an error 
		// and continues to be required
   		if (sVal != "" || sVal == true) { 
			return ("");
		} else {
			gContinue = false;
			return(" * ");
		}
		
}

function validateDate(sVal)
{
	// our date regular expression (http://www.regexlib.com)
 var regex=/(((0[13578]|10|12)([-.\/])(0[1-9]|[12][0-9]|3[01])([-.\/])(\d{4}))|((0[469]|11)([-.\/])([0][1-9]|[12][0-9]|30)([-.\/])(\d{4}))|((2)([-.\/])(0[1-9]|1[0-9]|2[0-8])([-.\/])(\d{4}))|((2)(\.|-|\/)(29)([-.\/])([02468][048]00))|((2)([-.\/])(29)([-.\/])([13579][26]00))|((2)([-.\/])(29)([-.\/])([0-9][0-9][0][48]))|((2)([-.\/])(29)([-.\/])([0-9][0-9][2468][048]))|((2)([-.\/])(29)([-.\/])([0-9][0-9][13579][26])))/;
 
	// do the comparison, if we have a match write thank you or else the date is invalid
	if (regex.test(sVal))
	{
      return "";
	}
	else 
	{
      return "Invalid Date";
	}

}

function validateEmail(sVal)
{
	
// our email regular expression (http://www.regexlib.com)
 var regex=/^[a-zA-Z0-9._-]+@([a-zA-Z0-9.-]+\.)+[a-zA-Z0-9.-]{2,4}$/;
 
	// do the comparison, if we have a match write thank you or else the email is invalid
	if (regex.test(sVal))
	{
      return "";
	}
	else
	{
      return "Invalid Email Address";
	}
}

function validatePhone(sVal)
{
	
// our phone regular expression
// This expression is a very simplex expression that allows null values or 3 digits, dash, 
//3 digits, dash, 4 digits. It validates a basic US phone number. Written by Jason N. Gaylord.(http://www.regexlib.com)
// Matches:  	 [555-555-1212], [123-456-7890]
 var regex=/^(\d{3}-\d{3}-\d{4})*$/;
 
	// do the comparison, if we have a match write thank you or else the email is invalid
	if (regex.test(sVal))
	{
      return "";
	}
	else
	{
      return "Invalid Phone";
	}
}

function validateZip(sVal)
{
	
// our email regular expression
//Javascript matches US zipcodes not allowing all zeros in first 5 or +4 (http://www.regexlib.com)
// Matches:  	 [12345], [12345-6789], [123456789]
 var regex=/(^(?!0{5})(\d{5})(?!-?0{4})(-?\d{4})?$)/;
 
	// do the comparison, if we have a match write thank you or else the email is invalid
	if (regex.test(sVal))
	{
      return "";
	}
	else
	{
      return "Invalid ZipCode";
	}
}

function validatePassword(sVal)
{ 
//Description: The password's first character must be a letter, it must contain at least 4 characters
//and no more than 15 characters and no characters other than letters, numbers and the underscore may be used
//Matches: 	[abcd], [aBc45DSD_sdf], [password] (http://www.regexlib.com)
 var regex=/^[a-zA-Z]\w{3,14}$/;
 
	// do the comparison, if we have a match write thank you or else the email is invalid
	if (regex.test(sVal))
	{
      return "";
	}
	else
	{
      return "Invalid Password";
	}
}

function validateName(sVal)
{ 
//This is the simplest RegEx for validating someone's name. The name can contain only alphabets(in either case) & 
//should be of minimum length 4 & maximum length 32. Only white spaces are allowed apart from alphabets.
//Matches: 	[some body], [hey there], [hello] (http://www.regexlib.com)
 var regex=/^([a-zA-z\s]{4,32})$/;
 
	// do the comparison, if we have a match write thank you or else the email is invalid
	if (regex.test(sVal))
	{
      return "";
	}
	else
	{
      return "Invalid Name";
	}
}


function validateNumeric(sVal)
{ 
//Input for Numeric values. Handles negatives, and comma formatted values. Also handles a single decimal point
//Matches: 	[5,000], [-5,000], [100.044] (http://www.regexlib.com)
 var regex=/^(\d|-)?(\d|,)*\.?\d*$/;
 
	// do the comparison, if we have a match write thank you or else the email is invalid
	if (regex.test(sVal))
	{
      return "";
	}
	else
	{
      return "Invalid Number";
	}
}

function validateLimit(sVal, limit) 
{
	var sText = sVal;
	if(sText.length > limit) {
		return "Limit of "+limit+" characters reached";
	} else {
		return "";	
	}
}

function validateMin(sVal, limit) 
{
	var sText = sVal;
	if(sText.length < limit) {
		return "Minimum of "+limit+" characters required";
	} else {
		return "";	
	}
}

function validateEvent() {
	var STARTDATE = getStartDate();
	var ENDDATE = getEndDate();
	if(!$('startdatemsg')) {
		var sdMsg = document.createElement('span');
		sdMsg.id = 'startdatemsg';
		sdMsg.className = 'rules';
		$('tdstartdate').appendChild(sdMsg);
	}
	if(!$('enddatemsg')) {
		var edMsg = document.createElement('span');
		edMsg.id = 'enddatemsg';
		edMsg.className = 'rules';
		$('tdenddate').appendChild(edMsg);
	}
	// Start Date
	if(!IsValidDate($('STARTDATE_Day').value,$('STARTDATE_Month').value,$('STARTDATE_Year').value)) {
		$('startdatemsg').innerHTML = '';
		$('startdatemsg').innerHTML = 'Start date is not valid.';
		return false;
	}
	
	// End Date
	if(!IsValidDate($('ENDDATE_Day').value,$('ENDDATE_Month').value,$('ENDDATE_Year').value)) {
		$('enddatemsg').innerHTML = '';
		$('enddatemsg').innerHTML = 'End date is not valid.';
		return false;
	}
	
	if(ENDDATE < STARTDATE || STARTDATE > ENDDATE) {
		//alert('End Date ('+ENDDATE+') must be after Start Date ('+STARTDATE+')');
		gErrors = gErrors + 1;
		$('startdatemsg').innerHTML = 'Start Date can not be after End Date.';
		$('enddatemsg').innerHTML = 'End Date can not be before Start Date.';
		return false;	
	}
	
	$('startdatemsg').innerHTML = '';
	$('enddatemsg').innerHTML = '';
}

function getStartDate() {
	
	var eStartDay = document.getElementById('STARTDATE_Day');
	var STARTDATE_Day = eStartDay.options[eStartDay.selectedIndex].value;
	var eStartMonth = document.getElementById('STARTDATE_Month');
	var STARTDATE_Month = eStartMonth.options[eStartMonth.selectedIndex].value;
	var eStartYear = document.getElementById('STARTDATE_Year');
	var STARTDATE_Year = eStartYear.options[eStartYear.selectedIndex].value;
	
	var eStartHours = document.getElementById('STARTDATE_Hours');
	var STARTDATE_Hours = eStartHours.options[eStartHours.selectedIndex].value;
	var eStartMinutes = document.getElementById('STARTDATE_Minutes');
	var STARTDATE_Minutes = eStartMinutes.options[eStartMinutes.selectedIndex].value;
	//var eStartSeconds = document.getElementById('STARTDATE_Seconds');
	//var STARTDATE_Seconds = eStartSeconds.options[eStartSeconds.selectedIndex].value;
	var eStartMeridiem = document.getElementById('STARTDATE_Meridiem');
	var STARTDATE_Meridiem = eStartMeridiem.options[eStartMeridiem.selectedIndex].value;
	
	//return new Date(yy,mm,dd,hh,mm,ss);
	var STARTDATE = STARTDATE_Year+'-'+STARTDATE_Month+'-'+STARTDATE_Day+' '+STARTDATE_Hours+':'+STARTDATE_Minutes+':00'+' '+STARTDATE_Meridiem;

	return STARTDATE;
}

function getEndDate() {
	
	var eEndDay = document.getElementById('ENDDATE_Day');
	var ENDDATE_Day = eEndDay.options[eEndDay.selectedIndex].value;
	var eEndMonth = document.getElementById('ENDDATE_Month');
	var ENDDATE_Month = eEndMonth.options[eEndMonth.selectedIndex].value;
	var eEndYear = document.getElementById('ENDDATE_Year');
	var ENDDATE_Year = eEndYear.options[eEndYear.selectedIndex].value;
	
	var eEndHours = document.getElementById('STARTDATE_Hours');
	var ENDDATE_Hours = eEndHours.options[eEndHours.selectedIndex].value;
	var eEndMinutes = document.getElementById('ENDDATE_Minutes');
	var ENDDATE_Minutes = eEndMinutes.options[eEndMinutes.selectedIndex].value;
	//var eStartSeconds = document.getElementById('STARTDATE_Seconds');
	//var STARTDATE_Seconds = eStartSeconds.options[eStartSeconds.selectedIndex].value;
	var eEndMeridiem = document.getElementById('STARTDATE_Meridiem');
	var ENDDATE_Meridiem = eEndMeridiem.options[eEndMeridiem.selectedIndex].value;
	
	
	var ENDDATE = ENDDATE_Year+'-'+ENDDATE_Month+'-'+ENDDATE_Day+' '+ENDDATE_Hours+':'+ENDDATE_Minutes+':00'+' '+ENDDATE_Meridiem;

	return ENDDATE;
}

function IsValidDate(Day,Mn,Yr)
{
    var DateVal = Mn + "/" + Day + "/" + Yr;
    var dt = new Date(DateVal);

    if(dt.getDate()!=Day){
        alert('Invalid Date');
        return(false);
        }
    else if(dt.getMonth()!=Mn-1){
    //this is for the purpose JavaScript starts the month from 0
        alert('Invalid Date');
        return(false);
        }
    else if(dt.getFullYear()!=Yr){
        alert('Invalid Date');
        return(false);
        }
        
    return(true);
}