//version 2.1.1 
var arrLogs = new Array();

var OUTPUT_STYLE = "text-align: left; background-color: #fff; border-top: 1px solid #bbb; border-bottom: 1px solid #bbb; cursor: text; margin-bottom: 2px; font-family: \"Courier New\", Courier, monospace; font-size: 11px; padding: 0 10px; ";
var LOG_OUTPUT_STYLE = OUTPUT_STYLE+"overflow-y: scroll; ";
var CM_OUTPUT_STYLE = OUTPUT_STYLE+"overflow: scroll;";
var PROFILER_OUTPUT_STYLE = OUTPUT_STYLE+"overflow-y: scroll; ";

var DETAILS_STYLE = "font-family: \"Courier New\", Courier, monospace; border: 1px solid #bbb; margin: 2px 0; background: #fff; padding: 2px 5px; "; 

var ICHR_Log = Class.create(
{

	m_objInstance: null,
	
	m_arrWindows: null,
	
	m_arrProcHeaders: null,
	m_arrProcCells: null,
	
	
	
	m_objActiveWindow: null,
	
	m_bInitialized: false,
	
	m_objSwitch: null,
	
	m_objLogOutput: null,
	m_objProfilerOutput: null,
	m_objControlStatus:null,
	
	m_objCSLegend: null,
	m_objCSInfo: null,
	
	m_objCSTable: null,
	m_objCSHeaders: null,
	
	m_arrCmdDetails: null,
	m_arrResetCounts: null,
	
	m_objWrapper: null,
	m_objEnabledInput: null,
	m_objPrioritySelect: null,
	m_objFilterInput: null,
	m_objFilterButton: null,
	
	m_strInstanceName: null,
	m_iWidth: 750,
	m_iHeight: 300,
	
	m_bMinimilized: false,
	m_objBottomWrapper: null,
	
	m_arrMsgHistory: null,
	m_arrMsgQueue: null,
	
	m_arrFilters: null,
	
	m_iMsgPointer: 0,
	
	m_activeCmdBox: null,
	
	m_arrTempMsgHistory: null,
	m_arrTempInstancesList: null,
	m_arrTempCSList: null,
	
	
	initialize: function(p_objAplication, p_strInstanceName, p_iWidth, p_iHeight){
		
		this.m_strInstanceName = p_strInstanceName;
		if(p_objAplication){
			this.m_objInstance = p_objAplication.getInstance();
			p_objAplication.addLoadListener(this._onAplicationLoad.bind(this));
		}
		
		if(p_iWidth)
			this.m_iWidth = p_iWidth;
		if(p_iHeight)
			this.m_iHeight = p_iHeight;
			
		document.observe("dom:loaded", this._onDocumentLoad.bindAsEventListener(this));
		
		this.m_arrMsgHistory = new Array();
		this.m_arrFilters = new Array();
		this.m_arrMsgQueue = new Array();
		this.m_arrWindows = new Array();
		
		this.m_arrProcHeaders = new Array();
		this.m_arrProcCells = new Array();
		
		this.m_arrCmdDetails = new Array();
		this.m_arrResetCounts = new Array();
		
		this.m_arrTempMsgHistory = new Array();
		this.m_arrTempInstancesList = new Array();
		this.m_arrTempCSList = new Array();
	},
	
	log: function(p_arrList){
		if(this.m_objProfilerOutput && this.m_bInitialized && this.m_objEnabledInput.checked){
			this.m_iMsgPointer = this.m_arrMsgHistory.length - 1;		
			this.m_arrMsgHistory = this.m_arrMsgHistory.concat(p_arrList);
			this.writeMessages(p_arrList);
		}
		else{
			this.m_arrTempMsgHistory = this.m_arrTempMsgHistory.concat(p_arrList);
		}
	},
	
	showInstances: function(p_arrList){
		if(this.m_objProfilerOutput && this.m_bInitialized && this.m_objEnabledInput.checked){
			this.m_objProfilerOutput.innerHTML = "";
			var strLastName = "";
			var iCounter = 1;
			var objLastName = null;
			for(var i = 0; i < p_arrList.length; i++){
				var strName = p_arrList[i];
				var strTime = strName;
				strName = strName.substr(0, strName.indexOf(" "));
				strTime = strTime.substr(strName.length);
				if(strName != strLastName){
					if(objLastName)
						objLastName.appendChild(document.createTextNode(strLastName+" ("+iCounter+")"));
					iCounter = 1;
					objLastName = document.createElement("b");
					if(i>0){
						this.m_objProfilerOutput.appendChild(document.createElement("br"));
						this.m_objProfilerOutput.appendChild(document.createElement("br"));
					}
					this.m_objProfilerOutput.appendChild(objLastName);
					this.m_objProfilerOutput.appendChild(document.createElement("br"));
					strLastName = strName;
				}
				else{
					iCounter++;
				}
				this.m_objProfilerOutput.appendChild(document.createTextNode(strTime));
				//this.m_objProfilerOutput.appendChild(document.createElement("br"));				
			}
			if(objLastName)
				objLastName.appendChild(document.createTextNode(strLastName+" ("+iCounter+")"));
		}
		else{
			this.m_arrTempInstancesList = p_arrList;
		}
	},
	
	
	
	showControlStatus: function(p_arrList){
		if(this.m_objControlStatus && this.m_bInitialized && this.m_objEnabledInput.checked){
			
			for(var i = 0; i < p_arrList.length; i++){
				this._updateProcStatus(p_arrList[i]);		
			}
		}
		else{
			this.m_arrTempCSList = this.m_arrTempCSList.concat(p_arrList);
		}
	},
	
	_setLogEnabled: function(event){
		if(this.m_objEnabledInput.checked){
			this.log(this.m_arrTempMsgHistory);
			this.showInstances(this.m_arrTempInstancesList);
			this.showControlStatus(this.m_arrTempCSList);
			this.m_arrTempMsgHistory = new Array();
			this.m_arrTempInstancesList = new Array();
			this.m_arrTempCSList = new Array();
		}			
	},
	
	_updateProcStatus: function(p_objStatus){
		if(p_objStatus && this.m_objControlStatus && this.m_bInitialized && this.m_objEnabledInput.checked){
			var strId = "procCell"+p_objStatus.procId;
			
			
			if(this.m_objCSTable == null || this.m_objCSHeaders == null){
				var objTable = new Element("table", {"style":"table-layout:fixed; border-spacing: 0;"});
				this.m_objCSHeaders = new Element("tr");
				objTable.insert(this.m_objCSHeaders);
				this.m_objCSTable = new Element("tr");
				objTable.insert(this.m_objCSTable);
				
				this.m_objControlStatus.insert(objTable);
			}
			
			
			
				
			var objProcHeader  = this.m_arrProcHeaders[strId];
			if(!objProcHeader){
				objProcHeader = new Element("th", {"style":"text-align: left; padding: 5px; margin: 0; border-right: 1px solid #cfcfcf; white-space:nowrap;"});
				this.m_objCSHeaders.insert(objProcHeader);
				this.m_arrProcHeaders[strId] = objProcHeader;
				
			}
			objProcHeader.innerHTML = "#"+(p_objStatus.procId?p_objStatus.procId:"default")+" ("+p_objStatus.pointer+"/"+p_objStatus.commandCount+")";
			
			
			var objProcCell  = this.m_arrProcCells[strId];
			if(!objProcCell){
				objProcCell = new Element("td", {"style":"vertical-align: top; margin: 0; border-right: 1px solid #cfcfcf; white-space:nowrap;"});
				this.m_objCSTable.insert(objProcCell);
				this.m_arrProcCells[strId] = objProcCell;
			}
			
			if(this.m_arrResetCounts[strId] != p_objStatus.resetCount){
				this.m_arrResetCounts[strId] = p_objStatus.resetCount;
				objProcCell.innerHTML = "";
			}
			
			
			if(p_objStatus.activeCommands){
				
				//alert(p_objStatus.activeCommands);
				for(var i = 0; i < p_objStatus.activeCommands.length; i++){
					var objCommandStatus = p_objStatus.activeCommands[i];
					if(objCommandStatus){
						var objCmdBox = objProcCell.childNodes[objCommandStatus.id];
						var strInfoId = p_objStatus.procId+"_"+objCommandStatus.id;
						if(!objCmdBox){
							objCmdBox = new Element("div", {"style":"color: #666; cursor: pointer; padding: 2px 5px;"});
							objProcCell.insert(objCmdBox);
							
							objCmdBox.innerHTML = objCommandStatus.type+" #"+objCommandStatus.id+" "+(objCommandStatus.synchronous?"[S]":"")+(objCommandStatus.waitAfter?"["+objCommandStatus.waitAfter+"]":"");
							objCmdBox.id = strInfoId;
							objCmdBox.onclick = this._showCmdInfo.bindAsEventListener(this);
						}
						
						if(objCommandStatus.startTime){
							objCmdBox.style.fontWeight = "bold";
						}
						
						if(objCommandStatus.startTime && !objCommandStatus.endTime)
							objCmdBox.style.color = "red";
						else if(objCommandStatus.endTime)
							objCmdBox.style.color = "#000000";
							
						if(objCommandStatus.terminated){
							objCmdBox.style.textDecoration = "line-through";
							objCmdBox.style.color = "#666";
						}
						this.m_arrCmdDetails[strInfoId] = objCommandStatus;
						
											
					}
					
					
				}
			}
		}
	},
	
	_showCmdInfo: function(event){
		var objCmdBox = Event.element(event);
		if(!objCmdBox)
			return;
		
		if(this.m_activeCmdBox)
			this.m_activeCmdBox.style.backgroundColor = "";
		
		objCmdBox.style.backgroundColor = "#cccccc";
		this.m_activeCmdBox = objCmdBox;
		var objStatus = this.m_arrCmdDetails[objCmdBox.id];
		if(objStatus){
			var strTimeRange = objStatus.startTime?(objStatus.startTime+" - "+(objStatus.endTime?objStatus.endTime:"still running")):"awaiting";
			var strInfo = "<div style='padding: 0 10px 0 0'>Command <b>"+objStatus.type+" #"+objStatus.id+"</b> on processor <b>#"+(objStatus.procId?objStatus.procId:"default")+"</b> ["+strTimeRange+"] :</div>";
			strInfo +="<div style='"+DETAILS_STYLE+"'>";
			for(strProperty in objStatus.properties){
				strInfo += "<div style='float: left; padding: 0 10px 2px 0'><b>"+strProperty+":</b> "+objStatus.properties[strProperty]+";</div>";
			}
			strInfo +="<div style='clear: both'></div></div>";
			this.m_objCSInfo.innerHTML = strInfo;
		}
	},
	
	writeMessages: function(p_arrList){
		if(this.m_objLogOutput && this.m_bInitialized){
			//var strOutput = "";
			for(var i = 0; i < p_arrList.length; i++){
				var strMsg = p_arrList[i];
				
				var iPriority = parseInt(strMsg.charAt(2));
				if(strMsg == "" || (this.isFiltered(strMsg) && iPriority <= this.m_objPrioritySelect.value)){
					//alert(strMsg);
					var strSource = strMsg.substr(0, strMsg.indexOf(":", 21));
					var strTrace = strMsg.substr(strSource.length);
					var arrTrace = strTrace.split("\n");
					var objSourceBold = document.createElement("b")
					objSourceBold.appendChild(document.createTextNode(strSource));
					this.m_objLogOutput.appendChild(objSourceBold);
					if(arrTrace.length > 1){
						for(var iPartNo = 0; iPartNo < arrTrace.length; iPartNo++){
							this.m_objLogOutput.appendChild(document.createTextNode(arrTrace[iPartNo]));
							this.m_objLogOutput.appendChild(document.createElement("br"));
						}
					}
					else
						this.m_objLogOutput.appendChild(document.createTextNode(strTrace));
					this.m_objLogOutput.appendChild(document.createElement("br"));
				}
				
			}
			
			this.m_objLogOutput.scrollTop = this.m_objLogOutput.scrollHeight - this.m_objLogOutput.clientHeight;
		}
	},
	
	isFiltered: function (p_strMsg){
		
		if(!this.m_arrFilters.length)
			return true;
		for (var i = 0; i < this.m_arrFilters.length; i++){
			var strFilter = this.m_arrFilters[i];
			if(p_strMsg.indexOf(strFilter) > -1 && strFilter.length > 0){
				return true;
			}
		}
		return false;
		
	},
	
	clear: function(){
		if(this.m_objLogOutput && this.m_bInitialized){
			this.m_objLogOutput.innerHTML = "";
			this.m_objLogOutput.scrollTop = this.m_objLogOutput.scrollHeight - this.m_objLogOutput.clientHeight;
		}
	},
	
	_onDocumentLoad: function(event){
		
	},
	
	_toggle: function(){
		if(this.m_bMinimilized){
			this.m_objWrapper
			this.m_objWrapper.style.height = this.m_iHeight+"px";
			this.m_bMinimilized = false;
			this.m_objBottomWrapper.style.display = "";
			var iTop = this.m_objWrapper.style.top;
			iTop = iTop.substr(0, iTop.indexOf("px"));
			var iValidTop = document.viewport.getHeight()-this.m_iHeight;
			if(iTop > iValidTop)
				this.m_objWrapper.style.top =  iValidTop+ "px";
		}
		else{
			this.m_objWrapper.style.height = "30px";			
			this.m_objBottomWrapper.style.display = "none";
			this.m_bMinimilized = true;
			this.m_objWrapper.style.left = "0px";
			this.m_objWrapper.style.top = (document.viewport.getHeight()-30) + "px";
		}
	},
	
	
	
	_changePriority: function(event){
		this.clear();
		this.writeMessages(this.m_arrMsgHistory);
	},
	
	_filter: function(event){
		if(this.m_objFilterInput.value){
			//if(this.m_objFilterInput.value.indexOf(" ") > -1)
				this.m_arrFilters = this.m_objFilterInput.value.split(" ");
			//else
				//this.m_arrFilters = [this.m_objFilterInput.value];
		}
		else
			this.m_arrFilters = new Array();
			
		this.clear();
		this.writeMessages(this.m_arrMsgHistory);
	},
	
	_startDrag: function(event){		
		this.m_bDraggable = true;
		var objPosition = this.m_objWrapper.positionedOffset();
		this.m_startX = Event.pointerX(event) - objPosition[0];
		this.m_startY = Event.pointerY(event) - objPosition[1];		
		this.m_funMoveListener = this._drag.bindAsEventListener(this);
		$(document).observe("mousemove", this.m_funMoveListener);
	},
	
	_stopDrag: function(event){
		this.m_bDraggable = false;	
		//this.log("stop drag");
		$(document).stopObserving("mousemove", this.m_funMoveListener);
	},
	
	_drag: function(event){
		//alert(this.m_objWrapper.positionedOffset());
		
		var iNewX = Event.pointerX(event) - this.m_startX;
		var iNewY = Event.pointerY(event) - this.m_startY;
		//this.log(iNewX+"/"+iNewY);
		this.m_objWrapper.style.left = iNewX+"px";
		this.m_objWrapper.style.top = iNewY+"px";
		
	},
	
	_switchWindow: function(event){
	
		
		this._activateWindow(this.m_objSwitch.value);
		 
	},
	
	
	_activateWindow: function(p_strId){
		var objWindow = this.m_arrWindows[p_strId];
		if(objWindow && objWindow != this.m_objActiveWindow){
			if(this.m_objActiveWindow)
				this.m_objActiveWindow.style.display = "none";
			objWindow.style.display = "block";
			this.m_objActiveWindow = objWindow;
		}
	},
	
	_createWindow: function(p_strId, p_strStyle, p_iWidth, p_iHeight, p_bHidden){
		if(p_iWidth)
			p_strStyle += "width: "+p_iWidth+"px; ";
		if(p_iHeight)
			p_strStyle += "height: "+p_iHeight+"px; ";
		if(p_bHidden)
			p_strStyle += "display: none; ";
		var objElement = new Element("div", {"id":p_strId, "style":p_strStyle});
		this.m_arrWindows[p_strId] = objElement;
		return objElement;
	},
	
	
	_onAplicationLoad: function(){
		//alert(this.m_objInstance.setLog);
		this.m_objWrapper = new Element("div", {"id" : this.m_strInstanceName, "style" : "position: absolute; z-index: 10000; overflow: hidden; top: "+(document.viewport.getHeight() - this.m_iHeight)+"px; font-family: Arial, Helvetica, sans-serif !important; font-size: 11px !important; border: 1px solid #000; background-color: #ccc; width: "+this.m_iWidth+"px; height: "+this.m_iHeight+"px"})
		this.m_objHeader = new Element("div", {"style" : "background-color: #ddd; cursor: move; height: 25px; padding: 2px 5px; font-size: 12px"});
		
		
		
		
		this.m_objSwitch = new Element("select", {"style":"float: right; margin-top:2px;"});
		this.m_objSwitch.insert((new Element("option", {"value" : "LogWindow"})).insert("Log console"));
		this.m_objSwitch.insert((new Element("option", {"value" : "IMWindow"})).insert("Profiler"));
		this.m_objSwitch.insert((new Element("option", {"value" : "CSWindow"})).insert("Processors"));
		
		this.m_objHeader.insert(this.m_objSwitch);		
		
		this.m_objEnabledInput = new Element("input", {"type" : "checkbox", "style":"vertical-align: middle;"});
		
		this.m_objHeader.insert((new Element("label", {"style" : "float: right; padding-top: 2px; font-family: Arial, Helvetica, sans-serif !important; font-size: 11px !important;"})).insert(this.m_objEnabledInput).insert("enable &nbsp;&nbsp;&nbsp;&nbsp; "));
		
		this.m_objHeader.insert("<b>InteliWISE | CHARACTER 2.1.1 - Debug console</b> <br/><span style='font-size: 10px'>[<b>dbclick</b> - minimalize/restore, <b>press</b> - and hold to drag]</span>");
		
		this.m_objWrapper.insert(this.m_objHeader);
		
		this.m_objBottomWrapper = new Element("div");	
		this.m_objWrapper.insert(this.m_objBottomWrapper);
		
		
		var objLogWindow = this._createWindow("LogWindow", "");					
		this.m_objLogOutput = this._createWindow("LogOutput",  LOG_OUTPUT_STYLE, null, this.m_iHeight - 60);		
		objLogWindow.insert(this.m_objLogOutput);
		this.m_objBottomWrapper.insert(objLogWindow);
		
		this._activateWindow(objLogWindow.id);
		
		var objIMWindow = this._createWindow("IMWindow", "", null, null, true);		
		this.m_objProfilerOutput = this._createWindow("IMOutput", PROFILER_OUTPUT_STYLE, null, this.m_iHeight - 30);
		objIMWindow.insert(this.m_objProfilerOutput);
		this.m_objBottomWrapper.insert(objIMWindow);
		
		var objCSWindow = this._createWindow("CSWindow", "", null, null, true);
		this.m_objControlStatus = this._createWindow("CSOutput", CM_OUTPUT_STYLE, this.m_iWidth - 20, this.m_iHeight - 105);
		objCSWindow.insert(this.m_objControlStatus);
		this.m_objBottomWrapper.insert(objCSWindow);
		var strLegend = "<div style='float: left; width: 120px; padding: 0 10px;'><b>Legend:</b>";
		strLegend += "<div style='"+DETAILS_STYLE+"'> - <span style='color: #666;'>awaiting</span>";
		strLegend += "<br/> - <span style='color: red; font-weight:bold;'>in progress</span>";
		strLegend += "<br/> - <span style='font-weight:bold;'>finished</span>";
		strLegend += "<br/> - <span style='color: #666; text-decoration: line-through; font-weight:bold;'>terminated</span>";
		strLegend += "</div></div>";
		
		objCSWindow.insert(strLegend);
		
		var strCmdInfo = "<b>Command details:</b><br/><br/>Click on any command label to see its details."
		
		this.m_objCSInfo = new Element("div", {"style":"float: left; height: 75px; width: 600px; overflow-y: auto;"});
		this.m_objCSInfo.insert(strCmdInfo);
		objCSWindow.insert(this.m_objCSInfo);
		
		//this.log(this.m_objEnabledInput.value);
		
		this.m_objPrioritySelect = new Element("select");
		this.m_objPrioritySelect.insert((new Element("option", {"value" : 0})).insert("0 - exceptions"));
		this.m_objPrioritySelect.insert((new Element("option", {"value" : 1})).insert("1 - very high"));
		this.m_objPrioritySelect.insert((new Element("option", {"value" : 2})).insert("2 - high"));
		this.m_objPrioritySelect.insert((new Element("option", {"value" : 3, "selected" : true})).insert("3 - medium"));
		this.m_objPrioritySelect.insert((new Element("option", {"value" : 4})).insert("4 - low"));
		this.m_objPrioritySelect.insert((new Element("option", {"value" : 5})).insert("5 - very low"));
		this.m_objFilterInput = new Element("input", {"type" : "text", "style" : "width: 400px"});
		this.m_objFilterButton = new Element("input", {"type" : "button", "value" : "filter"});
		
		
		objLogWindow.insert((new Element("label", {"style" : "font-family: Arial, Helvetica, sans-serif !important; font-size: 11px !important;"})).insert("&nbsp;&nbsp;Priority filter:&nbsp;").insert(this.m_objPrioritySelect));
		objLogWindow.insert((new Element("label", {"style" : "font-family: Arial, Helvetica, sans-serif !important; font-size: 11px !important;"})).insert("&nbsp;&nbsp;&nbsp;&nbsp;Keyword filter:&nbsp;").insert(this.m_objFilterInput).insert("&nbsp;"));
		objLogWindow.insert(this.m_objFilterButton);
		
		document.body.appendChild(this.m_objWrapper);
		
				
		
		
		this.m_objSwitch.observe("change", this._switchWindow.bindAsEventListener(this));
		
		this.m_objEnabledInput.observe("click", this._setLogEnabled.bindAsEventListener(this));		
		this.m_objPrioritySelect.observe("change", this._changePriority.bindAsEventListener(this));
		this.m_objFilterButton.observe("click", this._filter.bindAsEventListener(this));
		
		this.m_objHeader.observe("dblclick", this._toggle.bindAsEventListener(this));
		this.m_objHeader.observe("mousedown", this._startDrag.bindAsEventListener(this));
		$(document.body).observe("mouseup", this._stopDrag.bindAsEventListener(this));
		
		
		arrLogs[this.m_strInstanceName] = this;
		this.m_bInitialized = true;
		//this.writeMessages(this.m_arrMsgHistory);
		
		
		if(this.m_objEnabledInput){
			this.m_objEnabledInput.checked = true;
			try{		
				this.m_objInstance.setLog("arrLogs['"+this.m_strInstanceName+"']");
			}
			catch(error){
				alert('Log init error: \n'+error);
			}
		}
		
	}
	
}
);
