/* ============================================================================
*  The function assertValues(array) makes sure that elements of a form have a
*  value. It takes an array of element id's as a value and uses the standard
*  function getElementById(). It will strip the spaces at the beginning and
*  end of the element value. It will return a message string with the string
*  "The <<FIELD>> is missing." for every missing field.
*  ========================================================================= */
function assertValues(requiredParams)
{
	var message = '';

	for (var i = 0; i < requiredParams.length; i++)
	{
		var thisElement = document.getElementById(requiredParams[i]);

		if (thisElement != null)
		{
			var thisValue = thisElement.value;

			// Eliminate white space at beginning and end of string -- uses regular expressions
			thisValue.replace(/^\s*/, "").replace(/\s*$/, "");

			// Check length of string
			if (thisValue.length == 0)
			{
				var display_field = requiredParams[i].replace(/_/g, " ");
				message += "The " + display_field + " is missing.\n"
			}
		}
		else message += "The element [" + requiredParams[i] + "] does not exist.";
	}

	return message;
}


/* ============================================================================
*  The function hasValue will return a boolean, indicating whether the
*  provided element contains a value.
*  NOTE: If the email field is blank, this function will return false.
*  ========================================================================= */
function hasValue(elementid)
{
	var element = document.getElementById(elementid);

	if (element.value.length > 0)
	{
		return true;
	}
	else return false;
}


/* ============================================================================
*  The function isEmail will return a boolean, indicating whether the provided
*  element contains a string that is in valid email format.
*  NOTE: If the email field is blank, this function will return false.
*  ========================================================================= */
function isEmail(elementid)
{
	var element = document.getElementById(elementid);

	if (element.value.length > 0)
	{
		// Check email format -- @'s and .'s
		var emailFilter = /^(.)+@(.)+\.(.)+$/;
		if (!(emailFilter.test(element.value)))
		{
			//alert(name + ' does not appear to be a valid format.');
			return false;
		}

		// Check for illegal email characters
		var illegalChars= /[\(\)\<\>\,\;\:\\\/\"\[\]]/;
		if (element.value.match(illegalChars))
		{
		   //alert(name + ' contains illegal characters.');
		   return false;
		}
	}
	else return false;

	return true;
}


/* ============================================================================
*  The function isNumber will return a boolean, indicating whether the
*  provided element contains a string that is a valid number.
*  NOTE: If the email field is blank, this function will return false.
*  ========================================================================= */
function isNumber(elementid)
{
	var element = document.getElementById(elementid);

	if (element.value.length > 0)
	{
		var anum = /(^\d+$)|(^\d+\.\d+$)/;
		if (! anum.test(element.value))
		{
			//alert(name+' must be a number.  Please do not include commas or non-numeric characters in your submission.');
			return false;
		}
	}
	else return false;

	return true;
}


/* ============================================================================
*  The function isDate will return a boolean, indicating whether the
*  provided element contains a string that is a date in the format of
*  'mm/dd/yyyy' and within the proper numeric date ranges.
*  NOTE: If the email field is blank, this function will return false.
*  ========================================================================= */
function isDate(elementid)
{
	var element = document.getElementById(elementid);

	var validformat = /^\d{2}\/\d{2}\/\d{4}$/; // check for format
	var result = '';

	if (element != null && element.value.length > 0)
	{
		// Check format AND range.
		if (validformat.test(element.value))
		{
			// Check for date ranges
			var monthfield = element.value.split('/')[0];
			var dayfield = element.value.split('/')[1];
			var yearfield = element.value.split('/')[2];
			var dayobj = new Date(yearfield, monthfield - 1, dayfield);

			//alert('Checking date: [' + monthfield + '/' + dayfield + '/' + yearfield
			//	+ '] vs [' + (dayobj.getMonth() + 1)
			//	+ '/' + dayobj.getDate()
			//	+ '/' + dayobj.getFullYear()
			//	+ ']');

			if ((dayobj.getMonth() + 1 != monthfield)
				|| (dayobj.getDate() != dayfield)
				|| (dayobj.getFullYear() != yearfield))
				return false;
		}
		else
		{
			//alert('Failed validformat!');
			return false;
		}
	}
	else
		return false;

	return true;
}


/* ============================================================================
*  The function isPhone will return a boolean, indicating whether the
*  provided element contains a string that is a valid telephone number. It will
*  ignore spaces, periods, and dashes (-) between numbers.
*  NOTE: If the email field is blank, this function will return false.
*  ========================================================================= */
function isPhone(elementid)
{
	var element = document.getElementById(elementid);

	if (element.value.length > 0)
	{
		// Get rid of usual telephone number non-numbers
		// eg. Parenthesis () for area code or spaces, periods, or dashes(-) between number groups.
		var stripped = element.value.replace(/[\(\)\.\-\ ]/g, '');

		var anum = /(^\d+$)|(^\d+\.\d+$)/;

		if (! anum.test(stripped)) return false;
		else if (stripped.length != 10) return false;
	}
	else return false;

	return true;
}


/* ============================================================================
*  The function isZip will return a boolean, indicating whether the
*  provided element contains a string that is a valid zip code.
*  NOTE: If the email field is blank, this function will return false.
*  ========================================================================= */
function isZip(elementid)
{
	var element = document.getElementById(elementid);

	if (element.value.length > 0)
	{
		if (! isNumber(elementid)) return false;
		else if (element.value.length != 5) return false;
	}
	else return false;

	return true;
}


/* ============================================================================
*  The function isYear will return a boolean, indicating whether the
*  provided element contains a 4 digit year that is a valid year number.
*  NOTE: If the email field is blank, this function will return false.
*  ========================================================================= */
function isYear(elementid)
{
	var element = document.getElementById(elementid);

	if (element.value.length > 0)
	{
		if (! isNumber(elementid)) return false;
		else if (element.value.length != 4) return false;
	}
	else return false;

	return true;
}


/* ============================================================================
*  The function isMonth will return a boolean, indicating whether the
*  provided element contains a 2 digit month that is a valid month number.
*  NOTE: If the email field is blank, this function will return false.
*  ========================================================================= */
function isMonth(elementid)
{
	var element = document.getElementById(elementid);

	if (element.value.length > 0)
	{
		if (! isNumber(elementid)) return false;
		else if (element.value.length != 2
				|| element.value > 12)
			return false;
	}
	else return false;

	return true;
}


/* ============================================================================
*  The function isNumeric will return a boolean, indicating whether the
*  required element contains a valid numeric value. It will also automatically
*  use alerts to notify the user of problems.
*  ========================================================================= */
function isNumericAlert(fld, name)
{
	if (fld.value.length)
	{
		if (isNaN(fld.value))
		{
			alert(name+' must be a number.  Please do not include commas or non-numeric characters in your submission.');
			fld.focus();
			fld.select();
			return false;
		}
	}
	return true;
}


/* ============================================================================
*  The function isMoneyAlert will return a boolean, indicating whether the
*  required element contains a valid money value. It will also automatically
*  use alerts to notify the user of problems.
*  ========================================================================= */
function isMoneyAlert(fld, name, xmatch)
{
	// strip all the currency stuff
	money = removeCurrency(fld.value);
	if (fld.value.length)
	{
		if (isNaN(money) || !money.length)
		{
			alert(name+' appears to be an invalid money format.  Please do not include commas or dollar signs in your submission.');
			fld.focus();
			fld.select();
			return false;
		}
		else if (money > 99999)
		{
			alert(name+' is greater than $99,999.  Please enter a lower value.');
			fld.focus();
			fld.select();
			return false;
		}
		else
		{
			money -= 0;
			money = (money == Math.floor(money)) ? money + '.00' : ( (money*10 == Math.floor(money*10)) ?  money + '0' : money);
			// money = Math.round(money*100)/100;
			fld.value = money;
		}
	}

	return true;
}


/* ============================================================================
*  The function isReqDate will return a boolean, indicating whether the
*  required element contains a valid date. It will also automatically
*  use alerts to notify the user of problems.
*  ========================================================================= */
function isDateAlert(fld, name)
{
	if (fld.value.length)
	{
		var dateError = checkDate(fld);
		if (dateError !== '')
		{
			alert(name + ' appears to be invalid: ' + dateError + '\nPlease use the mm/dd/yyyy format.');
			fld.focus();
			fld.select();
			return false;
		}
	}
	else
	{
		alert(name + ' appears to be invalid.\nPlease use the mm/dd/yyyy format.');
	}

	return true;
}


/* ============================================================================
*  The function isEmailAlert will return a boolean, indicating whether the
*  required element contains a valid email address. It will also automatically
*  use alerts to notify the user of problems.
*  ========================================================================= */
function isEmailAlert(fld, name)
{
	if (fld.value.length > 0)
	{
		var error = '';

		var emailFilter = /^(.)+@(.)+\.(.)+$/;

		if (!(emailFilter.test(fld.value)))
			error = name + ' does not appear to be a valid format.';

		var illegalChars= /[\(\)\<\>\,\;\:\\\/\"\[\]]/;
		if (fld.value.match(illegalChars))
			error = name + ' contains illegal characters.';

		if (error != '')
		{
			alert(error);
			fld.focus();
			fld.select();
			return false;
		}
	}
	return true;
}


function isIdenticalAlert(fld1, fld2, label1, label2)
{
	if (fld1.value !== fld2.value)
	{
		alert(label1+' does not match '+label2+'.');
		fld2.focus();
		fld2.select();
		return false;
	}
	return true;
}


/* ============================================================================
*  The function checkReqDate will return a boolean, indicating whether the
*  required element contains a valid date. Called by isDateAlert()
*  ========================================================================= */
function checkDate(input)
{
	var validformat = /^\d{2}\/\d{2}\/\d{4}$/; // check for format
	var result = '';
	if (!validformat.test(input.value))
	{
		result = 'Invalid date format.';
	}
	else
	{ // check for date ranges
		var monthfield = input.value.split('/')[0];
		var dayfield = input.value.split('/')[1];
		var yearfield = input.value.split('/')[2];
		var dayobj = new Date(yearfield, monthfield - 1, dayfield);
		if ((dayobj.getMonth() + 1 != monthfield) || (dayobj.getDate() != dayfield) || (dayobj.getFullYear() != yearfield))
		{
			result = 'Invalid day, month, or year range.';
		}
	}

	return result;
}


/* ============================================================================
*  Removes currency formatting from source string. The strValue parameter is
*  the source string from which currency formatting will be removed. This
*  method will return the source string with commas removed. Called by
*  isMoneyAlert().
*  ========================================================================= */
function removeCurrency( strValue )
{
	var objRegExp = /\(/;
	var strMinus = '';

	//check if negative
	if(objRegExp.test(strValue))
		strMinus = '-';


	objRegExp = /\)|\(|[,]|[a-zA-Z]/g;
	strValue = strValue.replace(objRegExp,'');

	if(strValue.indexOf('$') >= 0)
		strValue = strValue.substring(1, strValue.length);

	return strMinus + strValue;
}


/* ============================================================================
*  The function displayError will display the provided string as an alert
*  message and transfer focus to the corresponding element.
*  ========================================================================= */
function displayError(elementid, message)
{
	var element = document.getElementById(elementid);

	alert(message);
	element.focus();
	element.select();
}


/* ============================================================================
*  The function isRequired will check if a particular field is required, and
*  if so, it will check that it has a value by checking its length.
*  ========================================================================= */
function isRequired(fld, name)
{
	if (fld.disabled) { return true; }
	//if (fld.value == null) alert(name+': null field!');
	if (!fld.value.length)
	{
		alert(name+' is a required field.');
		fld.focus();
		if (!fld.options) fld.select();
		return false;
	}

	return true;
}


/* ============================================================================
*  The function isRequiredSelect will check if a particular select is required,
*  and if so, it will check that it has a value by checking the length of
*  the selected option's value.
*  ========================================================================= */
function isRequiredSelect(fld, name)
{
	// alert('The selection field, ' + name + ', is being checked.');	// DEBUG
	if (fld.selectedIndex == null) alert(name+': null selectedIndex!');
	if (!fld.options[fld.selectedIndex].value.length)
	{
		alert(name+ ' is a required field.');
		fld.focus();
		return false;
	}
	// This is a horrible hack but it's the only way I can think of to keep the
	// data safe.  Bug 2043
	if (name == 'Ship Via')
	{
		if (fld.value == 4)
		{
			alert('Please choose another option for "Ship Via"');
			fld.focus();
			return false;
		}
	}

	return true;
}


/* ============================================================================
*  Message to display when a user is about to navigate away from a page.
*  To remove the prompt, use enableUnloadPrompt(false).
*  Only touch this function if you want to modify the message.
*  ========================================================================= */
function getUnloadPromptMsg()
{
    return "If you leave this page, your changes will be lost.";
}


/* ============================================================================
*  Pass true to this function to prompt the user before leaving a page.
*  Pass false to let the user leave unhindered.
*  Currently, this is added to all the onChange events for Form class elements.
*  ========================================================================= */
function enableUnloadPrompt(enabled)
{
	// this must return a callback function, not simply a string
	window.onbeforeunload = enabled ? getUnloadPromptMsg : null;
}


/* ============================================================================
*  Ugh, I need this redundant function since it appears callback functions
*  cannot have parameters.  I call this from activateUnloadPrompt()
*  ========================================================================= */
function enableUnloadPromptCallback()
{
	// apparently this must return a function call, not simply a string
	window.onbeforeunload = getUnloadPromptMsg;
}


/* ============================================================================
*  Change all the onChange event handlers for the specified form's elements
*  so that they turn on the unload prompt.
*  Note: If an element already has an onChange handler, the existing one will
*  be retained and enableUnloadPromptCallback() will not
*  Note: Don't use this if any elements already have onChange defined
*  If all the forms eventually use the Form class, we can remove this function
*  ========================================================================= */
function activateUnloadPrompt(frm, activate)
{
    for (var i = 0; i < frm.elements.length; i++)
    {
	if (!frm.elements[i].onchange)
	{
		frm.elements[i].onchange = activate ? enableUnloadPromptCallback : null;
	}
    }
}


/* ============================================================================
*  Disallow multiple submissions of the same form.
*  Be sure to run after all other validation or form will break.
*  ========================================================================= */
var submitOnceFlag = false;
function submitOnce(form)
{
	// this is a little lazy, but will ensure that forms do not show the
	// unload prompt as long as they all call submitOnce() (which they should)
	// if all the forms eventually use the Form class, we can remove this line
	// forms that aren't created from Form will still need to have their input
	//    fields call enableUnloadPrompt(true) from onChange
	// maybe submitOnce() should have been called generalValidation()
	enableUnloadPrompt(false);

	if (submitOnceFlag)
	{
		alert('Pressing the button once is enough. Please wait.');
		return false;
	}
	else
	{
		submitOnceFlag = true;
		return true;
	}
}


/* ============================================================================
*  Called by HTML, upon requests to change the page. This function makes sure
*  the requested page is within the bounds of available pages. If it is less
*  than 1, it sets the page number to 1. If it's greater than the allowable
*  max, then the page number is set to max value.
*  ========================================================================= */
function checkCurPage(field_id, max_page)
{
	max_page = parseInt(max_page);
	var field = document.getElementById(field_id);
	if (isNaN(field.value) || (field.value < 1))
		field.value = 1;
	if (field.value > max_page)
		field.value = max_page;
}


/* ============================================================================
*  Called by HTML, upon searches. This just checks to make sure there are at
*  least two characters in the search criteria.
*  ========================================================================= */
function checkSearchMinAlert(field_id)
{
	var el = document.getElementById(field_id);
	if (el.value.length < 2)
	{
		alert('Min. 2 characters required for search. Please try again.');
		return false;
	}
	return true;
}


/* ============================================================================
*  Called by HTML, when requiring a selection to be a particular value after
*  loading the page. The selection will be determined by the value of the
*  options, rather than the text.
*  ========================================================================= */
function selectOptionByValue (formName, targetSelectName, newSelection)
{
	// Use this as a reference to the selection element to manipulate
	var selectObject = eval("document." + formName + "." + targetSelectName);

	if (selectObject != null && newSelection != null)
		for (var j = 0; j < selectObject.options.length; j++)
		{
			if (selectObject.options[j].value == newSelection)
			{
				selectObject.options[j].selected = true;
				break;
			}
		}
}

/* ============================================================================
*  Called by HTML, when transferring a value from one select element to
*  another.
*  ========================================================================= */
function selectTransferSelection(formName, sourceSelectName, targetSelectName)
{
	// Use this as a reference to the selection element to read from
	var sourceSelectObject = eval("document." + formName + "." + sourceSelectName);

	if (sourceSelectObject != null && targetSelectName != null)
		for (var j = 0; j < sourceSelectObject.options.length; j++)
		{
			//alert('Checking ['+sourceSelectObject.options[j].value+'] ['+sourceSelectObject.options[j].selected+']');
			if (sourceSelectObject.options[j].selected == true)
			{
				selectOptionByValue(formName, targetSelectName, sourceSelectObject.options[j].value);
				break;
			}
		}
}
