// this object is used to validate form fields
/* $Revision: 1.3 $ */

// form management class
var Form = {

	submits: {},
	submit_onclick: {},


	// initialize forms on page
	init: function(){
		var i, j, form;

		// walk through forms
		for(i=0; i<document.forms.length; i++)
		{
			form = document.forms[i];

			Form.submits[form.name] = null;

			// skip forms with "onsubmit" defined
			if(!form.onsubmit)
			{
				// add "onsubmit" handler
				form.onsubmit = Form.save;
				form.onreset = Form.reset;

				// walk through all fields on form
				for(j=0; j<form.elements.length; j++)
				{
					// and initialize them
					Form.Field.init(form.elements[j]);
				}
			}
		}
	},



	// pack form data and send to server via RPC
	save: function(){
		var i, j, bAdd, data = {'__form': this.getAttribute('name')}, value, field;

		for(i=0; i<this.elements.length; i++)
		{
			bAdd = true;

			field = this.elements[i];

			// check if this is valid element
			if(field.tagName)
			{
				value = field.value;

				// get value of more complex fields
				switch(field.tagName.toUpperCase())
				{
					case 'SELECT':
						break;

					case 'TEXTAREA':
						break;

					case 'INPUT':
						switch(field.type.toUpperCase())
						{
							case 'RADIO':
								value = '';
								for(j=0; j<this.elements[field.name].length; j++)
								{
									if(this.elements[field.name][j].checked)
									{
										value = this.elements[field.name][j].value;
									}
								}
								break;


							case 'CHECKBOX':
								value = field.checked ? value : '';
								break;

							case 'SUBMIT':
								bAdd = false;
								if(Form.submits[this.name])
								{
									if(Form.submits[this.name].name == field.name)
									{
										bAdd = true;
									}
								}
								break;

							default:
								if(field.alt == value)
								{
									value = '';
								}
						}
						break;

					default:
						alert('Unknown form element: '+ this.elements[i].tagName);
				}

				// store as object member
				if(bAdd)
				{
					data[field.name] = value;
				}
			}
		}

		// send data to server
		rpc.send(data, Form.saveCallback, this.action, false, this.method.toUpperCase()=='GET'?true:false);

		// prevent normal form submit
		return false;
	},



	// this function called when response data received
	saveCallback: function(response){
		// __form contains form name
		var form = document.forms[response.js.__form];
		if(form)
		{
			// remove "required" class from all elements
			for(var i=0; i<form.elements.length; i++)
			{
				field = form.elements[i];

				// check if this is valid element
				if(field.tagName)
				{
					field.className = field.className.replace(/\s*required/ig, '');
				}
			}
		}

		// check if we got some error reports from server
		if(response.js.errors)
		{
			var text = '';

			if(typeof response.js.errors == 'string')
			{
				text += response.js.errors +"\n";
			}else{
				// convert list of errors into string
				for(var fieldName in response.js.errors)
				{
					text += response.js.errors[fieldName] +"\n";

					// if form exists
					if(form)
					{
						// and field exists
						if(form.elements[fieldName])
						{
							form.elements[fieldName].className += 'required';
						}
					}
				}
			}

			// show errors and do nothing
			alert(text);

		}else if(response.js.confirm){ // confirm dialog

			if(confirm(response.js.confirm))
			{
				response.js.__action = response.js.confirm_ok;
			}else{
				response.js.__action = response.js.confirm_cancel;

			}
			rpc.send(response.js, Form.saveCallback, response.js.__location, true);

		}else{// no errors, no confirmations

			// check if page should be redirected
			if(response.js.redirect)
			{
				if(response.js.__inline)
				{
					// request for new page
					rpc.send({'__inline':true, '__form':form.getAttribute('name')}, Form.saveCallback, response.js.redirect, true);
				}else{
					// change location location
					window.location = response.js.redirect;
				}

			}else{

				// inline form
				if(response.js.__inline)
				{
					if(form)
					{
						form.parentNode.innerHTML = response.js.html;
						Form.init();

						Hooks.Exec('Form_Init');
					}
				}

			}


			Hooks.Exec('Form_'+response.js.__form+'_OnLoad');
			Hooks.Exec('Form_OnLoad');
		}

	},



	// reset form
	reset: function(){
		// we have return path defined
		if(this.elements['__return'])
		{
			if(this.elements['__inline'])
			{
				rpc.send({'__inline':true, '__form':this.name}, Form.saveCallback, this.elements['__return'].value, true);
			}else{
				window.location = this.elements['__return'];
			}

			return false;
		}else{
			// just reset form
			return true;
		}
	},





	// field management class
	Field: {
		// initialize form field
		init: function(field){

			// if "alt" attribute is not blank - place it inside value
			if(field.alt && (field.value.replace(/\s*/g,'') == ''))
			{
				field.value = field.alt;
			}


			if((field.type+'').toUpperCase()=='SUBMIT' && field.name)
			{
				Form.submit_onclick[field.form.name+'__'+field.name] = field.onclick;
				field.onclick = Form.Field.onSubmitClick;
			}


			// add event handlers
			field.onfocus = Form.Field.onFocus;
			field.onblur  = Form.Field.onBlur;
		},


		// form may contain many submit buttons
		// we should transfer only clicked one
		onSubmitClick: function(){
			var onclick = Form.submit_onclick[this.form.name+'__'+this.name];
			if(onclick)
			{
				if(onclick() == false)
				{
					return false;
				}
			}
			Form.submits[this.form.name] = this;
		},


		// this fuction called when field gains focus
		onFocus: function(){
			// remove ALT text if not changed
			if(this.alt && (this.alt == this.value))
			{
				this.value = '';
			}

			this.className += ' focus';
		},


		// this fuction called when field loose focus
		onBlur: function(){
			// if "alt" attribute is not blank - place it inside value
			if(this.alt && (this.value.replace(/\s*/g,'') == ''))
			{
				this.value = this.alt;
			}

			this.className = this.className.replace(/\s*focus/ig,'');
		}
	}
}

// add Form class to window.onload event
Hooks.Add('Window_OnLoad', 'Form.init');