// JavaScript Document
Choquin.Control = {};

Choquin.Control.Base = Choquin.EventDispatcher.extend({
	constructor: function(element,options){
		this.id = String.randomString(20);

		this.constructor.controls = this.constructor.controls || [];
		this.constructor.controls.push(this);  /// guarda una lista de todos los controles creados en cada clase


		this.history = [];
		this.controls = this.controls||[];
		this.options = Object.extend(this.options||{},options||{});
		if(!element) element = new Element('div'); /// se puede crear un control de la nada, luego habrá que colgarlo en algún lugar.
		var _element = element;
		element = $(element);
		this.element = element;
		if(this.element){
			this.element.handler = this;
			this.create();
			this._setAttributes();		
			this._container = $(this.element.identify()+'_container');
			this._label = $('label_'+this.element.identify());
			if(this.options.onblur) this.element.observe('blur',Choquin.eval.bind(this.element,this.options.onblur));
		};
		
		//a continuacion codigo neuvo potencialmente danger..
		this.controls.each(function(control){
			if(!control.handler) control.handler = this;
		},this);
		//this._removeAutocomplete.bind(this).defer();
	},
	
	onvalidate: function(element,options){
		if (this.container()) 
			this.container() [ element.error ? 'addClassName' : 'removeClassName' ] (options.cssClassError || 'error');
	},
		
	_setAttributes: function(element){
		element = element || this.element;
		if(this.options.onvalidate) element.onvalidate = this.options.onvalidate;
		if(this.options.autocomplete) element.setAttribute("autocomplete","off");
	},
	
	create: function(){
		//throw new Error('you must override Choquin.Control.Base.create()');
		this._container = $(this.element.identify()+'_container');
		if(this.element.readAttribute('class')) this._container.addClassName(this.element.readAttribute('class'));

		if(this.options.caption){
			this._caption = new Element('span',{'class':'caption'}).update(this.options.caption);
			this._container.insert(this._caption);
			this.controls.push(this.controls.caption = this._caption);
		}
		
		this.element.observe('focus',this._onfocus);
		this.element.observe('blur',this._onblur);
	},
	
	_onfocus: function(evt){
		var handler = evt.element().handler;
		handler._hasFocus = true;
		handler.container() && handler.container().addClassName('focus');
		//Element.addClassName.delay(handler.options.focusdelay||.01,handler.container(),'focus');
	},

	_onblur: function(evt){
		var handler = evt.element().handler;
		handler._hasFocus = false;
		evt.element().fire('control:blur');
		handler.container() && handler.container().removeClassName('focus');
		//Element.removeClassName.delay(handler.options.blurdelay||.01,handler.container(),'focus');
	},
	
	hasFocus: function(){
		return this._hasFocus;
	},


	setValue:function(value,prevent_callbacks,dontSaveToHistory){
		if(!dontSaveToHistory) this.saveToHistory();
		this.value = value;
		if(!prevent_callbacks) this.fire('control:change',this);
	},

	saveToHistory: function(){
		//this.history = this.history || [];
		this.history.push(this.value);
		//this.lastValue = this.value;
	},
	
	undo: function(prevent_callbacks){
		//this.history = this.history || [];
		this.setValue(this.history.pop(),prevent_callbacks,true);
		//this.setValue(this.lastValue,prevent_callbacks,true);
	},

	
	valueOf: function(){return this.element},
	
	toString: function(){
		return '[control Choquin.Control]';
	},
	
	container: function(){
		return $(this._container);
	},

	label: function(){
		return $(this._label);
	},


	caption: function(){
		return this._caption;
	},
	
	setId: function(newId){
		this.element.id = newId;
		this.container().id = this.element.id+'_container';
	},
	
	_removeAutocomplete: function(){
		var defaultValue = this.element.readAttribute('value');
		if(defaultValue=="") this.element.setValue("");
	}

});


Choquin.Control.Checkbox = Choquin.Control.Base.extend({
	constructor: function(element,options){
		this.base.apply(this,$A(arguments));
		this.element.observe('change',this._onchange);
		this._setCheckedClassName();
	},
	
	_onchange: function(event){
		var element = event.element();
		element.handler._setCheckedClassName();
	},
	
	_setCheckedClassName: function(){
		this.container()[this.element.checked?'addClassName':'removeClassName']('checked');
	}
});


Choquin.Control.File = Choquin.Control.Base.extend({
	constructor: function(element,options){
		this.base(element,options);

		if(this.filename) this.revert();
		else this.newFile();
	},

	create: function(){
		this.base();
		
		this.controls.push(this.controls.fileinput = $(this.element));
		$(this.controls.fileinput).observe('change',this.changeFile.bindAsEventListener(this));
		
		this.filename = this.controls.fileinput.readAttribute("value")||this.options.value||"";

		//this.controls.push (this.controls.filename = new Element("input",{type:"text",value:this.filename,disabled:true,className:"filename"}));
		this.controls.push (this.controls.filename = new Element('a',{className:'filepath',href:this.options.filepath}).update(new Element('span',{className:'filename'}).update(this.filename)));
		//if(this.options.filepath) this.controls.filename.replace(new Element('a',{href:this.options.filepath}).update(this.filename)));
		this.controls.push (this.controls.deleted = new Element("input",{type:"text",name:this.controls.fileinput.readAttribute('name'),value:'deleted',readonly:true,className:"deleted"}));
		//this.container().insert(this.controls.filename);

		this.controls.push (this.controls.dummy = new Element("input",{type:"hidden",name:this.controls.fileinput.readAttribute('name'),value:'',readonly:true,className:"dummy"}));


		this.controls.push (this.controls.trash = new Element("input",{type:"button",value:"delete",className:"delete"}));
		//this.controls.filename.insert({after:this.controls.trash});
		this.controls.trash.onclick = this.deleteFile.bind(this);
		
		this.controls.push (this.controls.newFile = new Element("input",{type:"button",value:"new",className:"new"}));
		//this.controls.trash.insert({after:this.controls.newFile});
		this.controls.newFile.onclick = this.newFile.bind(this);

		this.controls.push (this.controls.revert = new Element("input",{type:"button",value:"revert",className:"revert"}));
		//this.controls.newFile.insert({after:this.controls.revert});
		this.controls.revert.onclick = this.revert.bind(this);
	},
	
	changeFile:function(){
		this._showTrash();
		//this.controls.trash.show();
	},
	
	_showTrash:function(){
		if(!this.controls.trash.parentNode) this.container().insert(this.controls.trash);
		if(this._caption) this.container().insert(this._caption);
		return this.controls.trash.show();
	},
	
	_showRevert:function(){
		if(!this.controls.revert.parentNode) this.container().insert(this.controls.revert);
		if(this._caption) this.container().insert(this._caption);
		return this.controls.revert.show();		
	},
	
	_showDeleted: function(){
		if(!this.controls.deleted.parentNode) this.container().insert(this.controls.deleted);
		if(this._caption) this.container().insert(this._caption);
		return this.controls.deleted.show();		
	},
	
	_showNewFile: function(){
		if(!this.controls.newFile.parentNode) this.container().insert(this.controls.newFile);
		if(this._caption) this.container().insert(this._caption);
		return this.controls.newFile.show();		
	},
	
	_showFilename: function(){
		if(!this.controls.filename.parentNode) this.container().insert(this.controls.filename);
		if(!this.controls.dummy.parentNode) this.container().insert(this.controls.dummy);
		if(this._caption) this.container().insert(this._caption);
		return this.controls.filename.show();		
	},
	
	_showFileinput: function(){
		if(!this.controls.fileinput.parentNode) this.container().insert(this.controls.fileinput);
		if(this._caption) this.container().insert(this._caption);
		return this.controls.fileinput.show();		
	},
	
	_removeAll: function(){
		this.controls.without(this._caption).invoke('removeFromParent');
	},
	
	deleteFile: function(){
		/*this.controls.fileinput = this.controls.fileinput.setType('hidden'); //setType may return a new node...
		this.controls.fileinput.value="delete";
		this.controls.filename.setValue("deleted").show();
		this.controls.trash.hide();
		if(!this.filename.blank()) this.controls.revert.show();
		this.controls.newFile.show();
		*/
		if(!this.filename) {
			this.controls.fileinput.setValue('');
			this.controls.trash.removeFromParent();
		}
		else {
			this._removeAll();
			this._showDeleted();
			this._showRevert();
		}

		this.fire("choquin.control:delete");
		this._setAttributes();
	},
	
	revert: function(){
		/*this.controls.fileinput = this.controls.fileinput.setType('hidden');//setType may return a new node...
		this.controls.fileinput.value="";
		this.controls.filename.setValue(this.filename).show();
		this.controls.revert.hide();
		this.controls.trash.show();
		this.controls.newFile.show();*/
		this._removeAll();
		if(this.filename){
			this._showFilename();//.setValue(this.filename);
			this._showNewFile();
		} else this._showFileinput();
		this._showTrash();
		this.fire("choquin.control:revert");
		this._setAttributes();
	},
	
	newFile: function(){
		/*this.controls.fileinput = $(this.controls.fileinput).setType("file");//setType may return a new node...
		this.controls.trash[this.controls.fileinput.value?'show':'hide']();
		this.controls.newFile.hide();
		this.controls.revert.showhide(!this.filename.blank());
		this.controls.filename.hide();*/
		this._removeAll();
		this._showFileinput();
		if(this.controls.fileinput.value) this._showTrash();
		if(!this.filename.blank()) this._showRevert();
		this.fire("choquin.control:newFile");
		this._setAttributes();
	}
},{
	init: function(){
	/*	console.debug("init");
		document.observe("dom:loaded ", function() {
			console.debug("content loaded");										   
		})*/
	}
});


Choquin.Control.File.Legacy = Choquin.Control.Base.extend({
	constructor: function(element,options){
		this.base(element,options);

		if(this.filename) this.revert();
		else this.newFile();
	},

	_setAttributes:function(){
		this.base(this.controls.fileinput);
	},

	create: function(){
		this.element.addClassName('choquinControlContainer choquin_controlFile');
		
		this.controls.fileinput = $(this.element.identify().trimFromLast('_container'));
		if(!this.controls.fileinput) {
			this.element.insert(this.controls.fileinput = new Element('input',{type:'file',name:this.options.name,id:this.options.id,className:'input'}));	
		}
		$(this.controls.fileinput).observe('change',this.changeFile.bindAsEventListener(this));
		
		this.filename = this.controls.fileinput.readAttribute("value")||this.options.value||"";

		this.controls.push (this.controls.filename = new Element("input",{type:"text",value:this.filename,disabled:true,className:"filename"}));
		this.element.insert(this.controls.filename);

		this.controls.push (this.controls.trash = new Element("input",{type:"button",value:"delete",className:"delete"}));
		this.controls.filename.insert({after:this.controls.trash});
		this.controls.trash.onclick = this.deleteFile.bind(this);
		
		this.controls.push (this.controls.newFile = new Element("input",{type:"button",value:"new",className:"new"}));
		this.controls.trash.insert({after:this.controls.newFile});
		this.controls.newFile.onclick = this.newFile.bind(this);

		this.controls.push (this.controls.revert = new Element("input",{type:"button",value:"revert",className:"revert"}));
		this.controls.newFile.insert({after:this.controls.revert});
		this.controls.revert.onclick = this.revert.bind(this);
	},
	
	changeFile:function(){
		this.controls.trash.show();
	},
	
	deleteFile: function(){
		this.controls.fileinput = this.controls.fileinput.setType('hidden'); //setType may return a new node...
		this.controls.fileinput.value="delete";
		this.controls.filename.setValue("deleted").show();
		this.controls.trash.hide();
		if(!this.filename.blank()) this.controls.revert.show();
		this.controls.newFile.show();
		this.fire("choquin.control:delete");
		this._setAttributes();
	},
	
	revert: function(){
		this.controls.fileinput = this.controls.fileinput.setType('hidden');//setType may return a new node...
		this.controls.fileinput.value="";
		this.controls.filename.setValue(this.filename).show();
		this.controls.revert.hide();
		this.controls.trash.show();
		this.controls.newFile.show();
		this.fire("choquin.control:revert");
		this._setAttributes();
	},
	
	newFile: function(){
		this.controls.fileinput = $(this.controls.fileinput).setType("file");//setType may return a new node...
		this.controls.trash[this.controls.fileinput.value?'show':'hide']();
		this.controls.newFile.hide();
		this.controls.revert.showhide(!this.filename.blank());
		this.controls.filename.hide();
		this.fire("choquin.control:newFile");
		this._setAttributes();
	}
},{
	init: function(){
	/*	console.debug("init");
		document.observe("dom:loaded ", function() {
			console.debug("content loaded");										   
		})*/
	}
});

Choquin.Control.Date = Choquin.Control.Base.extend({
	constructor: function(element,options){
		this.base(element,options);
	},
	
	create: function(){
		this.base();
		this.controls.push(this.controls.day = $(this.element.identify()+'_day'));
		this.controls.push(this.controls.month = $(this.element.identify()+'_month'));
		this.controls.push(this.controls.year = $(this.element.identify()+'_year'));
		this.controls.day.handler = this;
		this.controls.month.handler = this;
		this.controls.year.handler = this;
	},
	
	toString: function(){
		return '[object Choquin.Control.Date]';
	},
	
	onvalidate: function(element,options){
		var args = $A(arguments);
		var noerror = !args[0].error;
		var test = [this.controls.day,this.controls.month,this.controls.year];
		var control;
		while( (control = test.shift())!=element && control){
			noerror = (noerror && !control.error);
		}
		element.error = !noerror;
		this.base.apply(this,args);
		
	}

});




Choquin.Control.ImageFile = Choquin.Control.File.extend({
	constructor: function(element,options){
		this.base(element,options);
	},
	
	imageFile:true,
	
	create: function(){
		this.controls.push (this.controls.image = new Element("img",{alt:"",'class':'img'}));
		this.onImageErrorBind = this.onImageError.bind(this);
		this.setImageErrorHandler();
		this.controls.image.onerror();
		this.base();
		this.controls.fileinput.insert({before:this.controls.image});
		if(Choquin.Control.ImageViewer) this.controls.image = (new Choquin.Control.ImageViewer(this.controls.image)).element;
		//if(Choquin.Control.ImgPlus) this.controls.image = (new Choquin.Control.ImgPlus(this.controls.image)).element;
	},
	
	onImageError: function(){
		this.controls.image.onerror=null;
		this.controls.image.src="/funciones/v2/images/spacer.gif";
		this.controls.image.addClassName('empty');
		this.setImageErrorHandler.bind(this).defer();
		this.fire("choquin.control:imageError");
	},
	
	setImageErrorHandler: function(){
		this.controls.image.onerror = this.onImageErrorBind;
	},
	
	loadImage:function(){
		this.controls.image.src = this.controls.fileinput.readAttribute("value")||this.controls.filename.value;
		this.controls.image.removeClassName('empty');
	},
	
	deleteFile: function(){
		this.base();
		this.controls.image.src = '';
		this.controls.image.addClassName('empty');
		//this.controls.image.hide();
	},
	
	revert: function(){
		this.base();
		this.loadImage();
		this.controls.image.src = this.filename;
		//this.controls.image.show();
	},

	newFile: function(){
		this.base();
		this.controls.image.src="";
		this.controls.image.show();
	}
});




Choquin.Control.ImageFileAdvanced = Choquin.Control.ImageFile.extend({
	constructor: function(element,options){	
		/**
			options: name, value, fileid, filename, filedescription
		*/
		this.base(element,options);
	},
	
	create: function(){
		this.base();
		this.controls.push (this.element.insert(this.controls.id = new Element('input',{type:'hidden',name:this.controls.fileinput.name+'_id',value:this.options.fileid||''})));
		this.controls.push (this.element.insert(this.controls.name = new Element('input',{type:'text',className:'name',name:this.controls.fileinput.name+'_name',value:this.options.filename||''})));
		this.controls.push (this.element.insert(this.controls.description = new Element('textarea',{className:'description',name:this.controls.fileinput.name+'_description'}).update(this.options.filedescription)));
	},
	
	deleteFile: function(){
		this.base();
		[this.controls.name,this.controls.description].invoke('hide');
	},

	revert: function(){
		this.base();
		[this.controls.name,this.controls.description].invoke('show');
	},
	
	newFile: function(){
		this.base();
		[this.controls.name,this.controls.description].invoke(this.controls.fileinput.value?'show':'hide');
	},
	
	changeFile: function(){
		this.base();
		[this.controls.name,this.controls.description].invoke(this.controls.fileinput.value?'show':'hide');
	}
});




Choquin.Control.Repeater = Choquin.Control.Base.extend({
	constructor: function(element,options){	
		//options: {control:controlToRepeat,values:[], basename:"controlBaseNaem"}
		this.base(element,options);
		this.listControlIndex=0;
	},
	
	create: function(){
		this.base();
		this.element.addClassName('choquin_controlRepeater');
		this.controls.push (this.element.insert(this.controls.list = new Element('div',{className:'list'})));
		this.controls.push (this.controls.list.insert(this.controls.list.clearbefore = new Element('div',{style:'display:block;clear:both'})));
		this.controls.push (this.controls.list.insert(this.controls.list.clearafter = new Element('div',{style:'display:block;clear:both'})));
		this.controls.push (this.element.insert(this.controls.addButton = new Element('input',{type:'button',name:'add',value:'add'})));
		
		this.controls.addButton.observe('click',this.addControl.bindAsEventListener(this));
	},
	
	addControl: function(controlParameters){
		var container = new Element('div',{className:'listItem'});
		var button,control;
		var name = this.options.basename;
		name+="_"+(++this.listControlIndex);

		controlParameters = controlParameters || {};
		controlParameters.name = controlParameters.name || name;

		container.insert(control = new this.options.control(new Element('div'),controlParameters).element);
		
		container.insert(button = new Element('input',{type:'button',value:'remove',className:'btnRemove'}));
		button.relatedControl = control;
		button.relatedContainer = container;
		button.observe('click',this.removeControl);

		container.insert(new Element('input',{type:'hidden',name:this.options.basename,value:this.listControlIndex}));

		this.controls.list.clearafter.insert({before:container});
	},
	
	removeControl: function(evt){
		this.relatedContainer.remove();
	}

});





/************* EN CONSTUCCION *************************/
Choquin.Control.FileAutoUploader = Choquin.Control.Base.extend({
	constructor: function(element,options){	
		this.base(element,options);
		
		this.observe("choquin.control:uploadBegin",function(){
			this.controls.message.update(this.options.msgBegin || "uploading file...");
		});

		this.observe("choquin.control:uploadSuccess",function(evt,result){
			this.controls.message.update(['jpg','jpeg','gif','png'].include(String(result.files).ext())?'':result.files);
			this.controls.image.src = result.files;
			this.controls.image.title = result.files;
			this.currentFile = result.files;
		});

		this.observe("choquin.control:uploadError",function(evt,error){
			this.controls.message.update(error);
			this.controls.message.className = "error";
		});
		
		
		/*********** mouse enter, mouse leave *********/
		//this.element.addEnterLeave();

		this.element.observe("mouse:enter",function(){
			this.element.insert(this.controls.form);
			this.controls.formGhost.hide();
		}.bindAsEventListener(this));

		this.element.observe("mouse:leave",function(){
			this.controls.formGhost.setStyle({height:this.controls.form.getHeight()+'px'}).show();
			this.element.removeChild(this.controls.form);
		}.bindAsEventListener(this));

	},
	
	create: function(){
		this.base();
		/** labels **/
		this.controls.push (this.controls.image = new Element("img",{className:"imageViewer"}));
		this.element.insert(this.controls.image);		

		this.controls.push (this.controls.message = new Element("div",{className:"message"}));
		this.element.insert(this.controls.message);		


		this.controls.push (this.controls.iframe = new Element("iframe",{style:"display:none",name:this.element.identify()+'_hiddenIframe'}));
		this.element.insert(this.controls.iframe);
		$(this.controls.iframe).observe('load',this._iframeLoaded.bindAsEventListener(this));

		/** form **/
		this.controls.push(this.element.insert(this.controls.formGhost = new Element("div").update("upload your file here")));
		this.controls.push(this.controls.form = new Element("form",{method:"post",enctype:"multipart/form-data",action:"",target:this.controls.iframe.name}));
		//this.element.insert(this.controls.form);
		
		this.controls.form.insert(this.controls.fileinput = new Element('input',{type:'file',name:'file',className:'input'}));
		this.controls.form.insert(new Element('input',{type:'hidden',name:'callback',value:this.options.callback||"Choquin.Control.FileAutoUploader.onComplete"}));

		//this.controls.form.insert(new Element('label',{'for':'name',name:'name',value:"concha"}).update("nombre:"));
		//this.controls.form.insert(new Element('input',{type:'text',name:'name',value:this.options.value||""}));

		this.controls.fileinput.observe('change',this._submitForm.bind(this));
		/*************/
	},
	
	_submitForm: function(){
		this.fire("choquin.control:uploadBegin");
		var action = this.options.action || "";
		var queryString = {id:this.id, dir: this.options.dir, del: this.currentFile};
		this.controls.form.action = action+"?"+Object.toQueryString(queryString);
		this.controls.form.submit();
	},
	
	_iframeLoaded: function(){
		try{
			if(this.controls.iframe.getContentDocument().location.href!="about:blank")
				this.fire("choquin.control:iframeLoaded");
		}catch (e){
			this.fire("choquin.control:iframeLoaded");
		}
	}
},{
	onComplete: function(response){
		var control = Choquin.Control.FileAutoUploader.controls.find(function(control){
			return control.id == response.id;
		});
		if(control){
			if(response.error) 	control.fire('choquin.control:uploadError',response.error);
			if(response.result)	control.fire('choquin.control:uploadSuccess',response.result);
		}
	}
});


