function t_page(dir) {
	this.dir = dir;
}
// ***** Generic Functions ***** //
// *** absolute position functions
t_page.prototype.getwindowboundary = function() {
	var w = { x :0, y :0, width :0, height :0 };
	if (window.innerWidth || window.opera) {
		w.x = window.pageXOffset;
     	w.width = window.innerWidth;
     	w.y = window.pageYOffset;
     	w.height = window.innerHeight;
    } else if (document.body) {
		ie = (document.compatMode && document.compatMode!="BackCompat") ? document.documentElement : document.body;
		w.x = ie.scrollLeft;
		w.width = ie.offsetWidth;
     	w.y = ie.scrollTop;
     	w.height = ie.offsetHeight;
    }
	return w;
}
t_page.prototype.getposition = function(element) {
	var r = { x:element.offsetLeft, y:element.offsetTop };
    if (element.offsetParent) {
		var tmp = this.getposition(element.offsetParent);
		r.x += tmp.x;
		r.y += tmp.y;
    }
    return r;
}
// **** cookie functions
t_page.prototype.getcookie = function(c_name)
{
	if (document.cookie.length > 0) {
  		c_start = document.cookie.indexOf(c_name + "=");
  		if (c_start != -1) { 
    		c_start = c_start + c_name.length + 1; 
			c_end = document.cookie.indexOf(";", c_start);
			if (c_end == -1) c_end = document.cookie.length;
			return unescape(document.cookie.substring(c_start,c_end));
    	} 
  	}
	return "";
}
t_page.prototype.setcookie = function(c_name, value, expiredays) {
	var expire = '';
	if (expiredays != undefined && expiredays != null) {
		var exdate = new Date();
		exdate.setDate(exdate.getDate() + expiredays);
		expire = ";expires=" + exdate.toGMTString();
	}
	document.cookie = c_name + "=" + escape(value) + expire;
}
// *** string manipulation functions
t_page.prototype.strip_whitespace = function(input) {
	return input.replace(/^(\s|&nbsp;)+|(\s|&nbsp;)+$/g, '');
}
t_page.prototype.escape_string_quotes = function(value) {
	return value.replace(/'/g, "\\'");
}
t_page.prototype.str_pad = function(input, pad_length, pad_string, pad_type) {
    var str_pad_repeater = function (s, len) {
        var collect = '';
        while (collect.length < len)
			collect += s;
        collect = collect.substr(0,len);
        return collect;
    };
 
  	pad_string = (pad_string != undefined) ? pad_string :' ';
	
	var length_diff = pad_length - input.toString().length;
    if (length_diff > 0) {
        if (pad_type == 'STR_PAD_LEFT') {
			input = str_pad_repeater(pad_string, length_diff) + input; 
		} else if (pad_type == 'STR_PAD_RIGHT') { 
			input = input + str_pad_repeater(pad_string, length_diff);
		} else {//if (pad_type == 'STR_PAD_BOTH') {
            var half = str_pad_repeater(pad_string, Math.ceil(length_diff / 2));
            input = half + input + half;
            input = input.substr(0, pad_length);
        }
    }
    return input;
}
t_page.prototype.remove_str_pad = function(input, pad_char, pad_type) {
	pad_char = (pad_char != undefined) ? pad_char :' ';
	pad_char = (pad_char.length > 1) ? pad_char.charAt(0) :pad_char;
	var pattern;
	if (pad_type == 'STR_PAD_LEFT') {
		pattern = new RegExp('^' + pad_char + '+');
	} else if (pad_type == 'STR_PAD_RIGHT') { 
		pattern = new RegExp(pad_char + '+$');
	} else {//if (pad_type == 'STR_PAD_BOTH') {
	   pattern = new RegExp('^' + pad_char + '+|' + pad_char + '+$');
	}
	
	return input.replace(pattern, '');
}
t_page.prototype.number_round = function(number, decimals) {
    return Math.round(number*Math.pow(10,decimals))/Math.pow(10,decimals);
}
t_page.prototype.number_format = function(number, decimals, dec_point, thousands_sep) {
    var n = parseFloat(number), c = isNaN(decimals = Math.abs(decimals)) ? 2 :decimals;
    var d = (dec_point == undefined) ? "." :dec_point;
    var t = (thousands_sep == undefined) ? "," :thousands_sep, s = n < 0 ? "-" :"";
    var i = parseInt(n = Math.abs(+n || 0).toFixed(c)) + "", j = (j = i.length) > 3 ? j % 3 :0;
    return s + (j ? i.substr(0, j) + t :"") + i.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + t) + (c ? d + Math.abs(n - i).toFixed(c).slice(2) :"");
}
// *** element/event functions
t_page.prototype.get_key_code = function(e) {
	var code = 0;
	if (e.which) code = e.which;
	else if (e.keyCode) code = e.keyCode;
	return code;
}
t_page.prototype.get_mouse_button = function(e) {
	if (e.which) {
		switch(e.which) {
			case 1:return 'left';
			case 2:return 'middle';
			case 3:return 'right';
			default:return 'unknown';
		}
	} else if (e.button) {
		switch(e.button) {
			case 1:return 'left';
			case 4:return 'middle';
			case 2:return 'right';
			default:return 'unknown';
		}
	}
	return 'none';
}
t_page.prototype.get_wheel_delta = function(e) {
	var delta = 0;
	if (e.wheelDelta) { // IE & Opera
		delta = e.wheelDelta / 120;		// In Opera 9, delta differs in sign as compared to IE.
		if (window.opera) delta = -delta;
	} else if (e.detail) { // Mozilla Firefox
		delta = -e.detail / 3;	// In Mozilla, sign of delta is different than in IE. Also, delta is multiple of 3.
	}
	return delta;
}

t_page.prototype.remove_selection = function() {
	if (document.selection && document.selection.empty) {
        document.selection.empty();
    } else if (window.getSelection) {
        window.getSelection().removeAllRanges();
    }
}
// *** misc function
t_page.prototype.set_element_opacity = function(elem, opacity) {
	elem.style.opacity = opacity;
	elem.style.filter = "alpha(opacity=" + (opacity * 100) + ")";
}
t_page.prototype.is_array = function(input) {
	return typeof(input) == 'object' && (input instanceof Array);

}
// *** date & time functions
t_page.prototype.get_today_date = function() {		// return today's date in dd/mm/yyyy format
	var date = new Date();
	return date.getDate() + '/' + (date.getMonth() + 1) + '/' + date.getFullYear();
}
t_page.prototype.get_today_date_time = function() {		// return today's date in dd/mm/yyyy hh:mm:ss format
	var date = new Date();
	return date.getDate() + '/' + (date.getMonth() + 1) + '/' + date.getFullYear() + ' ' + date.getHours() + ':' + date.getMinutes() + ':' + date.getMinutes();
}
//...
t_page.prototype.to_datetime = function(value, null_parse, time_parse) {
	if (this.get_page_class(value) == 'Date') {
		var date = value;
		return date.getFullYear() + '-' + this.str_pad(date.getMonth() + 1, 2, '0', 'STR_PAD_LEFT') + '-' + this.str_pad(date.getDate(), 2, '0', 'STR_PAD_LEFT') + ' ' + date.getHours() + ':' + date.getMinutes() + ':' + date.getSeconds();
	} else if (value.match(/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/)) {
		return value;
	} else if (value.match(/^\d{1,2}\/\d{1,2}\/\d{4}$/)) {
		value = value.split('/');
		value = value[2] + '-' + this.str_pad(value[1],2,'0','STR_PAD_LEFT') + '-' + this.str_pad(value[0],2,'0','STR_PAD_LEFT');
		//...
		if (time_parse == 'end') return value + ' 23:59:59';
		if (time_parse == 'begin') return value + ' 00:00:00';
		//...
		var now = new Date();
		return value + ' ' + now.getHours() + ':' + now.getMinutes() + ':' + now.getSeconds();
	} else {
		if (value == '' && null_parse) return '';
		
		var date = value.match(/^\d+$/) ? new Date(value) :new Date();
		return date.getFullYear() + '-' + this.str_pad(date.getMonth() + 1, 2, '0', 'STR_PAD_LEFT') + '-' + this.str_pad(date.getDate(), 2, '0', 'STR_PAD_LEFT') + ' ' + date.getHours() + ':' + date.getMinutes() + ':' + date.getSeconds();
	}
}
t_page.prototype.to_date = function(value) {
	if (this.get_page_class(value) == 'Date') {
		var date = value;
		return this.str_pad(date.getDate(), 2, '0', 'STR_PAD_LEFT') + '/' + this.str_pad(date.getMonth() + 1, 2, '0', 'STR_PAD_LEFT') + '/' + date.getFullYear();
	} else if (value.match(/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/)) {
		value = value.split(' ');
		value = value[0].split('-');
		return value[2] + '/' + value[1] + '/' + value[0];
	} else if (value.match(/^\d{1,2}\/\d{1,2}\/\d{4}$/)) {
		return value;
	} else {
		var date = value.match(/^\d+$/) ? new Date(value) : new Date();
		return this.str_pad(date.getDate(), 2, '0', 'STR_PAD_LEFT') + '/' + this.str_pad(date.getMonth() + 1, 2, '0', 'STR_PAD_LEFT') + '/' + date.getFullYear();
	}
}
// *** parser functions
t_page.prototype.currency_to_float = function(value) {
	if (value != '') {
		value = value.replace(/[a-zA-Z\$, ]/g, '');
		return isNaN(value) ? 0 : parseFloat(value);
	} return 0;
}
t_page.prototype.float_to_currency = function(value, add) {
	value = isNaN(value) ? 0 : parseFloat(value);
	var result;
	if (value >= 0.01) result = '$' + this.number_format(value, 2);
	else if (value <= -0.01) result = '-$' + this.number_format(Math.abs(value), 2);
	else result = '$' + this.number_format(0, 2);
	return add ? 'AU ' + result : result;
}
t_page.prototype.percent_to_float = function($value) {
	if ($value != '') {
		$value = $value.replace(/[%, ]/g, '');
		return isNaN($value) ? 0 : parseFloat($value);
	} return 0;
}
t_page.prototype.float_to_percent = function(value, precision) {
	value = isNaN(value) ? 0 : parseFloat(value);
	return this.number_format(value, precision) + ' %';
}
t_page.prototype.basename = function(path) {
	var b = path.replace(/^.*[\/\\]/g, '');
    if (typeof(suffix) == 'string' && b.substr(b.length-suffix.length) == suffix)
		b = b.substr(0, b.length-suffix.length);
    return b;
}
t_page.prototype.create_element = function(type, attributes) {
	var elem = null;
	try {
		var create = '<' + type;
		if (attributes != undefined && attributes != null) {
			for(var i in attributes) {
				create += ' ' + attributes[i].name + '="' + attributes[i].value.replace('"', '\"') + '"';
			}
		}
		create += '>';
		elem = document.createElement(create);
	} catch (e) {
		elem = document.createElement(type);
		if (attributes != undefined && attributes != null) {
			for(var i in attributes) {
				elem.setAttribute(attributes[i].name, attributes[i].value);
			}
		}
	}
	return elem;
}
// *** object class
t_page.prototype.get_page_class = function(obj) {
    if (obj && obj.constructor && obj.constructor.toString) {
        var arr = obj.constructor.toString().match(/function\s*(\w+)/);
        if (arr && arr.length == 2) {
            return arr[1];
        }
    }
    return undefined;
}
t_page.prototype.in_array = function(array_obj, value) {
    for(var i in array_obj) {
		if (array_obj[i] == value)
			return true;
	}
	return false;
}
t_page.prototype.ucwords = function(str) {
	return str.toString().replace(/^(.)|\s(.)/g, function ($1) {return $1.toUpperCase();});
}
// ***** Listing Group ***** //
t_page.prototype.ListingGroupExpandCollapse = function(elem) {
	var target = elem.parentNode.parentNode.nextSibling;
	target.style.display = target.style.display ? '' : 'none';
	//...
	if (target.style.display) {
	  var msg = 'Show Group';
	  elem.firstChild.firstChild.firstChild.innerHTML = msg;
	  elem.firstChild.firstChild.lastChild.firstChild.src = this.dir + 'images_2010/icons/expand.png';
	} else {
	  var msg = 'Hide Group';
	  elem.firstChild.firstChild.firstChild.innerHTML = msg;
	  elem.firstChild.firstChild.lastChild.firstChild.src = this.dir + 'images_2010/icons/collapse.png';
	}
}
// ***** Product Upgrades ***** //
t_page.prototype.ProductUpgradeOnClick = function(elem) {
	var id = elem.id.match(/^upgrade_[a-z]+/);
	if (id != null) {
		var set_values = elem.value.split('::');
		var set_price = parseInt(set_values[1]);
		//...
		var product_total_price_elem = document.getElementById('product-total-price');
		var product_price_elem = document.getElementById('product-price-value');
		var total_price = this.currency_to_float(product_price_elem.innerHTML) + set_price;
		//...
		var i = 0;
		var all_inputs = new Array();
		var checked_inputs = new Array();
		while(++i) {
			var input = document.getElementById(id + i);
			if (!input) break;
			//...
			if (!input.disabled) {
				all_inputs[i] = input;
				if (input.checked)
					checked_inputs[checked_inputs.length] = input;
			}
		}
		if (checked_inputs.length > 1) {
			for(var i in all_inputs) {
				var input = all_inputs[i];
				//...
				var upgrade_price_elem = document.getElementById(id + i + '_price');
				if (upgrade_price_elem != null) {
					if (input == elem) {
						input.checked = true;
						//...
						upgrade_price_elem.setAttribute('class', 'bold_txt');
						upgrade_price_elem.innerHTML = '[Included in Price]';
					} else {
						if (input.checked) {
							var old_upgrade_values = input.value.split('::');
							var old_upgrade_price = parseInt(old_upgrade_values[1]);
							total_price -= old_upgrade_price;	
						}
						input.checked = false;
						//...
						var values = input.value.split('::');
						var new_price = parseInt(values[1]) - set_price;
						//...
						upgrade_price_elem.setAttribute('class', '');
						upgrade_price_elem.innerHTML = '[' + ((new_price >= 0) ? 'add $' : 'subtract $') + Math.abs(new_price) + '.00]';
					}
				}
			}
			//...
			total_price = this.float_to_currency(total_price, true);
			if (product_total_price_elem)
				product_total_price_elem.innerHTML = total_price;
			product_price_elem.innerHTML = total_price;
		}
	}	
}
t_page.prototype.ProductUpgradeTextOnClick = function(elem) {
	if (elem.parentNode) {
		var row_elem = elem.parentNode;
		if (row_elem.firstChild && row_elem.firstChild.firstChild) {
			var input_elem = row_elem.firstChild.firstChild;
			if (input_elem.type == 'radio' && !input_elem.disabled && input_elem.onclick) {
				input_elem.checked = true;
				input_elem.onclick();
			}
		}
	}
}
t_page.prototype.ProductUpgradeInit = function(upgrades) {
	upgrades = upgrades.split(' ');
	for(var i in upgrades) {
		var elem = document.getElementById(upgrades[i]);
		if (elem.disabled) {
			var elem_value = elem.value.split('::');
			alert('Upgrade \'' + elem_value[0] + '\' is no longer available!');
		} else {
			elem.checked = true;
			if (elem.onclick)
				elem.onclick();
		}
	}
}
t_page.prototype.ProductDisabledUpgradesInit = function(upgrades_disable) {
	upgrades_disable = upgrades_disable.split(',');
	for(var i in upgrades_disable) {
		var disable_info = upgrades_disable[i].split('=');
		var disabled_item = disable_info[0];
		var upgrade_to = disable_info[1];
		//...
		var disabled_item_elem = document.getElementById(disabled_item);
		var upgrade_to_elem = document.getElementById(upgrade_to);
		if (disabled_item_elem && upgrade_to_elem) {
			var disabled_item_elem_price = document.getElementById(disabled_item + '_price');
			var disabled_item_value = disabled_item_elem.value.split('::');
			var upgrade_to_value = upgrade_to_elem.value.split('::');
			//...
			var new_upgrade_to_value = upgrade_to_value.slice(0);
			new_upgrade_to_value[0] = upgrade_to_value[0] + ' (Free Upgrade)';
			new_upgrade_to_value[1] = disabled_item_value[1];
			upgrade_to_elem.value = new_upgrade_to_value.join('::');
			upgrade_to_elem.checked = true;
			if (upgrade_to_elem.onclick)
				upgrade_to_elem.onclick();
			//...
			disabled_item_elem.checked = false;
			disabled_item_elem.disabled = true;
			if (disabled_item_elem_price) {
				disabled_item_elem_price.innerHTML = '[Out of Stock - FREE upgrade to \'' + upgrade_to_value[0] + '\']';
				disabled_item_elem_price.setAttribute('class', 'red_txt bold_txt');
			}
		}
	}
}
t_page.prototype.ShoppingCartOnSubmit = function(form) {
	var main = document.getElementById('product-main');
	var inputs = main.getElementsByTagName('input');
	var upgrades = new Array();
	for(var i = 0; i < inputs.length; i++) {
		var input = inputs[i];
		if (input.type == 'radio' && !input.disabled && input.checked && input.id.match(/^upgrade_[a-z]+[0-9]+$/) != null)
			upgrades[upgrades.length] = input.id + '=' + input.value;
	}
	if (upgrades.length) {
		upgrades = upgrades.join('||');
		var elem = this.create_element('input', new Array({name:'type',value:'hidden'},{name:'name',value:'upgrades'},{name:'value',value:upgrades}));
		form.appendChild(elem);
	}
}
t_page.prototype.CheckEmailOnSubmit = function(form) {
	if (form.email) {
		email = form.email.value;
		//...
		var server_name = '';
		if (email.search(/\@gmail\.com/i) > 0) {
			server_name = 'GMail';
		} else if (email.search(/\@hotmail\.com/i) > 0) {
			server_name = 'Hotmail';
		} else if (email.search(/\@yahoo\.com/i) > 0) {
			server_name = 'Yahoo';
		} else if (email.search(/\@live\.com/i) > 0) {
			server_name = 'Windows Live';
		}
		//...
		if (server_name) {
			if (confirm('Emails sent to ' + server_name + ' accounts may be filtered into your Junk Mail folder.\n\nWould you like to continue using the email address\n\'' + email + '\'?'))
				return true;
			form.email.value = '';
			if (form.retype_email)
				form.retype_email.value = '';
			form.email.focus();
			return false;
		}
	}
	return true;
}
t_page.prototype.NoPaste = function(elem, e) {
	var key = this.get_key_code(e);
	if ((e.ctrlKey && key == 86) || (e.shiftKey && key == 45)) {
		elem.style.color = elem.style.color ? '' : '#FFF';
		elem.value = '';
		return false;
	}
	return true;
}
t_page.prototype.CookieDetection = function(dir) {
	if (!window.navigator.cookieEnabled) {
		window.location = dir + 'pages/browser_cookies.php';
	}
}
t_page.prototype.ShowElement = function(id) {
	var elem = document.getElementById(id);
	if (elem)
		elem.style.visibility = 'visible';
}
t_page.prototype.ReverseLayout = function() {
	var base1 = document.getElementById('base1');
	var base2 = document.getElementById('base2');
	if (base1 && base2) {
		base1.style.display = base1.style.display == 'none' ? 'block' : 'none';
		base2.style.display = base2.style.display == 'none' ? 'block' : 'none';
	}
}
