if(!console) {
	var console = {};
	console.log = function(msg) { /* do nothing */ }
}

function disableEnterKey(e)
{
     var key;
     if(window.event)
          key = window.event.keyCode;     //IE
     else
          key = e.which;     //firefox

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

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) : "");
}

/*!
 * All-in-one cooke function v1.0
 * http://hexmen.com/blog/2009/03/all-in-one-cookie-function/
 *
 * Copyright (c) 2009 Ash Searle
 * Dual licensed under the MIT and GPL licenses.
 *
 * Usage:
 * cookie('name', 'value'); Set the value of a cookie.
 * cookie('name'); Return the value of a cookie.
 * cookie('name', null); Delete a cookie.
 */
function cookie() {
    var a = arguments, n = a.length, r;
    if (n < 2) {
		var cookies = {}, raw = document.cookie.split(/;\s*/);
		for (var i = 0; i < raw.length; i++) {
			var parsed = raw[i].match(/^([^=]+)=?([^;]*)$/);
			cookies[unescape(parsed[1])] = unescape(parsed[2]) || '';
		}
		r = n ? cookies[a[0]] : cookies;
    } else if (n == 2) {
		r = cookie(a[0], a[1], (a[1] === null) ? -1 : 0);
    } else {
		var i = 0,
	      name = a[i++],
	      value = a[i++],
	      days = (typeof a[i] == 'number') ? a[i++] : (value === null ? -1 : 0),
	      path = (typeof a[i] == 'string') && /^\//.test(a[i]) && a[i++] || '/',
	      domain = (typeof a[i] == 'string') ? a[i++] : document.domain,
	      secure = !!a[i];

		document.cookie = escape(name)+'='+escape(value)+
	      (days?'; expires='+new Date(+new Date+days*86400000).toGMTString():'')+
	      '; path='+path+
	      '; domain='+domain+
	      (secure?'; secure':'');
    }
    return r;
}

/**
 * JavaScript printf/sprintf functions.
 *
 * This code is unrestricted: you are free to use it however you like.
 * 
 * The functions should work as expected, performing left or right alignment,
 * truncating strings, outputting numbers with a required precision etc.
 *
 * For complex cases, these functions follow the Perl implementations of
 * (s)printf, allowing arguments to be passed out-of-order, and to set the
 * precision or length of the output based on arguments instead of fixed
 * numbers.
 *
 * See http://perldoc.perl.org/functions/sprintf.html for more information.
 *
 * Implemented:
 * - zero and space-padding
 * - right and left-alignment,
 * - base X prefix (binary, octal and hex)
 * - positive number prefix
 * - (minimum) width
 * - precision / truncation / maximum width
 * - out of order arguments
 *
 * Not implemented (yet):
 * - vector flag
 * - size (bytes, words, long-words etc.)
 * 
 * Will not implement:
 * - %n or %p (no pass-by-reference in JavaScript)
 *
 * @version 2007.04.27
 * @author Ash Searle
 */
function sprintf() {
    function pad(str, len, chr, leftJustify) {
	var padding = (str.length >= len) ? '' : Array(1 + len - str.length >>> 0).join(chr);
	return leftJustify ? str + padding : padding + str;

    }

    function justify(value, prefix, leftJustify, minWidth, zeroPad) {
	var diff = minWidth - value.length;
	if (diff > 0) {
	    if (leftJustify || !zeroPad) {
		value = pad(value, minWidth, ' ', leftJustify);
	    } else {
		value = value.slice(0, prefix.length) + pad('', diff, '0', true) + value.slice(prefix.length);
	    }
	}
	return value;
    }

    function formatBaseX(value, base, prefix, leftJustify, minWidth, precision, zeroPad) {
	// Note: casts negative numbers to positive ones
	var number = value >>> 0;
	prefix = prefix && number && {'2': '0b', '8': '0', '16': '0x'}[base] || '';
	value = prefix + pad(number.toString(base), precision || 0, '0', false);
	return justify(value, prefix, leftJustify, minWidth, zeroPad);
    }

    function formatString(value, leftJustify, minWidth, precision, zeroPad) {
	if (precision != null) {
	    value = value.slice(0, precision);
	}
	return justify(value, '', leftJustify, minWidth, zeroPad);
    }

    var a = arguments, i = 0, format = a[i++];
    return format.replace(sprintf.regex, function(substring, valueIndex, flags, minWidth, _, precision, type) {
	    if (substring == '%%') return '%';

	    // parse flags
	    var leftJustify = false, positivePrefix = '', zeroPad = false, prefixBaseX = false;
	    for (var j = 0; flags && j < flags.length; j++) switch (flags.charAt(j)) {
		case ' ': positivePrefix = ' '; break;
		case '+': positivePrefix = '+'; break;
		case '-': leftJustify = true; break;
		case '0': zeroPad = true; break;
		case '#': prefixBaseX = true; break;
	    }

	    // parameters may be null, undefined, empty-string or real valued
	    // we want to ignore null, undefined and empty-string values

	    if (!minWidth) {
		minWidth = 0;
	    } else if (minWidth == '*') {
		minWidth = +a[i++];
	    } else if (minWidth.charAt(0) == '*') {
		minWidth = +a[minWidth.slice(1, -1)];
	    } else {
		minWidth = +minWidth;
	    }

	    // Note: undocumented perl feature:
	    if (minWidth < 0) {
		minWidth = -minWidth;
		leftJustify = true;
	    }

	    if (!isFinite(minWidth)) {
		throw new Error('sprintf: (minimum-)width must be finite');
	    }

	    if (!precision) {
		precision = 'fFeE'.indexOf(type) > -1 ? 6 : (type == 'd') ? 0 : void(0);
	    } else if (precision == '*') {
		precision = +a[i++];
	    } else if (precision.charAt(0) == '*') {
		precision = +a[precision.slice(1, -1)];
	    } else {
		precision = +precision;
	    }

	    // grab value using valueIndex if required?
	    var value = valueIndex ? a[valueIndex.slice(0, -1)] : a[i++];

	    switch (type) {
		case 's': return formatString(String(value), leftJustify, minWidth, precision, zeroPad);
		case 'c': return formatString(String.fromCharCode(+value), leftJustify, minWidth, precision, zeroPad);
		case 'b': return formatBaseX(value, 2, prefixBaseX, leftJustify, minWidth, precision, zeroPad);
		case 'o': return formatBaseX(value, 8, prefixBaseX, leftJustify, minWidth, precision, zeroPad);
		case 'x': return formatBaseX(value, 16, prefixBaseX, leftJustify, minWidth, precision, zeroPad);
		case 'X': return formatBaseX(value, 16, prefixBaseX, leftJustify, minWidth, precision, zeroPad).toUpperCase();
		case 'u': return formatBaseX(value, 10, prefixBaseX, leftJustify, minWidth, precision, zeroPad);
		case 'i':
		case 'd': {
			      var number = parseInt(+value);
			      var prefix = number < 0 ? '-' : positivePrefix;
			      value = prefix + pad(String(Math.abs(number)), precision, '0', false);
			      return justify(value, prefix, leftJustify, minWidth, zeroPad);
			  }
		case 'e':
		case 'E':
		case 'f':
		case 'F':
		case 'g':
		case 'G':
		          {
			      var number = +value;
			      var prefix = number < 0 ? '-' : positivePrefix;
			      var method = ['toExponential', 'toFixed', 'toPrecision']['efg'.indexOf(type.toLowerCase())];
			      var textTransform = ['toString', 'toUpperCase']['eEfFgG'.indexOf(type) % 2];
			      value = prefix + Math.abs(number)[method](precision);
			      return justify(value, prefix, leftJustify, minWidth, zeroPad)[textTransform]();
			  }
		default: return substring;
	    }
		    });
}
sprintf.regex = /%%|%(\d+\$)?([-+#0 ]*)(\*\d+\$|\*|\d+)?(\.(\*\d+\$|\*|\d+))?([scboxXuidfegEG])/g;


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;
		}
	}
}

var ConvertDirectoryField = function(field_id)
{
	this.dir_field = document.getElementById(field_id);
}//end ConvertDirectoryField

ConvertDirectoryField.prototype.update = function(value, append)
{
	this.dir_field.value = this.convertString(value);
	if(typeof append != 'undefined') {
		this.dir_field.value = this.dir_field.value + append;
	}
}

ConvertDirectoryField.prototype.convertString = function(value)
{
	value = value.toLowerCase().replace(/&/g, 'and').replace(/[^A-Za-z0-9]/g, '-').replace(/-{2,}/g, '-');
	return value;
}

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;
		}
	}
}
