function Validation(divid)
{
	var errordiv=divid;
	var valid=true;

	var conditional=new Array();
	var customConditional=new Array();
	var groups=new Array();
	var fields=new Array();
	var custom=0;
	var regex=1;
	var range=2;
	var gt=3;
	var lt=4;
	var required=5;
	var compare=6;
	
	this.addConditional=function(params)
	{
		conditional[params.group]=params;
	}
	
	this.addCustomConditional=function(params)
	{
		customConditional[params.group]=params;
	}

	this.addCustom=function(params)
	{
		if(params.group==null)
			params.group="main";
			
		if(params.message==null)
			params.message=params.name+" is not valid";
			
		this.initGroup(params.group,0);
		
		groups[params.group][custom].push(params);
		
		fields.push(params.field);
	}

	this.addRegex=function(params)
	{
		if(params.group==null)
			params.group="main";
			
		if(params.message==null)
			params.message=params.name+" is in an incorrect format";

		this.initGroup(params.group,1);
	
		groups[params.group][regex].push(params);
		
		fields.push(params.field);
	}

	this.addRange=function(params)
	{
		if(params.group==null)
			params.group="main";
			
		if(params.message==null)
			params.message=params.name+" must be between "+params.from+" and "+params.to;
			
		this.initGroup(params.group,2);
		
		groups[params.group][range].push(params);
		
		fields.push(params.field);
	}
	
	this.addMoreThan=function(params)
	{
		if(params.group==null)
			params.group="main";
			
		if(params.message==null)
			params.message=params.name+" must be at least "+(params.from+1);

		this.initGroup(params.group,3);
		
		groups[params.group][gt].push(params);
		
		fields.push(params.field);
	}
	
	this.addLessThan=function(params)
	{
		if(params.group==null)
			params.group="main";
			
		if(params.message==null)
			params.message=params.name+" must be less than or equal to "+(params.to-1);

		this.initGroup(params.group,4);
		
		groups[params.group][lt].push(params);
		
		fields.push(params.field);
	}

	this.addRequired=function(params)
	{
		if(params.group==null)
			params.group="main";
			
		if(params.message==null)
			params.message=params.name+" is a required field";
		
		this.initGroup(params.group,5);
					
		groups[params.group][required].push(params);
		
		fields.push(params.field);
	}
	
	this.addCompare=function(params)
	{
		if(params.group==null)
			params.group="main";
			
		if(params.message==null)
			params.message=params.name+" and "+params.name2+" must match";

		this.initGroup(params.group,6);
		
		groups[params.group][compare].push(params);
		
		fields.push(params.field1);
		fields.push(params.field2);
	}
	
	this.validate=function()
	{
		valid=true;
		
		//Hide all error displays for this validator
		for(var i=0;i<fields.length;i++)
		{
			this.hideError(fields[i]);		
		}
		
		//Remove any error messages from the error display, and then hide it
		var cNodes=document.getElementById(errordiv+'_ul').childNodes;
		while(cNodes.length>0)
			document.getElementById(errordiv+'_ul').removeChild(cNodes[0]);

		//Iterate through our validation groups
		for(var key=0;key<groups.length;key++)
		{
			//Check if there is a conditional validator for this field
			if(key in conditional)
			{
				if(document.getElementById(conditional[key].field).type=='checkbox')
				{
					var ret;
					if(conditional[key].test=="==")
						ret=document.getElementById(conditional[key].field).checked;
					else
						ret=!document.getElementById(conditional[key].field).checked;
					if(ret)
						continue; //skip this group
				}					
				else if(!this.condTest(conditional[key].field,conditional[key].value,conditional[key].test))
					continue; //skip this group
			}
			//Check if there is a custom conditional validator for this field
			if(key in customConditional)
			{
				var func="val_"+customConditional[key].method;
				if(window[func])
				{
					if(!window[func](fields[customConditional[key].field]))
						continue; //skip this group
				}
			}
			
			//Custom validators
			if(groups[key][custom]!=null)
			{
				for(var i=0;i<groups[key][custom].length;i++)
				{
					var obj=groups[key][custom][i];
					
					var func="val_"+obj.method;
					if(window[func])
					{
						if(!window[func](obj.field))
						{
							this.showError(obj.field);
							this.appendError(obj.message);
							valid=false;
						}
					}
				}
			}
			
			//Required validators
			if(groups[key][required]!=null)
			{
				for(var i=0;i<groups[key][required].length;i++)
				{
					var obj=groups[key][required][i];
					if(this.required(obj.field))
					{
						this.showError(obj.field);
						this.appendError(obj.message);
						valid=false;
					}
				}
			}
			
			//Regex validators
			if(groups[key][regex]!=null)
			{
				for(var i=0;i<groups[key][regex].length;i++)
				{
					var obj=groups[key][regex][i];
					
					if(this.trim(this.value(obj.field))!="")
					{
						if(this.trim(this.value(obj.field)).match(obj.regex))
						{
							this.showError(obj.field);
							this.appendError(obj.message);
							valid=false;
						}
					}
				}
			}
			
			//Range validators
			if(groups[key][range]!=null)
			{
				for(var i=0;i<groups[key][range].length;i++)
				{
					var obj=groups[key][range][i];
					
					if(this.value(obj.field)<obj.from || this.value(obj.field)>obj.to)
					{
						this.showError(obj.field);
						this.appendError(obj.message);
						valid=false;
					}
				}
			}
			
			//More than validators
			if(groups[key][gt]!=null)
			{
				for(var i=0;i<groups[key][gt].length;i++)
				{
					var obj=groups[key][gt][i];
					
					if(parseInt(this.value(obj.field))<=obj.from)
					{
						this.showError(obj.field);
						this.appendError(obj.message);
						valid=false;
					}
				}
			}
			
			//Less than validators
			if(groups[key][lt]!=null)
			{
				for(var i=0;i<groups[key][lt].length;i++)
				{
					var obj=groups[key][lt][i];
					
					if(parseInt(this.value(obj.field))>=obj.to)
					{
						this.showError(obj.field);
						this.appendError(obj.message);
						valid=false;
					}
				}
			}
			
			//Compare validators
			if(groups[key][compare]!=null)
			{
				for(var i=0;i<groups[key][compare].length;i++)
				{
					var obj=groups[key][compare][i];
					
					if(this.value(obj.field1)!=this.value(obj.field2))
					{
						this.showError(obj.field2);
						this.showError(obj.field1);
						this.appendError(obj.message);
						valid=false;
					}
				}
			}
		}
		if(valid)
			document.getElementById(errordiv).style.display='none';
		else
		{
			document.getElementById(errordiv).style.display='block';
			window.scroll(document.getElementById(errordiv).offsetTop,document.getElementById(errordiv).offsetLeft);
		}
			
		return valid;
	}
	
	this.condTest=function(id,val2,test)
	{
		var ret=false;
		var val1=this.value(id);

		switch(test)
		{
			default:
			case "==":
				if(val1==val2)
					ret=true;
				break;
			case "===":
				if(val1==val2)
					ret=true;
				break;
			case "!=":
				if(val1!=val2)
					ret=true;
				break;
			case "!==":
				if(val1!=val2)
					ret=true;
				break;
			case ">":
				if(val1>val2)
					ret=true;
				break;
			case ">=":
				if(val1>=val2)
					ret=true;
				break;
			case "<":
				if(val1<val2)
					ret=true;
				break;
			case "<=":
				if(val1<=val2)
					ret=true;
				break;
		}
		return ret;
	}
	
	this.showError=function(id)
	{
		var item=document.getElementById(id+'_error');
		if(item!=null)
		{
			item.style.display='inline';
			item=null;
		}
		else
			alert(id+' is not a valid error display');
	}
	
	this.hideError=function(id)
	{
		var item=document.getElementById(id+'_error');
		if(item!=null)
		{
			item.style.display='none';
			item=null;
		}
		else
			alert(id+' is not a valid error display');
	}
	
	this.appendError=function(text)
	{
		if(text!='')
		{
			listNode = document.getElementById(errordiv+'_ul');
			itemNode = document.createElement('li');
			itemNode.innerHTML=text;
			listNode.appendChild(itemNode);
		}
	}
	
	this.isnum=function(id)
	{
		return (parseInt(document.getElementById(id).value)==document.getElementById(id).value);
	}
	
	this.value=function(id)
	{
		try
		{
			return document.getElementById(id).value;
		}
		catch(err)
		{
			alert(err);
		}	
	}
	
	this.required=function(id)
	{
		try
		{
			if(document.getElementById(id).type=='checkbox')
				return document.getElementById(id).checked;
			return (this.trim(document.getElementById(id).value)=='');
			
		}
		catch(err)
		{
			alert(err);
			return false;
		}
	}
	
	this.trim=function(str)
	{
		while(''+str.charAt(0)==' ')
			str=str.substring(1,str.length);
		while(''+str.charAt(str.length-1)==' ')
			str=str.substring(0,str.length-1);
		return str;
	}
	
	this.initGroup=function(group,type)
	{
		if(groups[group]==null)
			groups[group]=new Array();
		if(groups[group][type]==null)
			groups[group][type]=new Array();
	}
}

/**
 * e-Commerce System
 * Copyright (c) 2002-2007 Philip John, All Rights Reserved.
 * Author	: Philip John
 * Version	: 6.4
 *
 * PROPRIETARY/CONFIDENTIAL.  Use is subject to license terms.
 */

/**
 * Form postback methods
 */
function postback(button,url,vars,vals)
{
	button.setAttribute('action','none');
	form=document.getElementById('postback');
	form.action=dir+"index.php?fuseaction="+url;
	for(var i=0;i<vars.length;i++)
	{
		node=document.createElement('input');
		node.setAttribute('type','hidden');
		node.setAttribute('name',vars[i]);
		node.setAttribute('value',vals[i]);
		form.appendChild(node);
		node=null;
	}
	form.submit();
	form=null;
	return false;
}

function postbackConf(button,url,vars,vals,verb,noun)
{
	button.setAttribute('action','none');
	var answer = confirm("Are you sure you want to "+verb+" this "+noun+"?");
	if(answer)
	{
		form=document.getElementById('postback');
		form.action=dir+"index.php?fuseaction="+url;
		for(var i=0;i<vars.length;i++)
		{
			node=document.createElement('input');
			node.setAttribute('type','hidden');
			node.setAttribute('name',vars[i]);
			node.setAttribute('value',vals[i]);
			form.appendChild(node);
			node=null;
		}
		form.submit();
	}
	form=null;
	return false;
}

function postbackMulti(button,url)
{
	button.setAttribute('action','none');
	form=document.getElementById('postback_multi');
	form.action=dir+"index.php?fuseaction="+url;
	form.submit();
	form=null;
	return false;
}

function changeState(checkbox,vars,count)
{
	for(var i=0;i<vars.length;i++)
		for(var j=0;j<count[i];j++)
			document.getElementById(vars[i]+"_"+j).checked=checkbox.checked;
	checkbox=null;
}

/**
 * Confirmation functions
 */

function confAct(location)
{
	var answer = confirm ("Are you sure?")
	if (answer)
		window.location=location;
}

function formConfAct(form,url,verb,noun)
{
	var answer = confirm("Are you sure you want to "+verb+" this "+noun+"?");
	if(answer)
		form.action=dir+url;
	form=null;
	return answer;
}

/**
 * Caps lock detection
 */

function caps(event,elem)
{
	if(!event)
		event=window.event;
	if(!event)
		return;
	if(event.charCode)
		keypress=event.charCode;
	else if(event.which)
		keypress=event.which;
	else if(event.keyCode)
		keypress=event.keyCode;
	else
		keypress=0;

	var shiftkey=event.shiftKey || (event.modifiers && (event.modifiers & 4));
	if((keypress>64 && keypress<91 && !shiftkey) || (keypress>96 && keypress<123 && shiftkey))
		elem.className='capslock';
	else
		elem.className='';
	event=null;
}

/**
 * Generic functions
 */

function isArray(obj)
{
   if (obj.constructor.toString().indexOf("Array") == -1)
      return false;
   else
      return true;
}

function getElementsByClassName(oElm, strTagName, strClassName){
	var arrElements = (strTagName == "*" && document.all)? document.all :
	oElm.getElementsByTagName(strTagName);
	var arrReturnElements = new Array();
	strClassName = strClassName.replace(/\-/g, "\\-");
	var oRegExp = new RegExp("(^|\\s)" + strClassName + "(\\s|$)");
	var oElement;
	for(var i=0; i<arrElements.length; i++){
		oElement = arrElements[i];
		if(oRegExp.test(oElement.className)){
			arrReturnElements.push(oElement);
		}
	}
	return (arrReturnElements)
}

/**
* Function : dump()
* Arguments: The data - array,hash(associative array),object
*    The level - OPTIONAL
* Returns  : The textual representation of the array.
* This function was inspired by the print_r function of PHP.
* This will accept some data as the argument and return a
* text that will be a more readable version of the
* array/hash/object that is given.
*/
function dump(arr,level) {
var dumped_text = "";
if(!level) level = 0;

//The padding given at the beginning of the line.
var level_padding = "";
for(var j=0;j<level+1;j++) level_padding += "    ";

if(typeof(arr) == 'object') { //Array/Hashes/Objects
 for(var item in arr) {
  var value = arr[item];
 
  if(typeof(value) == 'object') { //If it is an array,
   dumped_text += level_padding + "'" + item + "' ...\n";
   dumped_text += dump(value,level+1);
  } else {
   dumped_text += level_padding + "'" + item + "' => \"" + value + "\"\n";
  }
 }
} else { //Stings/Chars/Numbers etc.
 dumped_text = "===>"+arr+"<===("+typeof(arr)+")";
}
return dumped_text;
} 
