if (!window.Richfaces) window.Richfaces = {};
Richfaces.InplaceInput = Class.create();


Richfaces.InplaceInput.prototype = {
	
	initialize: function(clientId, temValueKeepId, valueKeepId, tabberId, attributes, events, classes, barParams) {
		this.inplaceInput = $(clientId);
		this.inplaceInput.component = this;
		
		this.tempValueKeeper = $(temValueKeepId);
		this.valueKeeper = $(valueKeepId);
		this.attributes = attributes;
		this.tabber = $(tabberId);
		this.events = events;
		
		this.classes = classes;
		
		this.currentText = this.getCurrentText();
		this.value = this.valueKeeper.value;
		
		this.currentState = Richfaces.InplaceInput.STATES[0];
		this.prevState = Richfaces.InplaceInput.STATES[0];
		
		if (this.attributes.showControls) {
			this.bar = new Richfaces.InplaceInputBar(barParams[0], barParams[1], barParams[2], barParams[3], barParams[4],  
													 this.attributes.verticalPosition, this.attributes.horizontalPosition);
		}
		
		this.editEvent = this.attributes.editEvent.substring(2,this.attributes.editEvent.length);
		
		this.initHandlers();	
		this.initEvents();
		this["rich:destructor"] = "destroy";
		
	},
	
	destroy: function() {
		this.inplaceInput.component = null;
	},
		
	initHandlers : function() {
		this.inplaceInput.observe(this.editEvent, function(e){this.switchingStatesHandler(e);}.bindAsEventListener(this));
		this.inplaceInput.observe("mouseout", function(e){this.inplaceMouseOutHandler(e);}.bindAsEventListener(this));
		this.inplaceInput.observe("mouseover", function(e){this.inplaceMouseOverHandler(e);}.bindAsEventListener(this));
	
				
		this.tempValueKeeper.observe("blur", function(e){this.tmpValueBlurHandler(e);}.bindAsEventListener(this));
		this.tempValueKeeper.observe("keydown", function(e){this.tmpValueKeyDownHandler(e);}.bindAsEventListener(this));
		
		if (this.bar) {
			if (this.bar.ok) {
				this.bar.ok.observe("mousedown", function(e){this.okHandler(e);}.bindAsEventListener(this));			
			}
			if (this.bar.cancel) {
				this.bar.cancel.observe("mousedown", function(e){this.cancelHandler(e)}.bindAsEventListener(this));
			}
			
			//this.bar.bar.observe("mousedown", function(e){this.barMouseDownHandler(e);}.bindAsEventListener(this));
		}
		
		this.tabber.observe("focus", function(e){this.switchingStatesHandler(e);}.bindAsEventListener(this));
		this.tabber.observe("blur", function(e){this.tmpValueBlurHandler(e);}.bindAsEventListener(this));
		
	},
	
	initEvents : function() {
		for (var e in this.events) {
			if (e) {
				this.inplaceInput.observe("rich:" + e, this.events[e]);
			}
		}
	},
	
	/*
	 *  HANDLERS
	 */
	 
	inplaceMouseOverHandler : function(e) {
		var className = this.inplaceInput.className; 
		if (this.currentState == Richfaces.InplaceInput.STATES[0]) {
			if (className.indexOf(this.classes.COMPONENT.VIEW.HOVERED) == -1) {
				className += " " + this.classes.COMPONENT.VIEW.HOVERED;
			}
		} else if (this.currentState == Richfaces.InplaceInput.STATES[2]) {
			if (className.indexOf(this.classes.COMPONENT.CHANGED.HOVERED) == -1) { 
				className += " " + this.classes.COMPONENT.CHANGED.HOVERED;
			}	 
		}
		this.inplaceInput.className = className;
	},
	
	inplaceMouseOutHandler : function(e) {
		if (this.currentState == Richfaces.InplaceInput.STATES[0]) {
			this.inplaceInput.className = this.classes.COMPONENT.VIEW.NORMAL;
		} else if (this.currentState == Richfaces.InplaceInput.STATES[2]) {
			this.inplaceInput.className = this.classes.COMPONENT.CHANGED.NORMAL; 
		}
	},
	
	switchingStatesHandler : function(e) {
		var el = (e.srcElement) ? e.srcElement : e.target;
		if ((el.id == this.inplaceInput.id) || (e.type == "focus")) {
		
			var target;
			if (e.target) {
				target = e.target;		
			} else if (target = e.srcElement) {
				target = e.srcElement;
			} else {
				//TO DO: to catch this exception
			}
			if (target.tagName.toLowerCase() == "input") {
				if (target.id == this.tabber.id) {
					this.byTab = true;
				} else {
					return;				
				}
			}
			
			if (this.events.oneditactivation) {
				this.inplaceInput.fire("rich:oneditactivation", {oldValue : this.valueKeeper.value, value : this.tempValueKeeper.value});
			}
			var textSize = this.inplaceInput.offsetWidth;
			
			this.startEditableState(textSize);
			//this.endViewState();
			
			if (this.events.oneditactivated) {
				this.inplaceInput.fire("rich:oneditactivated", {oldValue : this.valueKeeper.value, value : this.tempValueKeeper.value});
			}
		}	
	},
	
	tmpValueBlurHandler : function() {
		if (this.clickOnBar || this.byTab) {
			this.clickOnBar = false;
			this.byTab = false;
			return;
		}
		
		if (!this.attributes.showControls) {
			this.save();
		}
	},
	
	tmpValueKeyDownHandler : function(e) {
		switch (e.keyCode) {
			case Event.KEY_ESC :
				this.cancel(e, this.valueKeeper.value); 
				break;
			case Event.KEY_RETURN :
				Event.stop(e);
				this.tempValueKeeper.blur();
				break;
			case Event.KEY_TAB :
				this.save();
				this.byTab = true;
				break;
		}
	},
	
	/*barMouseDownHandler : function(e) {
		this.clickOnBar = true;
	},*/
	
	okHandler : function(e) {
		this.save();
		Event.stop(e);
	},
	
	cancelHandler : function(e) {
		this.cancel(e, this.valueKeeper.value);
		Event.stop(e);
	},
	
	/**
	 * STATE'S API
	 */
	/*endViewState : function() {
		this.deleteViewArtifacts();
	},*/
	
	endEditableState : function() {
		this.inplaceInput.style.position = "";
		if (this.bar) {
			this.bar.hide();
		}
		this.tabber.show();
		this.tempValueKeeper.hide();
	},
	
	/*endChangedState : function() {
		this.deleteViewArtifacts();
	},*/
	
	startEditableState : function(textSize) {
		this.inplaceInput.style.position = "relative";
		
		this.changeState(Richfaces.InplaceInput.STATES[1]);
		var inputSize = this.setInputWidth(textSize);
		
		this.tabber.hide();
		
		this.tempValueKeeper.show();
		this.inplaceInput.className = this.classes.COMPONENT.EDITABLE;
		
		if (this.bar) {
			this.bar.show(inputSize, this.tempValueKeeper.offsetHeight);
		}
		
		if (this.attributes.selectOnEdit) {
			Richfaces.InplaceInput.textboxSelect(this.tempValueKeeper, 0, this.tempValueKeeper.value.length);
		} 
		this.tempValueKeeper.focus();
	},
	
	startViewState : function() {
		this.deleteViewArtifacts();
		this.changeState(Richfaces.InplaceInput.STATES[0]);
		
		this.createNewText(this.currentText);
		this.inplaceInput.className = this.classes.COMPONENT.VIEW.NORMAL;
		this.inplaceInput.observe("mouseover", function(e){this.inplaceMouseOverHandler(e);}.bindAsEventListener(this));
	},
	
	startChangedState : function () {
		this.deleteViewArtifacts();
		
		this.changeState(Richfaces.InplaceInput.STATES[2]);
		
		//this.createNewText(this.valueKeeper.value);
		this.createNewText(this.currentText);
		this.inplaceInput.className = this.classes.COMPONENT.CHANGED.NORMAL;
	},
	
	/**
	 * UTILITIES
	 */
	 
	setInputWidth : function(textSize) {
		if (this.currentState != 1) {
			return;
		}
		var width = parseInt(this.attributes.inputWidth);
		if (!width) {
			var max = parseInt(this.attributes.maxInputWidth);
			var min = parseInt(this.attributes.minInputWidth);
			if (textSize > max) {
				width = max;
			} else if (textSize < min) {
				width = min;
			} else {
				width = textSize;
			}
		}
		this.tempValueKeeper.style.width = width + "px";
		return width;
	},
	
	changeState : function(newState) {
		this.prevState = this.currentState; 	
		this.currentState = newState;
	},
	
	cancel : function(e, value) {
		this.endEditableState();
		if (!value) {
			value = this.valueKeeper.value;	
		} 
		this.tempValueKeeper.value = value;
		this.currentText = value; 
		if ( this.tempValueKeeper.value == "") {
			this.setDefaultText();
		}
		switch (this.prevState) {
			case Richfaces.InplaceInput.STATES[0] :
				this.startViewState();
				break;
			case Richfaces.InplaceInput.STATES[2] : 
				this.startChangedState();
				break;
		}
	},
	
	save : function() {
		var userValue = this.tempValueKeeper.value;
		var currentText = userValue;
		this.saveValue(userValue, currentText);
	},
	
	saveValue : function(userValue, currentText) {
		var value = this.valueKeeper.value;
		if (this.events.onviewactivation) {
			this.inplaceInput.fire("rich:onviewactivation", {oldValue : this.valueKeeper.value, value : this.tempValueKeeper.value});
		}
		this.endEditableState();
		if (userValue == "") {
			this.setDefaultText();
			this.valueKeeper.value = "";
				//this.startViewState();
		} else {
			if (currentText == "") {
				this.setDefaultText();
			} else {
				this.currentText = currentText;
			}
			this.valueKeeper.value = userValue;
		}
		if (userValue != this.value) {
			this.startChangedState();
		} else {
			this.startViewState();
		}
		/*if (userValue != this.value) {
			if (userValue == "") {
				this.setDefaultText();
				this.valueKeeper.value = "";
				//this.startViewState();
			} else {
				this.currentText = userValue;
				this.valueKeeper.value = userValue;
			}
			this.startChangedState();
		} else {
			if (userValue == "") {
				this.setDefaultText();
				this.valueKeeper.value = "";
			} else {
				this.currentText = userValue;
				this.valueKeeper.value = userValue;
			}
			this.startViewState();
		} */
		if (this.events.onviewactivated) {
			this.inplaceInput.fire("rich:onviewactivated", {oldValue : this.valueKeeper.value, value : this.tempValueKeeper.value});
		}
	},
	
	setDefaultText : function() {
		this.currentText = this.attributes.defaultLabel;
	},
	
	deleteViewArtifacts : function () {
		var text = this.inplaceInput.childNodes[4];
		if (text) {
			this.inplaceInput.removeChild(text);
		}
	},
	
	getCurrentText : function() {
		return this.inplaceInput.childNodes[4];
	},
	
	createNewText : function(text) {
		if (!this.getCurrentText()) {
			this.inplaceInput.appendChild(document.createTextNode(text.nodeValue||text));
		}
	}
	
};

Richfaces.InplaceInputBar = Class.create();
Richfaces.InplaceInputBar.prototype = {
	initialize : function(barId, okId, cancelId, buttonsPanelId, buttonsShadowId, verticalPosition, horizontalPosition) {
		this.bar = $(barId);
		this.ok = $(okId);
		this.cancel = $(cancelId);
		this.bsPanel = $(buttonsPanelId);
		this.buttonsShadow = $(buttonsShadowId);
		
		this.verticalPosition = verticalPosition;
		this.horizontalPosition = horizontalPosition;
		this.initDimensions();
	},
	
	initDimensions : function() {
		
		/*this.bar.style.visibility = "hidden";
		this.bar.show();*/
		
		//var dim = this.bsPanel.getDimensions();
		this.BAR_WIDTH = 26;
		this.BAR_HEIGHT = 12;	
				
		/*this.bar.hide();
		this.bar.style.visibility = "visible";*/
	},
	
	show : function(inpWidth, inpHeight) {
		this.positioning(inpWidth, inpHeight);
		if (Richfaces.browser.isIE6 && this.buttonsShadow) {
			this.buttonsShadow.style.visibility = "hidden";
		}
		this.bar.show();
	},
	
	hide : function() {
		this.bar.hide();
	},
	
	positioning : function(inpWidth, inpHeight) {
		if (this.bsPanel) {
			this.bsPanel.style.height = inpHeight + "px";
		}	
		
		
		this.bar.style.position = "absolute";
		var bs = this.bar.style;
		
		if (this.verticalPosition == "top" || this.verticalPosition == "bottom") {
			switch (this.horizontalPosition) {
				case "left" : 
					bs.left = "0px"; 
					break;
				case "right" : 
					bs.left = inpWidth + "px"; 
					break;
				case "center" : 
					bs.left = parseInt(inpWidth/2 - this.BAR_WIDTH/2) + "px"; 
					break; 
			}
			
			if (this.verticalPosition == "top") {
				bs.top = -this.BAR_HEIGHT + "px";
			} else {
				bs.top = inpHeight + "px";
			}
		} else if (this.verticalPosition == "center") {
			bs.top = "0px";
			switch (this.horizontalPosition) {
				case "left" : 
					bs.left = -this.BAR_WIDTH + "px";
					break;
				case "right" :
					bs.left = inpWidth + "px"; 
					break;
			}
		}
	}
	
};

Richfaces.InplaceInput.STATES = [0, 1, 2];// 0 - view, 1- editable, 2 - changed

Richfaces.InplaceInput.textboxSelect = function(oTextbox, iStart, iEnd) {
   if (Prototype.Browser.IE) {
       var oRange = oTextbox.createTextRange();
       oRange.moveStart("character", iStart);
       oRange.moveEnd("character", -oTextbox.value.length + iEnd);      
       oRange.select();                                              
   } else if (Prototype.Browser.Gecko) {
       oTextbox.setSelectionRange(iStart, iEnd);
   } else {
   		//FIXME
   		oTextbox.setSelectionRange(iStart, iEnd);
   }                    
};