function SF_Validator()
{
	this.elements = new Array();
	this.errors = new Array();
}

SF_Validator.prototype.addElement = function(id, ruleType, compareValue, invalidMessage)
{	
	var rules = '';
	
	if (this.isArray(ruleType)) {
		rules = ruleType;
	}
	else {
		if (ruleType != undefined && ruleType != '') {
			rule = new Array();
			rule.push(ruleType);
			rule.push(compareValue);
			rule.push(invalidMessage);
			
			rules = new Array();
			rules.push(rule);
		}
	}

	if (this.isArray(rules)) {
	
		var element = new Array();
		
		if (typeof(id) == 'object') {
			element['object'] = id;
			element['id'] = 'null_id';
		}
		else
		{
			element['id'] = id;
		}
		
		element['invalidMessage'] = invalidMessage;
		element['rules'] = rules;
		
		this.elements.push(element);
	}
}

SF_Validator.prototype.isArray = function(obj)
{
	//alert(typeof(obj));
	if (obj == null || typeof(obj) != 'object' || obj.constructor.toString().indexOf("Array") == -1) {
		return false;
	}
	
	return true;
}

SF_Validator.prototype.generateError = function(element, rule)
{
	if ((rule[2] != undefined && rule[2] != '') || (element['invalidMessage'] != undefined && element['invalidMessage'] != '')) {
		
		if (!this.isArray(this.errors[element['id']])) {
			this.errors[element['id']] = new Array();
		}
		
		if (rule[2] != undefined && rule[2] != '')
		{
			this.errors[element['id']].push(rule[2]);
		}
		else
		{
			this.errors[element['id']].push(rule['invalidMessage']);
		}
	}
}

SF_Validator.prototype.inArray = function(itm, arr)
{
	for (i in arr)
	{
		if (itm == arr[i])
			return true;
	}
	
	return false;
}

SF_Validator.prototype.validate = function()
{
	var result = true;
	this.errors = new Array();
	
	for (i in this.elements)
	{
		var curr = this.elements[i];
		
		//jei keletas id'u
		if (curr['id'].indexOf(',') != -1) {
			
			var ids = curr['id'].split(',');
			
			var objs = new Array();
			
			for (k in ids)
			{
				objs.push(document.getElementById(ids[k]));
			}
			
			for (j in curr['rules']) 
			{
				currRule = curr['rules'][j];
				
				switch (currRule[0]) 
				{
					case 'required':
						var tmpRes = false;
						var tmpOk = true;
						
						for (k in objs)
						{
							if (objs[k].tagName.toLowerCase() != 'input' || objs[k].type.toLowerCase() != 'radio')
							{
								tmpOk = false;
							}
							
							if (tmpOk && objs[k].checked)
							{
								tmpRes = true;
							}
						}
						
						if (!tmpRes || !tmpOk)
						{
							this.generateError(curr, currRule);	
							result = false;
						}
						
						break;
				}
			}
		}
		else {
			if (curr['id'] == 'null_id') {
				var obj = curr['object'];
			}
			else {
				var obj = document.getElementById(curr['id']);
			}
			
			for (j in curr['rules'])
			{
				currRule = curr['rules'][j];
				
				if (obj.getHTMLBody != null && typeof(obj.getHTMLBody) == 'function') {
					var value = obj.getHTMLBody();
				}
				else {
					var value = obj.value;
				}
				
				switch (currRule[0])
				{
					case 'checked':
						if ((obj.tagName != null && obj.tagName.toLowerCase() == 'input' && !this.inArray(obj.type.toLowerCase(), Array('checkbox', 'radio'))) || !obj.checked)
						{
							this.generateError(curr, currRule);	
							result = false;
						}
						break;
					case 'unchecked':
						if ((obj.tagName != null && obj.tagName.toLowerCase() == 'input' && !this.inArray(obj.type.toLowerCase(), Array('checkbox', 'radio'))) || obj.checked)
						{
							this.generateError(curr, currRule);	
							result = false;
						}
						break;
					case 'notEmpty':
						
						if ((obj.tagName != null && obj.tagName.toLowerCase() == 'input' && !this.inArray(obj.type.toLowerCase(), Array('hidden', 'password', 'text', 'file'))) || value == '')
						{
							this.generateError(curr, currRule);	
							result = false;
						}
						break;
					case 'int':
						
						if ((obj.tagName != null && obj.tagName.toLowerCase() == 'input' && !this.inArray(obj.type.toLowerCase(), Array('hidden', 'password', 'text'))) || isNaN(value) || Math.floor(value) != value)
						{
							this.generateError(curr, currRule);	
							result = false;
						}
						break;
					case 'real':
						
						if ((obj.tagName != null && obj.tagName.toLowerCase() == 'input' && !this.inArray(obj.type.toLowerCase(), Array('hidden', 'password', 'text'))) || !value.match(/^\-?\d+([\,\.]\d+)?$/))
						{
							this.generateError(curr, currRule);	
							result = false;
						}
						break;
					case 'email':
						
						if ((obj.tagName != null && obj.tagName.toLowerCase() == 'input' && !this.inArray(obj.type.toLowerCase(), Array('hidden', 'password', 'text'))) || value == '' || !value.match(/^([a-zA-Z0-9_\.\-\+])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/))
						{
							this.generateError(curr, currRule);	
							result = false;
						}
						break;
					case 'alfanum':
						
						if ((obj.tagName != null && obj.tagName.toLowerCase() == 'input' && !this.inArray(obj.type.toLowerCase(), Array('hidden', 'password', 'text'))) || value == '' || !value.match(/^[a-zA-Z0-9]+$/))
						{
							this.generateError(curr, currRule);	
							result = false;
						}
						break;
					case 'date':
						
						var doesNotMeet = false;
						var dt = new Date();
						var dateStr= dt.getFullYear() + '-' + (dt.getMonth() < 9?'0':'') + (dt.getMonth() + 1) + '-' + (dt.getDate() < 10?'0':'') + dt.getDate();
												
						if (currRule[1] == 'past' && (value >= dateStr))
						{
							doesNotMeet = true;
						}
						if (currRule[1] == 'future' && (value <= dateStr))
						{
							doesNotMeet = true;
						}
						
						if ((obj.tagName != null && obj.tagName.toLowerCase() == 'input' && !this.inArray(obj.type.toLowerCase(), Array('hidden', 'password', 'text'))) || value == '' || !value.match(/^\d\d\d\d-\d\d-\d\d$/) || doesNotMeet)
						{
							this.generateError(curr, currRule);	
							result = false;
						}
						break;
					case 'time':
					
						var doesNotMeet = false;
						var dt = new Date();
						var dateStr= (dt.getHours() < 10?'0':'') + dt.getHours() + ':' + (dt.getMinutes() < 10?'0':'') + (dt.getMinutes() + 1) + ':' + (dt.getSeconds() < 10?'0':'') + dt.getSeconds();
												
						if (currRule[1] == 'past' && (value >= dateStr))
						{
							doesNotMeet = true;
						}
						if (currRule[1] == 'future' && (value <= dateStr))
						{
							doesNotMeet = true;
						}
						if ((obj.tagName != null && obj.tagName.toLowerCase() == 'input' && !this.inArray(obj.type.toLowerCase(), Array('hidden', 'password', 'text'))) || value == '' || !value.match(/^\d\d:\d\d:\d\d$/) || doesNotMeet)
						{
							this.generateError(curr, currRule);	
							result = false;
						}
						break;
					case 'datetime':
						
						if ((obj.tagName != null && obj.tagName.toLowerCase() == 'input' && !this.inArray(obj.type.toLowerCase(), Array('hidden', 'password', 'text'))) || value == '' || !value.match(/^\d\d\d\d-\d\d-\d\d\s\d\d:\d\d:\d\d$/))
						{
							this.generateError(curr, currRule);	
							result = false;
						}
						break;
					case 'currency':
						if ((obj.tagName != null && obj.tagName.toLowerCase() == 'input' && !this.inArray(obj.type.toLowerCase(), Array('hidden', 'password', 'text'))) || value == '' || !value.match(/^\d+[\.|,]\d{2}$/))
						{
							this.generateError(curr, currRule);	
							result = false;
						}
						break;
					case 'number':
						if ((obj.tagName != null && obj.tagName.toLowerCase() == 'input' && !this.inArray(obj.type.toLowerCase(), Array('hidden', 'password', 'text'))) || value == '' || isNaN(value))
						{
							this.generateError(curr, currRule);	
							result = false;
						}
						break;
					case 'regexp':
						var evalResult = true;
						
						if (obj.tagName != null && obj.tagName.toLowerCase() == 'input' && !this.inArray(obj.type.toLowerCase(), Array('hidden', 'password', 'text')))
						{
							evalResult = false;
						}
						else if (currRule[1] != '')
						{
							var tmpStr = 'evalResult = obj.value.match(' + currRule[1] + ');';
							eval(tmpStr);
						}
						
						if (currRule[1] == '' || !evalResult)
						{
							this.generateError(curr, currRule);	
							result = false;
						}
						break;
					case 'delegate':
						var evalResult = true;
						
						if (currRule[1] != '')
						{
							var tmpStr = 'evalResult = ' + currRule[1] + '(\'' + value + '\');';
							eval(tmpStr);
						}
						
						if (currRule[1] == '' || !evalResult)
						{
							this.generateError(curr, currRule);	
							result = false;
						}
						break;
					case 'equal':
						if (value != currRule[1])
						{
							this.generateError(curr, currRule);	
							result = false;
						}
						break;
					case 'notEqual':
						if (value == currRule[1])
						{
							this.generateError(curr, currRule);	
							result = false;
						}
						break;
					case 'fileExtension':
						
						var extension = value.substr(value.lastIndexOf('.') + 1).toLowerCase();
						
						var allowedExtensions = currRule[1].split('|');
						
						if (value != '' && !this.inArray(extension, allowedExtensions))
						{
							this.generateError(curr, currRule);	
							result = false;
						}
						break;
				}
			}
		}
	}
	
	return result;
}

SF_Validator.prototype.collectElements = function(vId)
{
	var oArray = new Array();
	
	var oTmp = document.getElementsByTagName('input');
	
	for (i in oTmp) 
	{
		var curr = oTmp[i];
		
		if (typeof(curr) == 'object') {
			oArray.push(curr);
		}
	}
	
	var oTmp = document.getElementsByTagName('textarea');
	
	for (i in oTmp) 
	{
		var curr = oTmp[i];
		
		if (typeof(curr) == 'object') {
			oArray.push(curr);
		}
	}
	
	var oTmp = document.getElementsByTagName('select');
	
	for (i in oTmp) 
	{
		var curr = oTmp[i];
		
		if (typeof(curr) == 'object') {
			oArray.push(curr);
		}
	}
	
	for (i in oArray)
	{
		var curr = oArray[i];
		
		if (typeof(curr) == 'object') {
			var att = curr.getAttribute('sf_validate_id');
			
			if (att == vId) {
				
				if (curr.getAttribute('id') == null)
				{
					var id = curr;
				}
				else
				{
					var id = curr.getAttribute('id')
				}
				
				this.addElement(id, curr.getAttribute('sf_validate_rule'), curr.getAttribute('sf_validate_value'), curr.getAttribute('sf_validate_error'));
			}
		}
	}
}
