/* Este fichero contiene la definición de la clase Cell
 * La clase será utilizada como el elemento más básico de un formulario, una entrada, un elemento.
 * Cada cell tiene asociado una field, la columna de una tabla (de una base de datos, generalmente).
 * Dicha field, o columna, le indicará las propiedades que tiene: tipo de input, valores que puede tomar, etc.
 */

/* Constructor
 * Esta función se encarga de inicializar un cell.
 *
 * parent_div:	Es el div donde queremos introducir el elemento.
 * div_id:		Es la id que se le pondrá al div.
 * name:		Nombre de la célula.
 * value:		Es el valor inicial.
 * field:		Es la field
 */
function Cell(parent_div, field, value)
{
	this.parent_div = parent_div;
	this.field = field;

	this.value = value;
	this.new_value = value;
	
	this.div_cell = false;
	this.div_error = false;
	this.div_name = false;
	this.input = false;
	
	this.error = 0;
	this.error_obj = false;
	
	this.timeout = false;
	this.timeout_prim = false;

	this.change = false;

	this.input = false;

}

Cell.prototype = 
{
	/* Mostrar el elemento
	 * Esta función muestra un elemento: [ Nombre de la field ] --> [ VALOR / INPUT ]
	 *
	 * type:		Es el tipo de cell, puede ser	IN: input, para introducir datos.
	 *												OUT: output, para ver datos.
	 * className:	Es la clase (css) que tiene asociada.
	 */
	show: function(type)
	{
		// Inicializar datos
		if(this.div_cell)
			this.div_cell.parentNode.removeChild(this.div_cell);

		var conf = this.field.settings[type];

		this.div_cell = conf.contents.div_cell;
		this.div_cell.className = conf.class_names.div_cell;

		this.div_title = conf.contents.div_title;
		this.div_title.className = conf.class_names.div_title;

		this.div_title.appendChild(document.createTextNode(this.field.settings.data.name));

		this.div_cell.appendChild(this.div_title);

			// Datos de salida -> TextNode
		if(type == "output")
		{
			var div_value = conf.contents.div_value;
			div_value.className = conf.class_names.div_value;

			div_value.appendChild(document.createTextNode(this.value));
			this.div_cell.appendChild(div_value);
		}
		// Datos de entrada -> input
		else
		{
			var self = this;
			this.input = this.field.getInput(self);

			if(this.input)
			{
				this.div_error = conf.contents.div_error;
				this.div_error.className = conf.class_names.div_error;

				this.div_cell.appendChild(this.input);
				this.div_cell.appendChild(this.div_error);
			}

		}

		if(this.parent_div)
			this.parent_div.appendChild(this.div_cell);

	},


	/* Comrpeuba que se cumplan todas las condiciones
	 *
	 * def_error:	Es un 'parche' para las funciones de error que da el usuario.
	 *				El usuario puede dar una condición que se tiene que cumplir en
	 *				un cierto número de cell (cell[0] == cell[1], implicados: 0 1).
	 *				Así que una de las cell comprueba la condición y llama al reto
	 *				de implicados para ver si también la cumplen, con def_error = 1
	 *				para que éstos no llamen al resto de implicados y crear recursión infinita
	 */
	check: function(def_error)
	{
		var error = 0;

		// Función de error del usuario, ésta cell llamará al resto de implicados.
		if(!def_error && this.field.def_error.func)
		{
			var c;

			for(c in this.field.def_error.cells)
			{
				var cell = this.field.def_error.cells[c];
				if(cell && cell.div_id != this.div_id)
					cell.check(1);
			}
		}


		if(this.value && this.input.value == this.value)
		{
			this.change = false;
			this.setError(false, false);
		}
		else
		{
			this.change = true;

			// Cadena vacía, aceptado ?
			if(this.input.value.length == 0)
			{
				if(this.field.isNotNull())
				{
					error = 1;
					this.setError("ERROR: No puede dejar este campo vacío", "#BF3333");
				}
			}
			else
			{
				// Expresión regular, aceptado ?
				if(this.field.settings.data.reg_exp)
				{
					if(!this.field.settings.data.reg_exp.test(this.input.value))
					{
						error = 1;
						this.setError("ERROR: Formato incorrecto", "#7F0000");
					}
				}

				// Tamaño máximo, aceptado ?
				if(!error && this.field.len < this.input.value.length)
				{
					error = 1;
					this.setError("ERROR: Sobrepasa el tamaño máximo permitido (" + this.field.len + ")", "#7F0000");
				}

				if(!error)
				{
					// Si es una clave primaria (Base de datos), tendrá que comprobar si es aceptado por la base de
					// datos. No implementado.
					if(this.field.isPrimKey())
					{
						this.setError(false, "yellow");
						error = 2; 
						this.error = true;

						if(this.timeout_prim)
							clearTimeout(this.timeout_prim);

						var self = this;
						this.timeout_prim = setTimeout(function() { self.primCheck(input) }, 2000);
					}

					// Función de error por usuario, aceptado ?
					else if(this.field.def_error.func && !this.field.def_error.func(this))
					{
							this.setError(this.field.def_error.text, "#7F0000");
							this.error = 1;
					}
					else
					{
						// CORRECTO
						this.setError(false, "#007F00");
						this.error = 0;
					}
				}
				else		
					this.error = 1;
			}
		}

		return error;

	},

	// Comprueba si no hay entradas repetidas
	// No implementado --- Prácitca 3
	primCheck: function()
	{
		/*
		SQLconnect(this, "out", "SELECT `" + this.field.name + "` FROM " + this.field.table + " WHERE `" + this.name + "` = '" + this.input.value + "'", "none",
				function(req)
				{
					if(!req.responseXML.getElementsByTagName("error")[0].firstChild)
					{
						if(!req.responseXML.getElementsByTagName("rows_data")[0].firstChild)
						{
							this.setError("Correcto", "#00FFDD");
							this.error = 0;
						}
						else
						{
							this.setError("Campo en uso", "red");
							this.error = 1;
						}
					}
					else
						this.setError(req.responseXML.getElementsByTagName("error")[0].firstChild.nodeValue, "red");
				}
		);
		*/
	},

	// Pone el borde de input de un color.
	setError: function(text, color)
	{
		if(this.div_error && this.input)
		{
			if(this.div_error.firstChild)
				this.div_error.removeChild(this.div_error.firstChild);

			if(text)
			{
				var img = document.createElement("img");
				img.setAttribute("src", "img/warning.png");
				img.setAttribute("title", text);
				this.div_error.appendChild(img);
			}

			if(color)
			{
				var xobj = new XObject(this.div_title);
				//xobj.style.color = "rgb(255, 255, 255)";
				
				xobj.setColor(color, 40);
			}
				
			else
				this.div_cell.style.border = "";
		}		
	},

	// Borra una cell.
	erase: function()
	{
		if(this.div_cell)
			this.div_cell.parentNode.removeChild(this.div_cell);
	}
}

	


		
