// Global translation
_trans = new Array();
function _( str ) {
	if ( _trans[str] ) return _trans[str];
	return str;
}

function formValidator( form ) {
	this.form = form;
	this.rules = new Array();
	this.errors = new Array();
}

formValidator.prototype.addTranslation = function( from, to ) {
	_trans[from] = to;
}

formValidator.prototype.getContext = function() {
	var field = $("#"+this.form+"_context_");
	return field.val();
}

formValidator.prototype.resetContext = function() {
	$("#"+this.form+"_context_").val('');
}

formValidator.prototype.addFieldRule = function( field, type ) {
	var args = arguments[2];
	
	if ( !this.rules[field] ) this.rules[field] = new Array();
	this.rules[field].push( [type, args] );
}

formValidator.prototype.reset = function() {
	var containers = $( ".ui_validate" );
	containers.html("");
	containers.hide();
	this.errors = new Array();
}

formValidator.prototype.checkForm = function( debug ) {
	if ( debug ) debugger;
	
	this.reset();
	var context = this.getContext();
	var form = document.forms[this.formname];
	var valid = true;
	for ( var p in this.rules ) {
		if ( typeof(this.rules[p]) == "object" ) {
			var result = this.checkField( p, context );
			if ( !result.isValid ) {
				this.errors.push( [p, result.errors] );
				if ( valid ) {
					var field = $("#"+p)[0];
					if ( field ) {
						try {
							// IE doesn't like focusing hidden fields
							field.focus();
						}
						catch(e) {
							
						}
					}
				}
			}
			valid = valid && result.isValid;
		}
	}
	if ( !valid ) {
		this.printErrors()
	}
	this.resetContext();
	return valid;
}

formValidator.prototype.checkSingleField = function( field ) {
	this.reset();
	var context = this.getContext();
	var form = document.forms[this.formname];
	var valid = true;
	for ( var p in this.rules ) {
		if ( typeof(this.rules[p]) == "object" ) {
			if ( p == field ) {
				var result = this.checkField( p, context );
				if ( !result.isValid ) {
					this.errors.push( [p, result.errors] );
					if ( valid ) {
						var field = $("#"+p)[0];
						if ( field ) {
							try {
								// IE doesn't like focusing hidden fields
								field.focus();
							}
							catch(e) {
								
							}
						}
					}
				}
				valid = valid && result.isValid;
			}
		}
	}
	if ( !valid ) {
		this.printErrors()
	}
	this.resetContext();
	return valid;
}

formValidator.prototype.checkField = function( field, context ) {
	if ( !this.rules[field] ) return true;
	
	var result = {
		isValid: true,
		errors: []
	}
	for ( var i=0; i < this.rules[field].length; i++ ) {
		var rule = this.rules[field][i];
		if ( this.validate[rule[0]] ) {
			var args = rule[1];
			if ( !args.context || args.context == context ) {
				var validation = this.validate[rule[0]]( field, args );
				if ( !validation.isValid ) {
					result.isValid = false;
					result.errors.push( validation.msg );
				}
			}
		}
		else {
			alert( "No such validator: "+rule[0] );
		}
	}
	return result;
}

formValidator.prototype.printErrors = function(  ) {
	for ( var i=0; i < this.errors.length; i++ ) {
		var error = this.errors[i];
		
		var container = $( "#validate_feedback_"+error[0] );
		container.html("");
		var displayError = false;
		for ( var j=0; j < error[1].length; j++ ) {
			container.append( "<div class=\"ui_error\">"+error[1][j]+"</div>" );
			displayError = true;
		}
		
		if ( displayError ) {
			container.addClass( "ui_validate_error" );
			container.show();
		}
		else {
			container.removeClass( "ui_validate_error" );
		}
	}
}

/********** Validators **********/
formValidator.prototype.validate = {
	// Required
	required: function( field, args ) {
		var f = $("#"+field);
		if ( f[0].type == "checkbox" ) {
			var valid = f[0].checked;
		}
		else {
			var valid = f.val() != "";
		}
		return {
			isValid: valid,
			msg: (valid) ? "" : _("This field is required")
		}
	},
	
	email: function( field, args ) {
		var f = $("#"+field).val();
		var emailReg = "^[\\w-_\.]*[\\w-_\.]\@[\\w]\.+[\\w]+[\\w]$";
		var regex = new RegExp(emailReg);
     	var valid = regex.test(f);
		return {
			isValid: valid,
			msg: (valid) ? "" : _("This field must be a valid email address")
		}
	},
	
	number: function( field, args ) {
		var f = $("#"+field).val();
		var numberReg = "^[0-9]*$";
		var regex = new RegExp(numberReg);
     	var valid = regex.test(f);
		return {
			isValid: valid,
			msg: (valid) ? "" : _("This field must be a number")
		}
	},
	
	range: function( field, args ) {
		var f = $("#"+field).val();
		var min = args.min;
		var max = args.max;
		var valid = f >= min && f <= max;
		return {
			isValid: valid,
			msg: (valid) ? "" : $.format( _("This field must be between % and &"), [args.min,args.max] )
		}
	},
	
	checkcount: function( field, args ) {
		var result = {
			isValid: true,
			msg: ""
		}
		
		var checked = $("input[name^='"+field+"['][checked]").length;
		switch( args.type ) {
			case 1:
				if ( checked != args.min ) {
					result.isValid = false;
					result.msg = $.format( _("You must choose exactly % rows"), [args.min] );
				}
			break;
			
			case 2:
				if ( checked < args.min ) {
					result.isValid = false;
					result.msg = $.format( _("You must choose at least % rows"), [args.min] );
				}
			break;
			
			case 3:
				if ( checked < args.min || checked > args.max ) {
					result.isValid = false;
					result.msg = $.format( _("You must choose between % and % rows"), [args.min,args.max] );
				}
			break;
			
		}
		
		return result;
	},
	
	textlength: function( field, args ) {
		var result = {
			isValid: true,
			msg: ""
		}
		
		var length = $("#"+field+"").val().length;
		switch( args.type ) {
			case 1:
				if ( length != args.min ) {
					result.isValid = false;
					result.msg = $.format( _("The text must be exactly % characters"), [args.min] );
				}
			break;
			
			case 2:
				if ( length < args.min ) {
					result.isValid = false;
					result.msg = $.format( _("The text must be at least % characters"), [args.min] );
				}
			break;
			
			case 3:
				if ( length < args.min || length > args.max ) {
					result.isValid = false;
					result.msg = $.format( _("The text must be between % and % characters"), [args.min,args.max] );
				}
			break;
			
			case 4:
				if ( length > args.max ) {
					result.isValid = false;
					result.msg = $.format( _("The text must be no more than % characters"), [args.max] );
				}
			break;
		}
		
		return result;
	},
	
	/**
	 * Value must be in set
	 */
	in_set: function( field, args ) {
		var result = {
			isValid: true,
			msg: ""
		}
		
		var val = $("#"+field+"").val();
		if ( args.case_ins ) val = val.toLowerCase();
		if ( $.inArray( val, args.stringset ) == -1 ) {
			result.isValid = false;
			result.msg = args.msg;
		}
		
		return result;
	},
	
	/**
	 * Value must NOT be in set
	 */
	not_in_set: function( field, args ) {
		var result = {
			isValid: true,
			msg: ""
		}
		
		var val = $("#"+field+"").val();
		if ( args.case_ins ) val = val.toLowerCase();
		if ( $.inArray( val, args.stringset ) != -1 ) {
			result.isValid = false;
			result.msg = args.msg;
		}
		
		return result;
	}
}

/********************************************************************************
	functions to toggle visibility of an element in a group of elements
********************************************************************************/
var form_element_toggle_groups = new Array();

function form_add_to_toggle_group( group, name, id ) {
	if ( !form_element_toggle_groups[group] ) {
		form_element_toggle_groups[group] = new Array();
	}
	form_element_toggle_groups[group].push([id,name]);
}

function form_toggle( group, id ) {
	if ( !form_element_toggle_groups[group] ) return;
	for ( var i=0; i<form_element_toggle_groups[group].length; i++ ) {
		var entryid = form_element_toggle_groups[group][i][0];
		var entryname = form_element_toggle_groups[group][i][1];
		if ( entryid == id ) {
			form_show_element( entryname )
		}
		else {
			form_hide_element( entryname );
		}
	}
}

function form_show_element( name ) {
	var name = name;
	var obj = document.getElementById(name);
	if ( obj ) {
		obj.style.display = "";
	}
}

function form_hide_element( name ) {
	var name = name;
	var obj = document.getElementById(name);
	if ( obj ) {
		obj.style.display = "none";
	}
}

function form_set_hidden( formname, name, value ) {
	$('#'+formname+'_'+name).val(value);
}



/********************************************************************************/

function absX(obj) {
	var curleft = 0;
	if ( obj && obj.offsetParent)
	{
		while (obj.offsetParent)
		{
			curleft += obj.offsetLeft
			obj = obj.offsetParent;
		}
	}
	else if (obj.x)
		curleft += obj.x;
	return curleft;
}

function absY( obj ) {
	var curtop = 0;
	if ( obj.offsetParent)
	{
		while (obj.offsetParent)
		{
			curtop += obj.offsetTop
			obj = obj.offsetParent;
		}
	}
	else if (obj.y)
		curtop += obj.y;
	return curtop;
}

function getKeyCode( evt ) {
	alert('');
	var e = window.event || evt;
	return e.keyCode;
}

function combineValues() {
	var text = new Array();
	for( var i=0; i < arguments.length; i++ ) {
		text.push( $(arguments[i]).val() );
	}
	
	return {
		inField : function( name ) {
			$(name)[0].value = this.asString( arguments[1] );
		},		
		asString : function() {
			var sep = (arguments[0]) ? arguments[0] : ",";
			return text.join(sep);
			
			var out = "";
			var prefix = "";
			for ( var i=0; i < text.length; i++ ) {
				out = out+prefix+text[i];
				prefix = sep;
			}
			return out;
		}
	}
}

function prependZero( val ) {
	var isNeg = val < 0;
	val = Math.abs(val);
	if ( val < 10 ) val = '0'+val;
	if ( isNeg ) val = '-'+val;
	return ''+val;
}

function add_time_strings( base, add ) {
	// No idea why this happens:
	// parseInt("07") = 7
	// parseInt("08") = 0 ????
	// Removing first any prepended Zero
	if ( base.charAt(0) == 0 ) {
		base = base.substring( 1, base.length );
	}
	
	var base = parseInt( base );
	var add = parseInt( add );
	var result = base+add;
	
	return prependZero( result );
}
