// Global Namespace

var AppGlobal;
if (!AppGlobal) AppGlobal = {};

// Declare global variables
AppGlobal.BASE_URL = '/';

// Declare global variables
var win = null;

// Define prototypes
Number.prototype.NaN0 = function() { return isNaN(this)?0:this; }
String.prototype.trim = function() { return this.replace(/^\s+|\s+$/g, ''); };
String.prototype.toInteger = function() { return (isNaN(this)) ? 0 : parseInt(this); };
String.prototype.toCurrency = function() { 
	num = this;
	num = num.toString().replace(/\$|\,/g,'');
	if(isNaN(num)) return "0.00";
	sign = (num == (num = Math.abs(num)));
	num = Math.floor(num*100+0.50000000001);
	cents = num%100;
	num = Math.floor(num/100).toString();
	var rgx = /(\d+)(\d{3})/;
	if (arguments.length > 0) {
		if (arguments[0]) {
			while (rgx.test(num)) num = num.replace(rgx, '$1' + ',' + '$2');
		}
	}
	if(cents<10)
	cents = "0" + cents;
	return num + "." + cents;
};
String.prototype.padLeft = function(len) {
	var char = "0";
	var str = this;
	if (arguments > 1) char = arguments[1];
	for (var x = str.length; x < len; x++) str = char + str + '';
	return str;
};
String.prototype.padRight = function(len) {
	var char = "0";
	var str = this;
	if (arguments > 1) char = arguments[1];
	for (var x = str.length; x < len; x++) str += char + '';
	return str;
};
String.prototype.toDate = function() {
	var val = this.replace(/[-.]/g, "/");
	var tmp = Date.parse(val);
	if (isNaN(tmp)) return this;
	else {
		var yearDigits = (val.match(/\/[0-9]{2}$/) != null) ? 2 : 4;
		d = new Date(tmp);
		if (d.getFullYear() < '1950' && yearDigits == 2) d.setFullYear(d.getFullYear() + 100);
		return parseInt(d.getMonth() + 1) + "/" + d.getDate() + "/" + d.getFullYear();
	}
};
// Strips HTML from a string
String.prototype.stripHTML = function() {
	return this.replace(/<[^>]*>/g, "");
}
// Add to a date
Date.prototype.Add = function(strInterval, intIncrement) {
	if (strInterval != "M" &&
		strInterval != "D" &&
		strInterval != "Y" &&
		strInterval != "h" &&
		strInterval != "m" &&
		strInterval != "ms" &&
		strInterval != "uM" &&
		strInterval != "uD" &&
		strInterval != "uY" &&
		strInterval != "uh" &&
		strInterval != "um" &&
		strInterval != "us" &&
		strInterval != "ums") throw("DateAdd: Second parameter must be M, D, Y, h, m, ms, uM, uD, uY, uh, um, us, or ums");
	if (typeof(intIncrement) != "number") throw("DateAdd: Third parameter must be a number");
	var dtNew = new Date(this.toString());
	switch (strInterval) {
		case "M":
			dtNew.setMonth(parseInt(this.getMonth()) + parseInt(intIncrement));
			break;
		case "D":
			dtNew.setDate(parseInt(this.getDate()) + parseInt(intIncrement));
			break;
		case "Y":
			dtNew.setYear(parseInt(this.getYear()) + parseInt(intIncrement));
			break;
		case "h":
			dtNew.setHours(parseInt(this.getHours()) + parseInt(intIncrement));
			break;
		case "m":
			dtNew.setMinutes(parseInt(this.getMinutes()) + parseInt(intIncrement));
			break;
		case "s":
			dtNew.setSeconds(parseInt(this.getSeconds()) + parseInt(intIncrement));
			break;
		case "ms":
			dtNew.setMilliseconds(parseInt(this.setMilliseconds()) + parseInt(intIncrement));
			break;
		case "uM":
			dtNew.setUTCMonth(parseInt(this.getUTCMonth()) + parseInt(intIncrement));
			break;
		case "uD":
			dtNew.setUTCDate(parseInt(this.getUTCDate()) + parseInt(intIncrement));
			break;
		case "uY":
			dtNew.setUTCFullYear(parseInt(this.getUTCFullYear()) + parseInt(intIncrement));
			break;
		case "uh":
			dtNew.setUTCHours(parseInt(this.getUTCHours()) + parseInt(intIncrement));
			break;
		case "um":
			dtNew.setUTCMinutes(parseInt(this.getUTCMinutes()) + parseInt(intIncrement));
			break;
		case "us":
			dtNew.setUTCSeconds(parseInt(this.getUTCSeconds()) + parseInt(intIncrement));
			break;
		case "ums":
			dtNew.setUTCMilliseconds(parseInt(this.getUTCMilliseconds()) + parseInt(intIncrement));
			break;
	}
	return dtNew;
}
// Gets the week of the year
Date.prototype.getWeek = function() {
	var onejan = new Date(this.getFullYear(),0,1);
	return Math.ceil((((this - onejan) / 86400000) + onejan.getDay()+1)/7);
}
// Gets the day of the year
Date.prototype.getDayOfYear = function() {
	var onejan = new Date(this.getFullYear(),0,1);
	return Math.ceil((this - onejan) / 86400000);
}
// Determine whether or not it's a leap year
Date.prototype.isLeapYear = function() {
	return (new Date(theYear,1,29).getDate() == 29);
}
// Date formatter
Date.prototype.toFormattedString = function(args) {
	var str = "";
	var months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
	var shortmonths = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
	var days = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
	var shortdays = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
	var monthdays = ["31","28","31","30","31","30","31","31","30","31","30","31"];
	var ampm = ["AM", "AM", "AM", "AM", "AM", "AM", "AM", "AM", "AM", "AM", "AM", "AM", "PM", "PM", "PM", "PM", "PM", "PM", "PM", "PM", "PM", "PM", "PM", "PM"];
	var hr12time = ["12", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11"];
	var ordsuff = ["st", "nd", "rd", "th", "th", "th", "th", "th", "th", "th", "th", "th", "th", "th", "th", "th", "th", "th", "th", "th", "st", "nd", "rd", "th", "th", "th", "th", "th", "th", "th", "st"];
	for (var x = 0; x < args.length; x++) {
		switch (args.charAt(x)) {
			// DAY
			case "d":
				// Day of the month, 2 digits with leading zeros - Example: 01 to 31
				str += this.getDate().toString().padLeft(2);
				break;
			case "D":
				// A textual representation of a day, three letters - Example: Mon through Sun
				str += shortdays[this.getDay()];
				break;
			case "j":
				// Day of the month without leading zeros - Example: 1 to 31
				str += this.getDate().toString();
				break;
			case "l":
				// (lowercase 'L') A full textual representation of the day of the week - Example: Sunday through Saturday
				str += days[this.getDay()];
				break;
			case "N":
				// ISO-8601 numeric representation of the day of the week - Example: 1 (for Monday) through 7 (for Sunday)
				str += (this.getDay() + 1).toString();
				break;
			case "S":
				// English ordinal suffix for the day of the month, 2 characters - Example: st, nd, rd or th. Works well with j
				str += ordsuff[this.getDate() - 1];
				break;
			case "w":
				// Numeric representation of the day of the week - Example: 0 (for Sunday) through 6 (for Saturday)
				str += this.getDay().toString();
				break;
			case "z":
				// The day of the year (starting from 0) - Example: 0 through 365
				str += this.getDayOfYear().toString();
				break;
			// WEEK
			case "W":
				// ISO-8601 week number of year, weeks starting on Monday - Example: 42 (the 42nd week in the year)
				str += this.getWeek().toString();
				break;
			// MONTH
			case "F":
				// A full textual representation of a month, such as January or March - Example: January through December
				str += months[this.getMonth()];
				break;
			case "m":
				// Numeric representation of a month, with leading zeros - Example: 01 through 12
				str += (this.getMonth() + 1).toString().padLeft(2);
				break;
			case "M":
				// A short textual representation of a month, three letters - Example: Jan through Dec
				str += shortmonths[this.getMonth()];
				break;
			case "n":
				// Numeric representation of a month, without leading zeros - Example: 1 through 12
				str += (this.getMonth() + 1).toString();
				break;
			case "t":
				// Number of days in the given month - Example: 28 through 31
				str += (this.isLeapYear() && this.getMonth() == 1) ? "29" : monthdays[this.getMonth()];
				break;
			// YEAR
			case "L":
				// Whether it's a leap year - Example: 1 if it is a leap year, 0 otherwise.
				str += (this.isLeapYear()) ? "1" : "0";
				break;
			case "Y":
				// A full numeric representation of a year, 4 digits - Example: 1999 or 2003
				str += this.getFullYear().toString();
				break;
			case "y":
				// A two digit representation of a year - Example: 99 or 03
				str += this.getFullYear().toString().substr(2);
				break;
			// TIME
			case "a":
				// Lowercase Ante meridiem and Post meridiem - Example: am or pm
				str += ampm[this.getHours()].toLowerCase();
				break;
			case "A":
				// Uppercase Ante meridiem and Post meridiem - Example: AM or PM
				str += ampm[this.getHours()];
				break;
			case "g":
				// 12-hour format of an hour without leading zeros - Example: 1 through 12
				str += hr12time[this.getHours()];
				break;
			case "G":
				// 24-hour format of an hour without leading zeros - Example: 0 through 23
				str += this.getHours().toString();
				break;
			case "h":
				// 12-hour format of an hour with leading zeros - Example: 01 through 12
				str += hr12time[this.getHours()].padLeft(2);
				break;
			case "H":
				// 24-hour format of an hour with leading zeros - Example: 00 through 23
				str += this.getHours().toString().padLeft(2);
				break;
			case "i":
				// Minutes with leading zeros - Example: 00 to 59
				str += this.getMinutes().toString().padLeft(2);
				break;
			case "s":
				// Seconds, with leading zeros - Example: 00 through 59
				str += this.getSeconds().toString().padLeft(2);
				break;
			default:
				str += args.charAt(x);
				break;
		}
	}
	return str;
}
// Validates a date in M/D/Y format
String.prototype.isDate = function() {
	return /^\d{1,2}(\/|-)\d{1,2}(\/|-)\d{2,4}$/.test(this);
}
// Validates an integer
String.prototype.isInteger = function() { return (isNaN(this) || this.indexOf('.') != -1) ? false : true; };
// Validates currency
String.prototype.isCurrency = function() {
	return /^\d+(\.\d{2})?$/.test(this);
}

// HTML element positioning global function
AppGlobal.getPos = function(e){
	var left = 0;
	var top  = 0;
	while (e.offsetParent){
		left += e.offsetLeft + (e.currentStyle?(parseInt(e.currentStyle.borderLeftWidth)).NaN0():0);
		top  += e.offsetTop  + (e.currentStyle?(parseInt(e.currentStyle.borderTopWidth)).NaN0():0);
		e     = e.offsetParent;
	}
	left += e.offsetLeft + (e.currentStyle?(parseInt(e.currentStyle.borderLeftWidth)).NaN0():0);
	top  += e.offsetTop  + (e.currentStyle?(parseInt(e.currentStyle.borderTopWidth)).NaN0():0);
	return { x:left, y:top };
}

// Returns a style property for an item
AppGlobal.getStyle = function(oElm, strCssRule){
	var strValue = "";
	if (document.defaultView && document.defaultView.getComputedStyle) strValue = document.defaultView.getComputedStyle(oElm, "").getPropertyValue(strCssRule);
	else if (oElm.currentStyle) {
		strCssRule = strCssRule.replace(/\-(\w)/g, function (strMatch, p1){ return p1.toUpperCase(); });
		strValue = oElm.currentStyle[strCssRule];
	}
	return strValue;
}

// Sets a given element to a text value
AppGlobal.setText = function(elem, text) {
	while (elem.firstChild) elem.removeChild(elem.firstChild);
	elem.appendChild(document.createTextNode(text));
}

// Set up the online payment form
AppGlobal.initPaymentForm = function() {
	var form = document.getElementById("frmPayment");
	var txtMonthlyRent = document.getElementById("txtMonthlyRent");
	var ddlNumMonths = document.getElementById("ddlNumMonths");
	var lblTotalRent = document.getElementById("lblTotalRent");
	if (txtMonthlyRent && ddlNumMonths && lblTotalRent) {
		var calcRent = function() {
			if (txtMonthlyRent.value.isCurrency()) {
				txtMonthlyRent.value = txtMonthlyRent.value.toCurrency();
				var totalRent = (parseFloat(txtMonthlyRent.value) * parseFloat(ddlNumMonths.value));
				if (totalRent > 0) totalRent += 3;
				AppGlobal.setText(lblTotalRent, totalRent.toString().toCurrency(true));
			} else alert("Please enter a valid rent amount in dollars and cents");
		}
		txtMonthlyRent.onchange = calcRent;
		ddlNumMonths.onchange = calcRent;	
	}
}

// OnLoad directive
AppGlobal.onLoad = function() {
	if (document.getElementById("frmPayment")) AppGlobal.initPaymentForm();
}

// Browser detection methods
var Browser = {
	detect: function () {
		this.NAME = this.searchString(this.dataBrowser) || "An unknown browser";
		this.VERSION = this.searchVersion(navigator.userAgent) || this.searchVersion(navigator.appVersion) || "an unknown version";
		this.OS = this.searchString(this.dataOS) || "an unknown OS";
	},
	searchString: function (data) {
		for (var i=0;i<data.length;i++)	{
			var dataString = data[i].string;
			var dataProp = data[i].prop;
			this.versionSearchString = data[i].versionSearch || data[i].identity;
			if (dataString) {
				if (dataString.indexOf(data[i].subString) != -1) return data[i].identity;
			}
			else if (dataProp) return data[i].identity;
		}
	},
	searchVersion: function (dataString) {
		var index = dataString.indexOf(this.versionSearchString);
		if (index == -1) return;
		return parseFloat(dataString.substring(index+this.versionSearchString.length+1));
	},
	dataBrowser: [
		// Google Chrome
		{ string: navigator.userAgent, subString: "Chrome", identity: "Chrome" },
		// OmniWeb
		{ string: navigator.userAgent, subString: "OmniWeb", versionSearch: "OmniWeb/", identity: "OmniWeb" },
		// Safari
		{ string: navigator.vendor, subString: "Apple", identity: "Safari", versionSearch: "Version" },
		// Opera
		{ prop: window.opera, identity: "Opera" },
		// iCab
		{ string: navigator.vendor, subString: "iCab", identity: "iCab" },
		// Konqueror
		{ string: navigator.vendor, subString: "KDE", identity: "Konqueror" },
		// Firefox
		{ string: navigator.userAgent, subString: "Firefox", identity: "Firefox" },
		// Camino
		{ string: navigator.vendor, subString: "Camino", identity: "Camino" },
		// Newer Netscapes (6+)
		{ string: navigator.userAgent, subString: "Netscape", identity: "Netscape" },
		// Internet Explorer
		{ string: navigator.userAgent, subString: "MSIE", identity: "Internet Explorer", versionSearch: "MSIE" },
		// Generic Gecko-based Mozilla browsers
		{ string: navigator.userAgent, subString: "Gecko", identity: "Mozilla", versionSearch: "rv" },
		// Older Netscapes (4-)
		{ string: navigator.userAgent, subString: "Mozilla", identity: "Netscape", versionSearch: "Mozilla" }
	],
	dataOS : [
		// Microsoft Windows
		{ string: navigator.platform, subString: "Win", identity: "Windows" },
		// Mac OS
		{ string: navigator.platform, subString: "Mac", identity: "Mac" },
		// Linux
		{ string: navigator.platform, subString: "Linux", identity: "Linux" }
	]

};
Browser.detect();


// Assign onload parameter
if (window.addEventListener) window.addEventListener("load", AppGlobal.onLoad, false);
else if (window.attachEvent) window.attachEvent("onload", AppGlobal.onLoad);

