/**
 * Form validator
 **/
 
function keySaltEncrypt(s, key) {
    s = s.toLowerCase();
    var r = s.length - 4;
    var f = "";
    var x = 0;
    for(var i = 0; i != 4; i++) {
        f += s.charAt(parseInt((key.charAt(i))-1));
        x += (parseInt(f.charCodeAt(i)) - 96);
    }
    x = x - r;
    f = x + f;
    return f;
}
 
/** 
 *  NOTE: Uses innerHTML() - would need to be adapted if serving as application/xhtml+xml
 */
 validators = new Array();
 
 validators["Contact"] = "[^ \\n]+";
 validators["Position"] = "[^ \\n]+";
 validators["phone-business"] = "^[^a-zA-Z]{6,}$" // non-alphabetical 
 validators["Media-Outlets"] = "[^ \\n]+";
 validators["user-email"] = "^([0-9a-zA-Z]+[-._+&])*[0-9a-zA-Z_]+@([-0-9a-zA-Z]+[.])+[a-zA-Z]{2,6}$";
 validators["friends-email"] = "^([0-9a-zA-Z]+[-._+&])*[0-9a-zA-Z_]+@([-0-9a-zA-Z]+[.])+[a-zA-Z]{2,6}$";
 validators["fullName"] = "[^ \\n]+";
 validators["full-name"] = "[^ \\n]+"; 
 validators["first-name"] = "[^ \\n]+"; 
 validators["surname"] = "[^ \\n]+"; 
 validators["event-name"] = "[^ \\n]+"; 
 validators["event-date"] = "[^ \\n]+"; 
 validators["event-time"] = "[^ \\n]+"; 
 validators["event-venue"] = "[^ \\n]+"; 
 validators["name"] = "[^ \\n]+"; 
 validators["letter"] = "[^ \\n]+"; 
 validators["address"] = "[^ \\n]+"; 
 validators["yourAddress"] = "[^ \\n]+";
 validators["street-address"] = "[^\\n]+";
 validators["phone"] = "^[^a-zA-Z]{6,}$" // non-alphabetical
 validators["yourPhone"] = "^[^a-zA-Z]{6,}$" // non-alphabetical
 validators["ltotelephone"] = "^[^a-zA-Z]{6,}$" // non-alphabetical
 validators["location"] = "[^ \\n]+";
 validators["suburb"] = "[^ \\n]+";
 validators["postcode"] = "[^ \\n]+";
 validators["yourTown"] = "[^ \\n]+";
 validators["comment"] = "[^ \\n]+";
 validators["comments"] = "[^ \\n]+";
 validators["yourComments"] = "[^ \\n]+";
 validators["my-comment"] = "[^ \\n]+";
 validators["email"] = "^([0-9a-zA-Z]+[-._+&])*[0-9a-zA-Z_]+@([-0-9a-zA-Z]+[.])+[a-zA-Z]{2,6}$";
 validators["rcptName"] = "[^ \\n]+"; 
 validators["yourName"] = "[^ \\n]+"; 
 validators["yourEmail"] = "^([0-9a-zA-Z]+[-._+&])*[0-9a-zA-Z_]+@([-0-9a-zA-Z]+[.])+[a-zA-Z]{2,6}$";
 validators["rcptEmail"] = "^([0-9a-zA-Z]+[-._+&])*[0-9a-zA-Z_]+@([-0-9a-zA-Z]+[.])+[a-zA-Z]{2,6}$";
 validators["option"] = true;
 validators["yourState"] = true;

/* matchfields for use with passwords.*/
 matchfields = new Array(); 
 matchfields["pwd"] = "pwdvalidate"; 
 
 /* error messages go here */
 messages = new Array();
 
 messages["Contact"] = "Please enter a vaild contact name";
 messages["Position"] = "Please enter a valid position";
 messages["Media-Outlets"] = "Please enter a valid media outlet";
 messages["phone-business"] = "Please enter a valid phone number";
 messages["user-email"] = "Please enter a valid email address";
 messages["friends-email"] = "Please enter a valid email address for your friend";
 messages["default"] = "Please check the value of field '1', it does not validate."; // 1 will be replaced by name of form element
 messages["fullName"] = "Please enter your name";
 messages["full-name"] = "Please enter your name";
 messages["first-name"] = "Please enter your first name";
 messages["surname"] = "Please enter your last name";
 messages["event-name"] = "Please enter the name of this event";
 messages["event-date"] = "Please enter the date this event occurs";
 messages["event-time"] = "Please enter the time this event commences/ends";
 messages["event-venue"] = "Please enter the venue/location of this event";
 messages["name"] = "Please enter your name";
 messages["email"] = "Please enter your (valid) email address";
 messages["address"] = "Please enter your street address";
 messages["yourAddress"] = "Please enter your street address";
 messages["street-address"] = "Please enter your street address";
 messages["letter"] = "Please enter your letter to the editor";
 messages["phone"] = "Please enter your phone number";
 messages["yourPhone"] = "Please enter your phone number";
 messages["yourTown"] = "Please enter your suburb/town";
 messages["suburb"] = "Please enter your suburb/town";
 messages["postcode"] = "Please enter your postcode";
 messages["ltotelephone"] = "Please enter your phone number";
 messages["location"] = "Please enter your location";
 messages["comment"] = "Please enter your comments";
 messages["comments"] = "Please enter your comments";
 messages["yourComments"] = "Please enter your comments";
 messages["my-comment"] = "Please enter your comments";
 messages["rcptName"] = "Please enter a name for recipient";
 messages["rcptEmail"] = "Please enter valid email address for recipient";
 messages["yourName"] = "Please enter a name for sender";
 messages["yourEmail"] = "Please enter a valid email address for sender";
 messages["option"] = "Please select an option";


/* Called on form submit */
function validate(form) {
	var out = "";
	for (var i=0; i<form.elements.length; i++) {
		var element = form.elements[i];
		var validated = true;
		if(element.className.indexOf("is-optional") < 0) {
		        switch (element.type) {
			        case "reset": break;
			        case "submit": break;
			        case "button": break;
			        case "hidden": validated = validateText(element); break;
			        case "password": validated = validateText(element)&&validatePassword(element); break;
			        case "text": validated = validateText(element); break;
			        case "radio": validated = validateRadio(element, form); break;
			        case "textarea": validated = validateText(element); break;
			        case "checkbox": validated = validateCheckbox(element); break;
			        case "select": validated = validateSelect(element); break;
			        case "select-one": validated = validateSelectOne(element); break;
			        case "select-multiple": validated = validateSelectMultiple(element); break;
			        default: break;
		        }
			
		}
		
		if (!validated) {
			if (out.length > 0) out += "<br/>";
			out += ((messages[element.name])?messages[element.name]:messages["default"]).replace(/\1/g, element.name);
			element.className += " error-highlight";
			element.onfocus = function() {
			    this.className = this.className.replace("error-highlight", "");
			}
		} else {
		    if((element.className != "") && (element.className != "undefined") && (element.className != null)) {
		        element.className = element.className.replace("error-highlight", "");
			}
		}
	}
	
	if(document.getElementById("comment")) {
		if(!(assertCharLimit(document.getElementById("comment")))) {
		    return false;
			document.getElementById("comment").className += " error-highlight";
			document.getElementById("comment").onfocus = function() {
			    document.getElementById("comment").className = document.getElementById("comment").className.replace("error-highlight", "");
			}
		}
    }
	
	
	if (out.length > 0) {
	    if(typeof(singleErrorMessage) != "undefined") {
	        out = singleErrorMessage;
	    }
        
		if(!(document.getElementById("single-error"))) {
		    var errorAlert = document.createElement("p");
		    errorAlert.className = "error";
		    errorAlert.id = "single-error";
		} else {
		    var errorAlert = document.getElementById("single-error");
			errorAlert.innerHTML = "";
		}
		//var errorAlertText = document.createTextNode(out);
		//errorAlert.appendChild(errorAlertText);
		errorAlert.innerHTML = out;
		formFieldset = form.getElementsByTagName("fieldset")[0];
		if(formFieldset) {
		    formErrorLegend = formFieldset.getElementsByTagName("legend")[0];
		    if(formErrorLegend) {
		        if((formFieldset.className).indexOf("error-parent") >= 0 ) {
			        formErrorLegend.innerHTML = out;
					formErrorLegend.id = "single-error";
					formErrorLegend.className += " error";
			    }
			} else if((formFieldset.className).indexOf("error-parent") >= 0 ) {
		        formFieldset.insertBefore(errorAlert, formFieldset.firstChild);
		    } else {	    
		        form.insertBefore(errorAlert, form.firstChild);
			} 
		} else {
		    form.insertBefore(errorAlert, form.firstChild);
		}
		return false;
	} else { 
	    // success - try to barf log to hbx
		try {
		    if(window.location.href.match(/story|comments/gi)) {
			    var sid = window.location.href.split(",")[2];
				_hbSet("cv.c5", sid + "-" + hbx.mlc + "|" + hbx.pn);
			    _hbSend();
			}
		} catch(e) {
		    // no hbx available. leave
		}
	    return true;
	}
 } 
 
 function validateRadio(element, theForm) {
	var elements = theForm.getElementsByTagName("input");
	if(validators[element.name]) {
		var redundant = false;
		var firstEncounter = -1;
		for (var i=0; i<elements.length&&!redundant; i++) {
			if(elements[i].type==element.type&&elements[i].name==element.name) {
				if(firstEncounter==-1) {
				    firstEncounter = i;
				}
				if(elements[i].value==element.value&&firstEncounter!=i) {
				    return true;
				}
				if(elements[i].checked) {
				   return true;
				}
				
				// onclick seems to work for label too
				element.onclick = function() {
			        if(document.getElementById("single-error")) {
			            document.getElementById("single-error").style.display = "none";
			        }
			    }
			}
		}
		return false;
	}
	else return true;
 } 
 
function validateText(element) {
    var inputToValidate = element;
    if(element.className.indexOf("honey") >= 0) {
	    inputToValidate = document.getElementById(keySaltEncrypt(element.name, document.getElementById("form-num").value));
    }
	if (validators[element.name]) {
		switch (typeof validators[element.name]) {
			case "string":var re = new RegExp(validators[element.name]);
			    // use the value from the salted input to validate
				return re.test(inputToValidate.value);
			case "function": return validators[element.name](element);
		} return true;
	}
	else return true;
 } 
 
 function validateCheckbox(element) {
	if (validators[element.name]) {
		switch (typeof validators[element.name]) {
			case "string": return (element.checked);
			case "function": return validators[element.name](element);
		} return true;
	}
	else return true;
}
 
 function validateSelect(element) {
    if (validators[element.name]) {
		switch (typeof validators[element.name]) {
			case "string": return (element.value.length > 0);
			case "function": return validators[element.name](element);
		} return true;
     }
     else return true; 
 }
 
 function validateSelectOne(element) {
	if (validators[element.name]) {
		switch (typeof validators[element.name]) {
			case "string": return (element.value.length > 0);
			case "function": return validators[element.name](element);
		} return true;
	}
	else return true;
 } 
 
 function validateSelectMultiple(element) {
	if (validators[element.name]) {
		switch (typeof validators[element.name]) {
			case "string": return (element.value.length > 0);
			case "function": return validators[element.name](element);
		} return true;
	}
	else return true;
 } 
 
 function validatePassword(element) {
	if (matchfields[element.name]) {
		return (element.value==element.form.elements[matchfields[element.name]].value);
	}
	else return true;
 }

 function assertCharLimit(caller) {
     if(caller.className.indexOf("char-limit") < 0) {
	     return true;
	 }
     if (caller.value.length > 1200) { 
		 if(!(document.getElementById("single-error"))) {
		    var errorAlert = document.createElement("p");
		    errorAlert.className = "error";
		    errorAlert.id = "single-error";
		} else {
		    var errorAlert = document.getElementById("single-error");
			errorAlert.innerHTML = "";
		}
		
		errorAlert.innerHTML += "Unable to submit your comment as it exceeds the character limit of 1200 characters. If you need to send a longer message, please send us an email at <a href=\"mailto:news@news.com.au\">news@news.com.au</a>";
		if(document.getElementById("story-your-say")) {
		    parentForm = document.getElementById("story-your-say");
		} else {
		    nd = caller;
		    while(nd.parentNode) {
			    nd = nd.parentNode;
				if(nd.nodeName === "FORM") {
				    parentForm = nd;
					break;
				}
			}
		}
		parentForm.insertBefore(errorAlert, parentForm.firstChild);
		return false;
	 } else {
	     return true;
     }
 }
 
function pseudoRandomString() {
	var chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz";
	var stringLength = 8;
	var rs = "";
	for (var i=0; i<stringLength; i++) {
		var rnum = Math.floor(Math.random() * chars.length);
		rs += chars.substring(rnum,rnum+1);
	}
    return rs;
}
 
function createPollCookie(value) {
	var date = new Date();
	date.setTime(date.getTime()+10000);
	var expires = "; expires="+date.toGMTString();
	document.cookie = "syncopator="+value+expires+"; path=/";
}
 
 function pollValidate(pollForm, samePage) {
	var option = selectedValue(pollForm.option);
	var formAction = pollForm.getAttribute("action");
	if(formAction.indexOf("#") === 0) {
	    formAction = formAction.replace("#", "");
	    var ky = "6";
	    pollForm.setAttribute("action", getFormLocation(formAction, ky));
	}
	var plasNode = document.createElement("input");
	var randText = pseudoRandomString();
	createPollCookie(randText);
	plasNode.setAttribute("type", "hidden");
	plasNode.setAttribute("name", "syncopator");
	plasNode.setAttribute("value", randText);
	pollForm.insertBefore(plasNode, pollForm.childNodes[0]);
	var addr = pollForm.getAttribute("action") + "?option="+option+"&syncopator="+randText;
	if(validate(pollForm)) {
	    if(samePage) {
		    pollForm.submit();
		} else {
		    popUp("nipoll", addr);
		}
	}	
	return false;
}

function getFormLocation(str, pwd) {
    var postLocation = str;
	str = str.split(",")[2];
    if(str == null || str.length < 8) {
        return;
    }
    if(pwd == null || pwd.length <= 0) {
        return;
    }
    var prand = "";
    for(var i=0; i<pwd.length; i++) {
        prand += pwd.charCodeAt(i).toString();
    }
    var sPos = Math.floor(prand.length / 5);
    var mult = parseInt(prand.charAt(sPos) + prand.charAt(sPos*2) + prand.charAt(sPos*3) + prand.charAt(sPos*4) + prand.charAt(sPos*5));
	var incr = Math.round(pwd.length / 2);
	var modu = Math.pow(2, 31) - 1;
	var salt = parseInt(str.substring(str.length - 8, str.length), 16);
	str = str.substring(0, str.length - 8);
	prand += salt;
	while(prand.length > 10) {
	    prand = (parseInt(prand.substring(0, 10)) + parseInt(prand.substring(10, prand.length))).toString();
	}
	prand = (mult * prand + incr) % modu;
	var enc_chr = "";
	var enc_str = "";
	for(var i=0; i<str.length; i+=2) {
	    enc_chr = parseInt(parseInt(str.substring(i, i+2), 16) ^ Math.floor((prand / modu) * 255));
	    enc_str += String.fromCharCode(enc_chr);
	    prand = (mult * prand + incr) % modu;
	}
	
	var tmps = postLocation.split(",")[2];
	var rval = postLocation.replace(tmps, enc_str);
	return rval;
}