
if (document.layers){
        document.captureEvents(Event.KEYPRESS);
}

document.onkeypress = kH;
var dt = new Hashtable();
var colTotals = new Hashtable();
var centsPerMile = 0.45;

function kH(e)
{
        var pK = document.all? window.event.keyCode:e.which;
        return pK != 13;
}

// Validates the submitted form for input errors
function checkForm(_CF_this)
{
	var strErrorMessage = '';

	// Used to store the form object that will need focus
	var objFocusOnField = null;

	var boolErrorsFound = false;

	// If the name field is empty
	if (_CF_this['name'].value == '')
	{
		strErrorMessage = 'Please Enter Your Name';
		objFocusOnField = _CF_this['name'];
	}

	// If the date field is empty
	if (_CF_this['date'].value == '')
	{
		if (strErrorMessage != '') strErrorMessage += '\n';
		strErrorMessage += 'Please Enter the Date';

		if (objFocusOnField == null) objFocusOnField = _CF_this['date'];
	}

	// If the email field is empty
	if (_CF_this['email'].value == '')
	{
		if (strErrorMessage != '') strErrorMessage += '\n';
		strErrorMessage += 'Please Enter Your Email Address';

		if (objFocusOnField == null) objFocusOnField = _CF_this['email'];
	}
	// Else if the value in the email field fails to validate as a real email address
	else if (!validateEmailAddress(_CF_this['email'].value)) {
		if (strErrorMessage != '') strErrorMessage += '\n';
		strErrorMessage += 'Please Enter a Valid Email Address';

		if (objFocusOnField == null) objFocusOnField = _CF_this['email'];
	}

	// If the error messages string is not empty
	if (strErrorMessage != '') {
		alert(strErrorMessage);

		if (objFocusOnField != null) objFocusOnField.focus();

		return false;
	}
	else {
		return true;
	}
}

// Used to validate an email address
function validateEmailAddress(emailFieldValue)
{
	/* The following variable tells the rest of the function whether or not
	to verify that the address ends in a two-letter country or well-known
	TLD.  1 means check it, 0 means don't. */
	var checkTLD = 1;

	/* The following is the list of known TLDs that an e-mail address must end with. */
	var knownDomsPat = /^(com|net|org|edu|int|mil|gov|arpa|biz|aero|name|coop|info|pro|museum)$/;

	/* The following pattern is used to check if the entered e-mail address
	fits the user@domain format.  It also is used to separate the username
	from the domain. */
	var emailPat = /^(.+)@(.+)$/;

	/* The following string represents the pattern for matching all special
	characters.  We don't want to allow special characters in the address. 
	These characters include ( ) < > @ , ; : \ " . [ ] */
	var specialChars = "\\(\\)><@,;:\\\\\\\"\\.\\[\\]";
	
	/* The following string represents the range of characters allowed in a 
	username or domainname.  It really states which chars aren't allowed.*/
	var validChars = "\[^\\s" + specialChars + "\]";

	/* The following pattern applies if the "user" is a quoted string (in
	which case, there are no rules about which characters are allowed
	and which aren't; anything goes).  E.g. "jiminy cricket"@disney.com
	is a legal e-mail address. */
	var quotedUser = "(\"[^\"]*\")";

	/* The following pattern applies for domains that are IP addresses,
	rather than symbolic names.  E.g. joe@[123.124.233.4] is a legal
	e-mail address. NOTE: The square brackets are required. */
	var ipDomainPat = /^\[(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\]$/;
	
	/* The following string represents an atom (basically a series of non-special characters.) */
	var atom = validChars + '+';
	
	/* The following string represents one word in the typical username.
	For example, in john.doe@somewhere.com, john and doe are words.
	Basically, a word is either an atom or quoted string. */
	var word = "(" + atom + "|" + quotedUser + ")";
	
	// The following pattern describes the structure of the user
	var userPat = new RegExp("^" + word + "(\\." + word + ")*$");
	
	/* The following pattern describes the structure of a normal symbolic
	domain, as opposed to ipDomainPat, shown above. */
	var domainPat = new RegExp("^" + atom + "(\\." + atom +")*$");
	
	/* Finally, let's start trying to figure out if the supplied address is valid. */
	/* Begin with the coarse pattern to simply break up user@domain into
	different pieces that are easy to analyze. */
	var matchArray = emailFieldValue.match(emailPat);

	if (matchArray == null) {
		/* Too many/few @'s or something; basically, this address doesn't
		even fit the general mould of a valid e-mail address. */
		//return "Your email address seems incorrect (check @ and .'s)";
		return false;
	}
	var user = matchArray[1];
	var domain = matchArray[2];
	

	// Start by checking that only basic ASCII characters are in the strings (0-127).
	for (i = 0; i < user.length; i++) {
		if (user.charCodeAt(i) > 127) {
			return false;
			//return "Your email address seems to be invalid";
	   }
	}

	for (i = 0; i < domain.length; i++) {
		if (domain.charCodeAt(i) > 127) {
			return false;
			//return "Your email address seems to be invalid";
	   }
	}

	// See if "user" is valid
	if (user.match(userPat) == null) {
		// user is not valid
		return false;
		//return "Your email address seems to be invalid";
	}

	/* if the e-mail address is at an IP address (as opposed to a symbolic
	host name) make sure the IP address is valid. */
	var IPArray = domain.match(ipDomainPat);
	if (IPArray != null) {
		// this is an IP address
		for (var i = 1; i <= 4; i++) {
			if (IPArray[i] > 255) {
				return false;
		   }
		}

		return true;
		//return "";
	}

	// Domain is symbolic name.  Check if it's valid.
	var atomPat = new RegExp("^" + atom + "$");
	var domArr = domain.split(".");
	var len = domArr.length;
	for (i = 0; i < len; i++) {
		if (domArr[i].search(atomPat) == -1) {
			return false;
	   }
	}

	/* domain name seems valid, but now make sure that it ends in a
	known top-level domain (like com, edu, gov) or a two-letter word,
	representing country (uk, nl), and that there's a hostname preceding 
	the domain or country. */
	if (checkTLD && domArr[domArr.length-1].length != 2 && domArr[domArr.length - 1].search(knownDomsPat) == -1) {
		return false;
	}

	// Make sure there's a host name preceding the domain.
	if (len < 2) {
		return false;
	}

	// If we've gotten this far, everything's valid!
	return true;
}

// Used to format a number as currency (0.00)
function formatCurrency(obj)
{
	// If an object was provided
	if (obj != "" && obj != null) {
		var numCurrency = new NumberFormat(obj);
		numCurrency.setPlaces(2);

		if (parseFloat(numCurrency.toFormatted()) == 0) return "";
		else return numCurrency.toFormatted();
	}
	else {
		return "";
	}
}

function calcMiles(evt)
{
    evt = (evt) ? evt : event;

    if (evt) {
		var elem = (evt.target) ? evt.target : evt.srcElement;
		var re = new RegExp(/\d+$/);
		var fieldNumber = re.exec(elem.name);
		var outputField = document.getElementById("miles_dollars" + fieldNumber);

		if (!isNaN(parseFloat(elem.value))) {
			if (elem.value != "" && elem.value != "0") {
				if (outputField != null) {
					dt.add(outputField.name, formatCurrency(elem.value * centsPerMile));
					outputField.value = dt.get(outputField.name);

					updateTotals(evt);
				}
			}
			else if (elem.value == "0") {
				dt.remove(outputField.name);
				elem.value = "";
				outputField.value = "";
				updateTotals(evt);
			}
		}
		else {
			dt.remove(outputField.name);
			elem.value = "";
			outputField.value = "";
			updateTotals(evt);
		}

		updateColumnTotals(outputField);
    }
}

function moveFocus(evt)
{
	evt = (evt) ? evt : event;

    if (evt) {
		var elem = (evt.target) ? evt.target : evt.srcElement;

		var re = new RegExp(/\d+$/);
		var fieldNumber = re.exec(elem.name);
		var focusOnField = document.getElementById("meals" + fieldNumber);

		if (focusOnField != null) {
			focusOnField.focus();
		}
    }
}

function displayDailyTotal(evt)
{
	evt = (evt) ? evt : event;

    if (evt) {
		var elem = (evt.target) ? evt.target : evt.srcElement;

		var re = new RegExp(/\d+$/);
		var fieldNumber = re.exec(elem.name);
		var dailyTotalsField = document.getElementById("daily_total" + fieldNumber);

		dailyTotalsField.value = formatCurrency(dt.get(dailyTotalsField.name));
	}
}

function displayTotal(evt)
{
	evt = (evt) ? evt : event;

    if (evt) {
		var elem = (evt.target) ? evt.target : evt.srcElement;
		var overallDailyTotalsField = getRawObject("overall_daily_total");
		var totalsField = getRawObject("total");

		if (elem != null) {
			if (elem.name == 'rental_car' || elem.name == 'cab' || elem.name == 'hotel_expense')
			{
				if (elem.value != "") {
					dt.add(elem.name, formatCurrency(elem.value));
					elem.value = formatCurrency(elem.value);
				}
			}
		}

		var dt_keys = dt.keys();
		var runningTotal = 0;
		var overAllTotal = 0;

		for (i = 0; i < dt_keys.length; i++) {
			if (dt_keys[i].indexOf("daily_total") != -1 && dt_keys[i].indexOf("overall_daily_total") == -1) {
				runningTotal = parseFloat(runningTotal) + parseFloat(dt.get(dt_keys[i]));
			}
			else if (dt_keys[i].indexOf("overall_daily_total") == -1) {
				overAllTotal = parseFloat(overAllTotal) + parseFloat(dt.get(dt_keys[i]));
			}
		}

		dt.add(overallDailyTotalsField.name, runningTotal);
		overallDailyTotalsField.value = formatCurrency(runningTotal);
		totalsField.value = formatCurrency(overAllTotal);
	}
}

function updateTotals(evt)
{
    evt = (evt) ? evt : event;

    if (evt) {
		var elem = (evt.target) ? evt.target : evt.srcElement;

		var re = new RegExp(/\d+$/);
		var fieldNumber = re.exec(elem.name);
		var dailyTotalsField = document.getElementById('daily_total' + fieldNumber);
		
		if (elem.value != "" && (elem.name.indexOf('charts') == -1 && elem.name.indexOf('hours') == -1 && elem.name.indexOf('mile_traveled') == -1)) {
			dt.add(elem.name, formatCurrency(elem.value));
		}
		var dt_keys = dt.keys();

		var runningTotal = 0;
		for (i = 0; i < dt_keys.length; i++) {
			if (dt_keys[i].indexOf(fieldNumber) != -1 && dt_keys[i].indexOf('daily_total' + fieldNumber) == -1) {
				//alert('Adding: ' + dt_keys[i] + ' - ' + dt.get(dt_keys[i]));
				runningTotal = parseFloat(runningTotal) + parseFloat(dt.get(dt_keys[i]));
			}
		}
		dt.add(dailyTotalsField.name, runningTotal);
		dailyTotalsField.value = formatCurrency(runningTotal);

		displayTotal(getRawObject("overall_daily_total"));
		
		updateColumnTotals(evt);
    }
}

function updateColumnTotals(evt)
{
	var boolIsCurrency = false;
    evt = (evt) ? evt : event;

    if (evt) {
		var elem = (evt.target) ? evt.target : evt.srcElement;
		if (elem == null) elem = evt;
		var columnTotalFieldName;
		var objColumnTotalField;

		var re = new RegExp(/([a-zA-Z_]+)\d+$/);
		if (re.exec(elem.name)[1] != null) {
			columnTotalFieldName = re.exec(elem.name)[1];

			objColumnTotalField = getRawObject(columnTotalFieldName + '_total');
		}

		if (elem.name.indexOf('charts') == -1 && elem.name.indexOf('hours') == -1 && elem.name.indexOf('mile_traveled') == -1) {
			boolIsCurrency = true;
		}

		if (!isNaN(parseInt(elem.value))) {
			// If the value is not an integer, format it as currency
			if (boolIsCurrency) {
				elem.value = formatCurrency(elem.value);
			}

			if (elem.value != "" && elem.value != "0") {
				var tmpValue = elem.value;
				// If the value starts with 0, strip them
				var removeZeros = new RegExp(/^0+(\d+)$/);
				if (removeZeros.exec(elem.value) != null) {
					if (removeZeros.exec(elem.value)[1] != '0') {
						tmpValue = removeZeros.exec(elem.value)[1];
					}
				}

				elem.value = tmpValue;
				colTotals.add(elem.name, elem.value);
			}
			else if (elem.value == "0") {
				colTotals.remove(elem.name);
				elem.value = "";
			}
		}
		else {
			colTotals.remove(elem.name);
			elem.value = "";
		}

		var runningTotal = 0;
		var dt_keys = colTotals.keys();
		for (i = 0; i < dt_keys.length; i++) {
			if (dt_keys[i].indexOf(re.exec(elem.name)[1]) != -1) {
				runningTotal = parseFloat(runningTotal) + parseFloat(colTotals.get(dt_keys[i]));
			}
		}

		if (boolIsCurrency) {
			runningTotal = formatCurrency(runningTotal);
		}

		if (runningTotal == 0)
			objColumnTotalField.value = '';
		else {
			objColumnTotalField.value = runningTotal;
		}
    }
}

function displayColumnTotals(evt)
{
    evt = (evt) ? evt : event;

    if (evt) {
		var elem = (evt.target) ? evt.target : evt.srcElement;
		var columnTotalFieldName;
		var objColumnTotalField;

		var re = new RegExp(/([a-zA-Z_]+)_total$/);
		if (re.exec(elem.name)[1] != null) {
			columnTotalFieldName = re.exec(elem.name)[1];

			objColumnTotalField = document.getElementById(columnTotalFieldName + '_total');
		}

		var runningTotal = 0;
		var dt_keys = colTotals.keys();
		for (i = 0; i < dt_keys.length; i++) {
			if (dt_keys[i].match(columnTotalFieldName)) {
				//alert('Adding: ' + dt_keys[i] + ' - ' + dt.get(dt_keys[i]));
				runningTotal = parseFloat(runningTotal) + parseFloat(colTotals.get(dt_keys[i]));
			}
		}

		if (elem.name.indexOf('charts') == -1 && elem.name.indexOf('hours') == -1 && elem.name.indexOf('mile_traveled') == -1) {
			runningTotal = formatCurrency(runningTotal);
		}

		if (runningTotal == 0)
			objColumnTotalField.value = '';
		else {
			objColumnTotalField.value = runningTotal;
		}
    }
}