/**
*
*  This validate function works based on hidden fields defined within the form tags
*  and label tags wrapped around the text for each form field.  Please view the 
*  HTML page provided for more details.
*
*  Compatable with IE & FireFox
*
**/

function validate(config)
{
	// setup the form
	this.form = eval("document." + config.form_name);
	this.debug = new Array();
	this.required_fields = new Array();
	this.special_fields = new Array();
	this.old_errors = new Array();
	this.msgs = {};
	
	// setup some defaults	
	this.cfg = {
		form_name : config.form_name,
		debug : 0,
		realtime : 0,
		msg_all : 1,
		msg_type : "alert",
		alert : {
			msg_top : "The following has not been filled out correctly.",
			msg_bottom : "Please re-enter values and submit again!"
		},
		div : {
			id : "",
			msg_top : "The following has not been filled out correctly.",
			msg_bottom : "Please re-enter values and submit again!"
		},
		inline : {
			position : "right",
			xalign : "center",
			yalign : "center",
			xoffset : 5,
			yoffset : 0,
			spdin : 30,
			spdout : 30,
			fadeout : 5,
			htmlpre : "",
			htmlpost : ""
		},	
		tooltip : {
			repeat : 1,
			position : "right",
			xalign : "center",
			yalign : "center",
			xoffset : 5,
			yoffset : 0,
			spdin : 30,
			spdout : 30,
			fadeout : 5,
			htmlpre : "",
			htmlpost : ""
		},
		fire : {
			pre : "",
			error : "",
			success : ""
		},
		hl_field : {},
		hl_label : {},
		focus : false
	};
	
	// over write debug default
	if (config.debug > 0)
		this.cfg.debug = 1;
		
	// over write realtime default
	if (config.realtime > 0)
		this.cfg.realtime = 1;
		
	// over write fire function defaults
	if (typeof(config.fire) == 'object')
	{
		if (value_exists(config.fire.pre))
			this.cfg.fire.pre = config.fire.pre;
		if (value_exists(config.fire.error))
			this.cfg.fire.error = config.fire.error;
		if (value_exists(config.fire.success))
			this.cfg.fire.success = config.fire.success;
	}

	// over write msg type default
	if (config.msg_type != undefined)
		this.cfg.msg_type = config.msg_type;
		
	// over write msg all default
	if (config.msg_all == 0)
		this.cfg.msg_all = 0;
		
	// over write alerts defaults
	if (typeof(config.alert) == 'object')
	{
		if (value_exists(config.alert.msg_top))
			this.cfg.alert.msg_top = config.alert.msg_top;
		if (value_exists(config.alert.msg_bottom))
			this.cfg.alert.msg_bottom = config.alert.msg_bottom;
	}

	// over write div defaults
	if (typeof(config.div) == 'object')
	{
		if (value_exists(config.div.id))
			this.cfg.div.id = config.div.id;			
		if (value_exists(config.div.msg_top))
			this.cfg.div.msg_top = config.div.msg_top;
		if (value_exists(config.div.msg_bottom))
			this.cfg.div.msg_bottom = config.div.msg_bottom;
	}
	
	// over write inline defaults
	if (typeof(config.inline) == 'object')
	{	
		if ((config.inline.position == "left") || (config.inline.position == "top") || (config.inline.position == "bottom"))
			this.cfg.inline.position = config.inline.position;
		if ((config.inline.yalign == "top") || (config.inline.yalign == "bottom"))
			this.cfg.inline.yalign = config.inline.yalign;
		if ((config.inline.xalign == "left") || (config.inline.xalign == "right"))
			this.cfg.inline.xalign = config.inline.xalign;				
		if (!isNaN(config.inline.xoffset))
			this.cfg.inline.xoffset = config.inline.xoffset;
		if (!isNaN(config.inline.yoffset))
			this.cfg.inline.yoffset = config.inline.yoffset;				
		if (!isNaN(config.inline.spdin))
			this.cfg.inline.spdin = config.inline.spdin;
		if (!isNaN(config.inline.spdout))
			this.cfg.inline.spdout = config.inline.spdout;
		if (!isNaN(config.inline.fadeout))
			this.cfg.inline.fadeout = config.inline.fadeout;

		if (value_exists(config.inline.htmlpre))
		{
			this.cfg.inline.htmlpre = config.inline.htmlpre;

			if (value_exists(config.inline.htmlpost))
				this.cfg.inline.htmlpost = config.inline.htmlpost;			
		}
	}
	
	// over write tooltip defaults
	if (typeof(config.tooltip) == 'object')
	{
		if (config.tooltip.repeat == 0)
			this.cfg.tooltip.repeat = config.tooltip.repeat;
		if ((config.tooltip.position == "left") || (config.tooltip.position == "top") || (config.tooltip.position == "bottom"))
			this.cfg.tooltip.position = config.tooltip.position;
		if ((config.tooltip.yalign == "top") || (config.tooltip.xyalign == "bottom"))
			this.cfg.tooltip.yalign = config.tooltip.yalign;
		if ((config.tooltip.xalign == "left") || (config.tooltip.xalign == "right"))
			this.cfg.tooltip.xalign = config.tooltip.xalign;				
		if (!isNaN(config.tooltip.xoffset))
			this.cfg.tooltip.xoffset = config.tooltip.xoffset;
		if (!isNaN(config.tooltip.yoffset))
			this.cfg.tooltip.yoffset = config.tooltip.yoffset;				
		if (!isNaN(config.tooltip.spdin))
			this.cfg.tooltip.spdin = config.tooltip.spdin;
		if (!isNaN(config.tooltip.spdout))
			this.cfg.tooltip.spdout = config.tooltip.spdout;
		if (!isNaN(config.tooltip.fadeout))
			this.cfg.tooltip.fadeout = config.tooltip.fadeout;

		if (value_exists(config.tooltip.htmlpre))
		{
			this.cfg.tooltip.htmlpre = config.tooltip.htmlpre;

			if (value_exists(config.tooltip.htmlpost))
				this.cfg.tooltip.htmlpost = config.tooltip.htmlpost;			
		}
	}
	
	// over write highlight field default
	if (typeof(config.hl_field) == 'object')
		this.cfg.hl_field = config.hl_field;
		
	// over write highlight label default
	if (typeof(config.hl_label) == 'object')
		this.cfg.hl_label = config.hl_label;
		
	/* --------------------------------------------
	 * defines all fields that are required
	 * ----------------------------------------- */
	this.required = function(_input)
	{
		var exists = false;
		
		// roll through all required fields
		for (var x=0; x < this.required_fields.length; x++)
		{
			var input = this.required_fields[x];
			
			if (input.field == _input.field)
				exists = true;
		}
		
		// if field does not already exist
		if (!exists)
		{
			this.required_fields.push(_input);
			
			// if we are doing realtime checking
			if ((this.cfg.realtime) || (_input.realtime))
			{
				var obj = this;
				var input_field = eval("this.form." + _input.field);

				if (input_field != undefined)
				{
					var field_type = this.input_type(_input.field);

					// if we have a radio or check box then we need to do an onfocus for all elements
					if (((field_type == "radio") || (field_type == "checkbox")) && (eval("this.form." + _input.field +".length") > 1))
					{
						for (var x=0; x < eval("this.form." + _input.field +".length"); x++)
						{
							input_field = eval("this.form." + _input.field +"[x]");
							input_field.onblur = function(){ obj.check_input(_input.field); }
						}
					}
					else
					{
						input_field.onblur = function(){ obj.check_input(_input.field); }
					}
				}
			}
		}
			
		this.required.global = this;
	}

	/* --------------------------------------------
	 * removes a field from required_fields array
	 * ----------------------------------------- */
	this.required.remove = function(_field)
	{
		var new_required = new Array();

		// roll through all required fields
		for (var x=0; x < this.global.required_fields.length; x++)
		{
			var input = this.global.required_fields[x];
			
			// looks to see if required field equals field passed in
			if (input.field != _field)
				new_required.push(input);
		}		

		this.global.required_fields = new_required;
	}
	
	/* --------------------------------------------
	 * clears out all fields required_fields array
	 * ----------------------------------------- */
	this.required.clear = function()
	{
		this.global.required_fields = Array();
	}
	
	/* --------------------------------------------
	 * defines all fields that have special requirements
	 * ----------------------------------------- */
	this.special = function(_input)
	{
		var exists = false;
		
		// roll through all required fields
		for (var x=0; x < this.special_fields.length; x++)
		{
			var input = this.special_fields[x];
			
			if ((input.field == _input.field) && (input.type == _input.type))
				exists = true;
		}
		
		// if field does not already exist
		if (!exists)
		{
			this.special_fields.push(_input);
			
			// if we are doing realtime checking
			if ((this.cfg.realtime) || (_input.realtime))
			{
				var obj = this;
				var input_field = eval("this.form." + _input.field);

				if (input_field != undefined)
				{
					var field_type = this.input_type(_input.field);

					// if we have a radio or check box then we need to do an onfocus for all elements
					if (((field_type == "radio") || (field_type == "checkbox")) && (eval("this.form." + _input.field +".length") > 1))
					{
						for (var x=0; x < eval("this.form." + _input.field +".length"); x++)
						{
							input_field = eval("this.form." + _input.field +"[x]");
							
							if (input_field.onblur == null)
								input_field.onblur = function(){ obj.check_input(_input.field); }
						}
					}
					else
					{
						if (input_field.onblur == null)
							input_field.onblur = function(){ obj.check_input(_input.field); }
					}
				}
			}
		}
			
		this.special.global = this;
	}
	
	/* --------------------------------------------
	 * removes a field from special_fields array
	 * ----------------------------------------- */
	this.special.remove = function(_field, _type)
	{
		var new_special = new Array();

		// roll through all required fields
		for (var x=0; x < this.global.special_fields.length; x++)
		{
			var input = this.global.special_fields[x];
			
			// looks to see if required field equals field passed in
			if ((input.field != _field) && (input.type != _type))
				new_special.push(input);
		}		

		this.global.special_fields = new_special;
	}
	
	/* --------------------------------------------
	 * clears out all fields special_fields array
	 * ----------------------------------------- */
	this.special.clear = function(_field, _type)
	{
		this.global.special_fields = Array();
	}
	
	/* --------------------------------------------
	 * defines all tool tips 
	 * ----------------------------------------- */
	this.tooltip = function(_input)
	{
		var obj = this;
		var input_field = eval("this.form." + _input.field);

		if (input_field != undefined)
		{
			var field_type = this.input_type(_input.field);
			
			// if we have a radio or check box then we need to do an onfocus for all elements
			if (((field_type == "radio") || (field_type == "checkbox")) && (eval("this.form." + _input.field +".length") > 1))
			{
				for (var x=0; x < eval("this.form." + _input.field +".length"); x++)
				{
					input_field = eval("this.form." + _input.field +"[x]");
					input_field.onfocus = function(){ obj.set_tooltip(_input); }
				}
			}
			else
			{
				input_field.onfocus = function(){ obj.set_tooltip(_input); }
			}
		}
		else
			this.debug.push("Unknown input for tooltip or tooltip was defined before input field: " + _input.field);
	}
	
	/* --------------------------------------------
	 * checks form element passed in
	 * ----------------------------------------- */
	this.check_input = function(_field_name)
	{
		this.error_msg = new Array();
		this.error_field = new Array();
		
		// roll through all required fields
		for (var x=0; x < this.required_fields.length; x++)
		{
			var required = this.required_fields[x];

			// if we pass in a field name then we are validating in just this one field
			// if the field name does not equal required field then continue onto the next
			if (_field_name == required.field)
				this.validate_required(required);
		}
		
		// roll through all special required fields
		for (var x=0; x < this.special_fields.length; x++)
		{
			var special = this.special_fields[x];

			// if we pass in a field name then we are validating in just this one field
			// if the field name does not equal required field then continue onto the next
			if (_field_name == special.field)
				this.validate_special(special);
		}
	}
	
	/* --------------------------------------------
	 * runs through all form elements
	 * ----------------------------------------- */
	this.check_form = function()
	{
		if (this.form == undefined)
		{
			alert("Form name has not been defined, validation can not continue");
			return false;
		}
		
		this.error_msg = new Array();
		this.error_field = new Array();
		
		// fire pre function if defined before any validation is done
		if (value_exists(this.cfg.fire.pre))
			eval(this.cfg.fire.pre+"(this)");
		
		// check some of the configuration
		if ((this.cfg.inline.htmlpre != "") && (this.cfg.inline.htmlpost == ""))
			this.debug.push("Inline pre HTML (inline_htmlpre) found... expecting post HTML (inline_htmlpost)");
		
		// roll through old errors to make sure all the 
		// highlights were reverted back to default
		for (var x=0; x < this.old_errors.length; x++)
		{
			this.set_old_values(this.old_errors[x]);	
		}
		
		// reset array
		this.old_error = new Array();		
		this.old_error.length = 0;
		
		// roll through all required fields
		for (var x=0; x < this.required_fields.length; x++)
		{
			this.validate_required(this.required_fields[x]);
		}
		
		// roll through all special required fields
		for (var x=0; x < this.special_fields.length; x++)
		{
			this.validate_special(this.special_fields[x]);
		}
		
		// before we display anything check the div
		if ((this.cfg.msg_type == 'div')  && (document.getElementById(this.cfg.div.id) == undefined))
		{
			this.debug.push("Div tag '" + this.cfg.div.id + "' does not appear to exist");
		}
		
		// if we need to display debug info
		if ((this.cfg.debug) && (this.debug.length > 0))
		{
			alert ("Debug Info:\n\n" + this.debug.join("\n") + "\n\nThe form was not submitted.");
			
			return false;
		}
		else
		{
			// display any error that may have occured
			if (this.error_msg.length > 0)
			{
				if (this.cfg.msg_type == "alert")
					alert (this.cfg.alert.msg_top + "\n\n- " + this.error_msg.join("\n- ") + "\n\n" + this.cfg.alert.msg_bottom);
				else if ((this.cfg.msg_type == "div") && (document.getElementById(this.cfg.div.id) != undefined))
				{
					document.getElementById(this.cfg.div.id).innerHTML = this.cfg.div.msg_top + "<ul><li>" + this.error_msg.join("<li>") + "</ul>" + this.cfg.div.msg_bottom;
					
					if (document.getElementById(this.cfg.div.id).style.visibility == "hidden")
						document.getElementById(this.cfg.div.id).style.visibility = 'visible';
					if (document.getElementById(this.cfg.div.id).style.display == "none")
						document.getElementById(this.cfg.div.id).style.display = 'block';
				}

				this.cfg.focus = false;
				
				// fire error function if defined
				if (value_exists(this.cfg.fire.error))
					eval(this.cfg.fire.error+"(this)");
				
				return false;
			}
			else
			{
				// fire success function if defined
				if (value_exists(this.cfg.fire.success))
					eval(this.cfg.fire.success+"(this)");
			
				return true;
			}
		}
	}
	
	/* --------------------------------------------
	 * validates a required field
	 * ----------------------------------------- */
	this.validate_required = function (_input)
	{
		// look to see if this is an object in our form
		if (typeof(eval("this.form." + _input.field)) == 'object')
		{
			var valid = 1;

			// check to see if the field is conditional on some other field
			if (typeof(_input.conditional) == 'object')
			{
				if (_input.conditional.condition == 'blank')
				{
					var rtn = this.check_required(_input.conditional.field, 0);

					if (rtn == 0)
						valid = this.check_required(_input.field, 0);
					else if (valid == -1)
						this.debug.push("Field '" + _input.conditional.field + "' is disabled so it will not be checked as part of the conditional for field: " + _input.field);
					else if (valid == -2)
						this.debug.push("Unknown input type for conditional field in field: " + _input.field);
				}
				else if (_input.conditional.condition == 'filled in')
				{
					var rtn = this.check_required(_input.conditional.field, 0);

					if (rtn == 1)
						valid = this.check_required(_input.field, 0);
					else if (valid == -1)
						this.debug.push("Field '" + _input.conditional.field + "' is disabled so it will not be checked as part of the conditional for field: " + _input.field);
					else if (valid == -2)
						this.debug.push("Unknown input type for conditional field in field: " + _input.field);
				}
				else if (_input.conditional.condition == 'equals')
				{
					if (this.check_required(_input.conditional.field, 1) == _input.conditional.value)
						valid = this.check_required(_input.field, 0);
				}
			}
			else
			{
				valid = this.check_required(_input.field, 0);
			}

			if (valid == 0)
				this.report_error(_input);
			else if (valid == -1)
				this.debug.push("Field '" + _input.field + "' is disabled so it will not be checked");
			else if (valid == -2)
				this.debug.push("Unknown input type for required field: " + _input.field);	
		}
		else
		{
			this.debug.push("Unknown input for required field: " + _input.field);
		}
	}
	
	/* --------------------------------------------
	 * validates a special field
	 * ----------------------------------------- */
	this.validate_special = function (_input)
	{
		// look to see if this is an object in our form
		if (typeof(eval("this.form." + _input.field)) == 'object')
		{
			if (_input.type == "email")
				this.check_email(_input);
			else if (_input.type == "date")
				this.check_date(_input);
			else if (_input.type == "number")
				this.check_number(_input);
			else if (_input.type == "compare")
				this.check_compare(_input);
			else if (_input.type == "str_length")
				this.check_str_between(_input);
			else if (_input.type == "num_size")
				this.check_num_between(_input);
			else if (_input.type == "mask")
				this.check_mask(_input);
			else if (_input.type == "regexp")
				this.check_regexp(_input);
			else if (_input.type == "password")
				this.check_password(_input);
			else
				this.debug.push("Special validation '" + _input.type + "' is invalid");
		}
		else
		{
			this.debug.push("Unknown input for special validation: " + _input.field);
		}
	}

	/* --------------------------------------------
	 * returns input type
	 * ----------------------------------------- */
	this.input_type = function (_field_name)
	{
		try
		{
			var field_type = eval("this.form." + _field_name + ".type");

			if (field_type == undefined)
				field_type = eval("this.form." + _field_name + "[0].type");
		}
		catch(e) {}
		
		return field_type;
	}
	
	/* --------------------------------------------
	 * runs through all form elements
	 * ----------------------------------------- */
	this.check_required = function (field_name, rtn_type)
	{
		var field_type = this.input_type(field_name);
		var valid = 0;

		if ((field_type == "text") || (field_type == "password") || (field_type == "file") || (field_type == "textarea"))
			valid = this.check_text(field_name, rtn_type);
		else if ((field_type == "select-one") || (field_type == "select-multiple"))
			valid = this.check_select(field_name, rtn_type);
		else if ((field_type == "radio") || (field_type == "checkbox"))
			valid = this.check_radio_checkbox(field_name, rtn_type);
		else
			valid = -2;
			
		return valid;
	}

	/* --------------------------------------------
	 * checks text fields
	 * ----------------------------------------- */
	this.check_text = function (field_name, rtn_type)
	{
		var rtn = 1;
		
		// if field is disabled 
		if (!eval("this.form." + field_name + ".disabled"))
		{
			// if field is blank
			if (eval("this.form." + field_name + ".value") == "")
				rtn = 0;
			else if (rtn_type == 1)
				rtn = eval("this.form." + field_name + ".value");
		}
		else
		{
			rtn = -1;
		}
		
		return rtn;
	}
	
	/* --------------------------------------------
	 * checks select field to see if it's selected 
	 * and if what is selected has a value
	 * ----------------------------------------- */
	this.check_select = function (field_name, rtn_type)
	{
		var rtn = 1;
		
		if (!eval("this.form." + field_name + ".disabled"))
		{
			var option_selected = eval("this.form." + field_name + ".selectedIndex");

			if (option_selected == -1)
				rtn = 0;
			else if (eval("this.form." + field_name + ".options[" + option_selected + "].value") == "")
				rtn = 0;
			else if (rtn_type == 1)
				rtn = eval("this.form." + field_name + ".options[" + option_selected + "].value");
		}
		else
		{
			rtn = -1;
		}
		
		return rtn;
	}
	
	/* --------------------------------------------
	 * checks radio field or a check boxes
	 * ----------------------------------------- */
	this.check_radio_checkbox = function (field_name, rtn_type)
	{
		var rtn = 0;

		if (eval("this.form." + field_name +".length") > 1)
		{
			for (var x=0; x < eval("this.form." + field_name +".length"); x++)
			{
				if (eval("this.form." + field_name +"[x].checked"))
					if (rtn_type == 1)
						rtn = eval("this.form." + field_name +"[x].value");
					else
						rtn = 1;
			}
		}
		else
		{
			if (eval("this.form." + field_name +".checked"))
				if (rtn_type == 1)
					rtn = eval("this.form." + field_name +".value");
				else
					rtn = 1;
		}
		
		return rtn;
	}
	
	/* --------------------------------------------
	 * checks text fields for a valid email format
	 * ----------------------------------------- */
	this.check_email = function (_input)
	{
		var field_type = this.input_type(_input.field);
		var email = eval("this.form." + _input.field + ".value");

		// check field type
		if ((field_type == "text") || (field_type == "password") || (field_type == "textarea"))
		{
			// if email is not disabled
			if (!eval("this.form." + _input.field + ".disabled"))
			{
				// if email is not blank & does not meet regexp for email address
				if ((email != "") && (! /^([A-Za-z0-9_\-\.])+\@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,4})$/.test(email)))
					this.report_error(_input);
			}
			else
			{
				this.debug.push("Field '" + _input.field + "' is disabled so it will not be checked");
			}	
		}
		else
		{
			this.debug.push("Invalid input type '" + field_type + "' for email field: " + _input.field);
		}
	}

	/* --------------------------------------------
	 * checks text fields a valid date this.format
	 * ----------------------------------------- */
	this.check_date = function (_input)
	{
		var field_type = this.input_type(_input.field);
		var date = eval("this.form." + _input.field + ".value");

		// check field type
		if ((field_type == "text") || (field_type == "password") || (field_type == "textarea"))
		{
			// if date is not disabled
			if (!eval("this.form." + _input.field + ".disabled"))
			{
				// if date is not blank and format is an array
				if ((date != "") && (_input.format instanceof Array))
				{
					var valid = false;
					
					for (var x=0; x < _input.format.length; x++)
					{	
						format = this.make_regexp_safe(_input.format[x]);
						format = format.replace(/%D/g, "([1-9]|0[1-9]|[1-2][0-9]|3[0-1])");
						format = format.replace(/%M/g, "([1-9]|0[1-9]|1[0-2])");
						format = format.replace(/%Y/g, "([1-2][0-9][0-9][0-9])");
						format = format.replace(/%y/g, "[0-9]{2}");

						format = format.replace(/%H/g, "([1-9]|0[1-9]|1[0-9]|2[0-3])");
						format = format.replace(/%h/g, "([1-9]|0[1-9]|1[0-2])");
						format = format.replace(/%m/g, "([1-9]|0[1-9]|[1-5][0-9])");
						format = format.replace(/%s/g, "([1-9]|0[1-9]|[1-5][0-9])");
						format = format.replace(/%p/g, "(AM|PM)");

						var date_rexp = new RegExp("^" + format + "$", "i");

						if (date_rexp.test(date))
							valid = true;
					}
					
					if (!valid)
						this.report_error(_input);
				}
			}
			else
			{
				this.debug.push("Field '" + _input.field + "' is disabled so it will not be checked");
			}
		}
		else
		{
			this.debug.push("Invalid input type '" + field_type + "' for date field: " + _input.field);
		}
	}

	/* --------------------------------------------
	 * checks field is a number
	 * ----------------------------------------- */
	this.check_number = function (_input)
	{
		var field_type = this.input_type(_input.field);
		var number = eval("this.form." + _input.field + ".value");
		//number.replace(".","");

		// check field type
		if ((field_type == "text") || (field_type == "password") || (field_type == "textarea"))
		{
			// if number is not disabled
			if (!eval("this.form." + _input.field + ".disabled"))
			{
				// if number is not blank and is not a numeric
				if ((number != "") && (isNaN(number)))
					this.report_error(_input);	
			}
			else
			{
				this.debug.push("Field '" + _input.field + "' is disabled so it will not be checked");
			}
		}
		else
		{
			this.debug.push("Invalid input type '" + field_type + "' for number field: " + _input.field);
		}
	}

	/* --------------------------------------------
	 * checks 2 text fields to make sure they are the same
	 * ----------------------------------------- */
	this.check_compare = function (_input)
	{
		var field1_type = this.input_type(_input.field);
		var field2_type = this.input_type(_input.field);
		var field1 = eval("this.form." + _input.field + ".value");
		var field2 = eval("this.form." + _input.compare + ".value");
		
		// check field type for field1
		if ((field1_type == "text") || (field1_type == "password") || (field1_type == "textarea"))
		{		
			// check field type for field2
			if ((field2_type == "text") || (field2_type == "password") || (field2_type == "textarea"))
			{
				// if field is not disabled
				if (!eval("this.form." + _input.field + ".disabled"))
				{
					if (field1 != field2)
					{
						this.report_error(_input);
						
						// report this error but only to 
						// highlight the error, we don't want to 
						// print a second msg in this case
						var tmp = new Array;
						tmp.ignore_msg = 1;						
						tmp.field = _input.compare;
						tmp.msg = _input.msg;						
						
						if (_input.hl_by_id != null)
							tmp.hl_by_id = _input.hl_by_id;
						if (_input.hl_field != null)
							tmp.hl_field = _input.hl_field;
						if (_input.hl_label != null)
							tmp.hl_label = _input.hl_label;
						
						this.report_error(tmp);
					}
				}
				else
				{
					this.debug.push("Field '" + _input.field + "' is disabled so it will not be checked");
				}
			}
			else
			{
				this.debug.push("Invalid input type '" + field2_type + "' for compare field: " + _input.compare);
			}
		}
		else
		{
			this.debug.push("Invalid input type '" + field1_type + "' for compare field: " + _input.field);
		}
	}
	
	/* --------------------------------------------
	 * checks field to make sure string length
	 * falls between min and max values   
	 * ----------------------------------------- */
	this.check_str_between = function (_input)
	{
		var field_type = this.input_type(_input.field);
		var between = eval("this.form." + _input.field + ".value");
		
		// check field type
		if ((field_type == "text") || (field_type == "password") || (field_type == "textarea"))
		{
			// if between is not disabled
			if (!eval("this.form." + _input.field + ".disabled"))
			{
				// if between is not blank
				if (between != "")
				{
					var error = false;

					if (_input.min != null)
						if (between.length < _input.min)
							{ this.report_error(_input); error = true; }
					if ((_input.max != null) && (!error))
						if (between.length > _input.max)
							{ this.report_error(_input); error = true; }
				}
			}
			else
			{
				this.debug.push("Field '" + _input.field + "' is disabled so it will not be checked");
			}
		}
		else
		{
			this.debug.push("Invalid input type '" + field_type + "' for between field: " + _input.field);
		}
	}
	
	/* --------------------------------------------
	 * checks field to make sure numeric value 
	 * falls between min and max values
	 * ----------------------------------------- */
	this.check_num_between = function (_input)
	{
		var field_type = this.input_type(_input.field);
		var between = eval("this.form." + _input.field + ".value");
		
		// check field type
		if ((field_type == "text") || (field_type == "password") || (field_type == "textarea"))
		{
			// if between is not disabled
			if (!eval("this.form." + _input.field + ".disabled"))
			{
				// if between is not blank
				if (between != "")
				{
					// if this is a number
					if (!isNaN(between))
					{
						var error = false;
						
						if (_input.min != null)
							if (between < _input.min)
								{ this.report_error(_input); error = true; }
						if ((_input.max != null) && (!error))
							if (between > _input.max)
								{ this.report_error(_input); error = true; }
					}
					else
					{
						this.report_error(_input);
					}
				}
			}
			else
			{
				this.debug.push("Field '" + _input.field + "' is disabled so it will not be checked");
			}
		}
		else
		{
			this.debug.push("Invalid input type '" + field_type + "' for between field: " + _input.field);
		}
	}

	/* --------------------------------------------
	 * checks field against the mask that is defined
	 * ----------------------------------------- */
	this.check_mask = function (_input)
	{
		var field_type = this.input_type(_input.field);
		var mask = eval("this.form." + _input.field + ".value");

		// check field type
		if ((field_type == "text") || (field_type == "password") || (field_type == "textarea"))
		{
			// if field is not disabled
			if (!eval("this.form." + _input.field + ".disabled"))
			{
				// if value is not blank and format is an array
				if ((mask != "") && (_input.format instanceof Array))
				{
					var valid = false;
					
					for (var x=0; x < _input.format.length; x++)
					{	
						var format = this.make_regexp_safe(_input.format[x]);
						format = format.replace(/%N/g, "\\d");
						format = format.replace(/%A/g, "[A-Za-z0-9]");
						format = format.replace(/%U/g, "[A-Z]");
						format = format.replace(/%l/g, "[a-z]");
						format = format.replace(/%M/g, "[A-Za-z]");						
						format = format.replace(/%\*/g, ".");

						var field_rexp = new RegExp("^" + format + "$", "i");

						if (field_rexp.test(mask))
							valid = true;
					}
					
					if (!valid)
						this.report_error(_input);
				}
			}
			else
			{
				this.debug.push("Field '" + _input.field + "' is disabled so it will not be checked");
			}
		}
		else
		{
			this.debug.push("Invalid input type '" + _input_type + "' for mask field: " + _input.field);
		}
	}
	
	/* --------------------------------------------
	 * checks field against the regexp that is defined
	 * ----------------------------------------- */
	this.check_regexp = function (_input)
	{
		var field_type = this.input_type(_input.field);
		var value = eval("this.form." + _input.field + ".value");

		// check field type
		if ((field_type == "text") || (field_type == "password") || (field_type == "textarea"))
		{
			// if field is not disabled
			if (!eval("this.form." + _input.field + ".disabled"))
			{
				// if value is not blank
				if (value != "")
				{
					var field_rexp = new RegExp(_input.format, "i");

					if (!field_rexp.test(value))
						this.report_error(_input);
				}
			}
			else
			{
				this.debug.push("Field '" + _input.field + "' is disabled so it will not be checked");
			}
		}
		else
		{
			this.debug.push("Invalid input type '" + _input_type + "' for regexp field: " + _input.field);
		}
	}
	
	/* --------------------------------------------
	 * check field against the password format 
	 * ----------------------------------------- */
	this.check_password = function (_input)
	{
		var field_type = this.input_type(_input.field);
		var password = eval("this.form." + _input.field + ".value");

		// check field type
		if ((field_type == "text") || (field_type == "password") || (field_type == "textarea"))
		{
			// if field is not disabled
			if (!eval("this.form." + _input.field + ".disabled"))
			{
				// if value is not blank
				if (password != "")
				{
					var error = false;
					
					// check for number
					if (_input.format.indexOf("N") != -1)
						if (password.search(/\d/) == -1)
							{ this.report_error(_input); error = true; }
					
					// check for upper case character
					if ((_input.format.indexOf("U") != -1) && (!error))
						if (password.search(/[A-Z]/) == -1)
							{ this.report_error(_input); error = true; }
					
					// check for lower case character
					if ((_input.format.indexOf("l") != -1) && (!error))
						if (password.search(/[a-z]/) == -1)
							{ this.report_error(_input); error = true; }
					
					// check for special character
					if ((_input.format.indexOf("?") != -1) && (!error))
						if (password.search(/[^A-Z0-9]/i) == -1)
							{ this.report_error(_input); error = true; }		
				}
			}
			else
			{
				this.debug.push("Field '" + _input.field + "' is disabled so it will not be checked");
			}
		}
		else
		{
			this.debug.push("Invalid input type '" + field_type + "' for password field: " + _input.field);
		}
	}

	/* --------------------------------------------
	 * reset highlight on all fields
	 * ----------------------------------------- */
	this.set_old_values = function (_input)
	{
		// if inline messages are enabled then hide old error
		if (this.cfg.msg_type == "inline")
		{
			if (document.getElementById(_input.field + '_msg'))
			{
				var msg = document.getElementById(_input.field + '_msg');
				msg.style.display = "none";
				clearInterval(msg.timer);
				clearInterval(msg.timerout);
			}
		}
			
		// reset label tag if provided
		if (_input.hl_label != null)
		{
			// look through all elements of the this.form for matching label tags
			for (var x=0; x < document.getElementsByTagName('label').length; x++)
			{ 
				if (_input.field == document.getElementsByTagName('label')[x].htmlFor)
				{
					// highlight label if color is provided
					if (_input.hl_label.color != null)
						document.getElementsByTagName('label')[x].style.color = _input.hl_label.color;
					if (_input.hl_label.class_name != null)
						document.getElementsByTagName('label')[x].className = _input.hl_label.class_name;
				}
			}
		}

		// reset field if provided
		if (_input.hl_field != null)
		{
			var input_field = eval("this.form." + _input.field);
			var length = eval("this.form."+_input.field+".length");

			// accounts for radio and checkboxes
			if ((length != undefined) && (this.input_type(_input.field) == "radio" || this.input_type(_input.field) == "checkbox"))
			{
				for (var y=0; y < length; y++)
				{
					var input_field = eval("this.form."+_input.field+"[y]");

					if (_input.hl_field.color != null)
						input_field.style.backgroundColor = _input.hl_field.color;
					if (_input.hl_field.class_name != null)
						input_field.className = _input.hl_field.class_name;
				}
			}
			else
			{
				if (_input.hl_field.color != null)
					input_field.style.backgroundColor = _input.hl_field.color;
				if (_input.hl_field.class_name != null)
					input_field.className = _input.hl_field.class_name;
			}
		}

		// reset div if provided
		if (_input.hl_by_id != null)
		{
			var hl_by_id = document.getElementById(_input.hl_by_id.id);

			if (hl_by_id != undefined)
			{
				if (_input.hl_by_id.color != null)
					hl_by_id.style.backgroundColor = _input.hl_by_id.color;
				if (_input.hl_by_id.class_name != null)
					hl_by_id.className = _input.hl_by_id.class_name;
			}
		}
	}
	
	/* --------------------------------------------
	 * displays the tool tip for the input field
	 * ----------------------------------------- */
	this.set_tooltip = function (_input)
	{
		// look to see if we currently have an error displayed for this field
		// if so then we don't want to display the tooltip
		if (typeof(this.msgs[_input.field+'_err']) == 'object')
		{
			if (this.msgs[_input.field+'_err'].display)		
				return;
		}
		
		// define input field
		var input_field = eval("this.form." + _input.field);
		var length = eval("this.form."+_input.field+".length");

		// accounts for radio and checkboxes
		if ((length != undefined) && (this.input_type(_input.field) == "radio" || this.input_type(_input.field) == "checkbox"))
		{
			input_field = input_field[length - 1];
		}

		// define the tip element
		var tip = null;

		// create tip element
		if (!document.getElementById(_input.field + '_tip'))
		{
			tip = document.createElement('div');			
			tip.id = _input.field + '_tip';
			document.body.appendChild(tip);
		}
		else
		{
			tip = document.getElementById(_input.field + '_tip');

			// make sure to start with a clean slate
			this.clear_fadein_fadeout(tip.id);
		}

		tip.style.position = "absolute";
		tip.style.display = "block";
		tip.style.filter = 'alpha(opacity=0)';
		tip.style.opacity = 0;
		tip.alpha = 0;

		// set html/format of tip
		if (this.cfg.tooltip.htmlpre != "")
			tip.innerHTML = this.cfg.tooltip.htmlpre + _input.msg + this.cfg.tooltip.htmlpost;
		else
			tip.innerHTML = _input.msg;

		var top_position = 0;
		var left_position = 0;
		var settings = {};
		
		// merge the default parameters with the individual tooltip object
		if (typeof(_input.tooltip) == 'object')
			settings = this.extend_obj(this.cfg.tooltip, _input.tooltip);
		else
			settings = this.cfg.tooltip;
			
		// set position element
		settings.position_element = input_field;
		
		// In some case we don't just want the msg positioned by the
		// input field, radio buttons and check box are good examples
		if (settings.position_id != undefined)
			if (document.getElementById(settings.position_id) != null)
				settings.position_element = document.getElementById(settings.position_id);

		// set positioning of tip
		if ((settings.position == 'right') || (settings.position == 'left'))
		{
			if (settings.yalign == "top")
				top_position = this.top_position(settings.position_element) + settings.yoffset;
			else if (settings.yalign == "bottom")
				top_position = (this.top_position(settings.position_element) - (tip.offsetHeight - settings.position_element.offsetHeight)) + settings.yoffset;
			else
				top_position = (this.top_position(settings.position_element) - ((tip.offsetHeight - settings.position_element.offsetHeight) / 2)) + settings.yoffset;

			if (settings.position == 'right')
				left_position = this.left_position(settings.position_element) + settings.position_element.offsetWidth + settings.xoffset;
			else if (settings.position == 'left')
				left_position = this.left_position(settings.position_element) - (tip.offsetWidth + settings.xoffset);
		}
		else if ((settings.position == 'top') || (settings.position == 'bottom'))
		{
			if (settings.position == 'top')
				top_position = this.top_position(settings.position_element) - (tip.offsetHeight + settings.yoffset);
			else if (settings.position == 'bottom')
				top_position = this.top_position(settings.position_element) + settings.position_element.offsetHeight + settings.yoffset;

			if (settings.xalign == "left")
				left_position = this.left_position(settings.position_element) + settings.xoffset;
			else if (settings.xalign == "right")
				left_position = (this.left_position(settings.position_element) - (tip.offsetWidth - settings.position_element.offsetWidth)) + settings.xoffset;
			else
				left_position = (this.left_position(settings.position_element) - ((tip.offsetWidth - settings.position_element.offsetWidth) / 2)) + settings.xoffset;					
		}

		tip.style.top = top_position + 'px';
		tip.style.left = left_position + 'px';

		// setup both the fade in and fade out 
		var obj = this;
		
		this.msgs[tip.id] = {};		
		this.msgs[tip.id].spdout = settings.spdout;

		// look to see if we need to fade tip in		
		if (settings.spdin > 0)
			this.msgs[tip.id].timer_in = setInterval(function(){ obj.fade_in(tip.id) }, settings.spdin);
		else
			this.display_msg(tip.id);
			
		this.msgs[tip.id].display = true;

		// set fade out if value is set
		if (settings.fadeout > 0)
		{
			this.msgs[tip.id].fade_out = setTimeout(function(){ obj.hide(tip.id); }, settings.fadeout * 1000);
		}
		
		// now we need to clear the tip when focus is gone
		// this also account for radio and check boxes which can have multiple focus points
		if ((length != undefined) && (this.input_type(_input.field) == "radio" || this.input_type(_input.field) == "checkbox"))
		{
			for (var x=0; x < eval("this.form." + _input.field +".length"); x++)
			{
				var elements = eval("this.form." + _input.field +"[x]");
				
				if (new RegExp("check_input").test(elements.onblur))
					elements.onblur = function(){ obj.hide(tip.id); obj.check_input(_input.field); }
				else
					elements.onblur = function(){ obj.hide(tip.id); }
				
				// if we are not repeating the tip for evey focus
				// then clear the focus so it doesn't display again
				if (!settings.repeat)
				{
					elements.onfocus = "";
				}
			}
		}
		else
		{
			if (new RegExp("check_input").test(input_field.onblur))
				input_field.onblur = function(){ obj.hide(tip.id); obj.check_input(_input.field); }
			else
				input_field.onblur = function(){ obj.hide(tip.id); }
			
			// if we are not repeating the tip for evey focus
			// then clear the focus so it doesn't display again
			if (!settings.repeat)
			{
				input_field.onfocus = "";
			}
		}
	}

	/* --------------------------------------------
	 * doing everything we need to do when we run into an error
	 * ----------------------------------------- */
	this.report_error = function (_input)
	{
		var ignore_error = false;
		
		// if inline messages are enabled then 
		// check to see if we have already shown 
		// an error for this field
		if (this.cfg.msg_type == "inline")
		{
			// roll through old errors to make sure we have not 
			// reported an error already for this field
			for (var x=0; x < this.error_field.length; x++)
			{
				if (this.error_field[x] == _input.field)
					ignore_error = true;
			}		
		}
		
		// if we are displaying one message at a time then look to see if we already have an error
		// we do this so that we can roll through all the debugging if that is enabled
		if (((this.error_msg.length < 1) && (this.cfg.msg_all == 0)) || ((this.cfg.msg_all == 1) && (!ignore_error)))
		{	
			// define input field
			var input_field = eval("this.form." + _input.field);

			// we need to hold current values to make sure if the form
			// is submitted more then once with errors that we can reset 
			// field back to their origianl state
			var current_values = { field: _input.field };
			
			// check to see if we ignore message this 
			// is mainly used for the compare function
			// where we don't want to display 2 msgs
			if (_input.ignore_msg == null)
			{
				this.error_msg.push(_input.msg);
				this.error_field.push(_input.field);

				// if inline messages are enabled then display error
				if (this.cfg.msg_type == "inline")
				{
					var length = eval("this.form."+_input.field+".length");

					// accounts for radio and checkboxes
					if ((length != undefined) && (this.input_type(_input.field) == "radio" || this.input_type(_input.field) == "checkbox"))
					{
						input_field = input_field[length - 1];
					}

					// define the error element
					var err = null;

					// create error element
					if (!document.getElementById(_input.field + '_err'))
					{
						err = document.createElement('div');			
						err.id = _input.field + '_err';
						document.body.appendChild(err);
					}
					else
					{
						err = document.getElementById(_input.field + '_err');

						// make sure to start with a clean slate
						this.clear_fadein_fadeout(err.id);
					}

					err.style.position = "absolute";
					err.style.display = "block";
					err.style.filter = 'alpha(opacity=0)';
					err.style.opacity = 0;
					err.alpha = 0;

					// set html/format of error
					if (this.cfg.inline.htmlpre != "")
						err.innerHTML = this.cfg.inline.htmlpre + _input.msg + this.cfg.inline.htmlpost;
					else
						err.innerHTML = _input.msg;

					var top_position = 0;
					var left_position = 0;
					var settings = {};

					// merge the default parameters with the individual inline object
					if (typeof(_input.inline) == 'object')
						settings = this.extend_obj(this.cfg.inline, _input.inline);
					else
						settings = this.cfg.inline;

					// set position element
					settings.position_element = input_field;

					// In some case we don't just want the msg positioned by the
					// input field, radio buttons and check box are good examples					
					if (settings.position_id != undefined)
						if (document.getElementById(settings.position_id) != null)
							settings.position_element = document.getElementById(settings.position_id);
						

					// set positioning of error
					if ((settings.position == 'right') || (settings.position == 'left'))
					{
						if (settings.yalign == "top")
							top_position = this.top_position(settings.position_element) + settings.yoffset;
						else if (settings.yalign == "bottom")
							top_position = (this.top_position(settings.position_element) - (err.offsetHeight - settings.position_element.offsetHeight)) + settings.yoffset;
						else
							top_position = (this.top_position(settings.position_element) - ((err.offsetHeight - settings.position_element.offsetHeight) / 2)) + settings.yoffset;

						if (settings.position == 'right')
							left_position = this.left_position(settings.position_element) + settings.position_element.offsetWidth + settings.xoffset;
						else if (settings.position == 'left')
							left_position = this.left_position(settings.position_element) - (err.offsetWidth + settings.xoffset);
					}
					else if ((settings.position == 'top') || (settings.position == 'bottom'))
					{
						if (settings.position == 'top')
							top_position = this.top_position(settings.position_element) - (err.offsetHeight + settings.yoffset);
						else if (settings.position == 'bottom')
							top_position = this.top_position(settings.position_element) + settings.position_element.offsetHeight + settings.yoffset;

						if (settings.xalign == "left")
							left_position = this.left_position(settings.position_element) + settings.xoffset;
						else if (settings.xalign == "right")
							left_position = (this.left_position(settings.position_element) - (err.offsetWidth - settings.position_element.offsetWidth)) + settings.xoffset;
						else
							left_position = (this.left_position(settings.position_element) - ((err.offsetWidth - settings.position_element.offsetWidth) / 2)) + settings.xoffset;					
					}

					err.style.top = top_position + 'px';
					err.style.left = left_position + 'px';

					// setup both the fade in and fade out 
					var obj = this;

					this.msgs[err.id] = {};		
					this.msgs[err.id].spdout = settings.spdout;

					// look to see if we need to fade error in		
					if (settings.spdin > 0)
						this.msgs[err.id].timer_in = setInterval(function(){ obj.fade_in(err.id) }, settings.spdin);
					else
						this.display_msg(err.id);

					this.msgs[err.id].display = true;

					// set fade out if value is set
					if (settings.fadeout > 0)
					{
						this.msgs[err.id].fade_out = setTimeout(function(){ obj.hide(err.id); }, settings.fadeout * 1000);
					}
				}
			}

			// highlight label tag if provided
			if ((_input.hl_label != null) || (this.cfg.hl_label != null))
			{
				// look through all elements of the this.form for matching label tags
				for (var x=0; x < document.getElementsByTagName('label').length; x++)
				{ 
					if (_input.field == document.getElementsByTagName('label')[x].htmlFor)
					{
						
						if (_input.hl_label != null)
						{
							// highlight label if color is provided
							if ((_input.hl_label.color != "") && (_input.hl_label.color != null))
							{
								current_values.hl_label = { 'color': document.getElementsByTagName('label')[x].style.color };
								document.getElementsByTagName('label')[x].style.color = _input.hl_label.color;
							}
							
							// change class name if class is provided
							if ((_input.hl_label.class_name != "") && (_input.hl_label.class_name != null))
							{
								current_values.hl_label = { 'class_name': document.getElementsByTagName('label')[x].className };
								document.getElementsByTagName('label')[x].className = _input.hl_label.class_name;
							}
						}
						else if (this.cfg.hl_label != null)
						{
							// highlight label if color is provided
							if ((this.cfg.hl_label.color != "") && (this.cfg.hl_label.color != null))
							{
								current_values.hl_label = { 'color': document.getElementsByTagName('label')[x].style.color };
								document.getElementsByTagName('label')[x].style.color = this.cfg.hl_label.color;
							}
							
							// change class name if class is provided
							if ((this.cfg.hl_label.class_name != "") && (this.cfg.hl_label.class_name != null))
							{
								current_values.hl_label = { 'class_name': document.getElementsByTagName('label')[x].className };
								document.getElementsByTagName('label')[x].className = this.cfg.hl_label.class_name;
							}
						}
					}
				}
			}

			// highlight field if provided
			if ((_input.hl_field != null) || (this.cfg.hl_field != null))
			{
				var length = eval("this.form."+_input.field+".length");

				// accounts for radio and checkboxes
				if ((length != undefined) && (this.input_type(_input.field) == "radio" || this.input_type(_input.field) == "checkbox"))
				{
					for (var y=0; y < length; y++)
					{
						var input_field = eval("this.form."+_input.field+"[y]");
						
						current_values = this.field_highlight(_input, input_field, current_values);
					}
				}
				else
				{
					current_values = this.field_highlight(_input, input_field, current_values);
				}
			}

			// highlight div if provided
			if (_input.hl_by_id != null)
			{
				var hl_by_id = document.getElementById(_input.hl_by_id.id);

				if (hl_by_id == undefined)
				{
					this.debug.push("Highlight element '"+ _input.hl_by_id.id + "' does not exist for field " + _input.field);
				}
				else
				{
					// highlight element if color is provided
					if ((_input.hl_by_id.color != "") && (_input.hl_by_id.color != null))
					{
						try
						{
							current_values.hl_by_id = { id: _input.hl_by_id.id, 'color': hl_by_id.style.backgroundColor };
							hl_by_id.style.backgroundColor = _input.hl_by_id.color;
						}
						catch (e)
						{
							this.debug.push("backgroundColor for element '"+ _input.hl_by_id.id + "' does not exist for field " + _input.field);
						}
					}
					// change class name if class is provided
					if ((_input.hl_by_id.class_name != "") && (_input.hl_by_id.class_name != null))
					{
						try
						{
							current_values.hl_by_id = { id: _input.hl_by_id.id, 'class_name': hl_by_id.className };
							hl_by_id.className = _input.hl_by_id.class_name;
						}
						catch (e)
						{
							this.debug.push("className for element '"+ _input.hl_by_id.id + "' does not exist for field " + _input.field);
						}
					}
				}
			}
			
			// push current values in old errors
			this.old_errors.push(current_values);

			// set focus to the first error thrown
			if (!this.cfg.focus)
			{
				// accounts for radio and checkboxes
				try
				{
					if ((eval("this.form."+_input.field+".length") != undefined) && (this.input_type(_input.field) == "radio" || this.input_type(_input.field) == "checkbox"))
						eval("this.form."+_input.field+"[0].focus()");
					else
						input_field.focus();
				}
				catch (e)
				{
					// if focus Id is passed in
					if (_input.focus_id != undefined)
						document.getElementById(_input.focus_id).focus();
				}

				this.cfg.focus = true;
			}
		}
	}
	
	/* --------------------------------------------
	 * sets highlight for input field
	 * ----------------------------------------- */
	this.field_highlight = function (_input, input_field, current_values)
	{
	 	if (_input.hl_field != null)
	 	{
			// highlight field color if provided
			if ((_input.hl_field.color != "") && (_input.hl_field.color != null))
			{
				current_values.hl_field = { 'color': input_field.style.backgroundColor };
				input_field.style.backgroundColor = _input.hl_field.color;
			}
			
			// change class name if class is provided
			if ((_input.hl_field.class_name != "") && (_input.hl_field.class_name != null))
			{
				current_values.hl_field = { 'class_name': input_field.className };
				input_field.className = _input.hl_field.class_name;
			}
	 	}
	 	else if (this.cfg.hl_field != null)
	 	{
	 		// highlight field color if provided
			if ((this.cfg.hl_field.color != "") && (this.cfg.hl_field.color != null))
			{
				current_values.hl_field = { 'color': input_field.style.backgroundColor };
				input_field.style.backgroundColor = this.cfg.hl_field.color;
			}
			
			// change class name if class is provided
			if ((this.cfg.hl_field.class_name != "") && (this.cfg.hl_field.class_name != null))
			{
				current_values.hl_field = { 'class_name': input_field.className };
				input_field.className = this.cfg.hl_field.class_name;
			}
	 	}
	 	
		return current_values;
	}
	
	/* --------------------------------------------
	 * fades inline messages in and out
	 * ----------------------------------------- */
	this.fade_in = function (div_id)
	{
		var msg = document.getElementById(div_id);

		if(msg.alpha >= 95) 
		{	
			clearInterval(this.msgs[div_id].timer_in);
			this.display_msg(div_id);
		}
		else
		{
			var opacity = msg.alpha + 5;
			msg.alpha = opacity;
			msg.style.opacity = (opacity / 100);
			msg.style.filter = 'alpha(opacity=' + opacity + ')';		
		}
	}
	
	/* --------------------------------------------
	 * imidiately displays the error/tooltip
	 * ----------------------------------------- */
	this.display_msg = function (div_id)
	{
		var msg = document.getElementById(div_id);

		msg.alpha = 100;
		msg.style.opacity = 100;
		msg.style.filter = 'alpha(opacity=100)';
	}
	
	/* --------------------------------------------
	 * hides inline messages 
	 * ----------------------------------------- */
	this.hide = function (div_id)
	{
		var msg = document.getElementById(div_id);
		var obj = this;
		
		clearInterval(this.msgs[div_id].timer_in);
		clearInterval(this.msgs[div_id].timer_out);
		clearTimeout(this.msgs[div_id].fade_out);

		// look to see if we fade out
		if (this.msgs[div_id].spdout > 0)
			this.msgs[div_id].timer_out = setInterval(function(){ obj.fade_out(div_id) }, this.msgs[div_id].spdout);
		else
			this.clear_fadein_fadeout(div_id);
			
	}
	
	/* --------------------------------------------
	 * fades inline messages in and out
	 * ----------------------------------------- */
	this.fade_out = function (div_id)
	{
		var msg = document.getElementById(div_id);

		if(msg.alpha <= 1)
		{
			this.clear_fadein_fadeout(div_id);
		}
		else
		{
			var opacity = msg.alpha - 5;
			msg.alpha = opacity;
			msg.style.opacity = (opacity / 100);
			msg.style.filter = 'alpha(opacity=' + opacity + ')';		
		}
	}
	
	/* --------------------------------------------
	 * completely remove the fade in and fade out timers
	 * this is important when users flip back and forth
	 * quickly between input fields
	 * ----------------------------------------- */
	this.clear_fadein_fadeout = function (div_id)
	{
		var msg = document.getElementById(div_id);
		
		msg.alpha = 0;
		msg.style.opacity = 0;
		msg.style.filter = 'alpha(opacity=0)';
		msg.style.display = "none";
		
		if (typeof(this.msgs[div_id]) == 'object')
		{
			clearInterval(this.msgs[div_id].timer_in);		
			clearInterval(this.msgs[div_id].timer_out);
			clearTimeout(this.msgs[div_id].fade_out);
			this.msgs[div_id].display = false;
		}
	}
	 
	// calculate the position of the element in relation to the left of the browser //
	this.left_position = function (target)
	{
		var left = 0;
		
		if(target.offsetParent)
		{
	    		while(1)
	    		{
	      			left += target.offsetLeft;

	      			if(!target.offsetParent) 
					break;

	      			target = target.offsetParent;
	    		}
	  	}
	  	else if (target.x)
	  	{
	    		left += target.x;
	  	}

		return left;
	}

	// calculate the position of the element in relation to the top of the browser window //
	this.top_position = function (target)
	{
		var top = 0;
		
		if(target.offsetParent)
		{
	    		while(1)
	    		{
	      			top += target.offsetTop;
	      			
	      			if(!target.offsetParent)
					break;
					
				target = target.offsetParent;
			}
		}
		else if(target.y)
		{
			top += target.y;
		}

		return top;
	}

	/* --------------------------------------------
	 * makes sure characters are commented out for regexp
	 * ----------------------------------------- */
	this.make_regexp_safe = function (str)
	{
		str = str.replace(/\(/g, "\\(");
		str = str.replace(/\)/g, "\\)");
		str = str.replace(/\[/g, "\\[");
		str = str.replace(/\]/g, "\\]");
		str = str.replace(/\-/g, "\\-");
		str = str.replace(/\*/g, "\\*");
		str = str.replace(/\?/g, "\\?");
		str = str.replace(/\./g, "\\.");
		str = str.replace(/\$/g, "\\$");
		str = str.replace(/\^/g, "\\^");
		str = str.replace(/\|/g, "\\|");

		return str;
	}
	
	/* --------------------------------------------
	 * recursively merge properties of two objects 
	 * ----------------------------------------- */
	this.extend_obj = function (obj1, obj2) 
	{
		// first we need to clone the object
		var local_obj = {};
		for (var property in obj1)
		{
			local_obj[property] = obj1[property];
		}
		
		// now we can merge the objects
		for (var p in obj2) 
		{
			try 
			{
	      			// Property in destination object set; update its value.
				if ( obj2[p].constructor==Object ) 
					local_obj[p] = this.extend_obj(local_obj[p], obj2[p]);
				else
					local_obj[p] = obj2[p];

			} 
			catch(e) 
			{
				// Property in destination object not set; create it and set its value.
				local_obj[p] = obj2[p];

			}
		}

		return local_obj;
	}
}

/* --------------------------------------------
 * return true or false based on if a value exists
 * ----------------------------------------- */
function value_exists (parm)
{
	if ((parm != "") && (parm != undefined))
		return 1;
	else
		return 0;
}
