zCore.Forms = {
	initialize : function() {
		var forms = document.getElementsBySelector('form.navigate');
		for (var fi = 0; form = forms[fi]; fi++) new zCore.Forms.Navigator(form);
		
		var forms = document.getElementsBySelector('form.validate');
		for (var fi = 0; form = forms[fi]; fi++) new zCore.Forms.Validator(form);
	}
};

zCore.Forms.Navigator = Class.create();
zCore.Forms.Navigator.prototype = {
	form : null,
	menu : null,
	currentFieldset : null,
	currentMenuItem: null,
	
	initialize : function(form) {
		this.form = form;
		
		this.form.navigator = this;
		
		this.addNavigation();
	},
	
	addNavigation : function() {
		var fieldsets = this.form.getElementsByTagName('fieldset');
		
		if (fieldsets.length < 2) return;
		
		var nav = document.createElement('ol');
		nav.className = 'navigation';
		
		for (var i = 0; i < fieldsets.length; i++) {
			var li = document.createElement('li');
			var a = document.createElement('a');			
			var legend = fieldsets[i].getElementsByTagName('legend').item(0);
			var t = document.createTextNode(legend.firstChild.nodeValue);
			
			a.setAttribute('href', '#' + fieldsets[i].id);
			//zCore.Events.addEventListener(a, 'click', this.navigate.bind(this), false);
			a.onclick = this.navigate.bind(this);
			
			a.appendChild(t);
			li.appendChild(a);
			nav.appendChild(li);
			
			if (i > 0)
				fieldsets[i].className += ' hidden';
			if (i == (fieldsets.length - 1))
				a.className += ' last';
		}
		
		this.currentFieldset = fieldsets.item(0);
		this.currentMenuItem = nav.getElementsByTagName('a').item(0);
		this.currentMenuItem.className += ' active';
		
		this.form.insertBefore(nav, this.form.firstChild);
	},

	navigate : function(evt) {
		var anchor = zCore.Events.getEventTarget(evt);
		var id = anchor.getAttribute('href').substring(
			anchor.getAttribute('href').indexOf('#') + 1);

		this.currentMenuItem.className = anchor.className.replace(/ ?active/, '');
		anchor.className += ' active';
		this.currentMenuItem = anchor;
		
		var to_show = document.getElementById(id);
		this.currentFieldset.className += ' hidden';
		to_show.className = to_show.className.replace(/ ?hidden/, '');	
		this.currentFieldset = to_show;

		return false;
	},

	navigateTo : function(fieldset) {
		this.currentFieldset.className += ' hidden';
		fieldset.className = fieldset.className.replace(/ ?hidden/, '');	
		this.currentFieldset = fieldset;
	}
};

zCore.Forms.Validator = Class.create();
zCore.Forms.Validator.prototype = {
	form : null,
	inputs : new Array,
	
	initialize : function(form) {
		this.form = form;
		this.form.validator = this;
		
		var inputs = form.getElementsByTagName('input');
		for (var i = 0; input = inputs[i]; i++) {
			if (input.type != 'text') {
				continue;
			}
			
			input.rules = new Array();
			
			if (input.className.match(/\brequired\b/)) {
				input.rules.push(Validator.isNotEmpty.bind(input));
			}
			if (input.className.match(/\bunique\b/)) {
				input.rules.push(Validator.isNotEmpty.bind(input));
				input.rules.push(Validator.isUnique.bind(input));
			}
			if (input.className.match(/\balpha\b/)) {
				input.rules.push(Validator.isAlpha.bind(input));
			}
			if (input.className.match(/\balphanum\b/)) {
				input.rules.push(Validator.isAlphanumeric.bind(input));
			}
			if (input.className.match(/\bnum\b/)) {
				input.rules.push(Validator.isNumeric.bind(input));
			}
			if (input.getAttribute('minlength') && input.getAttribute('maxlength')) {
				input.rules.push(Validator.isWithinRange.bind(input));
			}
			if (input.className.match(/\bequals\w+\b/)) {
				input.rules.push(Validator.isEqualTo.bind(input));
			}
			if (input.className.match(/\bemail\b/)) {
				input.rules.push(Validator.isEmail.bind(input));
			}
			
			if (input.rules.length > 0) {
				zCore.Events.addEventListener(input, 'blur', Validator.validate.bind(input), false);
				this.inputs.push(input);
			}
		}

		var selects = form.getElementsByTagName('select');
		for (var i = 0; select = selects[i]; i++) {
			select.rules = new Array();
			
			if (select.className.match(/\bnotnull\b/)) {
				select.rules.push(Validator.isNotNull.bind(select));
			}
			
			if (select.rules.length > 0) {
				zCore.Events.addEventListener(select, 'change', Validator.validate.bind(select), false);
				this.inputs.push(select);
			}
		}

		this.form.onsubmit = this.process.bind(this);
	},
	
	process : function() {
		var isValid = true;
		var firstInvalid = null;
		
		if (arguments.length == 1) {
			var useVisuals = arguments[0];
		} else {
			var useVisuals = true;
		}

		for (var i = 0; input = this.inputs[i]; i++) {
			var isInputValid = Validator.validate.bind(input)(useVisuals);
			
			if (firstInvalid == null && !isInputValid && this.form.navigator) {
				this.form.navigator.navigateTo(zCore.DOM.getParentWithTagName(input, 'fieldset'));
				firstInvalid = input;
			}
			
			isValid = isValid & isInputValid;
		}

		if (!isValid) {
			return false;
		}
		
		return true;
	}
};

zCore.Events.addEventListener(window, 'load', zCore.Forms.initialize, false);
