////////////////////////////////////////////////////////////////////
// Javascript functions for the CircleLending account section
////////////////////////////////////////////////////////////////////

function checkInterestRate(rate) {
	if((rate.value/1) > 15) {
		alert("Notice: CircleLending provides no advice as to interest rates "+
			"appropriate for any transaction or concerning fair-credit rules, disclosure "+
			"requirements, usury, taxation or other laws regarding financial transactions. "+
			"As rules vary by state, CircleLending recommends contacting your professional "+
			"advisors and officials in the state(s) having jurisdiction over you, your "+
			"counterparty(ies) and the agreement you intend to enter.");
	} //end if
} //end function
	
	function checkProposalForm() {
	
		var name = document.form1.sendeename.value;
		var email = document.form1.sendeeemail.value;
		var check = true;
		
		if((email == "") || (name == "")) {
			alert("CircleLending alert:\n\nPlease enter a name and e-mail address to send your proposal.");
			check = false;
		} else {
			if((email.indexOf("@") < 0) || (email.indexOf(".") < 0)) {
				alert("CircleLending alert:\n\nPlease enter a valid e-mail address.\n(For example, johndoe@circlelending.com)");
				check = false;
			} //end if
		} //end if-else
		
		return check;
	
	} //end function checkForm()

	
	function checkForProposer() {

		var proposers = document.form1.proposertype;
		var proposerTypeSelected = false
						
		for(var i=0; i<proposers.length; i++) {
			if(proposers[i].checked) {
				proposerTypeSelected = true;
			} //end if
		} //end for
		
		if(!proposerTypeSelected) {
			alert("Please indicate whether you are the borrower or lender for this loan.\n\n");
			return false;
		} else {
			return checkRequired();
		} //end if

	} //end function checkForProposer
	
	function checkPasswordForm() {
		
		var currentPwd = document.form1.currentPassword;
		var newPwd = document.form1.newPassword;
		var confirmPwd = document.form1.confirmPassword;
		
		var errors = false;
		var errorMessage = "CircleLending Alert:\n\n";
		
		if (currentPwd.value == "") {
			errors = true;
			errorMessage += "Please enter your current password.\n";
		} else { //end id
			if(newPwd.value.length < 7) {
				errors = true;
				errorMessage += "Please use a password of at least 8 characters.\n";
			} else {//end id
				if(confirmPwd.value != newPwd.value) {
					errors = true;
					errorMessage += "The new passwords that you entered do not match.\n";
				} //end id
			} //end if-else
		} //end if-else
		
		if(errors) {
			alert(errorMessage);
			return false;
		} else {
			return true;
		} //end if-else

	} //end checkForm


	function checkSigned(){
		if( document.promissoryNote.read.checked ){
			return true;
		} else {
			alert("In order to continue, you must check the box that confirms you have read your Promissory Note");
			return false;
		}
	}


function checkUserForm() {
	
		var address = document.form1.regaddress1;
		var city = document.form1.regcity;
		var state = document.form1.regstate;
		var zip = document.form1.regzip;
		var ph1 = document.form1.regphone1;
		var ph2 = document.form1.regphone2;
		var ph3 = document.form1.regphone3;
		
		var errors = false;
		var errorMessage = "CircleLending Alert:\n\nPlease enter the following information:\n";
		
		if(address.value == "") {
			errors = true;
			errorMessage += "Your address\n";
		} //end id
		
		if(city.value == "") {
			errors = true;
			errorMessage += "Your city\n";
		} //end id
		
		if(state.value == "") {
			errors = true;
			errorMessage += "Your state\n";
		} //end id
		
		if(zip.value == "") {
			errors = true;
			errorMessage += "Your zip code\n";
		} //end id
		
		if((ph1.value == "") || (ph2.value == "") || (ph3.value == "")) {
			errors = true;
			errorMessage += "Your phone number\n";
		} //end id
		
		if(errors) {
			alert(errorMessage);
			return false;
		} else {
			return true;
		} //end if-else

	} //end checkForm


function checkPastDate() {

		uMonth = document.form1.startmonth.options[document.form1.startmonth.selectedIndex].value; 
		uDay = document.form1.startday.options[document.form1.startday.selectedIndex].value;
		uYear = document.form1.startyear.options[document.form1.startyear.selectedIndex].value;
		
		//check if start date is later than today
		var pastDate = false;
		var d = new Date();
		var month = d.getMonth() + 1;
		var day = d.getDate();
		var year = d.getYear();
					
		//If the user has completed inputing the start date,
		//check if it is later than today.
		if((uYear != "") && (uDay != "") && (uMonth != "")) {
	
			if(uYear < year)
				pastDate = true;
			else if((uMonth < month) && (uYear == year))
					pastDate = true;
				else if((uDay < day) && (uMonth == month) && (uYear == year))
						pastDate = true;
			
			if(pastDate) {
				alert("The start date for this loan has passed.\n\nIf you have existing documentation that you would like included in your CircleLending agreement or if any payments have already been made, please finish drafting your terms and then CALL US AT 1.800.805.2472.");
			} // end if
		
		} //end if
	
	} // end function checkPastDate
	
function checkRequired() {

		var errors = false;
		var errorMessage = "";
		
		var y = document.form1.loantermyears.options[document.form1.loantermyears.selectedIndex].value;
		var m = document.form1.loantermmonths.options[document.form1.loantermmonths.selectedIndex].value;
		var a = document.form1.loanamount.value;
		uMonth = document.form1.startmonth.options[document.form1.startmonth.selectedIndex].value; 
		uDay = document.form1.startday.options[document.form1.startday.selectedIndex].value;
		uYear = document.form1.startyear.options[document.form1.startyear.selectedIndex].value;

		
		if((parseInt(y) == 0) && (parseInt(m)) == 0) {
			errorMessage += "Please enter a valid loan period for your loan.\n\n";
			errors = true;
		} //end if
		
		if(a != "") {
			if(isNaN(a)) {
				errorMessage += "Please enter a loan amount using only numbers.\n\n";
				errors = true;
			} else {
				if(a <= 0) {
					errorMessage += "Please enter a loan amount greater than $0.00.\n\n";
					errors = true;
				}
			} //end if-else
		}
		
		//check that start date is later than today
		var checkDate = false;
		var d = new Date();
		var month = d.getMonth() + 1;
		var day = d.getDate();
		var year = d.getYear();
					
		//If the user's inputed anything as a date, check that it's in the future.
		if((uYear != "") && (uDay != "") && (uMonth != "")) {
	
			if(uYear < year)
				checkDate = true;
			else if((uMonth < month) && (uYear == year))
					checkDate = true;
				else if((uDay < day) && (uMonth == month) && (uYear == year))
						checkDate = true;
			
			var dateString = "" + uMonth + "/" + uDay + "/" + uYear;
			
			if(!isDate(dateString, "M/d/y")) {
				errorMessage += "Please be sure to enter a valid date.\n\n";
				errors = true;
			} else {
				if(checkDate) {
					//errorMessage += "Please be sure to enter a start date later than today.\n\n";
					//errors = true;
				} // end if
			} //end if-else
		
		} //end if
		
		if (errors) {
			alert(errorMessage);
			return false;
		} else {
			return true;
		} //end if-else

	} //end function checkRequired


function checkForDynamicCalc() {

	var a = document.form1.loanamount.value;
	var i = document.form1.loaninterestrate.value;
	var y = document.form1.loantermyears.options[document.form1.loantermyears.selectedIndex].value;
	var m = document.form1.loantermmonths.options[document.form1.loantermmonths.selectedIndex].value;
	var f = document.form1.loanpayments.options[document.form1.loanpayments.selectedIndex].value;
	var p = document.form1.paymentamount.value;
	var np = document.form1.numpayments.value;
	var ia = document.form1.interestamount.value;
	var lib = document.form1.loaninterestbegins.options[document.form1.loaninterestbegins.selectedIndex].value;
	var psd = document.form1.paymentstartdate.options[document.form1.paymentstartdate.selectedIndex].value;
	
	//If user is playing with terms, keep recalculating as they play unless
	//they clear a term
		if ((a != "") && (i != "") && (y != "") && (m != "") && (f != "") && (lib != "") && (psd != "")) {
			checkTerms();
		} else {
			p = "";
			np = "";
			ia = "";
		} //end if-else

} //end function checkForDynamicCalc()




/*checkTerms checks that all calculation-dependent
loan terms are suitable.
	1)Make sure all necessary fields are completed
	2)Check that start date is later than today
	3)Check that loan period is greater than 0 months
	4)Check that payment frequency is divisible by loan term
	
	Arguments: name of the form containing inputs
*/
function checkTerms() {
	
	var errors = false;
	var errorMessage = "CircleLending alert:\n\n";
	
	//assign aliases to form items
	var a = document.form1.loanamount;
	var i = document.form1.loaninterestrate;
	var y = document.form1.loantermyears.options[document.form1.loantermyears.selectedIndex];
	var m = document.form1.loantermmonths.options[document.form1.loantermmonths.selectedIndex];
	var f = document.form1.loanpayments.options[document.form1.loanpayments.selectedIndex];
	var p = document.form1.paymentamount;
	var np = document.form1.numpayments;
	var ia = document.form1.interestamount;
	var lib = document.form1.loaninterestbegins.options[document.form1.loaninterestbegins.selectedIndex];
	var psd = document.form1.paymentstartdate.options[document.form1.paymentstartdate.selectedIndex];

		
	//check that all necessary fields are completed
	if((a.value == "") || (i.value == "") || (y.value == "") || (m.value == "") || (f.value == "") || (lib.value == "") || (psd.value == "")) {
		errorMessage += "In order to calculate your loan terms, you must enter all of the following:\n\nLoan amount\nInterest rate\nLoan period\nPayment frequency\nInterest start date\nPayment start date\n";
		errors = true
	
	} else {
	
	//check that start date is later than today
		var checkDate = false;
		var d = new Date();
		var month = d.getMonth() + 1;
		var day = d.getDate();
		var year = d.getYear();
		
		//user input
		uMonth = document.form1.startmonth.options[document.form1.startmonth.selectedIndex].value; 
		uDay = document.form1.startday.options[document.form1.startday.selectedIndex].value;
		uYear = document.form1.startyear.options[document.form1.startyear.selectedIndex].value;
					
		if(uYear < year)
			checkDate = true;
		else if((uMonth < month) && (uYear == year))
				checkDate = true;
			else if((uDay < day) && (uMonth == month) && (uYear == year))
					checkDate = true;
			
			var dateString = "" + uMonth + "/" + uDay + "/" + uYear;
			
			if(!isDate(dateString, "M/d/y")) {
				errorMessage += "Please be sure to enter a valid date.\n\n";
				errors = true;
			} else {
				if(checkDate) {
					//errorMessage += "Please be sure to enter a start date later than today.\n\n";
					//errors = true;
				} // end if
			} //end if-else
	
	//check that loan period is greater than 0 years 0 months.
		if((parseInt(y.value) == 0) && (parseInt(m.value)) == 0) {
			errorMessage += "Please enter a valid loan period for your loan.\n\n"
			errors = true;
		} //end if
	
	//check that payment frequency is valid for the term of the loan
		//get loan term and payment frequency (in months)
		var years = parseInt(y.value);
		var months = parseInt(m.value);
		var period = (years * 12) + months;
		var frequency = parseInt(f.value);
		var frequencyInMonths = parseInt(getFrequencyInMonths(frequency));

		if((period % frequencyInMonths) > 0) {
			errorMessage += "Please make sure that the payment frequency is suitable for your loan term.  For example, for quarterly payments, your loan period must be a multiple of 3 months.";
			errors = true;
		} //end if
	
	} //end if-else
	
	if(isNaN(a.value)) {
		errorMessage += "Please enter a loan amount using only numbers.\n\n"
		errors = true;
	} else {
		if(a.value <= 0) {
			errorMessage += "Please enter a loan amount greater than $0.00.\n\n";
			errors = true;
		}
	} //end if-else
	
	if(isNaN(i.value)) {
		errorMessage += "Please enter an interest rate using only numbers.\n\n"
		errors = true;
	}
	
	if(errors) {
		/*if( document.form1.status.value == "1" ){
			return true;
		}*/
		alert(errorMessage);
		return false;
	} else {
		calculateTerms(a,i,y,m,f,p,np,ia,lib,psd);
		return true;
	} //end if-else

} //end function checkTerms()




function calculateTerms(a,intrate,y,m,f,p,np,ia,lib,psd) {
	
	var amount = document.form1.loanamount.value;
	var amountArray = new Array;
		
	//if there is a decimal point in the loan
	//amount, delete it and all that's after it.
		if(amount.indexOf(".") > 0) {
			amountArray = amount.split(".");
			amount = "";
			for(var i=0; i<amountArray.length - 1; i++) {
				amount = amount + amountArray[i];
			} //end for
		} //end if
		
	//delete all commas from the loan amount.
		amountArray = amount.split(",");
		amount = "";
		for(var i=0; i<amountArray.length; i++) {
			amount = amount + amountArray[i];
		} //end for
			
	amount = parseInt(amount);
	var interest = parseFloat(intrate.value);
	var years = parseInt(y.value);
	var months = parseInt(m.value);
	var period = (years * 12) + months;
	var frequency = parseInt(f.value);
	var frequencyInMonths = parseInt(getFrequencyInMonths(frequency));
		
	//new variables for post-calculation terms
	var resPaymentAmount, tempamount, tempexp;
	
	//interest capitalization
	
	if (lib.value == 1) {
		if (frequencyInMonths == 0) {
			tempexp = Math.pow(1+interest/100,psd.value-1);
		} else {
			tempexp = Math.pow((1+(interest/100)/(12/frequencyInMonths)),(psd.value-1)*12/frequencyInMonths);	 
		}
		tempamount = round_decimals(amount*tempexp, 2);
	} else {
		tempamount = amount;
		
	}
	
	//*****calculations*****//
	var interest = calculateInterest(tempamount, interest, period, frequencyInMonths);
	var numPayments;
	
	if(frequency == 7) {
		numPayments = 1;
	} else {
		numPayments = period / frequencyInMonths;
	} //end if-else
	
	resPaymentAmount = (amount + interest) / numPayments;
	
			
	p.value = formatNumWithCommas(round_decimals(resPaymentAmount, 2));
	np.value = numPayments;
	ia.value = formatNumWithCommas(round_decimals(interest, 2));
	a.value = amount;

} //end function calculateTerms()





function calculateInterest(a,r,t,f) {
	
	var interest, years, N, T, payment, power;
	
	var amount = parseInt(a);
	var rate = parseFloat(r);
	var term = parseInt(t);
	var frequencyInMonths = parseInt(f);
	
	if(rate == 0) {
		interest = 0;
	} else {
		if(frequencyInMonths == 0) {
			years = term / 12;
			power = Math.pow((1 + (rate/100)),years);
			interest = amount * power - amount;
		} else {
			rate = rate/100;
			N = 12/frequencyInMonths;
			T = term/12;
			power = Math.pow((1+(rate/N)),(N*T));
			payment = (amount * rate)/(N*(1-(1/power)));
			interest = payment*N*T-amount;
		} //end if-else
	} //end if-else
	
	return interest;
	
} //function calculateInterest()






function getFrequencyInMonths(f) {

	var frequency = parseInt(f);
	var frequencyInMonths;
	
	switch (frequency) {
		case 1:
			frequencyInMonths = 1;
			break;
		case 2:
			frequencyInMonths = 3;
			break;
		case 3:
			frequencyInMonths = 6;
			break;
		case 4:
			frequencyInMonths = 12;
			break;			
		default:
			frequencyInMonths = 0;
			break;
	} //end switch statements
	
	return parseInt(frequencyInMonths);

} //end function getFrequencyInMonths(f)



//If user selected a number of years, and hasn't set the months field
//set it to 0
function setMonths() {
	
	var months = document.form1.loantermmonths;
	
	if (months.selectedIndex == 0) {
		months.selectedIndex = 1;
	}
	
} //end function setMonths()



//If user selected a number of months, and hasn't set the years field
//set it to 0
function setYears() {
	
	var years = document.form1.loantermyears;
	
	if (years.selectedIndex == 0) {
		years.selectedIndex = 1;
	}
	
} //end function setYears()





/* This script is Copyright (c) Paul McFedries and 
Logophilia Limited (http://www.mcfedries.com/).
Permission is granted to use this script as long as 
this Copyright notice remains in place.*/

function round_decimals(original_number, decimals) {
    var result1 = original_number * Math.pow(10, decimals)
    var result2 = Math.round(result1)
    var result3 = result2 / Math.pow(10, decimals)
    return pad_with_zeros(result3, decimals)
}

function pad_with_zeros(rounded_value, decimal_places) {

    // Convert the number to a string
    var value_string = rounded_value.toString()
    
    // Locate the decimal point
    var decimal_location = value_string.indexOf(".")

    // Is there a decimal point?
    if (decimal_location == -1) {
        
        // If no, then all decimal places will be padded with 0s
        decimal_part_length = 0
        
        // If decimal_places is greater than zero, tack on a decimal point
        value_string += decimal_places > 0 ? "." : ""
    }
    else {

        // If yes, then only the extra decimal places will be padded with 0s
        decimal_part_length = value_string.length - decimal_location - 1
    }
    
    // Calculate the number of decimal places that need to be padded with 0s
    var pad_total = decimal_places - decimal_part_length
    
    if (pad_total > 0) {
        
        // Pad the string with 0s
        for (var counter = 1; counter <= pad_total; counter++) 
            value_string += "0"
        }
    return value_string
}


function formatNumWithCommas(inputNumber) {

	numberString = inputNumber + '';
	var n = numberString.split(".");
	var decimal = "";
	
	if(n.length > 1) {
		decimal = n[1];
	} //end if
	
	var number = n[0];

    number = '' + number
    if (number.length > 3) {
        var mod = number.length%3;
        var output = (mod > 0 ? (number.substring(0,mod)) : '');
        for (i=0 ; i < Math.floor(number.length/3) ; i++) {
            if ((mod ==0) && (i ==0))
                output+= number.substring(mod+3*i,mod+3*i+3);
            else
                output+= ',' + number.substring(mod+3*i,mod+3*i+3);
        }
        return (output + "." + decimal);
    }
    else return (number + "." + decimal);
}

// ===================================================================
// Author: Matt Kruse <matt@mattkruse.com>
// WWW: http://www.mattkruse.com/
//
// NOTICE: You may use this code for any purpose, commercial or
// private, without any further permission from the author. You may
// remove this notice from your final code if you wish, however it is
// appreciated by the author if at least my web site address is kept.
//
// You may *NOT* re-distribute this code in any way except through its
// use. That means, you can include it in your product, or your web
// site, or any other form where the code is actually being used. You
// may not put the plain javascript up on your site for download or
// include it in your javascript libraries for download. Instead,
// please just point to my URL to ensure the most up-to-date versions
// of the files. Thanks.
// ===================================================================


// ------------------------------------------------------------------
// These functions use the same 'format' strings as the 
// java.text.SimpleDateFormat class, with minor exceptions.
// The format string consists of the following abbreviations:
// 
// Field        | Full Form          | Short Form
// -------------+--------------------+-----------------------
// Year         | yyyy (4 digits)    | yy (2 digits), y (2 or 4 digits)
// Month        | MMM (name or abbr.)| MM (2 digits), M (1 or 2 digits)
// Day of Month | dd (2 digits)      | d (1 or 2 digits)
// Hour (1-12)  | hh (2 digits)      | h (1 or 2 digits)
// Hour (0-23)  | HH (2 digits)      | H (1 or 2 digits)
// Hour (0-11)  | KK (2 digits)      | K (1 or 2 digits)
// Hour (1-24)  | kk (2 digits)      | k (1 or 2 digits)
// Minute       | mm (2 digits)      | m (1 or 2 digits)
// Second       | ss (2 digits)      | s (1 or 2 digits)
// AM/PM        | a                  |
//
// NOTE THE DIFFERENCE BETWEEN MM and mm! Month=MM, not mm!
// Examples:
//  "MMM d, y" matches: January 01, 2000
//                      Dec 1, 1900
//                      Nov 20, 00
//  "M/d/yy"   matches: 01/20/00
//                      9/2/00
//  "MMM dd, yyyy hh:mm:ssa" matches: "January 01, 2000 12:30:45AM"
// ------------------------------------------------------------------

var MONTH_NAMES=new Array('January','February','March','April','May','June','July','August','September','October','November','December','Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec');
function LZ(x) {return(x<0||x>9?"":"0")+x}

// ------------------------------------------------------------------
// isDate ( date_string, format_string )
// Returns true if date string matches format of format string and
// is a valid date. Else returns false.
// It is recommended that you trim whitespace around the value before
// passing it to this function, as whitespace is NOT ignored!
// ------------------------------------------------------------------
function isDate(val,format) {
	var date=getDateFromFormat(val,format);
	if (date==0) { return false; }
	return true;
	}

// -------------------------------------------------------------------
// compareDates(date1,date1format,date2,date2format)
//   Compare two date strings to see which is greater.
//   Returns:
//   1 if date1 is greater than date2
//   0 if date2 is greater than date1 of if they are the same
//  -1 if either of the dates is in an invalid format
// -------------------------------------------------------------------
function compareDates(date1,dateformat1,date2,dateformat2) {
	var d1=getDateFromFormat(date1,dateformat1);
	var d2=getDateFromFormat(date2,dateformat2);
	if (d1==0 || d2==0) {
		return -1;
		}
	else if (d1 > d2) {
		return 1;
		}
	return 0;
	}

// ------------------------------------------------------------------
// formatDate (date_object, format)
// Returns a date in the output format specified.
// The format string uses the same abbreviations as in getDateFromFormat()
// ------------------------------------------------------------------
function formatDate(date,format) {
	format=format+"";
	var result="";
	var i_format=0;
	var c="";
	var token="";
	var y=date.getYear()+"";
	var M=date.getMonth()+1;
	var d=date.getDate();
	var H=date.getHours();
	var m=date.getMinutes();
	var s=date.getSeconds();
	var yyyy,yy,MMM,MM,dd,hh,h,mm,ss,ampm,HH,H,KK,K,kk,k;
	// Convert real date parts into formatted versions
	var value=new Object();
	if (y.length < 4) {y=""+(y-0+1900);}
	value["y"]=""+y;
	value["yyyy"]=y;
	value["yy"]=y.substring(2,4);
	value["M"]=M;
	value["MM"]=LZ(M);
	value["MMM"]=MONTH_NAMES[M-1];
	value["d"]=d;
	value["dd"]=LZ(d);
	value["H"]=H;
	value["HH"]=LZ(H);
	if (H==0){value["h"]=12;}
	else if (H>12){value["h"]=H-12;}
	else {value["h"]=H;}
	value["hh"]=LZ(value["h"]);
	if (H>11){value["K"]=H-12;} else {value["K"]=H;}
	value["k"]=H+1;
	value["KK"]=LZ(value["K"]);
	value["kk"]=LZ(value["k"]);
	if (H > 11) { value["a"]="PM"; }
	else { value["a"]="AM"; }
	value["m"]=m;
	value["mm"]=LZ(m);
	value["s"]=s;
	value["ss"]=LZ(s);
	while (i_format < format.length) {
		c=format.charAt(i_format);
		token="";
		while ((format.charAt(i_format)==c) && (i_format < format.length)) {
			token += format.charAt(i_format++);
			}
		if (value[token] != null) { result=result + value[token]; }
		else { result=result + token; }
		}
	return result;
	}
	
// ------------------------------------------------------------------
// Utility functions for parsing in getDateFromFormat()
// ------------------------------------------------------------------
function _isInteger(val) {
	var digits="1234567890";
	for (var i=0; i < val.length; i++) {
		if (digits.indexOf(val.charAt(i))==-1) { return false; }
		}
	return true;
	}
function _getInt(str,i,minlength,maxlength) {
	for (var x=maxlength; x>=minlength; x--) {
		var token=str.substring(i,i+x);
		if (token.length < minlength) { return null; }
		if (_isInteger(token)) { return token; }
		}
	return null;
	}
	
// ------------------------------------------------------------------
// getDateFromFormat( date_string , format_string )
//
// This function takes a date string and a format string. It matches
// If the date string matches the format string, it returns the 
// getTime() of the date. If it does not match, it returns 0.
// ------------------------------------------------------------------
function getDateFromFormat(val,format) {
	val=val+"";
	format=format+"";
	var i_val=0;
	var i_format=0;
	var c="";
	var token="";
	var token2="";
	var x,y;
	var now=new Date();
	var year=now.getYear();
	var month=now.getMonth()+1;
	var date=now.getDate();
	var hh=now.getHours();
	var mm=now.getMinutes();
	var ss=now.getSeconds();
	var ampm="";
	
	while (i_format < format.length) {
		// Get next token from format string
		c=format.charAt(i_format);
		token="";
		while ((format.charAt(i_format)==c) && (i_format < format.length)) {
			token += format.charAt(i_format++);
			}
		// Extract contents of value based on format token
		if (token=="yyyy" || token=="yy" || token=="y") {
			if (token=="yyyy") { x=4;y=4; }
			if (token=="yy")   { x=2;y=2; }
			if (token=="y")    { x=2;y=4; }
			year=_getInt(val,i_val,x,y);
			if (year==null) { return 0; }
			i_val += year.length;
			if (year.length==2) {
				if (year > 70) { year=1900+(year-0); }
				else { year=2000+(year-0); }
				}
			}
		else if (token=="MMM"){
			month=0;
			for (var i=0; i<MONTH_NAMES.length; i++) {
				var month_name=MONTH_NAMES[i];
				if (val.substring(i_val,i_val+month_name.length).toLowerCase()==month_name.toLowerCase()) {
					month=i+1;
					if (month>12) { month -= 12; }
					i_val += month_name.length;
					break;
					}
				}
			if ((month < 1)||(month>12)){return 0;}
			}
		else if (token=="MM"||token=="M") {
			month=_getInt(val,i_val,token.length,2);
			if(month==null||(month<1)||(month>12)){return 0;}
			i_val+=month.length;}
		else if (token=="dd"||token=="d") {
			date=_getInt(val,i_val,token.length,2);
			if(date==null||(date<1)||(date>31)){return 0;}
			i_val+=date.length;}
		else if (token=="hh"||token=="h") {
			hh=_getInt(val,i_val,token.length,2);
			if(hh==null||(hh<1)||(hh>12)){return 0;}
			i_val+=hh.length;}
		else if (token=="HH"||token=="H") {
			hh=_getInt(val,i_val,token.length,2);
			if(hh==null||(hh<0)||(hh>23)){return 0;}
			i_val+=hh.length;}
		else if (token=="KK"||token=="K") {
			hh=_getInt(val,i_val,token.length,2);
			if(hh==null||(hh<0)||(hh>11)){return 0;}
			i_val+=hh.length;}
		else if (token=="kk"||token=="k") {
			hh=_getInt(val,i_val,token.length,2);
			if(hh==null||(hh<1)||(hh>24)){return 0;}
			i_val+=hh.length;hh--;}
		else if (token=="mm"||token=="m") {
			mm=_getInt(val,i_val,token.length,2);
			if(mm==null||(mm<0)||(mm>59)){return 0;}
			i_val+=mm.length;}
		else if (token=="ss"||token=="s") {
			ss=_getInt(val,i_val,token.length,2);
			if(ss==null||(ss<0)||(ss>59)){return 0;}
			i_val+=ss.length;}
		else if (token=="a") {
			if (val.substring(i_val,i_val+2).toLowerCase()=="am") {ampm="AM";}
			else if (val.substring(i_val,i_val+2).toLowerCase()=="pm") {ampm="PM";}
			else {return 0;}
			i_val+=2;}
		else {
			if (val.substring(i_val,i_val+token.length)!=token) {return 0;}
			else {i_val+=token.length;}
			}
		}
	// If there are any trailing characters left in the value, it doesn't match
	if (i_val != val.length) { return 0; }
	// Is date valid for month?
	if (month==2) {
		// Check for leap year
		if ( ( (year%4==0)&&(year%100 != 0) ) || (year%400==0) ) { // leap year
			if (date > 29){ return false; }
			}
		else { if (date > 28) { return false; } }
		}
	if ((month==4)||(month==6)||(month==9)||(month==11)) {
		if (date > 30) { return false; }
		}
	// Correct hours value
	if (hh<12 && ampm=="PM") { hh+=12; }
	else if (hh>11 && ampm=="AM") { hh-=12; }
	var newdate=new Date(year,month-1,date,hh,mm,ss);
	return newdate.getTime();
	}