/*
implementation notes: elements in the form should use class attributes to call these actions.
changelog:2011/01/10 added blur() to focus on swd-form-submission function
This file uses the filelib/jquery/functions.validation.php file to validate data, so new validation methods can be added there.

Successfully used in xajax5lib/forms/psp-edit-profile-edit-name-block.php

The submit button must use the id='swd-form-submit' or for generic form processing, it must have the id='swd-form-submission' and include a data element that includes the id of the form, two percent signs, and the ajax request.

Standard submit button implementation: (this uses the callfile action and passes parameters via the data element, used successfully in public-optin-validate-visitor.php
<input type='button' class='swd-form-submission' name='submitmember' id='submitmember' value='Submit Changes' data='editmember%%callfile_public-optin-validate-visitor_{$action}_action={$action},cid={$cid},mid={$mid}'>

typical implementation <input class='swd-form swd-validates-as-required swd-validates-as-text (validated or dovalidate)' id="sendername" type="text" name="sendername" value="some value, which can also be called from a class db query" max="75" size="40">

for each element to be validated, it must have a class of dovalidate or validated
onblur from any element causes a check for dovalidate class, if none, activate the submit button
when an element is validated, replace the class dovalidate with class validated
when the form is loaded, the parent form should run a script to assign validated class to any pre-loaded variables and disable the submit button
*/
jQuery(document).ready( function($) {

	var page=document.location.href;
	page=page.replace("#","");// we'll post back to the originating page

	function checkSubmitButton(){
		var dovalidate=0;
		
		// check all of the elements to see if it's time to activate the submit button
		$('input').each(function(){
			if($(this).hasClass('dovalidate')){
				dovalidate=dovalidate+1;
			}
		});
		
		if(dovalidate==0){
			// activate the submit button - since there are two possible, active them both
			var buttonid=$('.swd-form-submission').attr('id');
			
			if(buttonid!='undefined'){
			//	console.log('status for button ' + buttonid + ' is ' + $('#' + buttonid).attr('disabled') + ' and readonly status is ' + $('#' + buttonid).attr('readonly'));
				$('#' + buttonid).removeAttr('disabled').removeAttr('readonly');
			//	console.log('status for button ' + buttonid + ' is ' + $('#' + buttonid).attr('disabled'));
			}
			else{
			$('.swd-form-submission').removeAttr('disabled').removeAttr('readonly');
			$('.swd-form-submit').attr('disabled',false);
			}
		}
		else{
			$('.swd-form-submission').attr('disabled','disabled');
			$('.swd-form-submit').attr('disabled','disabled');
		}
	}

	function displayError(itemid){
		// changelog: 2010/12/17 removed class validated from the addClass statement
		$('input#' + itemid).val('').addClass('dovalidate').removeClass('validated');// return a blank to the form field and set the class to required and add the error to the validation div
		var divid='div'+itemid;
		var divcontents=$('#' + divid).html();
		if(divcontents==null){
			$('#' + 'swd_' + itemid).append("<div class='shadows-10 validation-error' id='" + divid + "'>" + $('#' + 'swd_' + itemid).attr('data') + "</div>");
		}

	}

	function showErrors(data,itemid){
		var dataarray=data.split("&&");// split the returned message into an array
	//	console.log(data + ' is the data for item ' + itemid);
		// the array that is returned the keys will be in this format:
		// validated=0, valid-result=1,valid-value=2
		var validated=dataarray[0].substring(10);// 0 (validation failed) or 1 (validation occured)
		var validresult=dataarray[1].substring(13);// 0 (invalid) or 1 (valid)
		var validvalue=dataarray[2].substring(12);// value of the data
		var validerror=dataarray[3].substring(12);// the error message from validation
		var divid="div" + itemid;
		
		if(validated==1 && validresult==1){// this was successfully validated
			$('input#' + itemid).val(validvalue).addClass('validated').removeClass('dovalidate');// assign the data to the input element if it is valid and add the validated class
			$('#' + divid).remove();// remove any error message
		}
		else{
			// the data was not validated or validation failed
			if(validated==1 && validresult==0){
			// data was validated, but is not valid
			displayError(itemid);
			}
			else{// the only remaining option is that the validation itself failed
				$('#swd-validation-errors').append("<div id='" + divid + "' style='background-color:blue;color:red'>Fatal Error - Validation Failed</div>");
			}
		$('.swd-form-submission').attr('disabled','disabled');// disable the submit button
		}
	}

	function decodeURLencode(data){
		// this function decodes data that has been encoded in php using rawurlencode()
		decoded=unescape(data);
		decoded=decoded.replace(/%40/g,"@").replace(/%2A/g,"*").replace(/%2B/g,"+").replace(/%2F/g,"/").replace(/\\/g,"");
		return decoded;
	}


	function updateElements(data){
		// update page elements based on passed in data.  Each element must be passed in as a key=>value pair that have been urlencoded on the php page.  Elements are separated by a comma.
		earray=data.split(",");// assign the data to an array
		ealength=earray.length;// how many elements are in the array?
		for(x=0;x<ealength;x++){// iterate through
			display=earray[x].split("=");// split out the element id and the value
			value=decodeURLencode(display[1]);// unencode the value
			// assign the value to the element
			//$('#' + display[0]).html(value); replaced this on 4/13 to allow for updates of both html and input elements
			if($('#' + display[0]).is('input')){
				$('#' + display[0]).val(value);
			}
			else{
				$('#' + display[0]).html(value);
			}

		}

		$('#dialog').dialog('close');
	}

	function calculateValidationStatus(data)
	{
		// derive the valid-status from the returned validation.  The placement of classes doesn't always seem to be accurate when processing, we need to try a more direct route
		var dataarray=data.split("&&");// split the returned message into an array
		// the array that is returned the keys will be in this format:
		// validated=0, valid-result=1,valid-value=2
		var validresult=dataarray[1].substring(13);// 0 (invalid) or 1 (valid)
		return validresult;
	}

	function validateDate(value,itemclass,itemid,data)
	{
		value=unescape(value);// each element passed in must be unescaped
		itemclass=unescape(itemclass);
		itemid=unescape(itemid);
		dataattributes=unescape(data);// the attributes first element contains the id that will be used for the ajax request.  the second is the name of the file to be used for validation, the third is the keyword used in the file to trigger validation, typically, "validate".  Successfully used in xajax5lib/forms/psp-edit-profile-edit-bio-block.php
	    $.post(page,{
			'ajaxrequest':dataattributes,
			'id':itemid,
			'value' : $('input#' + itemid).val(),
			'class' : itemclass
		},
			function(data){
				showErrors(data,itemid);
			});// end input-text section
	}

	// Dialog Link
	$('.form_link').live('click',function(){
		var requesttype=$(this).attr('id');
		var attributes=$(this).attr('data');
		var title=$(this).attr('title');
		var editable=null;
		if(title!==''){
			$('#dialog').dialog('option', 'title', title);
		}
		if($(this).hasClass('modal')){
			$('#dialog').dialog('option','modal',true);
		}

		$('#dialog').load(page,{
			'ajaxrequest':requesttype,
			'attributes':attributes
			},
			function(data){
			
				if($('#dialog').dialog('isOpen')==false){
					$('#dialog').dialog('open');
					$('#dialog').focus();
				}
				$('#dialog').html(data);// add the data to the div
				$('.adddatepicker').addClass('datepicker').removeClass('adddatepicker');
				$('.datepicker').datepicker({
					inline:true,
					dateFormat: 'yy-mm-dd',
					altField:'#alternate',
					altFormat: 'DD, d MM, yy',
					changeYear:true,
					changeMonth:true
				});

				// datepicker class
				$('.monthdaypicker').datepicker(
					{
						inline:true,
						dateFormat: 'M d',
						changeYear:true,
						changeMonth:true
					}
				);


				$('input.swd-form:first').focus().addClass('active');// put the focus on the first element
				$('.swd-validates-as-required').each(function(){
					// changelog 2010/12/17 removed class required from both addClass statements below
					if($(this).val()!=''){// this is data from the db, so as long as it's present, we can use it
						$(this).addClass('validated');
					}
					else{
						$(this).addClass('dovalidate');
					}
				});// end each function for input-text

				editable=$('#editable').val();// look for the editable hidden element
				if(editable=='no'){
					// set the elements that should not be edited to readonly if necessary
					$('.editable').each(function(){
						$('.editable').attr('readonly','readonly').removeClass('dovalidate').addClass('validated');
					});// end of editable function
				}

				checkSubmitButton();
			});
		return false;
	});// end form_link

	$('input.swd-validates-as-match').live('keyup',function(){
		var id=$(this).attr('id');
		var divid="div" + id;
		var id1=id.split("_");
		da[1]=$('#' + id1[0]).val();
		var matchvalue=$(this).val();
		
		if(matchvalue==da[1]){
			$('#' + id + 'ok').show('fast');
			$(this).removeClass('dovalidate').addClass('validated');
			$('#' + id1[0]).removeClass('dovalidate').addClass('validated');
			$('#' + divid).hide('slow');
		}
		else{
			$('#' + id + 'ok').hide('fast');
			$(this).removeClass('validated').addClass('dovalidate');
		}
		
		checkSubmitButton();
	});// end of the validatates as match

	$('input.swd-form-validation').live('blur',function(){// this is the validation of a form.  This option has the form go back to its own page for validation, unlike the swd-form option below, which is only intended for optinprocessing
		// see above notes for standard implementation and example
		if($(this).val().length<$(this).attr('min')){
			displayError($(this).attr('id'));
		}
		$(this).removeClass('active');// remove the active class when we leave a field

		// assign the variables needed for validation
		var itemid=$(this).attr('id');// with an id that goes through the processing file back to the originating form
		var attributes=$(this).attr('data');// these attributes can be passed to the validation function
		da=attributes.split("%%");// the attributes first element contains the id that will be used for the ajax request.  the second element are any additional attributes that must be passed along for processing
		var itemclass=$(this).attr('class');

		// diagnostics
	 //	if(document.domain=='kiwaniswebsites.org'){alert('The item id is ' +itemid + ' and the attributes are ' + attributes + ' and the item class is ' + itemclass);}

		// if this is a must-match element, we have to find the value of the first item
		if($(this).hasClass('swd-validates-as-match')){
			var id1=itemid.split("_");
			da[1]=$('#' + id1[0]).val();
		}

	    $.post(page,{
			'ajaxrequest':da[0],
			'validation':itemid,// this tells the originating form file that this is a validation action
			'value' : $('input#' + itemid).val(),
			'attributes':da[1],
			'class' : itemclass
		},
			function(data){
				showErrors(data,itemid);
				checkSubmitButton();
			});// end input-text section
		});// end post and data function call for form self submission

	$('.swd-validates-as-month-day').live('click',function(){
		// function clears a dovalidate class and error message for a field with this element
		$(this).removeClass('dovalidate');// remove the dovalidate class
		var itemid=$(this).attr('id');
		$('#swd_' + itemid).empty();// clear the error message
		checkSubmitButton();// reactivate the submit button
	});

	//the following function for newcontacttype is a temporary solution that can probably be improved later on. Current date 2011/10/14. This resolves a problem with no validation of new contact types
	$('#newcontacttype').live('change',function(){
		
		// transfer the value of the option to a class in the newcontact element
		var contacttype=$(this).val();
		$('#newcontact').addClass('swd-new-' + contacttype);	
	});// end newcontacttype function	

	// iterate through all of the elements to add focus, then blur to validate all for those that are in a field and go directly to the submit button with their mouse.  Added 2010/12/23
	$('.swd-form-submission').live('mouseover focus',
		function(){
			var id=$(this).attr('id');
			$('input.swd-form-validation').each(function(){
				$(this).focus().blur();
			});

			$('input.swd-validates-as-month-day').each(function(){
				if($(this).val!=''){
					validateDate(escape($(this).val()),escape($(this).attr('class')),escape($(this).attr('id')),escape($(this).attr('data')));
				}
			});

		});

	$('.swd-form-submission').live('click',function(){// this is the function to use for generic form processing.  the other swd-form-submit is for optinprocessing
		// standard implementation for the submit button is
		
		$(this).attr('disabled','disabled');
		var dovalidate=0;// declare the variable
		var parameters='';

		// if there are any elements with a dovalidate class, return focus to that element and enable the submit button
			$('input').each(function(){
				if($(this).hasClass('dovalidate')){dovalidate=dovalidate+1;}
			});

		if(dovalidate==0){
			var formdata=$(this).attr('data').split("%%");
			var formid=formdata[0];
			var ajaxrequest=formdata[1];
			var datalist='';

			$(':input.formfield').each(function(){
				itemid=$(this).attr('id');
				datalist=datalist + '%%' + $(this).attr('name') + '=' + escape($(this).val()) + ',id=' + $(this).attr('id') + ',class=' + $(this).attr('class') + ',type='+ $(this).attr('type');
				if($(this).attr('min')!=''){
					datalist=datalist + ',min='+ $(this).attr('min');
				}
				if($(this).attr('max')!=''){
					datalist=datalist + ',max='+ $(this).attr('max');
				}
			}); // end each statement

			// get the radio buttons
			$("input:radio:checked").each(function(){
				datalist=datalist + '%%' + $(this).attr('name') + '=' + $(this).val();
			});// end radio button section

			// get the checkboxes
			$("input:checkbox:checked").each(function(){
				datalist=datalist + '%%' + $(this).attr('name') + '=' + $(this).val();
			});// end checkbox section
			
		//	if(console){console.log('the datalist for submission is ' + datalist);}
			// we can now post the results
			$.post(page,{
			   'ajaxrequest':ajaxrequest,
			   'datalist':datalist
			   },
			   function(data){
				//	if(console){console.log(data);}
					result=data.split("::");
					if(result[1]=='undefined'){// this is a validation failure and we need to display the error messages
						var dataarray=data.split("&&");// split the returned message into an array
						var itemid=dataarray[4].substring(3);
						showErrors(data,itemid);
					}
					else if (result[0]=='updates'){
						// for diagnostics only
					 //	if(document.domain=="kiwaniswebsites.org"){alert(result[1]);}
						updateElements(result[1]);
					}
					else if(result[0]=='accordion'){
						alert('Please wait while the page reloads…');
						location.reload();
					}
					else if(result[0]=='dialog'){
						content=decodeURLencode(result[1]);// unencode the value
						title=result[2];
						$('#' + result[3]).html(content).dialog('option','title',title).dialog('option','modal',true).dialog("open");// place the contents into the dialog with the id of result[1]
					}
					else if(result[0]=='redirect'){
						content=decodeURLencode(result[1]);
						newlocation=result[2];
						alert(content);
						location.replace(newlocation);
						return true;
					}
					else{// this is success or processing failure and we can show a message
						$('#dialog').html(result[1]).focus();// add the data to the div.  This would be a success message

					}
				});// end of the post in form submit

			}
			else{
				// this means there are elements left to validate, return to the first one
				$('input.dovalidate:first').focus();
			}
		return false;
	});// end of the swd-form-submission loop

/*#############################################################################*/


	$('input.swd-form').live('blur',function(){// remove the active class
		$(this).removeClass('active');// remove the active class when we leave a field

		// assign the variables needed for validation
		var page=document.location.href;
		page=page.replace("#","");
		var itemid=$(this).attr('id');
		var parameters=$(this).attr('data');// these attributes can be passed to the validation function
		var itemclass=$(this).attr('class');
	    $.post(page,{
			'ajaxrequest':'optinprocessing',
			'f':itemid,
			'value' : $('input#' + itemid).val(),
			'parameters':parameters,
			'class' : itemclass
		},
			function(data){
				var dataarray=data.split("&&");// split the returned message into an array
				// the array that is returned the keys will be in this format:
				// validated=0, valid-result=1,valid-value=2
				var validated=dataarray[0].substring(10);// 0 (validation failed) or 1 (validation occured)
				var validresult=dataarray[1].substring(13);// 0 (invalid) or 1 (valid)
				var validvalue=dataarray[2].substring(12);// value of the data
				var validerror=dataarray[3].substring(12);// the error message from validation
				var divid="div" + itemid;
				var divcontents=$('#' + divid).html();
				if(validated==1 && validresult==1){// this was successfully validated
					$('input#' + itemid).val(validvalue).addClass('validated').removeClass('dovalidate');// assign the data to the input element if it is valid and add the validated class
					$('#' + divid).remove();// remove any error message
				}
				else{
					// the data was not validated or validation failed
					if(validated==1 && validresult==0){
						// data was validated, but is not valid
						$('input#' + itemid).val('').addClass('required dovalidate').removeClass('validated');// return a blank to the form field and set the class to required and add the error to the validation div
						if(divcontents==null){
							$('#' + 'swd_' + itemid).append("<div class='shadows-10 validation-error' id='" + divid + "'>" + $('#' + 'swd_' + itemid).attr('data') + "</div>");
						}
					}
					else{// the only remaining option is that the validation itself failed
						$('#swd-validation-errors').append("<div id='" + divid + "' style='background-color:blue;color:red'>Fatal Error - Validation Failed</div>");
					}
					$('.swd-form-submit').attr('disabled','disabled');// disable the submit button
				}

				// check the form to see if we should activate the submit button
				var dovalidate=0;// set a counter
				$('input').each(function(){// check each element for a class of dovalidate
					if($(this).hasClass('dovalidate')){
						if($(this).attr('id')!=$('input.swd-validates-as-required:last').attr('id')){
							dovalidate=dovalidate+1;
						}
					}
				});

				// activate the submit button if there are none
				if(dovalidate==0){
					$('.swd-form-submit').attr('disabled',false);// activate the submit button
				}
				else{
					$('.swd-form-submit').attr('disabled','disabled');// deactivate the submit button
				}
			});// end input-text section
		});// end post and data function call

	$('input.swd-form').live('focus',function(){// add the active class
		$(this).addClass('active').removeClass('required');
//		if($(this).attr('id')==$('input.swd-validates-as-required:last').attr('id')){
  //			$('input:[name=submit]').attr('disabled',false);// if this is the last element, enable the submit button
	//	}
	});

	$('.swd-form-submit').live('click',function(){
		$(this).attr('disabled','disabled');
		var datalist='';
		var id=$(this).attr('id');

		// validate the last item if it still has class dovalidate (visitor didn't focus on submit button, just did a click
		var dovalidate=0;// set a counter
		$('input.formfield').each(function(){// check each element for a class of dovalidate
			if($(this).hasClass('dovalidate')){
				itemid=$(this).attr('id');
				if(itemid==$('input.swd-validates-as-required:last').attr('id')){
					// this item would not have been validated if the visitor didn't focus on the button before clicking
					var page=document.location.href;
					page=page.replace("#","");
					var parameters=$(this).attr('data');// these attributes can be passed to the validation function
					var itemclass=$(this).attr('class');
				    $.post(page,{
						'ajaxrequest':'optinprocessing',
						'f':itemid,
						'value' : $('input#' + itemid).val(),
						'parameters':parameters,
						'class' : itemclass
					},
						function(data){
					        var dataarray=data.split("&&");// split the returned message into an array
							// the array that is returned the keys will be in this format:
							// validated=0, valid-result=1,valid-value=2
							var validated=dataarray[0].substring(10);// 0 (validation failed) or 1 (validation occured)
							var validresult=dataarray[1].substring(13);// 0 (invalid) or 1 (valid)
							var validvalue=dataarray[2].substring(12);// value of the data
							var validerror=dataarray[3].substring(12);// the error message from validation
							var divid="div" + itemid;
							var divcontents=$('#' + divid).html();
							if(validated==1 && validresult==0){
								// data was validated, but is not valid
								dovalidate=dovalidate+1;
								$('input#' + itemid).val('').addClass('required dovalidate').removeClass('validated');// return a blank to the form field and set the class to required and add the error to the validation div
								if(divcontents==null){
									$('#' + 'swd_' + itemid).append("<div class='shadows-10 validation-error' id='" + divid + "'>" + $('#' + 'swd_' + itemid).attr('data') + "</div>");
								}
							}
						});
					}
				}

			});

		// continue if dovalidate is 0
		if(dovalidate==0){
			$(':input.formfield').each(function(){
				datalist=datalist + '%%' + $(this).attr('name') + '=' + $(this).val();
			}); // end each statement

			// get the radio buttons
			$("input:radio:checked").each(function(){
				datalist=datalist + '%%' + $(this).attr('name') + '=' + $(this).val();
			});// end radio button section

			// get the checkboxes
			$("input:checkbox:checked").each(function(){
				datalist=datalist + '%%' + $(this).attr('name') + '=' + $(this).val();
			});// end checkbox section

			// we can now post the results
			var page=document.location.href;
			page=page.replace("#","");
			$.post(page,{
			   'ajaxrequest':id,
			   'datalist':datalist
			   },
			   function(data){
		//		array=data.split("::");// the data field must contain the slidedown action, so we need to ignore it
				$('#dialog').html(data);// add the data to the div
			   }
			);

		}
		else{// put the focus back on the first element that has a dovalidate class
			// there are still errors, show an alert
			if($('#dialog_messages').length==1){$('#dialog_messages').dialog({autoOpen:false,dialogClass:'dialogboxbold',title:'Message Errors',width:'300'}).dialog('open').html('There are still errors that must be fixed before you can send this message.  Please fix the errors and try again.');// replaced the alert with a dialog box
			}
		}
	});// end of the swd-form-submit loop


});// end main jquery call
