//-------------------------------------------------------------------------------
// UI convenience
//-------------------------------------------------------------------------------

// bad can be element or id
function hilite_bad(f, msg) {
	f = $(f);
	if (msg) alert(msg);
	new Effect.Highlight(f, {startcolor:"#FF0000", duration:1.0});
	return false;
	}

// can pass id or classname
function showhide(id,disp) {
	var one = $(id);
	var objs = one ? [ one ] : document.getElementsByClassName(id);
	
	$A(objs).each(function(obj) {
		if (obj.style.visibility == "visible") hide(obj);
		else show(obj,disp);
		});
	}

function show(obj, disp) {
	obj = $(obj);
	obj.style.display = disp;
	obj.style.visibility = "visible";
	}
function hide(obj) {
	obj = $(obj);
	obj.style.display = "none";
	obj.style.visibility = "hidden";
	}

//-------------------------------------------------------------------------------
// value verifiers
//-------------------------------------------------------------------------------
function is_bad_email(val) {
	return ! /^[^@]+@[^@]+$/.test(val);
	}

//-------------------------------------------------------------------------------
// field verifiers
//-------------------------------------------------------------------------------
function verify_nonblank(fields, msg) {
	if (!msg) msg = "Missing required field";
	var bad = fields.find(function(f) { return f.value == ""; });
	return bad ? hilite_bad(bad, msg) : true;
	}

function verify_email(fields, msg) {
	if (!msg) msg = "Bad email address";
	var bad = fields.find(function(f) { return is_bad_email(f.value); });
	return bad ? hilite_bad(bad, msg) : true;
	}

function verify_emaillist(fields, msg) {
	if (!msg) msg = "Bad email address '%s'";
	return ! fields.any(function(f) { 
		var badaddr = f.value.split(/\s*,\s*/).find(function(s) { return is_bad_email(s); });
		return badaddr ? ! hilite_bad(f, sprintf(msg, badaddr)) : false;
		});
	}

// f1/f2 can be element or id
function verify_same(f1, f2, msg) {
	f1 = $(f1); f2 = $(f2);
	if (!msg) msg = "Fields do not match";
	if (f1.value == f2.value) return true;
	return hilite_bad(f1, msg) || hilite_bad(f2);
	}

//-------------------------------------------------------------------------------
// Javascript sprintf
// http://www.webtoolkit.info/
//-------------------------------------------------------------------------------

sprintfWrapper = {
	init : function () {

		if (typeof arguments == "undefined") { return null; }
		if (arguments.length < 1) { return null; }
		if (typeof arguments[0] != "string") { return null; }
		if (typeof RegExp == "undefined") { return null; }

		var string = arguments[0];
		var exp = new RegExp(/(%([%]|(\-)?(\+|\x20)?(0)?(\d+)?(\.(\d)?)?([bcdfosxX])))/g);
		var matches = new Array();
		var strings = new Array();
		var convCount = 0;
		var stringPosStart = 0;
		var stringPosEnd = 0;
		var matchPosEnd = 0;
		var newString = '';
		var match = null;

		while (match = exp.exec(string)) {
			if (match[9]) { convCount += 1; }

			stringPosStart = matchPosEnd;
			stringPosEnd = exp.lastIndex - match[0].length;
			strings[strings.length] = string.substring(stringPosStart, stringPosEnd);

			matchPosEnd = exp.lastIndex;
			matches[matches.length] = {
				match: match[0],
				left: match[3] ? true : false,
				sign: match[4] || '',
				pad: match[5] || ' ',
				min: match[6] || 0,
				precision: match[8],
				code: match[9] || '%',
				negative: parseInt(arguments[convCount]) < 0 ? true : false,
				argument: String(arguments[convCount])
			};
		}
		strings[strings.length] = string.substring(matchPosEnd);

		if (matches.length == 0) { return string; }
		if ((arguments.length - 1) < convCount) { return null; }

		var code = null;
		var match = null;
		var i = null;

		for (i=0; i<matches.length; i++) {

			if (matches[i].code == '%') { substitution = '%' }
			else if (matches[i].code == 'b') {
				matches[i].argument = String(Math.abs(parseInt(matches[i].argument)).toString(2));
				substitution = sprintfWrapper.convert(matches[i], true);
			}
			else if (matches[i].code == 'c') {
				matches[i].argument = String(String.fromCharCode(parseInt(Math.abs(parseInt(matches[i].argument)))));
				substitution = sprintfWrapper.convert(matches[i], true);
			}
			else if (matches[i].code == 'd') {
				matches[i].argument = String(Math.abs(parseInt(matches[i].argument)));
				substitution = sprintfWrapper.convert(matches[i]);
			}
			else if (matches[i].code == 'f') {
				matches[i].argument = String(Math.abs(parseFloat(matches[i].argument)).toFixed(matches[i].precision ? matches[i].precision : 6));
				substitution = sprintfWrapper.convert(matches[i]);
			}
			else if (matches[i].code == 'o') {
				matches[i].argument = String(Math.abs(parseInt(matches[i].argument)).toString(8));
				substitution = sprintfWrapper.convert(matches[i]);
			}
			else if (matches[i].code == 's') {
				matches[i].argument = matches[i].argument.substring(0, matches[i].precision ? matches[i].precision : matches[i].argument.length)
				substitution = sprintfWrapper.convert(matches[i], true);
			}
			else if (matches[i].code == 'x') {
				matches[i].argument = String(Math.abs(parseInt(matches[i].argument)).toString(16));
				substitution = sprintfWrapper.convert(matches[i]);
			}
			else if (matches[i].code == 'X') {
				matches[i].argument = String(Math.abs(parseInt(matches[i].argument)).toString(16));
				substitution = sprintfWrapper.convert(matches[i]).toUpperCase();
			}
			else {
				substitution = matches[i].match;
			}

			newString += strings[i];
			newString += substitution;

		}
		newString += strings[i];

		return newString;

	},

	convert : function(match, nosign){
		if (nosign) {
			match.sign = '';
		} else {
			match.sign = match.negative ? '-' : match.sign;
		}
		var l = match.min - match.argument.length + 1 - match.sign.length;
		var pad = new Array(l < 0 ? 0 : l).join(match.pad);
		if (!match.left) {
			if (match.pad == "0" || nosign) {
				return match.sign + pad + match.argument;
			} else {
				return pad + match.sign + match.argument;
			}
		} else {
			if (match.pad == "0" || nosign) {
				return match.sign + match.argument + pad.replace(/0/g, ' ');
			} else {
				return match.sign + match.argument + pad;
			}
		}
	}
}
sprintf = sprintfWrapper.init;
