// standard on submit function used 

errors = new Array(1);

function standardOnSubmitEvent(formname) 
{
	Event.observe(formname, 'submit', function(e) 
	{
		if (!requiredCheckOk(formname,"bool")) 
		{
			display_notification(requiredReason(formname));
			e.stop();
		} else {
    		show_form_spinner(formname);
		}
	});
}

function callbackOnSubmitEvent(formname,callback) 
{
	Event.observe(formname, 'submit', function(e) 
	{
		errors = !(requiredCheckOk(formname,"bool"));
		if (errors) 
		{
			display_notification(requiredReason(formname));
			e.stop();
		} else {
    		show_form_spinner(formname);
		}
		var returnFunction = eval(callback);
		returnFunction(e);
	});
	
}


function show_form_spinner(formname) {
	$$('#'+formname+' .input-submit').each( function(s) {
		s.hide();
	});
	$$('#'+formname+' .spinner').each( function(s) {
		s.show();
	});
}
function hide_form_spinner(formname) {
	$$('#'+formname+' .input-submit').each( function(s) {
		s.show();
	});
	$$('#'+formname+' .spinner').each( function(s) {
		s.hide();
	});
}

// submit the form using ajax request
function ajaxOnSubmitEvent(formname, action, submitFunc, successFunc, failureFunc) {
	
	Event.observe(formname, 'submit', function(e) {
		// stop the normal submit
		e.stop();
		
		// is everything ok with the fields
		if (requiredCheckOk(formname)) {

      // is this a form only for use by logged in members?
      if ($(formname).hasClassName('login-required') && !logged_in()) {
        // throw-up the login form
        request_login( function(){ finishSubmit(formname, action, submitFunc, successFunc, failureFunc, e); } );
      } else {
        // we can drop straight into the submit now
        finishSubmit(formname, action, submitFunc, successFunc, failureFunc, e);
      }
		}
	});
};

function finishSubmit(formname, action, submitFunc, successFunc, failureFunc, e) {
  var params = Form.serialize(formname);
  // let the submit function look after a few things
  var result = submitFunc(formname, e);
	
  // ok to continue
  if (result == undefined || result) {
    // do the async submit
    var request = new Ajax.Request(action,
      {
      asynchronous:true, 
      parameters:params, 
      onSuccess:function(t) { successFunc(t, $(formname)); },
      onFailure:function(t) { failureFunc(t, $(formname)); }
      });
  }
}

function std_onSubmit() {
  // handle the progress bar
  $$('##'+formname+' .input-submit').each( function(s) {
  	s.hide();
  });
  $$('##'+formname+' .spinner').each( function(s) {
  	s.show();
  });
  // disable the form
  Form.disable(formname);
}


/*
  validation helpers
*/

// attached to all forms by default
function requiredCheckOk() {
	
	var arguments = requiredCheckOk.arguments;
	var rt = "bool";
	var formname = arguments[0];
	if (arguments[1] == "array") 
	{
		var rt = "array";
	} else {	
		var rt = "bool";
	}

	// assume it's all good to start with
	var ok = true;
	
	
	var errors = {main:false, email:false, postcode:false, telephone:false, url:false};

	// process the radio buttons first (if required one of them of each name needs to be checked)
	var radios = new Hash();  
	var checkboxes = new Hash();
	
	$$('#'+formname+' .required *').each( function(r) 
	{
		
		if (r.value != null && r.type && r.type == 'radio' && !r.disabled) 
		{
    		var last = radios.get(r.name);
    		if (!last)
        		radios.set(r.name, false);
      
      		if (r.checked)
        		radios.set(r.name, true);
	  }		
		
		if (r.value != null && r.type && r.type == 'checkbox' && !r.disabled){
			var last = checkboxes.get(r.name);
   		if (!last){
				checkboxes.set(r.name, false);
			}
			if (r.checked){
				checkboxes.set(r.name, true);
			}
		}
	});
	/*
 	$$('#'+formname+' .validate_local_checkbox input').each( function(r){
		var last = checkboxes.get(r.name);
   	if (!last){
			checkboxes.set(r.name, false);
		}
		if (r.checked){
			checkboxes.set(r.name, true);
		}
	});	
	*/
	// are all required fields complete?
	$$('#'+formname+' .required *').each( function(r) 
	{
		if (r.value != null && r.type){
			if (r.type == 'radio' && !radios.get(r.name) && !r.disabled){
				// already know this radio button has failed
   				r.up('.field').addClassName('error');
        		ok = false;
     	}else if (r.type == 'checkbox' && !checkboxes.get(r.name) && !r.disabled){
				// already know this radio button has failed
   				r.up('.field').addClassName('error');
        		ok = false;
       
	   	}else if (r.id.indexOf('__Config') == -1 && !r.disabled){
    			if ('' == r.value.strip()){
  		    		r.up('.field').addClassName('error');
    				ok = false;
    			} else {
   					r.up('.field').removeClassName('error');
    			}
	    }
	  }
	});
	
	errors["main"] = false;
	if(ok == false && rt == "bool")
	{
		return ok;
	} else if(ok == false) 
	{
		
		errors["main"] = true;
		return errors;
	}
	
		$$('#'+formname+' .validate_checkbox input').each( function(r) 
	{
		if(r.up("div",".required") == undefined)
		{
			if (r.value != "")
			{
				if(!r.checked)
				{	
					r.up('.field').addClassName('error');ok = false;
					errors["main"] = true;
				}
			}
		} else {
			if(!r.checked)
			{
				r.up('.field').addClassName('error'); ok = false;
				errors["main"] = true;
			}
		
		}
	});
	
	$$('#'+formname+' .validate_email input').each( function(r) 
	{
		if(r.up("div",".required") == undefined)
		{
			if (r.value != "")
			{
				if(!validate_email(r.value,false))
				{	
					r.up('.field').addClassName('error');ok = false;
					errors["email"] = true;
				}
			}
		} else {
			if(!validate_email(r.value,false))
			{
				r.up('.field').addClassName('error'); ok = false;
				errors["email"] = true;
			}
		
		}
	});
	
	$$('#'+formname+' .validate_harsh input').each( function(r) 
	{
		if(r.up("div",".required") == undefined)
		{
			if (r.value != "")
			{
				if(!validate_email_mx(r.value))
				{	
					r.up('.field').addClassName('error');ok = false;
					errors["email"] = true;
				}
			}
		} else {
			if(!validate_email_mx(r.value))
			{
				r.up('.field').addClassName('error'); ok = false;
				errors["email"] = true;
			}
		
		}
	});
	
	$$('#'+formname+' .validate_telephone input').each( function(r) 
	{
		
		if(r.up("div",".required") == undefined)
		{
			if (r.value != "")
			{
				if(!validate_telephone(r.value))
				{
					r.up('.field').addClassName('error'); ok = false;
					errors["telephone"] = true;
				}
			}
		} else {
			if(validate_telephone(r.value))
			{
				r.up('.field').addClassName('error'); ok = false;
				errors["telephone"] = true;
			}
		}
	});
	
	$$('#'+formname+' .validate_mobile input').each( function(r) 
	{
		
		if(r.up("div",".required") == undefined)
		{
			if (r.value != "")
			{
				if(!validate_telephone(r.value))
				{
					r.up('.field').addClassName('error'); ok = false;
					errors["telephone"] = true;
				}
			}
		} else {
			if(validate_telephone(r.value))
			{
				r.up('.field').addClassName('error'); ok = false;
				errors["telephone"] = true;
			}
		}
	});
	 
	  
	
	
	
	$$('#'+formname+' .validate_postcode input').each( function(r) 
	{
		if(r.up("div",".required") == undefined)
		{
			if (r.value != "")
			{
				if(!validate_postcode(r.value))
				{
					r.up('.field').addClassName('error'); ok = false;	
					errors["postcode"] = true;
				}
			}
		} else {
			if(!validate_postcode(r.value))
			{
				r.up('.field').addClassName('error'); ok = false;	
				errors["postcode"] = true;
			}
		} 
	});
	
	$$('#'+formname+' .validate_url input').each( function(r) 
	{	
		
		
		if(r.up("div",".required") == undefined)
		{
			if (r.value != "")
			{
				if(!validate_url(r.value))
				{
					r.up('.field').addClassName('error'); ok = false;
					errors["url"] = true;
				}
			}
		} else {
			if(!validate_url(r.value))
			{
				r.up('.field').addClassName('error'); ok = false;
					errors["url"] = true;
			}
		} 
	});
	if (rt == "bool") 
	{
		return ok;
	} else {
		return errors
	}
}

// ***************************************

function requiredReason(formname) {

	// assume it's all good to start with
	var ok = true;
	var theReg = "";	
	var errors = {};
	
	errors = requiredCheckOk(formname,"array") ;
	if(errors["main"] === true)
	{
		return  "Please enter all of the required fields";	
	}

	if(errors["email"] === true)
	{
		theReg = "Please enter a valid email address<br/><br/>";
	}
	if(errors["telephone"] === true)
	{
	
		theReg = theReg + "Please enter a valid phone number<br/><br/>";
	}
	if(errors["postcode"] === true)
	{
		theReg = theReg + "Please enter a valid UK Postal Code<br/><br/>";
	}
	
	if(errors["url"] === true)
	{
		theReg = theReg + "Please enter a valid Website URL<br/><br/>";
	}
	
	return theReg + "The fields highlighted in red are not in the correct format. Please check and try again.  ";
}

//*****************************************

// a coupla validation functions 

	function validate_email(string) 
	{
		var regexp = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/;
		var result = regexp.test(string);
		return result;
	}

	var $isvalidmx = true;
	
	function validate_email_mx(emailaddress)
	{
		var $result;
		$isvalidmx = true;
		new Ajax.Request('/utilities/validateemail.json?e='+emailaddress, 
		{
			method:'get',
			asynchronous: false,
			onSuccess: function(transport)
			{
				var $json = transport.responseText.evalJSON();
				if(parseInt($json.msc) > 0)
				{	
					$isvalidmx = true;
					//return true;	
				} else {
				
					$isvalidmx = false;
					//return false;	
				}
		   	}
		});
		return $isvalidmx;
		//return true;
		
		
	}

function validate_mobile(string)
{
	var telnum = string;

	if(validate_telephone == false)
	{
		return false;
	}
	
	
	/*
	var exp = /^(\+)44(.*)$/;
	if (exp.test(telnum) == true) {
		telnum = "0"+telnum.substr(3,telnum.length);
	}
	  
	var exp = /^0044(.*)$/;
	if (exp.test(telnum) == true) {
		telnum = "0"+telnum.substr(4,telnum.length);
	}
	
	var exp = /^07/;
	if (exp.test(telnum) == true) {
		return true
	}
	 */
	return false;
	  
}

function validate_url(string) 
{
	var regexp = /((http|ftp|https):\/\/)?([\w-]+\.)+(\/[\w- .\/?%&=]*)?/;
	var result = regexp.test(string);
	return result;
}

function validate_telephone(string) 
{
	
	 // Convert into a string and check that we were provided with something
	 var telnum = string + " ";
	 
	 
	 if (telnum.length == 1)  {
	    return false
	 }
	 telnum.length = telnum.length - 1;
	 
	 /* we're going international
	 
	  var exp = /^(\+)44(.*)$/;
	  if (exp.test(telnum) == true) {
	  	telnum = "0"+telnum.substr(3,telnum.length);
	  }
	  
	  var exp = /^0044(.*)$/;
	  if (exp.test(telnum) == true) {
	  	telnum = "0"+telnum.substr(4,telnum.length);
	  }
	  
	  
	 
	 
	 // Don't allow country codes to be included (assumes a leading "+")
	 var exp = /^(\+)[\s]*(.*)$/;
	 if (exp.test(telnum) == true) {
	    return false;
	 }
	 */
	 // Remove spaces from the telephone number to help validation
	 while (telnum.indexOf(" ")!= -1)  {
	   telnum = telnum.slice (0,telnum.indexOf(" ")) + telnum.slice (telnum.indexOf(" ")+1)
	 }
	 
	 // Remove hyphens from the telephone number to help validation
	 while (telnum.indexOf("-")!= -1)  {
	   telnum = telnum.slice (0,telnum.indexOf("-")) + telnum.slice (telnum.indexOf("-")+1)
	 }  
	 
	 // Now check that all the characters are digits
	 exp = /^[\+0-9]+$/;
	 if (exp.test(telnum) != true) {
	    return false;
	 }
	 
	 // Now check that the first digit is 0
	 /*
	 exp = /^0[0-9]{9,10}$/;
	 if (exp.test(telnum) != true) {
	    return false;
	 }
	*/
	// Disallow numbers allocated for dramas.
	 
	 // Array holds the regular expressions for the drama telephone numbers
	 var tnexp = new Array ();
	tnexp.push (/^(0113|0114|0115|0116|0117|0118|0121|0131|0141|0151|0161)(4960)[0-9]{3}$/);
	tnexp.push (/^02079460[0-9]{3}$/);
	tnexp.push (/^01914980[0-9]{3}$/);
	tnexp.push (/^02890180[0-9]{3}$/);
	tnexp.push (/^02920180[0-9]{3}$/);
	tnexp.push (/^01632960[0-9]{3}$/);
	tnexp.push (/^07700900[0-9]{3}$/);
	tnexp.push (/^08081570[0-9]{3}$/);
	tnexp.push (/^09098790[0-9]{3}$/);
	tnexp.push (/^03069990[0-9]{3}$/);
	
	for (var i=0; i<tnexp.length; i++) {
	   	if ( tnexp[i].test(telnum) ) {
	   		return false;
	   	}
	}
	 
	// Finally check that the telephone number is appropriate.
	/*
	exp = (/^(01|02|03|05|070|071|072|073|074|075|07624|077|078|079|08)[0-9]+$/);
	
	if (exp.test(telnum) != true) 
	{
	   	return false;
	 }
	 */
	 // Telephone number seems to be valid - return the stripped telehone number  
	 return true;
}

function validate_postcode (string) 
{

	// Permitted letters depend upon their position in the postcode.
	var alpha1 = "[abcdefghijklmnoprstuwyz]";                       // Character 1
	var alpha2 = "[abcdefghklmnopqrstuvwxy]";                       // Character 2
	var alpha3 = "[abcdefghjkstuw]";                                // Character 3
	var alpha4 = "[abehmnprvwxy]";                                  // Character 4
	var alpha5 = "[abdefghjlnpqrstuwxyz]";                          // Character 5
	 
	// Array holds the regular expressions for the valid postcodes
	var pcexp = new Array ();
	
	// Expression for postcodes: AN NAA, ANN NAA, AAN NAA, and AANN NAA
	pcexp.push (new RegExp ("^(" + alpha1 + "{1}" + alpha2 + "?[0-9]{1,2})(\\s*)([0-9]{1}" + alpha5 + "{2})$","i"));
	 
	// Expression for postcodes: ANA NAA
	pcexp.push (new RegExp ("^(" + alpha1 + "{1}[0-9]{1}" + alpha3 + "{1})(\\s*)([0-9]{1}" + alpha5 + "{2})$","i"));
	
	// Expression for postcodes: AANA  NAA
	pcexp.push (new RegExp ("^(" + alpha1 + "{1}" + alpha2 + "?[0-9]{1}" + alpha4 +"{1})(\\s*)([0-9]{1}" + alpha5 + "{2})$","i"));
	 
	// Exception for the special postcode GIR 0AA
	pcexp.push (/^(GIR)(\s*)(0AA)$/i);
	 
	// Standard BFPO numbers
	pcexp.push (/^(bfpo)(\s*)([0-9]{1,4})$/i);
	 
	// c/o BFPO numbers
	pcexp.push (/^(bfpo)(\s*)(c\/o\s*[0-9]{1,3})$/i);
	 
	// Overseas Territories
	pcexp.push (/^([A-Z]{4})(\s*)(1ZZ)$/i);
	
	// Load up the string to check
	var postCode = string;
	
	// Assume we're not going to find a valid postcode
	var valid = false;
	 
	// Check the string against the types of post codes
	for ( var i=0; i<pcexp.length; i++) 
	{
		if (pcexp[i].test(postCode)) {
	   
			// The post code is valid - split the post code into component parts
			pcexp[i].exec(postCode);
		     
		 	// Copy it back into the original string, converting it to uppercase and
			// inserting a space between the inward and outward codes
			postCode = RegExp.$1.toUpperCase() + " " + RegExp.$3.toUpperCase();
		     

			// Load new postcode back into the form element
			return(true);
		     
			// Remember that we have found that the code is valid and break from loop
			break;
		}
	}
	 
	 // Return with either the reformatted valid postcode or the original invalid 
	 // postcode
	 if (valid) {return true;} else return false;
}





// useful for registration forms
function makeSurePasswordsMatch(formname) 
{
	Event.observe(formname, 'submit', function (e) {
	
	    // check that the password fields are identical in the given form
	    passwords = $(formname).getInputs("password");
	    
	    // passwords must match
	    if (passwords[0].value != passwords[1].value) 
	    {
	    	display_notification('The passwords you entered do not match.');
	    	// highlight the fields
	    	passwords.each( function (element)
	    	{
	    		element.up('.field').addClassName('error');
	  	 	});
	  		// stop the normal submit
	  		e.stop();
	  		hide_form_spinner(formname);
	  		return false;
    	}
	});
}


// attach the datepickers to the datepicker fields
form_dpck = new Array();


function implementDatePickers() {
  Event.observe(window, 'load', function() {
    $$('.input-datepicker').each(function(elm){
      // create standard date pickers
      form_dpck[form_dpck.length] = new DatePicker({
        relative	    : elm.id,
        language	    : 'en',
        showDuration  : 0.2,
        hideDuration  : 0.2,
        showEffect    : 'slide'
        });
      // for some reason scoping like this means that load is never called
      form_dpck[form_dpck.length-1].load();
    });
  });
}
implementDatePickers();
