/*
 * Copyright © 2010 Russian multimedia company
 * $Date: 2010-01-26 22:39:49 +0500 (Tue, 26 Jan 2010) $
 * $Version: 1.0.5 $
 */
/**
 * Form's validator
 * 
 * Copyright (c) 2007 CSC
 *
 * @description Client side form validation. Integrating client side form validation is as simple 
 * as adding a css class to a form element
 * @param All parameters are optional
 * @author rz <roman@plotinka.ru>
 * @version 1.0.1
 */
 
var Forms = {};

Forms.conf = {
	prefix_req_field_id:   'req',
    prefix_error_elem_id:  'error',
	prefix_help_elem_id:   'help',
	error_field_classname: 'input-field-error'
};

Forms.Form = function (fid, pref) {
	fid = (null != fid && 'object' == typeof fid) ? fid : document.getElementById(fid);
	
	if (null == fid) {
		return false;
	}
	
	this.oForm    = fid;
	this.aFields  = {};
	this.aButtons = {};
	this.aLabels  = {};
	this.reqprefix   = pref || Forms.conf['prefix_req_field_id'];
	this.init();
};

Forms.Field = function (fid, type) {
    this.oField = fid;
	this.pType  = type || '';
};

Forms.Button = function (bid, type) {
    this.oButton = bid;
	this.pType   = type || '';
};

Forms.Label = function (lid, id) {
    this.oLabel = lid;
	this.pFor   = id;
};

Forms.Form.prototype.init = function() {
    var frm = this, i, j, l, k, commelem, f, labels, id, name, optelem, switcher, type;
	
	f = this.oForm.elements;

	for (i = 0, l = f.length; i < l; i++) {

		switch (f[i].type) {
			case 'submit': {

				this.aButtons[f[i].type] = new Forms.Button(f[i], type);
				f[i].onclick = function() {
					return function () {
					    if (frm.validate()) {
							this.value    = 'Loading...';
							this.disabled = true;
							this.form.submit();
						} else {
						    return false;
						}
					}
				}();
					
			}
			break;
			case 'reset': {
			
				this.aButtons[f[i].type] = new Forms.Button(f[i], type);
				f[i].onclick = function() {
					return function () {
					    return confirm(this.value + '?');
					}
				}();
				
			}
			break;
			default: {
				
				id = (f[i].name) ? f[i].name : f[i].id;

				if (-1 != id.indexOf(this.reqprefix + ':')) {
								  
					name = id.replace(this.reqprefix + ':', ''); //.slice(0, -1);
					type = f[i].value.replace(/\s.*/gi, '');

					if ('' == name) {
						continue;
					}

					if (null != f[name] && 'object' == typeof f[name]) {
						this.aFields[name] = new Forms.Field(f[name], type);

						if (null == this.oForm.focally) {
							if ('' == f[name].value && 1 == f[name].tabIndex) {
								this.oForm.focally = name;
								f[name].focus();
							}
						}
					}

				}

			}
		}

	}

	labels = this.oForm.getElementsByTagName('label');
	for (i = 0, l = labels.length; i < l; i++) {
		if (labels[i].htmlFor && null != this.aFields[labels[i].htmlFor]) {
			
			this.aLabels[labels[i].htmlFor] = new Forms.Label(labels[i], labels[i].htmlFor);
			
			commelem = document.getElementById(Forms.conf['prefix_help_elem_id'] + ':' + labels[i].htmlFor);
			
			if (null != commelem && 'object' == typeof commelem) {
				labels[i].onclick = function(elem) {
					return function () {
						if ('none' == frm.getElementStyle(elem, 'display')) {
							elem.style.display = 'block';
						} else {
							elem.style.display = 'none';
						}
						return true;
					}
				}(commelem);
				
			 // labels[i].style.textDecoration = 'underline';
				labels[i].style.borderBottom = '1px dashed';
			} else {
				labels[i].title= '';
			}
		}	
	}
	
	switcher = this.oForm.getElementsByTagName('a');
	for (i = 0, l = switcher.length; i < l; i++) {
		if (-1 != switcher[i].id.indexOf(Forms.conf['prefix_req_field_id'] + ':')) {
		    
			id = switcher[i].id.replace(Forms.conf['prefix_req_field_id'] + ':', ''); //.slice(0, -1);
																						   
			if (-1 != id.indexOf(':')) {
				name = id.substr(0, id.indexOf(':')); 
				id   = id.substr(id.indexOf(':') + 1);
				
                var optarr = [];
				optelem = this.oForm.getElementsByTagName(name);
				for (j = 0, k = optelem.length; j < k; j++) {
					if (id == optelem[j].className) {
						optarr[optarr.length] = optelem[j];
					}
				}
				
				switcher[i].onclick = function(obj) {
					return function () {
						var i, l;
						
						l = obj.childNodes.length;
						if (l > 1) {
							for (i = 0; i < l; i++) {
								obj.childNodes[i].style.display = ('none' == frm.getElementStyle(obj.childNodes[i], 'display')) ? 'inline' : 'none';
							}	
						}
						
						for (i = 0, l = optarr.length; i < l; i++) {
							optarr[i].style.display = ('none' == frm.getElementStyle(optarr[i], 'display')) ? 'block' : 'none';
						}
						return false;
					}
				}(switcher[i]);	
	
				break;
			}
			
		}
	}
    
	return true;
};

Forms.Form.prototype.validate = function() {
    var i, j, l, aFields = this.aFields, error = true, oFirstField = null;
	
    for (i in aFields) {

		switch (aFields[i].oField.type) {
			case 'text':
			case 'hidden':
			case 'file':
			case 'textarea': 
			case 'password': { 
			    error = this.errorHandler(aFields[i], aFields[i].oField.value);
			}
			break;
			case 'radio': {  
		      	for (j = 1, l = aFields[i].oField[aFields[i].oField.name].length; j < l; j++) {
		      		if (aFields[i].oField[aFields[i].oField.name][j].checked) {
						error = false;
						break;
		      		}
		      	}
			}
			break;
			case 'checkbox': { 
			    error = aFields[i].oField.checked;
			}
			break;
			case 'select-one': { 
			    error = (0 == aFields[i].oField.options.length) ? true : this.errorHandler(aFields[i], aFields[i].oField.options[aFields[i].oField.selectedIndex].value);
			}
			break;
			case 'select-multiple': { 
		      	for (j = 1, l = aFields[i].oField.options.length; j < l; j++) {
		      		if (aFields[i].oField.options[j].selected) {
						error = this.errorHandler(aFields[i], aFields[i].oField.options[j].value);
		      		}
		      	}
			}
			break;
			default: {
			}
		}
		
        if (!error) {
			this.errorShower(aFields[i], error);
		} else {
			oFirstField = (null == oFirstField) ? aFields[i] : oFirstField;
		}
		
    }
	
	if (null != oFirstField) {
		this.errorShower(oFirstField, true);
		return false;
	}
	
	return true;
};

Forms.Form.prototype.errorHandler = function(obj, str) {
    var error = true, etype = obj.pType, i, l, reg, str2 = '';
    
    if (null == str || 'undefined' == str || 0 == str.length) {
		return error;
	}

	switch (etype) {
		case 'login': {
			if (3 > str.length || 20 < str.length) {
				error = true;
			} else {
				reg   = /^[a-zA-Z0-9-]+$/;
				error = (str.match(reg)) ? false : true;
			}
		}
		break;
        case 'name':
		case 'surname': {
		    reg = /\s{2,}/;
			str = str.replace(reg, ' ');
			obj.oField.value = str;
			
			if (3 > str.length || 30 < str.length) {
				error = true;
			} else {
				reg   = /^([а-яА-Яa-zA-Z]+[-\s]?[а-яА-Яa-zA-Z]+)+$/;
				error = (str.match(reg)) ? false : true;
			}
		}
		break;
		case 'email': { 
		    reg = /\.{2,}/;
			str = str.replace(reg, '.');
			obj.oField.value = str;
			
			if (7 > str.length || 40 < str.length) {
				error = true;
			} else {
				reg   = /^[\w-]+(\.[\w-]+)*@([\w-]+\.)+[a-zA-Z]{2,7}$/;
				error = (str.match(reg)) ? false : true;
			}
		}
		break;
		case 'passw':
		case 'code': {
			if (3 > str.length || 32 < str.length) {
				error = true;
			} else {
				reg   = /^[a-zA-Z0-9]+$/;
				error = (str.match(reg)) ? false : true;
			}
		}
		break;
		case 'imgcode': {
			if (6 != str.length) {
				error = true;
			} else {
				reg   = /^[a-zA-Z0-9]+$/;
				error = (str.match(reg)) ? false : true;
			}
		}
		break;
		case 'phone': {
			reg = /[^0-9]/g;
			str2 = str.replace(reg, '');
			
			if (8 == str2.charAt(0) || 7 == str2.charAt(0)) {
		        str2 = str2.substr(1);
			}

			if (9 < str2.length || 12 > str2.length) {
			     str = '8 ';
				 for (i = 0, l = str2.length; i < l; i++) {
				     if (7 < l) {
					     str += (0 == i) ? '(' : ((3 == i) ? ') ' : '');
					 }
					 
					 str += str2.charAt(i) + ((((7 >= l && i == 2) || i == 4 || i == 7 || i == 9) && str2.charAt(i + 1)) ? '-' : '');
				 }
				 obj.oField.value = str;
				 
				 error = false;
			}
		}
		break;
		case 'int':
		case 'number':
		case 'float': {
		    reg = /[,\.]{2,}/;
			str = str.replace(reg, '.');
			if (obj.oField.value) {
				obj.oField.value = str;
			}
			
		    reg   = /^-?(\d+)\.?(\d+)?$/;
			error = (str.match(reg)) ? false : true;
		}
		break;
		case 'text':
		case 'string':
		case 'message': {
			str   = str.toString();
			error = (str.length >= 3) ? false : true;
		 // && str != obj.oField.defaultValue
		}
		break;
		default: {
		}
	}

	return error;
};

Forms.Form.prototype.errorShower = function(obj, error) {
    var i, classname, errorelem, commelem;

	errorelem = document.getElementById(Forms.conf['prefix_error_elem_id'] + ':' + obj.oField.id);
	commelem  = document.getElementById(Forms.conf['prefix_help_elem_id'] + ':' + obj.oField.id);

	if (null != errorelem && 'object' == typeof errorelem) {
		if (error) {
			errorelem.style.display = 'block';
			classname = obj.oField.className.replace(Forms.conf['error_field_classname'], '');	
			
		    switch (obj.oField.type) {
				case 'text':
				case 'file':
				case 'textarea': 
				case 'password': {
				    obj.oField.className = ('' == classname) ? Forms.conf['error_field_classname'] : classname + ' ' + Forms.conf['error_field_classname'];
				    obj.oField.focus();
			    }
		    }
			
			if (obj.oField.select) {
			    obj.oField.select();
			}
			
			if (null != commelem && 'object' == typeof commelem) {
			    commelem.style.display = 'block';
			}
		} else {
			errorelem.style.display = 'none';
			obj.oField.className = obj.oField.className.replace(Forms.conf['error_field_classname'], '');
			
			if (null != commelem && 'object' == typeof commelem) {
			    commelem.style.display = 'none';
			}
			
			return true;
		}
	}
		
	return false;
};

Forms.Form.prototype.getElementStyle = function(obj, ieProp, cssProp) {
	var val = '', cssProp = cssProp || ieProp;
	
	if (null == obj || 'object' != typeof obj || !ieProp) {
		return val;
	}
	
	if (obj.currentStyle) {
		val = obj.currentStyle[ieProp];
	} else if (window.getComputedStyle && cssProp) {
		val = window.getComputedStyle(obj, '').getPropertyValue(cssProp);
	} 

	return val;
}

