/*

	PerthWeb Standard Mail Forms Handler for PHP (Client Side Validation)
	
	Version : 1.2
	Author  : Dominic Manley (dominic@perthweb.com.au)
	Date    : 2nd December 2005

*/

function in_array(str, arr) {
	var found = false;
	for (var i = 0; i < arr.length; i++) {
		if (arr[i] == str) {
			found = true;
		}
	}
	return found;
}

/**
 * Decodes URL-decoded string
 * Info on what encoding functions to use from: http://xkr.us/articles/javascript/encode-compare/
 * Please be aware that this function expects to decode from UTF-8 encoded strings, as found on pages served as UTF-8.
 * @param string str String to decode
 * @version 1109.2015
 * @author Philip Peterson (original)
 * @link http://phpjs.org/functions/urldecode
 */
function urlDecode( str ) {
	return decodeURIComponent((str + '').replace(/\+/g, '%20'));
}

/**
 * Returns the query string value of the specified key.
 * If no value is found, then defaultValue is returned.
 *
 * @param string queryStringKey The key in the query string
 * @param string|null defaultValue The default value to return if queryStringKey not found (empty string if null)
 */
function getQueryString( queryStringKey, defaultValue) {
	if( defaultValue == null ) {
		defaultValue = '';
	}

	queryStringKey = queryStringKey.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
	var regex = new RegExp("[\\?&]"+queryStringKey+"=([^&#]*)");
	
	var queryString = regex.exec(window.location.href);
	if( queryString == null ) {
		return defaultValue;
	}
	else {
		return queryString[1];
	}
}

/**
 * Returns a message value stored in a key in the query string.
 * @param string queryStringKey The key in the query string to retrieve the message value from ('msg' by default)
 * @param string|null defaultValue The default value to return if queryStringKey not found (empty string if null)
 * @return string Url decoded message string
 */
function pwGetMessage( queryStringKey, defaultValue ) {
	if( queryStringKey == null ) {
		queryStringKey = 'msg';
	}

	if( defaultValue == null ) {
		defaultValue = '';
	}

	return urlDecode(getQueryString(queryStringKey, defaultValue));
}

function isPWFormName(formName) {
	var isPW = true;
	if (formName.substr(0, 2) != 'pw') {isPW = false;}
	var char3 = Array('m', 'o');
	if (in_array(formName.substr(2, 1), char3) != true) {isPW = false;}
	var char4 = Array('s', 'a', 'n', 'e', 'w', 'd', 'p', 'i', 'l');
	if (in_array(formName.substr(3, 1), char4) != true) {isPW = false;}
	return isPW;
}

function stripFormName(formName) {
	var stripped = formName.substr(4); // remove the 4 character code preffix
	stripped = stripped.replace(/_/g, ' '); // replace underscores with spaces
	stripped = stripped.replace(/\[/g, ''); // checkbox arrays (PHP only)
	stripped = stripped.replace(/\]/g, ''); //    "       "
	return stripped;
}

/**
 * Validates the date within dateString is in the valid format of dd-mm-yyyy or dd/mm/yyyy.
 * @param string dateString
 * @param object objError Used for returning by reference an error message when date is not valid within the property objError.error.
 * @return boolean
 */
function pwValidDate( dateString, objError ) {
	// Regular expression used to check if date is in correct format
	var patternDateHyphenSeparated = new RegExp("[0-3][0-9]\-(0|1)[0-9]\-(19|20|21)[0-9]{2}");
	var patternDateSlashSeparated = new RegExp("[0-3][0-9]\/(0|1)[0-9]\/(19|20|21)[0-9]{2}");
	var separator = '-';

	if( typeof objError == "undefined" )  {
	   objError = { 'error' : '' };
	}
	else if( typeof objError.error != "string" ) {
		objError.error = '';
	}

	if( dateString.match(patternDateHyphenSeparated) ) {
	   separator = '-';
	}
	else if( dateString.match(patternDateSlashSeparated) ) {
		separator = '/';
	}
	else {
	   objError.error = 'Invalid date or date format (expected dd' + separator + 'mm' + separator + 'yyyy) entered';
	   return false;
	}

	var datePartsArray = dateString.split(separator);
	var day = datePartsArray[0];
	var month = datePartsArray[1] - 1;	// Attention! Javascript consider months in the range 0 - 11
	var year = datePartsArray[2];

	// Create a date object to be validated
	var sourceDate = new Date(year,month,day);

	if( year != sourceDate.getFullYear() ) {
		objError.error = 'Year is not valid';
		return false;
	}

	if( month != sourceDate.getMonth() ) {
		objError.error = 'Month is not valid';
		return false;
	}

	if( day != sourceDate.getDate() ) {
		objError.error = 'Day is not valid';
		return false;
	}

	// Valid date.
	return true;
}

/**
 * Validates the value of formElement is valid according to its indicated format code.
 * @param string formElement
 * @param object objError Used for returning by reference an error message when value is not valid within the property objError.error.
 * @return boolean
 */
function pwValidFormatValue( formElement, objError ) {
	if( typeof objError == "undefined" )  {
	   objError = { 'error' : '' };
	}
	else if( typeof objError.error != "string" ) {
		objError.error = '';
	}

	if( typeof formElement == "undefined" )  {
	   return true;
	}

	var fieldName = formElement.name;
	var fieldValue = formElement.value;
	var fieldFormat = fieldName.substr(3, 1);

	if( fieldValue.length <= 0 ) {
		return true;
	}

	switch( fieldFormat ) {
		// Date (dd-mm-yyyy or dd/mm/yyyy)
		case 'd':
			var dateError = {'error' : ''};
			var isValidDate = pwValidDate(fieldValue, dateError);

			if( !isValidDate ) {
				objError.error = dateError.error + ' for ' + stripFormName(fieldName);
				return false;
			}
		break;
		// Email address
		case 'e':
			var validEmail = /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+[a-zA-Z0-9]{2,4}$/;
			if( !(validEmail.test(fieldValue)) ) {
				objError.error = stripFormName(fieldName) + ' is not a valid email address.';
				return false;
			}
		break;
		// Integers only
		case 'i':
			var validIntegers = /^\-?[0-9]+$/;
			if( !(validIntegers.test(fieldValue)) ) {
				objError.error = stripFormName(fieldName) + ' must contain numerical characters only.';
				return false;
			}
		break;
		// Letters only
		case 'l':
			var validLetters = /^[a-zA-Z]+$/;
			if( !(validLetters.test(fieldValue)) ) {
				objError.error = stripFormName(fieldName) + ' must contain alphabetical characters only.';
				return false;
			}
		break;
		// Phone Number
		// Regex based partly on http://blog.stevenlevithan.com/archives/validate-phone-number
		case 'p':
			var validTelephone = /^(\(\+?([0-9]{2,3})\)|\+?([0-9]{2,4}))?[-. ]?([0-9]{3,4})[-. ]?([0-9]{3,4})$/
			if( !(validTelephone.test(fieldValue)) ) {
				objError.error = stripFormName(fieldName) + ' is not a valid telephone number.';
				return false;
			}
		break;
		// Url
		case 'w':
			var validUrl = /^(ht|f)tp(s?)\:\/\/[a-zA-Z0-9\-\._]+(\.[a-zA-Z0-9\-\._]+){2,}(\/?)([a-zA-Z0-9\-\.\?\,\'\/\\\+&%\$#_]*)?$/;
			if( !(validUrl.test(fieldValue)) ) {
				objError.error = stripFormName(fieldName) + ' is not properly structured.';
				return false;
			}
		break;

		// == DEPRECATED CODES ==

		// Alphabet only (DEPRECATED)
		// NOTE: Sadly it's not strictly alphabetical characters, since many old sites mis-use the alphabet type.
		//		 The Letters (l) type now replaces the Alphabet (a) type.
		case 'a':
			var validAlphabet = /^[a-zA-Z]/;
			if( !(validAlphabet.test(fieldValue)) ) {
				objError.error = stripFormName(fieldName) + ' must contain alphabetical characters only.';
				return false;
			}
		break;
		// Numerics only (DEPRECATED)
		// NOTE: Sadly it's not strictly numerics, since many old sites mis-use numerics type for telephone numbers etc.
		//		 The Integer (i) type now replaces the Numerics (n) type.
		case 'n':
			var validNumerics = /^[0-9]/;
			if( !(validNumerics.test(fieldValue)) ) {
				objError.error = stripFormName(fieldName) + ' must contain numerical characters only.';
				return false;
			}
		break;
	}

	// Valid value
	return true;
}

function pwValidate( frmObj ) {

	var invalid = Array();
	var handled = Array();
	
	for (var i = 0; i < frmObj.elements.length; i++) {
		var fieldName = frmObj.elements[i].name;
		var fieldValue = frmObj.elements[i].value;
		var fieldType = frmObj.elements[i].type;

		if( (isPWFormName(fieldName)) && (!in_array(fieldName, handled)) && (fieldType != 'hidden') ) {
			// Check for valid value according to the format code.
			var invalidFormatValue = false;
			var fieldErrorObj = {};

			if( fieldType == 'checkbox' || fieldType == 'radio' ) {
				var totalGroupElements = parseInt(frmObj[fieldName].length, 10);
				if( totalGroupElements > 0 ) {
					for( var groupIndex = 0; groupIndex < totalGroupElements && !invalidFormatValue; groupIndex++) {
						fieldErrorObj = {};

						if( frmObj[fieldName][groupIndex].checked && !pwValidFormatValue(frmObj[fieldName][groupIndex], fieldErrorObj) ) {
							invalidFormatValue = true;
							invalid[invalid.length] = fieldErrorObj.error;
						}
					}
				}
				else if( frmObj.elements[i].checked && !pwValidFormatValue(frmObj.elements[i], fieldErrorObj) ) {
					invalidFormatValue = true;
					invalid[invalid.length] = fieldErrorObj.error;
				}
			}
			else if( !pwValidFormatValue(frmObj.elements[i], fieldErrorObj) ) {
				invalidFormatValue = true;
				invalid[invalid.length] = fieldErrorObj.error;
			}

			// Mandatory check
			if( !invalidFormatValue && fieldName.substr(2, 1) == 'm' ) { // mandatory
				if( fieldType == 'checkbox' || fieldType == 'radio' ) {
					var allEmpty = true;
					var totalGroupElements = parseInt(frmObj[fieldName].length, 10);
					if( totalGroupElements > 0 ) {
						for( var groupIndex = 0; groupIndex < totalGroupElements; groupIndex++ ) {
							if( frmObj[fieldName][groupIndex].checked != false ) {
								allEmpty = false;
							}
						}
					}
					else if( frmObj[fieldName].checked != false ) {
						allEmpty = false;
					}

					if (allEmpty == true) {
						var typeText = 'an option for '; 
						if (fieldType == 'checkbox') { typeText = 'at least one option for ';}
						if( totalGroupElements == 0 || isNaN(totalGroupElements) ) { typeText = ''; }
						var invalid_msg = 'You must select ' + typeText + stripFormName(fieldName) + '.';
						invalid[invalid.length] = invalid_msg;
					}
				} else {
					if (fieldValue == '') {
						var invalid_msg = stripFormName(fieldName) + ' must not be empty.';
						invalid[invalid.length] = invalid_msg;
					}
				}
			}

			handled[handled.length] = fieldName;
		}
	}
	
	if (invalid.length > 0) {
		invalid_txt = '';
		for (var i = 0; i < invalid.length; i++) {
			invalid_txt += invalid[i] + "\n";
		}
		alert(invalid_txt);
		return false;
	}
	
	return true;

}

function generate_securimage() {

	prefix = parent.location.protocol + '//';
	
	html = '<div id="smf_captcha" style="width: 170px; float: left; height: 55px">' +
		      '<img id="siimage" align="left" style="padding-right: 5px; border: 0" src="' + prefix + 'www.perthweb.com.au/smf/securimage/securimage_show.php" />' +
			/*
		      '<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0" width="19" height="19" id="SecurImage_as3" align="middle">' +
					    '<param name="allowScriptAccess" value="sameDomain" />' +
					    '<param name="allowFullScreen" value="false" />'+
					    '<param name="movie" value="http://www.perthweb.com.au/smf/securimage/securimage_play.swf?audio=securimage_play.php&bgColor1=#777&bgColor2=#fff&iconColor=#000&roundedCorner=0" />'+
					    '<param name="quality" value="high" />'+
					
					    '<param name="bgcolor" value="#ffffff" />'+
					    '<embed src="http://www.perthweb.com.au/smf/securimage/securimage_play.swf?audio=http://www.perthweb.com.au/smf/securimage/securimage_play.php&bgColor1=#777&bgColor2=#fff&iconColor=#000&roundedCorner=0" quality="high" bgcolor="#ffffff" width="19" height="19" name="SecurImage_as3" align="middle" allowScriptAccess="sameDomain" allowFullScreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" />'+
					  '</object>'+
				
		        '<br />'+*/
		        '<a href="' + prefix + 'www.perthweb.com.au/smf/securimage/securimage_play.php" title="Play this using your speakers">'+
				  '<img border="0" align="top" style="margin-bottom: 1px;" alt="" '+
						'src="' + prefix + 'www.perthweb.com.au/smf/securimage/images/speaker16.png"/> '+
				  '</a>'+
		        '<br />'+
		        '<div style="height: 15px; width: 10px"></div>'+
		        '<a tabindex="-1" style="border-style: none" href="#" title="Change Code" onclick="document.getElementById(\'siimage\').src = \'' + prefix + 'www.perthweb.com.au/smf/securimage/securimage_show.php?sid=\' + Math.random(); return false"><img src="' + prefix + 'www.perthweb.com.au/smf/securimage/images/refresh_16.png" alt="Reload Image" border="0" onclick="this.blur()" align="bottom" /></a>'+
		'</div>'+
		'<div id="smf_clear" style="clear: both"></div>';
	
	return html;
}

