function Field(field_element)
{
	this.element;
	this.field;
	this.form_mode;
	this.is_mandatory;
	this.is_unique;
	this.name;
	this.original_value;
	this.table;
	this.value;
	
	/* constructor */
	if(field_element != null)
	{
		this.element = field_element;
		var form_id = $(field_element).parents("form")[0].id;
		this.name = field_element.name;
		if(!(field_element.type == "checkbox" && !field_element.checked))
			this.value = $(field_element).val();
		this.form_mode = $("#" + form_id + " input[name='_mode']").val();
		this.is_mandatory = $("#" + form_id + " input[name='_" + this.name + "_is_mandatory']").length == 1;
		var original_value_elements = $("#" + form_id + " input[name='_" + this.name + "_original_value']");
		this.is_unique = original_value_elements.length == 1;
		if(this.is_unique)
		{
			this.original_value = original_value_elements.val();
			this.table = $("#" + form_id + " input[name='_" + this.name + "_table']").val();
			this.field = $("#" + form_id + " input[name='_" + this.name + "_field']").val();
			if(this.field == null)
				this.field = this.name;
		}
	}
	/* end of constructor */
	
	this.check_conditions = function ()
	{
		var conditions_met = true;
		if(this.is_mandatory)
			conditions_met = this.check_mandatory_value() ? conditions_met : false;
		if(this.is_unique)
			conditions_met = this.check_unique_value() ? conditions_met : false;		
		return conditions_met;
	}
	
	this.check_mandatory_value = function ()
	{
		if(this.value == "")
		{
			$("#" + this.name + "_empty").show();
			return false;
		}
		else
		{
			$("#" + this.name + "_empty").hide();
			return true;
		}
	}
	
	this.check_unique_value = function ()
	{
		if(   this.form_mode == "new"
	       || this.value != this.original_value)
	    {
			var current_field = this;
			var condition_met;
			sync_post(
				"/controllers/check_unique_value.php",
				{
					field: current_field.field,
					table: current_field.table,
					value: current_field.value
				},
				function (value_exists)
				{
					if(value_exists)
					{
						$("#" + current_field.name + "_exists").show();
						condition_met = false;
					}
					else
					{
						$("#" + current_field.name + "_exists").hide();
						condition_met = true;
					}
				}
			);
			return condition_met;
		}
		else
		{
			$("#" + this.name + "_exists").hide();
			return true;
		}
	}
	
	this.get_name_for_array = function ()
	{
		return this.name.substr(0, this.name.length - 2);
	}
	
	this.is_array_element = function ()
	{
		var length_of_name = this.name.length;
		if(this.name.substr(length_of_name - 2) == "[]")
			return true;
		else
			return false;
	}
}

function Form(form_id)
{
	this.controller = $("#" + form_id).attr("action");
	this.fields = new Array();
	this.form_id = form_id;
	this.mode = $("#" + form_id + " input[name='_mode']").val();
	
	this.check_and_submit = function ()
	{
		this.read_fields();
		if(this.check_conditions())
			this.submit();
	}
	
	this.check_conditions = function ()
	{
		var conditions_met = true;
		for(var i=0;i<this.fields.length;i++)
			conditions_met = this.fields[i].check_conditions() ? conditions_met : false;
		return conditions_met;
	}
	
	this.enable_field_monitoring = function (read_fields)
	{
		if(read_fields)
			this.read_fields();
		for(var i=0;i<this.fields.length;i++)
		{
			if(this.fields[i].is_unique)
			{
				$(this.fields[i].element).change(function (){
					field = new Field($(this)[0]);
					field.check_conditions();
				});
			}
		}
	}
	
	this.read_fields = function ()
	{
		var form_elements = $("#" + this.form_id + " *:input:not(:button[name^='_'])");
		for(var i=0;i<form_elements.length;i++)
		{
			var field = new Field(form_elements[i]);
			this.fields.push(field);
		}
	}
	
	this.serialize = function ()
	{
		var data = new Object();
		for(var i=0;i<this.fields.length;i++)
		{
			if(this.fields[i].is_array_element())
			{
				var name = this.fields[i].get_name_for_array();
				if(jQuery.isArray(data[name]))
					data[name].push(this.fields[i].value);
				else
				{
					data[name] = new Array();
					data[name].push(this.fields[i].value);
				}
			}
			else
				data[this.fields[i].name] = this.fields[i].value;
		}
		var json = JSON.encode(data);
		return json;
	}
	
	this.submit = function ()
	{
		$.post(
			this.controller,
			{ json: this.serialize() },
			function (js_code)
			{
				eval(js_code);
			}
		);
	}
}