/*
Class: Log
	Clase que inserta una capa en la página en la que se añaden los mensajes de log

Argumentos:
	options - (obligatorio) objeto que contiene las opciones de inicialización

Options:
	idRef 	- 'id' del elemento dentro del cual se va a insertar el contenedor de log

Ejemplo:
	> var miLog = new Log({idRef:'cont'});
*/

	var Log = new Class({
		options:{
			idRef:		null
		},

		initialize: function(options){
			this.setOptions(options)
			this.nombreContenedor = 'logDebug';
			new Element('div', {'id': this.nombreContenedor}).setStyles({'width':'400px','border':'1px solid #666','height':'400px','overflow':'scroll','background':'#000','padding':'10px','margin':'10px','position':'absolute','top':'0','right':'0'}).injectAfter(this.options.idRef).makeResizable({	modifiers: {x: false, y: 'height'}});

;
		},
		crearLog: function(campo,key,accion)
		{

			if ($('log-ultimo')) $('log-ultimo').setStyle('color','#FFF');

			if (accion == 'cache'){
				var texto = '- Campo: ' + campo + '<br /> :: Lee de Cache: ' + key;
			}
			else{
				var texto = '- Campo: ' + campo + '<br /> :: Petición Ajax<br /> :: Guarda en Cache: ' + key;
			}
			new Element('p', {'id': 'log-ultimo'}).setStyles({'color':'#FF0','font-size':'9px','border-bottom':'1px dotted #FFF'}).setHTML(texto).injectTop(this.nombreContenedor);
		}
	});
	Log.implement(new Options, new Events);

/*
Class: FormularioRecargable
	Clase que da a un formulario la funcionalidad de recargar el contenido de algunos de sus elementos en función de otros. Algunos campos tendrán la capacidad de lanzar de forma automática la petición de recarga.

Argumentos:
	options - (obligatorio) objeto que contiene las opciones de inicialización

Options:
	idForm 		- 'id' del formulario
	idLoad 		- 'id' del elemento donde se va a mostrar el icono de carga
	urlRecarga	- url a la que se hace la petición de datos para la recarga
	cache		- indica si se van a cachear los datos obtenidos
	debug		- indica si hay que visualizar el log de actividades
	efectoColor	- efecto que se visualiza en los campos recargador (Formato: {propiedad:[inicio,fin]})
	classElem	- clase de los elementos del formulario que pueden recargarse
	classlanzador - clase de los elementos del formulario que pueden lanzar la recarga
	classLoad	- clase que muestra el icono de recarga

Ejemplo:
	> var miFormulario = new FormularioRecargable({idForm:'formu', idLoad:'estado', urlRecarga:'./recarga.php'});

Formato JSON:
{
	"<nombre_campo_select>":{
					"<value>":"<texto>",
					"<value>":"<texto>",
					...
				},
	"<nombre_campo_input>":"<value>",
	...
}
*/

	var FormularioRecargable = new Class({
		options:{
			idForm:		null,
			idLoad:		null,
			urlRecarga:	null,
			cache:		true,
			debug:		false,
			efectoColor: {'background-color': ['#FFA','#FFF']},
			classElem:	'.jsForm',
			classLanzador:	'.jsFormRec',
			classLoad:	'loading'
		},

		initialize: function(options)
		{

			this.setOptions(options);
			this.effects = {};
			this.cache = {};
			this.key = null;

			if (this.options.debug) this.log = new Log({'idRef':this.options.idForm});

			if ($(this.options.idForm))
			{
				this.miForm = $(this.options.idForm);
				this.urlEnvio = this.miForm.getProperty('action');
			}

			if (this.options.urlRecarga)
			{
				this.urlRecarga = this.options.urlRecarga;

				// Opciones de la petición de recarga
				this.opcionesRecarga = {
						method:'post',
						data:'',
						onRequest: function()
						{
							if ($(this.options.idLoad))
								$(this.options.idLoad).addClass('loading');
						}.bind(this),
						onComplete: function(response) 
						{
							if (response != '')
							{
								var datos = Json.evaluate(response);
								if (datos) this.actualizarFormulario(datos);
							}
							if ($(this.options.idLoad))
								$(this.options.idLoad).removeClass('loading');
						}.bind(this)
					};
			}

			this.generarEfectos();
			this.definirLanzadores();

		},


		/*
		 Añadir efectos a los campos que pueden recargarse
		*/
		generarEfectos: function()
		{
			$$('#' + this.options.idForm + ' ' + this.options.classElem).each(function(campo){
				this.effects[campo.getProperty('id')] = campo.effects({duration:1000, wait:false});
			},this);
		},

		/*
		 Añadir evento 'onChange' a los campos que pueden lanzar la petición de recarga
		*/
		definirLanzadores: function()
		{
			$$('#' + this.options.idForm + ' ' + this.options.classLanzador).each(function(campo){
				campo.addEvent('change',this.enviarPeticion.bind(this, campo.getProperty('id')));
			},this);
		},

		/*
		 Generar la key de la peticion para la caché
		*/
		generarKey: function(campo){
			var fin = false;
			var key = '';
			$$('#' + this.options.idForm + ' ' + this.options.classLanzador).each(function(campoAux){
				if (!fin){
					key += campoAux.value;
					if (campo == campoAux.getProperty('id')) fin = true;
				}
			});
			return key;
		},

		/*
		 Formar la petición ajax
		*/
		enviarPeticion: function(campo)
		{

			this.opcionesRecarga['data'] = this.miForm.toQueryString() + "&_origen=" + campo + "&_ajax=1&_a=" + Math.random()

			if (this.options.cache)
			{
				this.key = this.generarKey(campo);
			}
			else
			{
				this.key = '';
			}

			if (this.cache[this.key])
			{	// Usar los datos cacheados

				this.actualizarFormulario( this.cache[this.key]);
				var accion = 'cache';
			}
			else
			{	// Pedir datos

				this.miForm.setProperty('action',this.urlRecarga);
				this.miForm.send(this.opcionesRecarga);
				this.miForm.setProperty('action',this.urlEnvio);
				var accion = 'ajax';

			}
			if (this.options.debug)
			{
				this.log.crearLog(campo,this.key,accion);
			}

		},


		/*
		 Actualizar un campo <select>
		*/
		actualizarSelect: function(cSelect,datos)
		{

			$(cSelect).empty();	// Vaciar el <select>
			var nuevoContenido = new Object();
			nuevoContenido = datos[cSelect];
			for( var opt in nuevoContenido)
			{	// Crea los nuevos elementos <option>
				new Element('option', {'value': opt}).setHTML(nuevoContenido[opt]).injectInside(cSelect);
			};
		},

		/*
		 Actualizar un campo <input>
		*/
		actualizarInput: function(cInput,datos)
		{
			$(cInput).value = datos[cInput];
		},

		/*
		 Actualizar los campos del formulario
		*/
		actualizarFormulario: function(datos)
		{

			for (var elem in datos){	// Recorrer los datos recibidos (Json)
				if ($(elem)){	// Si existe el elemento en la página
					if ($(elem).getTag() == 'select'){	// Si es un combo
						this.actualizarSelect(elem,datos)
					}
					else {	// Si es un campo de texto
						this.actualizarInput(elem,datos)
					}
				}
				// Si el elemento tiene asociado un efecto, lanzarlo
				if (this.effects[elem]) { this.effects[elem].start(this.options.efectoColor)};
			}
			/**/
			if (this.options.cache) {this.cache[this.key] = datos;}	// Guardar en caché

		}



	});

	FormularioRecargable.implement(new Options, new Events);

