// namespace shortcuts & definitions
var $D = YAHOO.util.Dom;
var $C = YAHOO.util.Connect;
var $E = YAHOO.util.Event;

var Forms = window.Forms || {};

Forms = {
	tests: {
		required: function(v) {return (v!=null && v.length>0)},
		'valid-number': function(v) {return (!isNaN(v))},
		'valid-email': function(v) {return (/\w{1,}[@][\w\-]{1,}([.]([\w\-]{1,})){1,3}$/.test(v))},
		'valid-date': function(v) {return (/\d{4}-\d{2}-\d{2}$/.test(v))},
		'valid-time': function(v) {return (/\d{2}:\d{2}[\.:]\d{2}$/.test(v))}

	},
	
	messages: {
		required: 'Ovo polje je obavezno unijeti!',
		'valid-email': 'Napišite ispravan e-mail!',
		'valid-number': 'Napišite ispravan broj!',
		'valid-date': 'Napišite ispravan datum (GGGG-MM-DD)!',
		'valid-time': 'Napišite ispravno vrijeme (HH:MM:SS ili MM:SS.ss)!'
	},

	form: null,
	fields: null,
	isValid: null,


	// generic form validation
	validate: function(obj, submitFn) {
		var errs;
		this.form = null; this.fields = null; this.isValid = true;


		// single element
		if (this.isFormElement(obj)) {
			this.fields = obj;
			errs = $D.getElementsByClassName('error','span', this.fields.parentNode)[0];

			if (errs!=null)
				this.fields.parentNode.removeChild(errs);
		}
		// form
		else if (obj.nodeName.toLowerCase()=='form') {
			this.form = obj;
			this.fields = $D.getElementsBy(this.isFormElement, '', obj);
			errs = $D.getElementsByClassName('error','span', obj);

			for (a in errs)
				errs[a].parentNode.removeChild(errs[a]);
			for (a in this.fields) {
				if ($D.hasClass(this.fields[a], 'invalid'))
					$D.removeClass(this.fields[a], 'invalid');
			}
		}
		// nothing important
		else
			return false;

		// check fields for tests and invalidate if failed
		for (i in this.fields) {
			for (test in this.tests) {
				if (($D.hasClass(this.fields[i], 'required') || this.fields[i].value!='') && $D.hasClass(this.fields[i], test) && !this.tests[test](this.fields[i].value))
					this.invalidate(this.fields[i], test);
			}
		}

		// submit if valid
		if (this.isValid && this.form!=null) {
			if (submitFn) {
				submitFn();
			}
			else
				this.form.submit();
		}
	},


	invalidate: function (field, test) {
		this.isValid = false;

		if (!$D.hasClass(field, 'invalid'))
			$D.addClass(field, 'invalid');

		var parent = field.parentNode;
		var err = $D.getElementsByClassName('error','span', parent)[0];

		// first error on field - create new error container
		if (err==null) {
			err = document.createElement('span');
			err.className = 'error';
			err.innerHTML = this.messages[test];

			$D.generateId(err, 'err');
			$D.setStyle (err , 'opacity', 0)

			parent.appendChild(err);

			if (Anim)
				Anim.fadeIn(document.getElementById(err.id))
			else
				$D.setStyle (document.getElementById(err.id) , 'opacity', 1);
		}
		// not the first error - just append the message
		else if (err.innerHTML.indexOf(this.messages[test])<0)
			err.innerHTML += "<br/>"+this.messages[test];
	},


	submit: function() {
		var uri = this.form.action.replace(/(http:\/\/[\w\.]{2,}[:\d]{0,})/g, "$1/async");

		// callback when request done
		var requestCallback = {
			success: Forms.submitSuccess,
			failure: Forms.submitFailure,
			scope: Forms
		};

		$C.setForm(this.form);
		var submitForm = $C.asyncRequest('POST', uri, requestCallback);
		if (Anim) {
			Anim.loadInProgress = true;
			Anim.slideContentOnLoad(submitForm, this.form.id, {x:500, speed:1});
		}
	},


	submitSuccess: function(o) {
		if (Anim)
			Anim.loadedContent = o.responseText;
		else {
			this.form.innerHTML = o.responseText;
		}
	},


	submitFailure: function(o) {
		 if (Anim)
			Anim.loadedContent = "Jadna li mi baba... \n\n"+o.status+"\n\n"+o.statusText+"\n\n"+o.getAllResponseHeaders;
		else {
			this.form.innerHTML = "Jadna li mi baba... \n\n"+o.status+"\n\n"+o.statusText+"\n\n"+o.getAllResponseHeaders;
		}
	},


	isFormElement: function(el) {
		if ((el.nodeName.toLowerCase() == 'input' && el.type.toLowerCase()!='button' && el.type.toLowerCase()!='submit')
		 	|| el.nodeName.toLowerCase() == 'select' || el.nodeName.toLowerCase() == 'textarea')
	 		return true;
	 	else
	 		return false;
	}
}