/*
Inject Logic 1.0 by Ari N. Karp, August 2008
using mooTools v.1.11

Blog: theuiguy.blogspot.com

You are free to use at will, just at least visit my blog and tell me
1. if you are using it and how (for curiosity sake)
2. some feedback on how you changed, enhanced, or minimized it. 

I believe in sharing code to the community, so if you feel the same, then
please share your changes with me to help make the UI a better place.

For help on this, please visit theuiguy.blogspot.com and I will get back asap.
*/

window.addEvent('domready', function(){
	app.initialize();
});

var app = {

	initialize : function(){
		this.inConversion = false;
		this.freeze = false;
		this.ajaxURL = ""; // fill in your own
		this.selectedRows = [];
		this.rowSelectionColor = "#B4D181";
		this.setUpRowEvents($$('.headerrow'),'injectRows'); // first arg can take >1 tables
		this.standardResponseDiv = new Element('div',{id:"standardResponse"});
		this.currentConCell = null;
	},
	
	submitConvertCell : function(att,value){ 
		app.updateTable(att,value);
	},
	
	returnConvertedCell : function(parent,att){	
		box = this.currentConCell;
		if($(box) && parent.getAttribute("injected")){
			$(box).parentNode.innerHTML = parent.getAttribute(att);	
		}
	},
			
	convertCell : function(type,child,parent,className,event){
		// although you can use textarea, I haven't tried to solve the enter issue yet. (enter key has two meanings here)
		if(app.inConversion) return;
		app.inConversion = true;
		switch(type){
			case "textarea": 
			case "text":
				if(type === "text") var tType = "input";
				if(type === "textarea") var tType = "textarea";
				var att = child.getAttribute("att");
				var newField = new Element(tType,{
					id:'textBox'+parent.id,
					att : att,
					parent : parent,
					parentId : parent.id,
					'class' : className,
					'type': 'text'
				});
				if($(app.currentConCell)) app.returnConvertedCell($(app.currentConCell).getAttribute("parent"),$(app.currentConCell).getAttribute("att"));	
				newField.onfocus = function(event){
					app.currentConCell = 'textBox'+parent.id;	
				};
				newField.addEvent('blur', function(event){
					this.focus();
				});				
				newField.addEvent('click', function(event){
					if(event) event.cancelBubble = true;
				});				
				newField.addEvent('keyup', function(event,xkey){
					event.cancelBubble = true;
					key = (xkey === undefined) ? event.keyCode : xkey;
					if(key === 27){						
						app.returnConvertedCell(parent,child.getAttribute("att"));	
						parent.setAttribute("injected","false");							
					}
					if(key === 13){
						var tVal = app._cleanse(this.value);
						if(tVal.length > 0){				
							parent.setAttribute(att,this.value);
							parent.setAttribute("injected","false");
							child.innerHTML = tVal;	
							app.submitConvertCell(child.getAttribute("att"),child.innerHTML);//should only be text.	
						}else{
							app.returnConvertedCell(parent,child.getAttribute("att"));	
						}
					};
					app.inConversion = false;
				});
				if(!$(newField.id)){
					child.innerHTML = "";
					newField.inject(child);
					newField.value = unescape(parent.getAttribute(att));
					newField.focus();
					parent.setAttribute("injected","true");
					app.forceClick(parent);
				}
			break;
		}		
	},

	forceClick : function(row){
		if(row.style.backgroundColor.toLowerCase() !== app.rowSelectionColor.toLowerCase()){
			row.selected = true;
			$each(row.cells, function(cell, index){cell.style.backgroundColor = app.rowSelectionColor});			
			// app.evaluateButtons(); Stub for you, if you want to enable or disable buttons anywhere.
			if(!app.selectedRows.contains(row)) app.selectedRows.push(row);			
		}	
	},

	setUpRowEvents : function(rows,className){ 
		$each(rows, function(hRow, index){
			var set = (hRow.id === "headerrow") ? hRow.parentNode.rows : [hRow];
			$each(set, function(row, index){						
				if(row.id !== "headerrow"){					
					row = new Element(row,{'styles':{'cursor':'pointer'}}); 			
					if(className !== undefined) row.className = className; // allows us to save rendering time by not initially loading classes.
					row.addEvent('mouseenter', function(event){
						if(!this.selected){
							if(event) event.cancelBubble = true;
							$each(this.cells, function(cell, index){cell.style.backgroundColor = "#ECF5DD";});
						}
						if($(app.currentConCell)) $(app.currentConCell).focus();
					});
					row.addEvent('mouseleave', function(event){						
						if(!this.selected){
							if(event) event.cancelBubble = true;
							$each(this.cells, function(cell, index){			
								cell["lastBackgroundColor"] = (cell["lastBackgroundColor"] !== null && cell["lastBackgroundColor"] !== undefined) ? cell["lastBackgroundColor"] : "#FFFFFF";
								if(cell.style.backgroundColor.toLowerCase() !== this.getAttribute("columnColor").toLowerCase()) cell.style.backgroundColor = cell["lastBackgroundColor"];
							},this);
						}
					});
					row.addEvent('mousedown', function(event){ // forces only 1 row.
						if(app.inConversion) return;							
						if(app.selectedRows.length > 0 && app.selectedRows[0] !== this) app.selectedRows[0].fireEvent("click"); 
						app.resetButtons();
					});
					row.addEvent('dblclick', function(event){	
						if(app.inConversion) return;	
						if(event) event.cancelBubble = true;	
						return false;	
					});
					row.addEvent('click', function(event){						
						if(app.inConversion) return;
						if(event) event.cancelBubble = true;
						if(!this.selected || this.selected === undefined){
							$each(this.cells, function(cell, index){cell.style.backgroundColor = app.rowSelectionColor});
							this.selected = true;		
							app.selectedRows.push(this);	
							app.evaluateButtons();
						}else{
							this.selected = false;
							this.fireEvent("mouseleave");								
							app.selectedRows.remove(this);	
							app.evaluateButtons();								
						}
					});				
				}						
			},app);
		},this);
	},
	
	updateTable : function(att,value){		
		$('notice').style.opacity = 50;
		$("notice").innerHTML = "Request submitted sucessfully to server.";
		app.fadeOutUpdate();
		/* 
		SET UP YOUR AJAX REQUEST. SOMETHING HERE TO GET YOU STARTED.
		USE FREEZE TO ALLOW ANY AJAX UPDATER TIME TO ANALYZE YOUR TABLE.
		*/
		/*
		someId = app.selectedRows[0]["id"]; 
		var name = (att === "name") ? app._escape(value) : "";
		var description = (att === "desc") ? app._escape(value) : "";		
		var strSend = this.generateRequest('someAction',{someIdentifier:someId,newName:name,newDescription:description})
		if(this.ajaxRequest) this.ajaxRequest = null;
		this.ajaxRequest = new Ajax(this.ajaxURL, {method: 'post', data:strSend, update:this.standardResponseDiv}).request();			
		this.ajaxRequest.addEvent('onComplete', function(event){							
			alert("ACTUAL request submitted sucessfully to server") // once you set up your ajax calls.
			app.standardResponseDiv.empty();				
			app.freezeCheck(); // give update time to run.
			window.setTimeout(function(){	
				app.unFreezeCheck(); 
			},2500);					
		});		
		*/
	},
	
	fadeOutUpdate : function(){
		new Fx.Style($('notice'), 'opacity', {duration: 1200,  transition: Fx.Transitions.Expo.easeInOut}).start(0.0);
	},
	
	freezeCheck : function(){ 
		this.freeze = true;
	},
	
	unFreezeCheck : function(){
		this.freeze = false;	
	},
	
	_cleanse : function(x){  
		x = x.replace("<", ""); 
		x = x.replace(">", ""); 
		x = x.replace("&lt;", ""); 
		x = x.replace("&gt;", ""); 
		x = x.replace("http://", ""); 
		x = x.replace("www", ""); 
		return x;
	},

	_escape : function(x){ 
		x = escape(x);
		x = x.replace(/\+/g, "%2b"); // replace plusses
		return x;
	},
		
	evaluateButtons : function(){
		// do something here to enable buttons on the screen.	
	},
	
	resetButtons : function(){	
		// do something here to reset buttons on the screen for next user action.
	},
	
	generateRequest : function(value){
		/*
		do something here to give your ajax call a string to send the server. Up to you.		
		this.strSend = ["name=" + value];					
		return this.strSend.join("");
		*/
	}
		
}
