function popupImage(image, title, alt)
{
	img = new Image();
	img.src = image;

	lPos = (screen.width) ? (screen.width-img.width+50)/2 : 0;
	tPos = (screen.height) ? (screen.height-img.height+100)/2 : 0;
	title = title ? title:'Image Popup';
	alt = alt ? alt:'';

	popup = this.open('', '_blank', "toolbar=no,width="+(img.width+50)+",height="+(img.height+100)+",left="+lPos+",top="+tPos+",directories=no,status=no,scrollbars=no,resize=no,menubar=no");

	popup.document.write('<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1-transitional.dtd">\n');
	popup.document.write('<html xmlns="http://www.w3.org/1999/xhtml">\n');
	popup.document.write('<head>\n');
	popup.document.write('<title>'+title+'</title>\n');
	popup.document.write('<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>\n');
	popup.document.write('<style type="text/css">\n');
	popup.document.write('body { margin: 0px; background-color: #aaa; }\n');
	popup.document.write('a { text-decoration: none; font: normal 10px Arial, Helvetica, sans-serif}\n');
	popup.document.write('img { border: 1px solid #000; }\n');
	popup.document.write('.description { font: normal 12px Arial, Helvetica, sans-serif; color: #000000; line-height: 20px; text-align:center; }\n');
	popup.document.write('.title { font: bold 12px Arial, Helvetica, sans-serif; color: #000000; text-align: center; }\n');
	popup.document.write('.navigation { text-align:center; }\n');
	popup.document.write('</style>\n');
	popup.document.write('</head>\n');
	popup.document.write('<body>\n');
	popup.document.write('<table cellspacing="0" cellpadding="10" style="text-align:center; height:100%; width:100%; border: 0">\n');
	popup.document.write('<tr><td align="center" class="title">'+title+'</td></tr>\n');
	popup.document.write('<tr><td align="center" class="description"><img src="'+image+'" alt="'+alt+'" /></td></tr>\n');
	popup.document.write('<tr><td align="center" class="navigation"><a href="javascript:window.close();">Close Window</a></td></tr>\n');
	popup.document.write('</table>\n');
	popup.document.write('</body>\n');
	popup.document.write('</html>');

	popup.document.close();
	popup.focus();
}

function popupWindow(url, width, height, name)
{
	lPos = (screen.width) ? (screen.width-width)/2 : 0;
	tPos = (screen.height) ? (screen.height-height)/2 : 0;
	name = (name) ? name : '_blank';

	newWin = this.open(url, name, "toolbar=no,width="+width+",height="+height+",left="+lPos+",top="+tPos+",directories=no,status=no,scrollbars=no,resize=no,menubar=no");
	newWin.focus();
}

function number_format( number, decimals, dec_point, thousands_sep ) 
{
	var n = 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) : "");
}

function addCommas(nStr)
{
	nStr += '';
	x = nStr.split('.');
	x1 = x[0];
	x2 = x.length > 1 ? '.' + x[1] : '';
	var rgx = /(\d+)(\d{3})/;

	while (rgx.test(x1)) {
		x1 = x1.replace(rgx, '$1' + ',' + '$2');
	}
	return x1 + x2;
}

function getCheckedValue(radioObj) {
	if(!radioObj)
		return "";
	var radioLength = radioObj.length;
	if(radioLength == undefined)
		if(radioObj.checked)
			return radioObj.value;
		else
			return "";
	for(var i = 0; i < radioLength; i++) {
		if(radioObj[i].checked) {
			return radioObj[i].value;
		}
	}
	return "";
}

function setCheckedValue(radioObj, newValue) {
	if(!radioObj)
		return;
	var radioLength = radioObj.length;
	if(radioLength == undefined) {
		radioObj.checked = (radioObj.value == newValue.toString());
		return;
	}
	for(var i = 0; i < radioLength; i++) {
		radioObj[i].checked = false;
		if(radioObj[i].value == newValue.toString()) {
			radioObj[i].checked = true;
		}
	}
}

function FormValidator()
{
	this.is_valid = true;
	this.errors = Array();

	this.alpha_regex =  /^[a-zA-Z]+$/;
	this.alpha_numeric_regex = /^[a-zA-Z0-9]+$/;
	this.email_regex = /(\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}\b)/i;
}

FormValidator.prototype.raiseError = function(msg)
{
	this.is_valid = false;
	this.errors[this.errors.length] = msg;
}

FormValidator.prototype.isValid = function() { return this.is_valid; }
FormValidator.prototype.countErrors = function() { return this.errors.length; }
FormValidator.prototype.getErrors = function() { return this.errors; }

FormValidator.prototype.alertErrors = function()
{
	var msg = 'Please correct the following errors:\n';
	for(var i=0;i<this.errors.length;i++) {
		msg += this.errors[i] + '\n';	
	}
	alert(msg);
}

FormValidator.prototype.notEmpty = function(value, msg)
{
	if(value.length == 0) {
		this.raiseError(msg);
		return false;
	}

	return true;
}

FormValidator.prototype.notEquals = function(value, not_value, msg)
{
	if(value == not_value) {
		this.raiseError(msg);
		return false;
	}
	return true;
}

FormValidator.prototype.isNumeric = function(value, msg)
{
	if(isNaN(value)) {
		this.raiseError(msg);
		return false;
	}
	return true;
}

FormValidator.prototype.isWithinNumericRange = function(value, min, max, msg)
{
	if(value < min || value > max) {
		this.raiseError(msg);
		return false;
	}
	return true;
}

FormValidator.prototype.isAlpha = function(value, msg)
{
	return this.matchRegex(value, this.alpha_regex, msg);
}

FormValidator.prototype.isAlphaNumeric = function(value, msg)
{
	return this.matchRegex(value, this.alpha_numeric_regex, msg);
}

FormValidator.prototype.isEmail = function(value, msg)
{
	return this.matchRegex(value, this.email_regex, msg);
}

FormValidator.prototype.matchRegex = function(value, regex, msg)
{
	if(typeof regex != 'Object') {
		regex = new RegExp(regex);
	}
	
	if(value.search(regex) == -1) {
		this.raiseError(msg);
		return false;
	}
	return true;
}

FormValidator.prototype.isChecked = function(field, msg)
{
	for(var i=field.length-1;i>-1;i--) {
		if(field[i].checked) {
			return true;
		}
	}

	this.raiseError(msg);
	return false;
}

/**
 * usage:
 *
 * var limiter = new CharacterLimit(150, document.getElementById('some-input-field'), document.getElementById('some-element'));
 * limiter.update();
 */
CharacterLimit = function(limit, field, track)
{
	this.limit = limit;
	this.field = field;
	this.track = track || false;

	var tmp = this;
	this.field.onkeyup = function() { tmp.update(); }

	this.update = function() {
		if(this.field.value.length > this.limit) {
			alert('Character limit has been reached.');
			this.field.value = this.field.value.substring(0, this.limit);
		}

		if(this.track) {
			this.track.innerHTML = '' + this.limit - this.field.value.length;
		}
	}
}

Querystring = function(qs)  // optionally pass a querystring to parse
{
    this.params = {};

    if (qs == null) qs = location.search.substring(1, location.search.length);
    if (qs.length == 0) return;

    // Turn <plus> back to <space>
	// See: http://www.w3.org/TR/REC-html40/interact/forms.html#h-17.13.4.1
	qs = qs.replace(/\+/g, ' ');
	var args = qs.split('&'); // parse out name/value pairs separated via &

	// split out each name=value pair
	for (var i = 0; i < args.length; i++) {
		var pair = args[i].split('=');
		var name = decodeURIComponent(pair[0]);

		var value = (pair.length==2) ? decodeURIComponent(pair[1]) : name;
		this.params[name] = value;
	}
}

Querystring.prototype.get = function(key, default_) 
{
	var value = this.params[key];
	return (value != null) ? value : default_;
}

Querystring.prototype.contains = function(key) 
{
	var value = this.params[key];
	return (value != null);
}

/**
 * usage:
 * new SupressNewline(element);
 * @element - Either the document element to supress newlines on (ie the body element or a form field) or the 
 * of an element to supress new line characters on.
 */
SupressNewline = function(el)
{
	if(typeof el != 'object') {
		el = document.getElementById(el);
	}

	el.onkeydown = function(ev)
	{
		var key;
		if(window.event)
			key = window.event.keyCode;     //IE
		else
			key = ev.which;     //firefox

		if(key == 13) {
			return false;
		}
		else {
			return true;
		}
	}
}

function AjaxRequest(url, callbackFunction) {

	var that=this;
	this.updating = false;

	this.abort = function() {
		if (that.updating) {
			that.updating=false;
			that.AJAX.abort();
			that.AJAX=null;
		}
	}

	this.send = function(passData,postMethod) {

		if(typeof(passData) == 'object') { passData = that.encodeDataObject(passData); }

		if (that.updating) { return false; }
			that.AJAX = null;
			if (window.XMLHttpRequest) {
				that.AJAX=new XMLHttpRequest();
			} else {
				that.AJAX=new ActiveXObject("Microsoft.XMLHTTP");
			}
			if (that.AJAX==null) {
			return false;
		} else {
			that.AJAX.onreadystatechange = function() {
				if (that.AJAX.readyState==4) {
					that.updating=false;
					that.callback(that.AJAX.responseText,that.AJAX.status,that.AJAX.responseXML);
					that.AJAX=null;
				}
			}
			that.updating = new Date();
			if (/post/i.test(postMethod)) {
				var uri=urlCall+'?'+that.updating.getTime();
				that.AJAX.open("POST", uri, true);
				that.AJAX.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
				that.AJAX.setRequestHeader("Content-Length", passData.length);
				that.AJAX.send(passData);
			} else {
				var uri=urlCall+'?'+passData+'&timestamp='+(that.updating.getTime());
				that.AJAX.open("GET", uri, true);
				that.AJAX.send(null);
			}
			return true;
		}
	}

	var urlCall = url;
	this.callback = callbackFunction || function () { };

}
AjaxRequest.prototype.objectToString = function(data) {
	var r='',j=0;
	for(var i in data) {
		if(j>0){ r = r + '&'; }
		r = r + i + '=' + data[i];
		j++;
	}
	return r;
}
AjaxRequest.prototype.encodeDataObject = function(data) {
	var pairs = [];
	var regexp = /%20/g;

	for(var name in data) {
		var value = data[name].toString();
		var pair = encodeURIComponent(name).replace(regexp, '+') + '=' +
		  encodeURIComponent(value).replace(regexp, '+');
		pairs.push(pair);
	}

	return pairs.join('&');
}
AjaxRequest.prototype.post = function(passData) { this.send(passData, 'POST'); }
AjaxRequest.prototype.get = function(passData) { this.send(passData); }

var Base64 = {
 
	// private property
	_keyStr : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
 
	// public method for encoding
	encode : function (input) {
		var output = "";
		var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
		var i = 0;
 
		input = Base64._utf8_encode(input);
 
		while (i < input.length) {
 
			chr1 = input.charCodeAt(i++);
			chr2 = input.charCodeAt(i++);
			chr3 = input.charCodeAt(i++);
 
			enc1 = chr1 >> 2;
			enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
			enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
			enc4 = chr3 & 63;
 
			if (isNaN(chr2)) {
				enc3 = enc4 = 64;
			} else if (isNaN(chr3)) {
				enc4 = 64;
			}
 
			output = output +
			this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) +
			this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4);
 
		}
 
		return output;
	},
 
	// public method for decoding
	decode : function (input) {
		var output = "";
		var chr1, chr2, chr3;
		var enc1, enc2, enc3, enc4;
		var i = 0;
 
		input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
 
		while (i < input.length) {
 
			enc1 = this._keyStr.indexOf(input.charAt(i++));
			enc2 = this._keyStr.indexOf(input.charAt(i++));
			enc3 = this._keyStr.indexOf(input.charAt(i++));
			enc4 = this._keyStr.indexOf(input.charAt(i++));
 
			chr1 = (enc1 << 2) | (enc2 >> 4);
			chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
			chr3 = ((enc3 & 3) << 6) | enc4;
 
			output = output + String.fromCharCode(chr1);
 
			if (enc3 != 64) {
				output = output + String.fromCharCode(chr2);
			}
			if (enc4 != 64) {
				output = output + String.fromCharCode(chr3);
			}
 
		}
 
		output = Base64._utf8_decode(output);
 
		return output;
 
	},
 
	// private method for UTF-8 encoding
	_utf8_encode : function (string) {
		string = string.replace(/\r\n/g,"\n");
		var utftext = "";
 
		for (var n = 0; n < string.length; n++) {
 
			var c = string.charCodeAt(n);
 
			if (c < 128) {
				utftext += String.fromCharCode(c);
			}
			else if((c > 127) && (c < 2048)) {
				utftext += String.fromCharCode((c >> 6) | 192);
				utftext += String.fromCharCode((c & 63) | 128);
			}
			else {
				utftext += String.fromCharCode((c >> 12) | 224);
				utftext += String.fromCharCode(((c >> 6) & 63) | 128);
				utftext += String.fromCharCode((c & 63) | 128);
			}
 
		}
 
		return utftext;
	},
 
	// private method for UTF-8 decoding
	_utf8_decode : function (utftext) {
		var string = "";
		var i = 0;
		var c = c1 = c2 = 0;
 
		while ( i < utftext.length ) {
 
			c = utftext.charCodeAt(i);
 
			if (c < 128) {
				string += String.fromCharCode(c);
				i++;
			}
			else if((c > 191) && (c < 224)) {
				c2 = utftext.charCodeAt(i+1);
				string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
				i += 2;
			}
			else {
				c2 = utftext.charCodeAt(i+1);
				c3 = utftext.charCodeAt(i+2);
				string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
				i += 3;
			}
 
		}
 
		return string;
	}
}

