var PASSWORD_MIN_LENGTH = 6;

String.prototype.trim = function () {
    return this.replace(/^\s*/, "").replace(/\s*$/, "");
}

/**
 * Changes a number-based select, by first nulling its existing option objects, 
 * then creating a new set of option objects, and then reselecting the initially 
 * selected option
 * 
 * @param {String} select is the id of the select whose options we want to change
 * @param {number} number is the number of new option objects you want to create
 * @param {number} initIndex is the initial value of the select's selectedIndex property 
 * @return null
 */
function updateSelectWithNumber(select, number, initIndex) {
    var selectElement = document.getElementById(select);
	
	//null the current select
	for (var i = 0; i < selectElement.options.length; i++) {
		selectElement.options[i] = null;
	}

	//recreate the select
	for (i = 0; i < number; i++) {
		selectElement.options[i] = new Option(i+1,i+1);
		
		//if we can maintain state then do so
		if (i == initIndex) {
			selectElement.options[i].selected = true;
		}
	}
}

/**
 * Function to check that an email form field is 1) populated and 2) a valid email address
 * If it is empty or invalid the function updates the DOM with  an error message retrieved 
 * from an associative array of error messages set in the calling page, and returns false
 * If the email exists and is valid, the function returns true.
 * 
 * @param {String} emailID is the id attribute of the email form field to be validated
 * @param {String} emailErrorID is the id attribute of the HTML element in which you want 
 * to display an error message if validation fails
 * @return Boolean
 */
function checkEmail(emailID,emailErrorID, formID) {
	var email = document.forms[formID][emailID].value;
	//var email = document.getElementById(emailID).value;
	var msg = "";
	if (email.length < 1) {
		msg = errorMessages['missingEmail'];
        setDisplayError(emailErrorID,msg);
	    return false;
	} else {
		if (isValidEmail(email)) {
			setInnerHTML(emailErrorID,'');
			dojo.html.hide(document.getElementById(emailErrorID));
			return true;
		} else {
			msg = errorMessages['invalidEmail'];
	    	setDisplayError(emailErrorID,msg);
			return false;
		}
	}
}

/**
 * Checks an email for validity. Regex taken from Dojo: 
 * @param {String} email is the email address to check for validity
 * @return {boolean}
 */
function isValidEmail(email) {
	var usernameRE = "([\\da-z]+[-._+&'])*[\\da-z]+";
	// Infrastructure top-level domain - only one at present
	var infraRE = "arpa";
	// Generic top-level domains RE.
	var genericRE = 
	"aero|biz|com|coop|edu|gov|info|int|mil|museum|name|net|org|pro|travel|xxx|jobs|mobi|post";
	// Country Code top-level domains RE
	var ccRE = 
	   "ac|ad|ae|af|ag|ai|al|am|an|ao|aq|ar|as|at|au|aw|az|ba|bb|bd|be|bf|bg|bh|bi|bj|bm|bn|bo|br|" +
	   "bs|bt|bv|bw|by|bz|ca|cc|cd|cf|cg|ch|ci|ck|cl|cm|cn|co|cr|cu|cv|cx|cy|cz|de|dj|dk|dm|do|dz|" +
	   "ec|ee|eg|er|eu|es|et|fi|fj|fk|fm|fo|fr|ga|gd|ge|gf|gg|gh|gi|gl|gm|gn|gp|gq|gr|gs|gt|gu|gw|"
	   +
	   "gy|hk|hm|hn|hr|ht|hu|id|ie|il|im|in|io|ir|is|it|je|jm|jo|jp|ke|kg|kh|ki|km|kn|kr|kw|ky|kz|" +
	   "la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|mg|mh|mk|ml|mm|mn|mo|mp|mq|mr|ms|mt|mu|mv|mw|mx|" +
	   "my|mz|na|nc|ne|nf|ng|ni|nl|no|np|nr|nu|nz|om|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|ps|pt|pw|py|qa|" +
	   "re|ro|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sk|sl|sm|sn|sr|st|su|sv|sy|sz|tc|td|tf|tg|th|tj|tk|tm|" +
	   "tn|to|tr|tt|tv|tw|tz|ua|ug|uk|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|ye|yt|yu|za|zm|zw";
	// Build top-level domain RE
	var a = [];
	a.push(infraRE);
	a.push(genericRE);
	a.push(ccRE);
	var tldRE = "(" + a.join("|") + ")";
	var domainNameRE = "([0-9a-zA-Z]([-0-9a-zA-Z]{0,61}[0-9a-zA-Z])?\\.)+" + tldRE;
	var emailAddressRE = usernameRE + "@" + domainNameRE;
	var re = new RegExp("^" + emailAddressRE + "$", "i");
	return re.test(email);
}

/**
 * TODO:
 */
function checkSecretQuestion(secretQuestionID, answerID, secretQuestionErrorID, secretAnswerErrorID) {
	var question = document.getElementById(secretQuestionID);
	var questionSelectedIndex = question.selectedIndex;
	var answer = document.getElementById(answerID);
	
	//if user hasn't chosen question or input answer
	if (questionSelectedIndex == 0 && (answer.value.length < 1 || answer.value == '')) {
		setDisplayError(secretQuestionErrorID, errorMessages['missingQA']);
		setDisplayError(secretAnswerErrorID,errorMessages['missingA']);
		return false;
	//if they have chosen a question but no answer
	} else if (questionSelectedIndex != 0 && (answer.value.length < 1 || answer.value == '')) {
		setInnerHTML(secretQuestionErrorID,"");
		dojo.html.hide(document.getElementById(secretQuestionErrorID));
		setDisplayError(secretAnswerErrorID, errorMessages['missingA']);
		return false;
	//if they have not chosen a question but have entered an answer
	} else if (questionSelectedIndex == 0 && (answer.value.length > 0 || answer.value != '')) {
		setInnerHTML(secretAnswerErrorID,"");
		dojo.html.hide(document.getElementById(secretAnswerErrorID));
		setDisplayError(secretQuestionErrorID, errorMessages['missingQ']);
		return false;
	//otherwise return true
	} else {
		setInnerHTML(secretQuestionErrorID,"");
		dojo.html.hide(document.getElementById(secretQuestionErrorID));
		setInnerHTML(secretAnswerErrorID,"");
		dojo.html.hide(document.getElementById(secretAnswerErrorID));
		return true;
	}
}

function checkFieldHasValueDisplayError(fieldID, errorID, errorMsg) {
	var fieldValue = document.getElementById(fieldID).value;
	if (fieldValue.length < 1) {
		setDisplayError(errorID,errorMsg);
		return false;
	} else {
		setInnerHTML(errorID,"");
		dojo.html.hide(document.getElementById(errorID));
		return true;
	}
}

/**
 * TODO: 
 */
function checkPasswords(passwordID, verifyPasswordID, passwordErrorID, verifyPasswordErrorID) {
	var password = document.getElementById(passwordID);
	var verifyPassword = document.getElementById(verifyPasswordID);

	if (password.value.length >= PASSWORD_MIN_LENGTH && password.value == verifyPassword.value) {
		setInnerHTML(passwordErrorID,"");
		dojo.html.hide(document.getElementById(passwordErrorID));
		return true;
	} else {
		//did the user create a password?
		if (password.value == '' || password.value.length < 1) {
			setDisplayError(passwordErrorID,errorMessages['missingPwd']);
			return false;
		} else {
			//if so, is it 6 characters long?
			if (password.value.length < PASSWORD_MIN_LENGTH) {
				setDisplayError(passwordErrorID,errorMessages['shortPwd']);
				return false;
			} else {
				//if so, did they verify the password?
				if (verifyPassword.value == '' || verifyPassword.value.length < 1) {
					setDisplayError(verifyPasswordErrorID,errorMessages['missingVerifyPwd']);
					return false;
				} else {
					//if so, does the second one match?
					if (password.value != verifyPassword.value) {
						setDisplayError(passwordErrorID,errorMessages['pwdNoMatch']);
						return false;
					} else {
						return true;
					}
				}	
			}
		}
	}
}

/**
 * Function to update the source of the security image in case the user thinks the original one
 * is illegible. We add a timestamp to the src to avoid caching
 * @param {String} element is the ID attribute of the img element whose source we will update
 */
function updateCaptcha(element) {
	var captcha = document.getElementById(element);
	var urlParts = captcha.src.split('?');
	var src = urlParts[0] + '?ts=' + returnTimeStampString();
	captcha.src = src;
}

/**
 * TODO:
 */
function isValidZipCode(value) {
	var zipCodeRE = "/^\d{5}([\-]\d{4})?$/";
	return zipCodeRE.test(value);	
}

/**
 * TODO:
 */
function checkPostalCode(zipElementId, countryElementId, errorDivId) {
	var country = document.getElementById(countryElementId).options[document.getElementById(countryElementId).selectedIndex].value;
	var zip = document.getElementById(zipElementId);
 	if (zip.value != '') {
	 	if (country == 'us') {
	 		if (isValidZipCode(zip)) {
	 			document.getElementById(errorDivId).innerHTML = '';
	  			return true;
	 		} else {
	 			document.getElementById(errorDivId).innerHTML = errorMessages['invalidZip'];
	  			return false;
	 		}
 		} else {
 			document.getElementById(errorDivId).innerHTML = '';
	  		return true;
 		}
 	} else {
 		document.getElementById(errorDivId).innerHTML = errorMessages['missingZip'];
	  	return false;
 	}
}

/**
 * TODO:
 */
function updateCal(yearId, monthId, dayId) {
	var year  = document.getElementById(yearId).options[document.getElementById(yearId).options.selectedIndex].value;
	var monthIndex = document.getElementById(monthId).options[document.getElementById(monthId).options.selectedIndex].value - 1;
	var day = document.getElementById(dayId);
	var numberOfDays = function(data) {
		var numberOfDays = data;
		if (numberOfDays != 0 && !isNaN(numberOfDays)) {
			updateSelectWithNumber(dayId, numberOfDays, day.selectedIndex);
		}
	}
	CalendarValidator.getNumberOfDaysInMonth(year, monthIndex, numberOfDays);
}

/**
 * TODO:
 */
function initCalendar(yearId, dayId){
	var MAXYEAR = new Date().getFullYear() - 13;
	var MINYEAR = MAXYEAR - 100;
	var j = 0;
	var yearSelect = document.getElementById(yearId);
	for (var i = MAXYEAR; i >= MINYEAR; i--) {
		yearSelect.options[j] = new Option(i,i);
		j++;
	}
	updateSelectWithNumber(dayId, 31, 0);
}

/**
 * TODO:
 */
function screenNameHasValue(screenName, screenNameMsg) {
	if (screenName == '') {
		screenNameMsg.innerHTML = errorMessages['screenNameMissing'];
		dojo.html.show(screenNameMsg);
		return false;
	} else {
		return true;
	}
}

/**
 * TODO:
 */
function screenNameIsValidLength(screenName, screenNameMsg) {
	var MAX = 16;
	var MIN = 4;
	if (screenName.length >= MIN && screenName.length <= MAX) {
		return true;
	} else {
		if (screenName.length < 4) {
			msg = errorMessages['screenNameShort'];
		} else {
			msg = errorMessages['screenNameLong'];
		}
		screenNameMsg.innerHTML = msg;
		dojo.html.show(screenNameMsg);
		return false;
	}
}

/**
 * TODO:
 */
function screenNameHasValidCharacters(screenName, screenNameMsg) {
	return true;
}
	   	
/**
 * TODO:
 */
function showScreenNameMessage(data,screenNameMsg) {
	var msg = '';
	var color;
	if(data.indexOf('true') > -1 || data.indexOf('false') > -1 ){
		//true means the screen name is taken
		if (data.indexOf('true') > -1) {
			msg = errorMessages['screenNameUnavailable'];
			color = 'red';
		//otherwise it's available
		} else if (data.indexOf('false') > -1) {
			msg = errorMessages['screenNameAvailable'];
			color = 'green';
		} 
	} else {
		//if there's no data, then there's a problem
		msg = errorMessages['screenNameProblem'];
		color = 'red';
	}
	screenNameMsg.style.color = color;
	screenNameMsg.innerHTML = msg;
	dojo.html.show(screenNameMsg);
}

/**
 * TODO:
 */
function checkScreenNameAvailability(screenName, screenNameMsg) {
	screenNameMsg.innerHTML = errorMessages['pleaseWait'] + '...';	
	dojo.html.show(screenNameMsg);
	var params = new Array();
	params['screenname'] = screenName;
	params['ts'] = returnTimeStampString();
	var bindArgs = {url: securePath + "checkScreenName.json",
		error: function(type, data, evt) {
			showScreenNameMessage(null,screenNameMsg);
		},
		timeoutSeconds: 5,
		timeout: function(type, data, evt){
			showScreenNameMessage(null,screenNameMsg);
		},
		load: function(type, data, evt) {
			showScreenNameMessage(data,screenNameMsg);
		},
		mimetype: "text/plain",
		content: params
	};
	dojo.io.bind(bindArgs);
}

/**
 * TODO:
 */
function checkScreenName(elementId, msgId) {
	var screenName = document.getElementById(elementId).value;
	var screenNameMsg = document.getElementById(msgId);
	if(screenNameHasValue(screenName,screenNameMsg) && screenNameIsValidLength(screenName,screenNameMsg) && screenNameHasValidCharacters(screenName,screenNameMsg)){
		checkScreenNameAvailability(screenName, screenNameMsg);
		return true;
	} else {
		return false;
	}
}

/**
 * TODO:
 */
function modalDispatcher(iframe) {
	if (inIframe()) {
		//refresh the parent
		parent.location.reload();
	} else {
		//send the browser to the service homepage
		parent.location.href = contextPath;
	}
}

/**
 * TODO:
 */
function checkPassword(passwordID, passwordErrorID) {
	var password = document.getElementById(passwordID);
	if (password.value.length >= PASSWORD_MIN_LENGTH) {
		setInnerHTML(passwordErrorID,"");
		dojo.html.hide(document.getElementById(passwordErrorID));
		return true;
	} else {
		if (password.value.length < 1) {
			setDisplayError(passwordErrorID,errorMessages['missingPwd']);
		} else {
			setDisplayError(passwordErrorID,errorMessages['shortPwd']);
		}
		return false;
	}
}

/**
 * TODO:
 */
function checkSearchForm(form) {
	var toCheck = document.forms[form]['titleSearch'].value;
	toCheck = toCheck.trim();
	if (toCheck == '' || toCheck.length < 1 || toCheck == jsLocStrings['search_banner_string']) {
		return false;
	} else {
		return true;
	}
}