/* Validation functions */
var ncValid = new Class({
	initialize: function(){
		this.forms  = new Hash();
		this.fields = new Hash();
		this.lastform = false;
		this.errStartColour = '#ff0000';
		this.errEndColour = '#ffffff';
	},
	regForm: function(form, params) {
		opt = Hash.extend({handle:true, ajax:true, evalScripts:true}, params);
		
		//make sure the form exists
		var formName = this.formName(form);

		if($(formName) === null) {
			alert('Form ' + formName + ' not found : aborting');
			return;
		}
		//register it
		this.fields.set(form, new Hash());// = new Array();
		
		this.forms.set(form, opt);
		

		//set it to be last form
		this.lastform = form;
		//do they want us to handle the form?
		if (opt.handle) {
			var oldsubmit = $(formName).onsubmit;
			
			$(formName).onsubmit = function() {
				if(typeof oldsubmit == 'function') oldsubmit();
				if (window.tinyMCE) {
					tinyMCE.triggerSave();
				}
				return Valid.submitForm(form)
			};
			
		}
	},
	
	unregisterAllForms : function() {
		if (window.tinyMCE) {
			this.killTinyMCE();
		}
		this.forms.each(function(pair){
			Valid.unregisterForm(pair.key);
		})
	},
	
	unregisterForm : function(name) {
		if (window.tinyMCE) {
			this.killTinyMCE();
		}
		this.forms.erase(name);
		this.fields.erase(name);
		if (this.lastform == name){
			this.lastform = false;
		}
	},
	
	killTinyMCE : function() {
		if (tinyMCE.majorVersion == 2) {
			for (var n in tinyMCE.instances) {
				if (!tinyMCE.isInstance(tinyMCE.instances[n]))
					continue;
//				var inst = tinyMCE.getInstanceById(n)
//				tinyMCE.removeInstance(inst);
				tinyMCE.removeMCEControl(n);
			}
		} else {
			for (var n in tinyMCE.editors) {
				if (!tinyMCE.get(n)){
							continue;
				}
				killMce(n);
			}
		}
//			var inst = tinyMCE.getInstanceById(n)
//			tinyMCE.removeInstance(inst);
		
	},
	
	unregisterField : function (name, form) {
		form = form?form:this.lastform;
		name = this.fieldName(name);
		this.fields.get(form).erase(name);
		this.removeError(name);
	},
	
	regField : function(name, params) {
		var field = this.fieldName(name);
		
		if($(field)===null){
			alert('field ' + field + ' not found : aborting');
			return;
		}
		var options = Hash.extend({type:'text', error:'', optional:false}, params);
		
		//add in the onchange event
		var formname = this.lastform;
		$(field).onchange = function() { Valid.check(name, formname)};
		this.fields.get(formname).set(field, options);
	},
	
	fieldName : function(name) {
		//var ucname = name;
		//ucname[0] = name.charAt(0).toUpperCase();
		//return this.lastform + ucname;
		return this.lastform + name.ucFirst();
	},
	
	formName : function(name) {
		return name + 'Form';
	},
	
	check : function(field, form, nameOK) {
		this.lastform = form;

		var fName = nameOK === true? field:this.fieldName(field);
		var cField = $(fName);

		opt = this.fields.get(form).get(fName);
		
		var valid = true;
		
		if (opt.optional && cField.value.trim() == '') {
			this.removeError(fName);
			return valid;
		}
		
		switch (opt.type) {
			case 'text':
				if (cField.value.trim() == '' && opt.optional == false) {
					valid = false;
					opt.error = 'Nothing entered';
				}
				break;
			case 'email':
				if(!cField.value.isEmail()) {
					valid = false;
					opt.error = 'Invalid Email Address';
				}
				break;
			case 'numeric':
				if(!cField.value.isNumeric()){
					valid = false;
					opt.error = 'Is not numeric';
				} else if(opt.start != undefined && !cField.value.isGreater(opt.start)) {
					valid = false;
					opt.error = 'Value must be ' + opt.start + ' or greater';
				} else if(opt.end != undefined && !cField.value.isLesser(opt.end)){
					valid = false;
					opt.error = 'Value must be ' + opt.end + ' or lesser';
				}
				break;
			case 'alpha':
				if(!cField.value.isAlpha()) {
					valid = false;
					opt.error = 'Value must contain only alphabetical characters';
				}
				break;
			case 'alphanum':
				if(!cField.value.isAlphaNum()) {
					valid = false;
					opt.error = 'Value must contain only alphanumeric characters';
				}
				break;
			case 'decimal':
				if(!cField.value.isDecimal()) {
					valid = false;
					opt.error = 'Value must be a decimal field';
				}
				break;
			case 'match':
				var mField = $(this.fieldName(opt.match));
				if (mField.value != cField.value) {
					valid = false;
					opt.error = 'Fields must match';
				}
				break;
			case 'url':
				if (cField.value.indexOf(" ") != -1) { 
					//url contains a space
					valid = false;
					opt.error = 'URL must not contain spaces';
				}
				break;
			case 'compare':
				break;
			case 'youtube':
				// Convert the youtube watch url to just the v parameter's value
				//alert(cField.value);
				cField.value = cField.value.replace(/http:\/\/www.youtube.com\/watch\?v=([^&]+).*$/, '$1');
				break;
				
			default: break;
		}
		
		if(valid && (!opt.optional || cField.value.length > 0)) {
			if (opt.sizeS != undefined && cField.value.length < opt.sizeS) {
				valid = false;
				opt.error = 'Minimum ' + opt.sizeS + ' characters';
			} else if (opt.sizeL != undefined && cField.value.length > opt.sizeL) {
				valid = false;
				opt.error = 'Maximum ' + opt.sizeL + ' characters';
			}
		}
		
		if (!valid) {
			//put an effect on the label
			this.fields.get(form).set(fName, opt);
			this.triggerError(fName);
			
			return valid;
		} else {
			this.removeError(fName);
			return valid;
		}
	},
	
	triggerError: function(field) {
		if ($(field)) {
			if (Fx.Style) {	
				var fx = new Fx.Style(field, 'background-color').start(this.errStartColour, this.errEndColour);
			} else {
				var fx = new Fx.Tween(field).start('background-color', this.errStartColour, this.errEndColour);
			}
		}
		//also check for label
		var lbl = $(field + 'Lbl');
		if (!lbl) {
			return;
		}
		var emsg = $(field + 'Emsg');
		if(!emsg) {
			//put some text inside the label
			var emsg = document.createElement('span');
			emsg.className = 'error';
			emsg.id = field + 'Emsg';
			lbl.appendChild(emsg);
		}
		emsg.style.display = '';
		emsg.innerHTML = this.fields.get(this.lastform).get(field).error;
		
		var erow = $(field + 'Row');
		if (erow) {
			erow.className = addClass(erow.className, 'error');
		}
	},
	
	triggerErrorText: function(field, errText) {
		if ($(field)) {
			if (Fx.Style) {	
				var fx = new Fx.Style(field, 'background-color').start(this.errStartColour, this.errEndColour);
			} else {
				var fx = new Fx.Tween(field).start('background-color', this.errStartColour, this.errEndColour);
			}
		}
		
		//also check for label
		var lbl = $(field + 'Lbl');
		if (!lbl) {
			return;
		}
		var emsg = $(field + 'Emsg');
		if(!emsg) {
			//put some text inside the label
			var emsg = document.createElement('span');
			emsg.className = 'error';
			emsg.id = field + 'Emsg';
			lbl.appendChild(emsg);
		}
		emsg.style.display = '';
		emsg.innerHTML = errText;
		
		var erow = $(field + 'Row');
		if (erow) {
			erow.className = addClass(erow.className, 'error');
		}
	},
	
	removeError : function(field) {
		if ($(field + 'Emsg')) {
//			$(field + 'Emsg').parentNode.removeChild($(field + 'Emsg'));
			$(field + 'Emsg').style.display = 'none';
		}
		
		var erow = $(field + 'Row');
		if (erow) {
			erow.className = removeClass(erow.className, 'error');
		}
	},
	
	checkForm : function(form) {
		if(!((MooTools.version < '1.2')?this.forms.hasKey(form):this.forms.has(form))) {
			return false;
		}
		this.lastform = form;
		var fields = this.fields.get(form), valid = true;

		fields.each(function(item, index){
			valid = Valid.check(index, form, true)?valid:false;
		});

		return valid;
	},
	
	submitForm : function(form) {
		var name = $(this.formName(form));
		if (!name) return false;
		if (!((MooTools.version < '1.2')?this.forms.hasKey(form):this.forms.has(form))) return false;
		
		//search for any xstandard objects. because of a bug or whatever, we look for
		//forms elements that are name with xstandard at the beginning, and use their
		//value to find the xstandard object
		$(name).getElements('input[name^=xstandard]').each(function(item,key) {
			//make sure it is xstandard
			if(typeof($(item.value).EscapeUnicode) != 'undefined') {
				//slot into the hidden form field
				$(item.value + 'Hidden').value = $(item.value).value;
			}
		});
		
		var opt = Hash.extend({data:$(name).toQueryString(), method:'post'}, this.forms.get(form));
		
		var valid = this.checkForm(form);
		if (!valid) {
			return false;
		}

		if (opt.upload || !opt.ajax) {
			return true;
		}
		
		this.loadingDiv(form)

		if (typeof(Request) == 'undefined') {
			var ajax = new Ajax(opt.url, opt).request();
		} else {
			var ajax = new Request.HTML(opt).send();
		}

		return false;
	},
	
	loadingDiv : function(form) {
		var name = $(this.formName(form));

		if (!name) return false;
		if (!this.forms.get(form)) return false;
		
		var subit = $(form + 'Subit');
		
		if (subit) subit.disabled = true;
		
		formDiv = $(form + 'Div');
		if (!formDiv) return false;
		
		formDiv.className += ' loadback';
		
		var loadingDiv = document.createElement('div');
		
		
		loadingDiv.style.height = formDiv.offsetHeight + 'px';
		loadingDiv.style.width  = formDiv.offsetWidth + 'px';
		loadingDiv.className = 'loading';
		loadingDiv.id = form + 'loadingDiv';
		
		loadingDiv.innerHTML = '<p>Please Wait</p><img src="/clientlib/cms/images/icons/itomic_loading.gif" />';
		formDiv.parentNode.insertBefore(loadingDiv, formDiv);
		
		if (typeof(browser) != 'undefined') {
			try {
				if (!browser.isIE) {
					loadingDiv.style.marginLeft = (formDiv.offsetLeft - loadingDiv.offsetLeft )+ 'px';
				}
			} catch (e) { }
		}
	},
	
	removeLoadingDiv : function(form) {

		var subit = $(form + 'Subit');
		
		if (subit) subit.disabled = false;

		var loadingDiv = $(form + 'loadingDiv');
		
		if(!loadingDiv)return false;
		
		loadingDiv.parentNode.removeChild(loadingDiv);
		
		var formDiv = $(form + 'Div');
		if(!formDiv) return false;
		
		formDiv.className = removeClass(formDiv.className, 'loadback');
	},
	
	uploadNotify : function(input, text) {
		var inpParent = $(input).parentNode;
		
		$(input).value = '';
		$(input).style.display = 'none';
		
		$(input + 'Uploaded').style.display = '';
		$(input + 'Info').innerHTML = text;
	},
	
	sendFrameData : function (form, id) {
		var iframe = top.frames[id + 'Iframe'];

		if (!iframe) return;

		var body = iframe.document.getElementById(form + 'IframeBody').innerHTML;
		
		var upDiv = this.forms.get(form).update;
		
		$(upDiv).innerHTML = body.replace(/<script[\s\S]+\/script>/gim,'');
	}
});

var Valid = new ncValid();
