//    Licensed Materials - Property of IBM
//
//    IBM Cognos Products:  cpscrn

//
//    (C) Copyright IBM Corp. 2005, 2011
//
//    US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
//
//
var _F_pipeline ={
	constants :{
		CSS_BOX : ";padding:3px;",
		CSS_THUMBNAIL	: ";vertical-align:middle; text-align:center; color:white;padding:2px",
		CSS_THUMBNAIL_BOX	: ";border:1px solid black;",
		DOCK_ANIMATION_STEPS : 5	
	},	
	utils : {
		getTime: function(){
			var date = new Date();			
			return ("0" + date.getHours()).substring((""+date.getHours()).length -1) +
					":"+ 
					("0" + date.getMinutes()).substring((""+date.getMinutes()).length -1) +
					":" +
					 ("0" + date.getSeconds()).substring((""+date.getSeconds()).length -1) ;
		},
		loadXml: function(text){
			var doc;
			if (window.ActiveXObject){
				doc=new ActiveXObject("Microsoft.XMLDOM");
				doc.async="false";
				doc.loadXML(text);
			}else{
				var parser=new DOMParser();
				doc=parser.parseFromString(text,"text/xml");
			}
			return doc.documentElement;
		},
		xmlToHtml: function(xml){	
			var root = _F_pipeline.utils.loadXml(xml);
			if (root == null || root.tagName == "parsererror")
				return "<b>"+xml+"</b>";
			
			function startTag(name, padding, id){
				var collpase = id != null ? "<span id=\"toggle_xml_tag_content"+id+"\" style=\"cursor:pointer\" onclick=\"_F_pipeline.utils.xml_node_toggle('xml_tag_content"+id+"')\">-</span>":"";					
				return "<div style=\"padding-left:"+ padding +"px\">"+
					collpase+"<font color=\"blue\">&lt;</font>"+"<font color=\"brown\">"+name+"</font>";
			}	
			function flushStartTag(id){				
				return "<font color=\"blue\">></font>" + (id != null ? "<div id=\"xml_tag_content"+id+"\">" : "");
			}
			function endTag(name, id){
				return (id != null ? "</div>":"")+"<font color=\"blue\">&lt;/</font>"+ 
				"<font color=\"brown\">"+name+"</font>" +
				"<font color=\"blue\">></font></div>";
			}
			function attributeName(name){
				return " <font color=\"red\">"+name+"</font>";
			}
			function attributeValue(value){
				return "<font color=\"blue\">=\"</font>" +		
				"<b>"+value+"</b>" +
				"<font color=\"blue\">\"</font>";
			}
			function textValue(value){
				return "<b>"+_F_Strings.xmlEncode(value)+"</b>";
			}
			function hasElement(node){
				var nodes = node.childNodes;							
				for (var i=0;i<nodes.length;i++){	
					var child = nodes.item(i);
					if (child.nodeType == 1)
						return true;
				}
				return false;
			}
			function deepScanText(node, html, padding,id, id_prefix){
				var collapseId = hasElement(node)? id_prefix + "_"+ id : null;
				html += startTag (node.tagName, padding, collapseId);
				var attrs = node.attributes;
				for (var i=0;i<attrs.length;i++){	
					var attribute = attrs.item(i);
					html += attributeName(attribute.name);
					html += attributeValue(attribute.value);
				}
				html += flushStartTag(collapseId);
				// check if we have children elements
				var n = node.firstChild;
				var counter = 0;
				while (n != null){
					if (n.nodeType == 3)
						html += textValue(n.data);
					else if (n.nodeType == 1)
						html = deepScanText(n, html, padding + 5, id++, id_prefix +"_" + counter);
					n = n.nextSibling;
					counter++;
				}
				html += endTag(node.tagName, collapseId);
				return html;
			}
			
			return deepScanText(root , "", 0, 0, new Date().getTime());	
		},
		xml_node_toggle: function(id){
			var object = $(id);
			if (object != null){
				if (object.style.display=="none"){
					object.style.display="block";
					$("toggle_"+id).innerHTML="-";
				}else {
					object.style.display="none";
					$("toggle_"+id).innerHTML="+";
				}
			}
		}
	},						
	ui : {	
		table: function (border, cellpadding, cellspacing,width, className){
			var table = document.createElement("table");
			
			if (className){
				table.className= className;
			}
			table.border= border;
			table.cellPadding = cellpadding;
			table.cellSpacing = cellspacing;
			if (width) {
				table.width = width;
			}
			var tbody = document.createElement("tbody");
			table.appendChild (tbody);
			return table;
		},
		tr:function(parent, id, className){
			return this.createHtmlObj(parent.firstChild, "tr", id, className);
		},
		td:function(parent, id, className){
			return this.createHtmlObj(parent, "td", id, className);
		},
		div:function(parent, id, className){
			return this.createHtmlObj(parent, "div", id, className);
		},		
		span:function(parent, id, className){
			return this.createHtmlObj(parent, "span", id, className);
		},
		text:function(parent, content){
			var text  = document.createTextNode(content);
			parent.appendChild(text);
			return text;
		},
		img:function(parent, id, image, onclick){
			var img = this.createHtmlObj(parent, "img", id, null);
			this.setImgSrc(img, image);
			if (onclick != null){
				img.style.cursor = "pointer";
				img.onclick = onclick;
			}
			return img;
		},
		setImgSrc:function(img, src){
			img.src=_F_config.webContent + "/fragments/debug/images/" + src;
		},
		textWithOnclick:function(parent, content, onclick){
			var span  = this.span(parent);
			span.innerHTML = "<a href=\"#\" onclick=\"return false;\">"+content+"</a>";
			xAddEventListener(span, "click", onclick);
			span.style.cursor = "pointer";
			return span;
		},			
		createHtmlObj:function(parent, tag, id, className){
			var obj = document.createElement(tag);
			if (id){
				obj.setAttribute("id", id);
			}				
			if (className){
				obj.setAttribute("class", className);
				obj.setAttribute("className", className);
			}		
			if (parent != null){	
				parent.appendChild(obj);
			}
			return obj;
		},	
		htmlStringToObject:function(s){
			var static_object_converter= document.createElement("DIV");
			static_object_converter.innerHTML = s;
			return static_object_converter.firstChild;
		},
		createBox :function(id, text, backgroundColor, height, width, contentStyle, boxStyle){
			var html = "<div id=\""+id+"\" type=\"box\" style=\"height:"+height+";width:"+width+";background-color:"+backgroundColor+";"+ _F_pipeline.constants.CSS_BOX + boxStyle ;	
			html += "\">";
				html += "<div style=\"width:100%;height:"+height+";" + contentStyle + "\" id=\""+id +"_content\">";
				if (text != null){
					html += text;
				}			
				html += "</div></div>";
			return this.htmlStringToObject(html);
		},
		createBoxWithShadow :function(id, text, backgroundColor, height, width, contentStyle, boxStyle){
			var html = "<div id=\""+id+"\" type=\"shadowbox\" style=\"height:"+height+";width:"+width+"; padding:5px; filter:shadow(color:gray, direction=135);\"" ;
			if (id != null)
				html +=" id=\""+id+"\"";
			html += ">";
			html += "<div style=\"height:"+height+"; background-color:"+backgroundColor+";"+ _F_pipeline.constants.CSS_BOX + boxStyle ;				
			html += "\">";
			html += "<div style=\"width:100%;height:"+height+";" + contentStyle + "\" id=\""+id +"_content\">";
			if (text != null){
				html += text;
			}
			html += "</div></div>";
			return this.htmlStringToObject(html);
		},
		changeBoxColor: function (id, newColor){
			var box = $(id);
			if (box != null){
				var type =box.getAttribute("type");
				if ("shadowbox" == type)
					box =  box.firstChild;			
				box.style.backgroundColor= newColor;			
				if ("shadowbox" == type)
				$(id).style.filter = "shadow(color:gray, direction=135)";
			}			
		},
		getBoxCanvas: function(box){
			var type =box.getAttribute("type");
			if ("box" == type)
				return box.firstChild;
			else if ("shadowbox" == type)
				return box.firstChild.firstChild;
			else
				return box;
		},		
		g_dialogs:{},
		createDialog: function(id, dataGetter){
			var dialog = this.g_dialogs[id];
			if (dialog == null){
				dialog = new _F_pipeline.ui.dockableDialog(id, dataGetter);
				this.g_dialogs[id] = dialog;				
			}else {
				dialog.dataGetter = dataGetter;
			}
			return dialog;
		},
		showDialog: function(id){
			var dialog = this.g_dialogs[id];
			if (dialog != null){
				dialog.show();
			}
		},
		hideDialog: function(id){
			var dialog = this.g_dialogs[id];
			if (dialog != null){
				dialog.hide();
			}
		},
		updateDialogs: function(){
			for (var id in this.g_dialogs){
				var dialog = this.g_dialogs[id];
				if (dialog.isShowing())
					dialog.show();
			}		
		}		
	}
}

_F_pipeline.ui.dockingManager = function(){
	this.widthOffest = 0;
	this.heightOffest = 0;	
	this.dockingOrder = [];	
}
_F_pipeline.ui.dockingManager.constants = {LEFT_DOCK_WIDTH:550,RIGHT_DOCK_WIDTH:450, BOTTOM_DOCK_HEIGHT:300};

_F_pipeline.ui.dockingManager.areas = {
	bottom:{x:0,
			y:-1 * _F_pipeline.ui.dockingManager.constants.BOTTOM_DOCK_HEIGHT,
			dx:-1,
			dy:-1},
	left:{	x:0,
			y:0,
			dx:_F_pipeline.ui.dockingManager.constants.LEFT_DOCK_WIDTH,
			dy:-1}, 
	right:{
			x:-1 * _F_pipeline.ui.dockingManager.constants.RIGHT_DOCK_WIDTH,
			y:0,
			dx:-1,
			dy:-1},
	content:{
			x:0,
			y:0,
			dx:-1,
			dy:-1}
			
};

_F_pipeline.ui.dockingManager.prototype = {
	getCoordinates:function(dock){
		var cod= _F_pipeline.ui.dockingManager.areas[dock];
		if (cod != null){
			var calculatedCod = new Object();
			calculatedCod.x = cod.x < 0 ?  xClientWidth() + cod.x: cod.x;
			calculatedCod.y = cod.y < 0 ?  xClientHeight() + cod.y: cod.y;
			calculatedCod.dx = cod.dx < 0 ?  xClientWidth() + cod.dx: cod.dx;
			calculatedCod.dy = cod.dy < 0 ?  xClientHeight() + cod.dy: cod.dy;	
			
			var index = _F_Array.indexOf(this.dockingOrder, dock);
			if (index  == -1 )
				index = this.dockingOrder.length;				
				for (var i = 0 ; i< index; i++){
					var c = this.getCoordinates(this.dockingOrder[i]);
					if ( this.dockingOrder[i] != "bottom"){
						calculatedCod.x =  calculatedCod.x >= c.x && calculatedCod.x <= c.dx ?  c.dx +1 : calculatedCod.x;
						calculatedCod.dx = calculatedCod.dx >= c.x && calculatedCod.dx <= c.dx ?  c.x -1 : calculatedCod.dx;
					}else{
						calculatedCod.y = calculatedCod.y >= c.y && calculatedCod.y <= c.dy ?  c.dy +1 : calculatedCod.y;					
						calculatedCod.dy = calculatedCod.dy >= c.y && calculatedCod.dy <= c.dy ?  c.y -1 : calculatedCod.dy;					
					}
				}			
			return calculatedCod;
		}		
		return null;	
	},	
	dock: function(where, viewId, animation){		
		if (animation == null)
			var animation  = true;
			
		var dialogObject = _F_pipeline.ui.g_dialogs[viewId];
		var previousDock = dialogObject.docked;
		var found = false;			
		for (var id in _F_pipeline.ui.g_dialogs){
			var d = _F_pipeline.ui.g_dialogs[id].dialog;
			if (dialogObject == d)
				continue;
			if (previousDock == d.docked){
				found = true;
				break
			}
		}
		
		if (!found && _F_Array.indexOf(this.dockingOrder, previousDock) != -1){				
			this.dockingOrder.splice(_F_Array.indexOf(this.dockingOrder, previousDock), 1);
		}
		
		if (!this.isDocked(where) && where != "restore")
			this.dockingOrder[this.dockingOrder.length] = where;

		var content = $("dock_view_content");
		if (content == null){
			var node = document.body;
			content = _F_pipeline.ui.div(null, "dock_view_content");
			content.style.overflow="auto";
			content.style.position ="absolute";	
			var nodes = node.childNodes;
			var children=[];
			var count = 0;						
			for (var i=0;i<nodes.length;i++){
				var child = nodes[i];
				if (child.nodeType == 1){
					var id = child.getAttribute("id");
					if (id == null || id.indexOf("dock_") != 0){
						children[count] = child;
						count++;
					}
				}else{
					children[count] = child;
					count++;
				}
				
			}
			for (var i=0;i<children.length;i++) {						
				node.removeChild(children[i]);
				content.appendChild(children[i]);
			}
			node.appendChild(content);
		}
		dialogObject.dock(where, animation ? null: 1);
		
		this.redraw();
		
	},
	redraw: function(){
		for (var id in _F_pipeline.ui.g_dialogs){
			var d = _F_pipeline.ui.g_dialogs[id];
			d.dock(d.docked, 1);
		}
	},
	updateContent: function(){	
		var cod = this.getCoordinates("content");
		var content = $("dock_view_content");
		xMoveTo(content,cod.x, cod.y);
		xResizeTo(content, cod.dx-cod.x, cod.dy - cod.y);		
	},
	isDocked:function(docked){
		for (var i = 0; i < this.dockingOrder.length; i++){
			if (docked == this.dockingOrder[i])
				return true;			
		}
		return false;
	}
}

var DOCKING_MANAGER = new _F_pipeline.ui.dockingManager();
xAddEventListener(window, "resize", function(){DOCKING_MANAGER.redraw()});

_F_pipeline.ui.dockableDialog = function(id, dataGetter){
	this.id = id;
	this.dataGetter= dataGetter;
	
	
	this.docked ="restore";
	this.dockingManager = DOCKING_MANAGER;
	var dlg_id = "dock_"+id;
	
	this.restoreHeight = 400;
	this.restoreWidth = 600;
	this.restoreX = (xClientWidth() - this.restoreWidth ) / 2;
	if (this.restoreX < 0) this.restoreX = 0;
	this.restoreY = (xClientHeight() - this.restoreHeight) / 2;
	if (this.restoreY < 0) this.restoreY = 0;
			
			
	this.dialog = new ui_dialog(dlg_id,"", 
			ui_dialog.style.BTN_NOBUTTONS | ui_dialog.style.RESIZABLE | ui_dialog.style.MODELESS, this.restoreX, this.restoreY,this.restoreWidth,this.restoreHeight);
	this.dialog.show();
	this.dialog.hide();	
	
	var captionRow = $(dlg_id+"caption").firstChild.rows[0];

	var dock;
	var _self = this;

	dock = _F_pipeline.ui.td();
	dock.width="15";
	dock.style.padding="2px";
	dock.onclick=function(){DOCKING_MANAGER.dock('left',_self.id)};
	dock.innerHTML="<table cellspacing='0' cellpadding='0' style ='cursor:pointer;border: 1px solid navy;height:17px;width:15px;padding:0px' ><tr><td style='width:5px;background-color:silver'></td><td style='width:10px'></td></tr></table>";
	captionRow.insertBefore(dock, captionRow.lastChild);

	dock = _F_pipeline.ui.td();
	dock.width="15";
	dock.style.padding="2px";
	dock.onclick=function(){DOCKING_MANAGER.dock('bottom',_self.id)};

	dock.innerHTML="<table cellspacing='0' cellpadding='0' style ='cursor:pointer;border: 1px solid navy;height:15px;width:15px;padding:0px' ><tr style='height:10px'><td></td></tr><tr style='height:5px;background-color:silver'><td></td></tr></table>";
	captionRow.insertBefore(dock, captionRow.lastChild);

	dock = _F_pipeline.ui.td();
	dock.width="15";
	dock.style.padding="2px";
	dock.innerHTML="<table cellspacing='0' cellpadding='0' style ='cursor:pointer;border: 1px solid navy;height:17px;width:15px;padding:0px' ><tr><td style='width:10px'></td><td style='width:5px;background-color:silver'></td></tr></table>";
	dock.onclick=function(){DOCKING_MANAGER.dock('right',_self.id)};
	captionRow.insertBefore(dock, captionRow.lastChild);

	dock = _F_pipeline.ui.td();
	dock.width="15";
	dock.style.padding="2px";
	dock.onclick=function(){DOCKING_MANAGER.dock('restore',_self.id)};
	dock.innerHTML="<table cellspacing='0' cellpadding='0' style ='cursor:pointer;border: 1px solid navy;height:17px;width:15px;padding:0px' ><tr><td></td></tr></table>";
	captionRow.insertBefore(dock, captionRow.lastChild);

	this.dialog.setContent("<div id='"+id+"dock_content'></div>");
	this.dialog.minDialogWidth=100;	
	
	var btn = $(dlg_id + "btn" + ui_dialog.button["CLOSEBOX"]);
	if (btn != null){	
		xAddEventListener(btn, "click", function(){_self.hide()});
	}	
}

_F_pipeline.ui.dockableDialog.prototype={
	hide: function(){this.dialog.hide();this.dockingManager.dock("restore", this.id, false)},
	show: function(){
		var data = null;
		if (this.dataGetter != null){
			try {data = this.dataGetter()} catch(e){};
		}		
		if (data != null)
			data.update(this);		
		this.dialog.show();
	},
	isShowing:function(){
		return this.dialog.dlg.style.display!="none";
	},
	setContent: function(content){
		if (content != null){
			if (typeof content == 'string')
				$(this.id + "dock_content").innerHTML=content;
			else{
				$(this.id + "dock_content").innerHTML="";
				$(this.id + "dock_content").appendChild(content);
			}
		}
	},
	setTitle: function(title){
		if (title != null){			
			this.dialog.setCaption(title +" - " + _F_pipeline.utils.getTime());
		}
	},
	dock: function(where, step){
	
		var dlg_id = "dock_"+this.id;		
		var obj = this.dialog;
				
		if (step == null){
			step = _F_pipeline.constants.DOCK_ANIMATION_STEPS;
		}	
		if (where != "restore" && this.docked=="restore"){		
			this.restoreHeight = xHeight(this.dialog.dlg);
			this.restoreWidth = xWidth(this.dialog.dlg);
			this.restoreX = this.dialog.x;
			this.restoreY = this.dialog.y;
		}				
		var cod = this.dockingManager.getCoordinates(where);		
		var newHeight = cod  != null ? cod.dy - cod.y : this.restoreHeight;
		var newWidth = cod  != null ? cod.dx - cod.x : this.restoreWidth;
		var newTop = cod  != null ? cod.y : this.restoreY;
		var newLeft = cod  != null ? cod.x : this.restoreX;		
		
		
		var ox = obj.x;
		var oy = obj.y;
		var oheight = xHeight(obj.dlg);
		var owidth = xWidth(obj.dlg);

		obj.lastX = ox;
		obj.lastY=oy;
		obj.startX = ox;
		obj.startY=oy;			
		if (step > 1){
			obj.onresize({	xdlg:obj},
					Math.floor((newWidth - owidth )/ step),
					Math.floor((newHeight - oheight )/ step));

			obj.onmove({	xdlg:obj,
					xDPX:ox + Math.floor((newLeft - ox )/ step),
					xDPY:oy + Math.floor((newTop - oy )/ step)
					});
					
			setTimeout("_F_pipeline.ui.g_dialogs['" + this.id+ "'].dock('"+where+"',"+ (step-1) +")",1);

		}else{		
			obj.onresize({	xdlg:obj},
					newWidth - owidth,
					newHeight - oheight);
			obj.onmove({	xdlg:obj,
					xDPX:newLeft,
					xDPY:newTop
					});
			this.docked = where;
			this.dockingManager.updateContent();
			
			if ("restore" == where)		
				xEnableDrag($(dlg_id+"caption"),obj.onstartmove, obj.onmove, null);
			else
				xDisableDrag($(dlg_id+"caption"));
		
		}				
	}
}

_F_pipeline.execution = function(obj){				
	this.id = obj.id;
	this.name = obj.name;
	this.outputs = [];
	this.params = [];
	this.paramsBefore = [];
	this.processes = [];
}

_F_pipeline.execution.prototype = {				
	getId: function(){
		return this.id; 
	},	
	getName: function(){
		return this.name;
	},				
	getOutputs: function(){
		return this.outputs;
	},
	getOutput: function(label){
		var length = this.outputs.length;
		for (var i = 0; i< length; i++){
			var output = this.outputs[i];
			if (label == output.getLabel()){
				return output;
			}
		}
		return null;
	},
	getParams: function(){
		return this.params;
	},
	getParamInitialValues: function(){
		return this.paramsBefore;
	},
	getParam: function(name){			
		var length = this.params.length;
		for (var i = 0; i< length; i++){
			var param = this.params[i];
			if (name == param.getName()){
				return param;
			}
		}
		return null;
	},
	getParamInitialValue: function(name){			
		var length = this.paramsBefore.length;
		for (var i = 0; i< length; i++){
			var param = this.paramsBefore[i];
			if (name == param.getName()){
				return param;
			}
		}
		return null;
	},
	getProcess: function(name){			
		var length = this.processes.length;
		for (var i = 0; i< length; i++){
			var process = this.processes[i];
			if (name == process.getName()){
				return process;
			}
		}
		return null;
	},
	getProcesses: function(){
		return this.processes;
	},
	addParam: function(obj){
		obj.process = this;
		this.params.push(obj);
	},
	addParamInitialValue: function(obj){
		obj.process = this;
		this.paramsBefore.push(obj);
	},
	addProcess: function(obj){
		obj.execution = this;
		this.processes.push(obj);
	},
	addOutput: function(obj){
		this.outputs.push(obj);
	},
	getDisplayName:function(){
		return this.getName();
	},
	getResolver: function(){		
		var id = this.id;
		return function(){
			return _F_pipeline.getExecution(id);				
		}		
	}
}

_F_pipeline.process = function(obj){
	this.execution = obj.execution;					
	this.name = obj.name;
	this.className = obj.className;
	this.params = [];
	this.paramsBefore = []
	this.outputs= [];
	this.inputs=[];
	this.traces=[];
}

_F_pipeline.process.prototype = {				
	getId: function(){
		return this.execution.getId() +"_process_"+ this.name; 
	},
	getName: function(){
		return this.name;
	},
	getExecution: function(){
		return this.execution;
	},
	getParams: function(){
		return this.params;
	},
	getParamInitialValues: function(){
		return this.paramsBefore;
	},
	getOutputs: function(){
		return this.outputs;
	},
	getInputs: function(){
		return this.inputs;
	},
	getTraces: function(){
		return this.traces;
	},
	addParam: function(param){
		param.process = this;
		this.params.push(param);
	},
	addOutput: function(output){
		output.process = this;
		this.execution.addOutput(output);
		this.outputs.push(output);
	},
	addTrace: function(trace){
		trace.process = this;
		trace.name = trace.name + " (trace"+(this.traces.length+1)+")";		
		this.traces.push(trace);
	},
	addInput: function(input){		
		input.process = this;
		var output = input.getOutput();
		if (output != null)
			output.addConsumer(this);
		this.inputs.push(input);
	},
	getOutput: function(label){
		var length = this.outputs.length;
		for (var i = 0; i< length; i++){
			var output = this.outputs[i];
			if (label == output.getLabel()){
				return output;
			}
		}
		return null;
	},
	getParam: function(name){			
		var length = this.params.length;
		for (var i = 0; i< length; i++){
			var param = this.params[i];
			if (name == param.getName()){
				return param;
			}
		}
		return null;
	},
	getTrace: function(name){			
		var length = this.traces.length;
		for (var i = 0; i< length; i++){
			var trace = this.traces[i];
			if (name == trace.getName()){
				return trace;
			}
		}
		return null;
	},
	getParamInitialValue: function(name){			
		var length = this.paramsBefore.length;
		for (var i = 0; i< length; i++){
			var param = this.paramsBefore[i];
			if (name == param.getName()){
				return param;
			}
		}
		return null;
	},	
	addParamInitialValue: function(obj){
		obj.process = this;
		this.paramsBefore.push(obj);
	},
	getInput: function(label){			
		var length = this.inputs.length;
		for (var i = 0; i< length; i++){
			var input = this.inputs[i];
			if (label == input.getLabel()){
				return input;
			}
		}
		return null;
	},
	getDisplayName:function(){
		return this.getName();
	},
	getResolver: function(){		
		var parentResolver = this.execution.getResolver();
		var name = this.name;
		return function(){
			return parentResolver().getProcess(name);
		}		
	}
}

_F_pipeline.param = function(obj)
{
	this.process = obj.process;
	this.name = obj.name;
	this.content = obj.content;
	this.initialValue = obj.initialValue;
}
_F_pipeline.param.prototype = {
	getId: function(){
		return this.process.getId() +"_param_"+ this.name + (this.initialValue ? "_before" : "_after"); 
		
	},
	getName:function(){
		return this.name;
	},
	getContent:function(){
		return this.content;
	},
	getProcess: function(){
		return this.process;
	}, 
	update: function(dialog){
		dialog.setContent(_F_pipeline.utils.xmlToHtml(this.getContent()));
		dialog.setTitle(this.process.getDisplayName() + " - "  + this.getDisplayName() +" parameter "+ (this.initialValue ? "(before execution)" : "(after execution)"));
	},
	getDisplayName:function(){
		return this.getName();
	},
	getResolver: function(){		
		var parentResolver = this.process.getResolver();
		var name = this.name;
		var initialValue = this.initialValue;			
		return function(){
			if (initialValue)
				return parentResolver().getParamInitialValue(name);
			else
				return parentResolver().getParam(name);
		}
	}
}

_F_pipeline.trace = function(obj)
{
	this.process = obj.process;
	this.name = obj.name;
	this.content = obj.content;	
}
_F_pipeline.trace.prototype = {
	getId: function(){
		return this.process.getId() +"_trace_"+ this.name; 
	},
	getName:function(){
		return this.name;
	},
	getContent:function(){
		return this.content;
	},
	getProcess: function(){
		return this.process;
	}, 
	update: function(dialog){
		dialog.setContent(_F_pipeline.utils.xmlToHtml(this.getContent()));
		dialog.setTitle(this.process.getDisplayName() + " - "  + this.getDisplayName());
	},
	getDisplayName:function(){
		return this.getName().replace("_"," ").replace("_"," ") ;
	},
	getResolver: function(){		
		var parentResolver = this.process.getResolver();
		var name = this.name;
		return function(){
			return parentResolver().getTrace(name);
		}		
	}
}

_F_pipeline.output = function(obj){
	this.label = obj.label;
	this.name = obj.name;
	this.process = obj.process;
	this.content = obj.content;
	this.consumers=[];
}

_F_pipeline.output.prototype = {
	getId: function(){
		return this.process.getId() + "_param_"+ this.getLabel(); 
	},
	getLabel: function(){
		return this.label;
	},
	getName: function(){
		return this.name;
	},
	getContent: function(){
		return this.content;
	},
	getProcess: function(){
		return this.process;
	}, 
	addConsumer: function(obj){
		this.consumers.push(obj);
	},
	getConsumers:function(){
		return this.consumers; 
	},
	update: function(dialog){		
		dialog.setContent(_F_pipeline.utils.xmlToHtml(this.getContent()));
		dialog.setTitle(this.process.getDisplayName() + " - " + this.getDisplayName() +" Output");
	},
	getDisplayName:function(){		
		return this.getName() + (this.getContent() == "NULL" ? " (NULL)" : "");
	},
	getResolver: function(){		
		var parentResolver = this.process.getResolver();
		var label = this.getLabel();
		return function(){
			return parentResolver().getOutput(label);
		}		
	}
}

_F_pipeline.input = function(obj){
	this.name = obj.name;
	this.label = obj.label;
	this.process = obj.process;
	this.content = obj.content;
}

_F_pipeline.input.prototype = {
	getId: function(){
		return this.process.getId()+ "_input_" + this.getLabel(); 
	},
	getContent: function(){
		if (this.label != null && this.label != ""){
			return this.process.getExecution().getOutput(this.label).getContent();
		}
		return this.content;
	},
	getProcess: function(){
		return this.process;
	}, 
	getName: function(){
		return this.name;
	},
	getLabel: function(){
		return (this.label != null && this.label != "") ? this.label : this.getName();
	},
	getOutput: function(){
		if (this.label != null && this.label != ""){
			return this.process.execution.getOutput(this.label);
		}
		return null;
	},
	getProducer: function(){
		var output = this.getOutput();
		return output != null ? output.getProcess(): null;
	}
	,
	update: function(dialog){		
		dialog.setContent(_F_pipeline.utils.xmlToHtml(this.getContent()));
		dialog.setTitle(this.process.getDisplayName() + " - " +this.getName()  +" Input");
	},
	getDisplayName:function(){
		return this.getName() + (this.getContent() == "NULL" ? "( NULL)" : "");;
	},
	getResolver: function(){
		var parentResolver = this.process.getResolver();
		var label = this.getLabel();
		return function(){
			return parentResolver().getInput(label);
		}
	}
}


_F_pipeline.view = {
	constants :{
		UI_PARAM_INPUT_COLOR : "#666699",
		UI_PARAM_OUTPUT_COLOR : "#666699",
		UI_OUTPUT_COLOR : "#778899",
		UI_TRACE_COLOR : "gray",
		UI_INPUT_COLOR : "#99aacc",
		UI_PROCESS_COLOR : "#336699",
		UI_PIPELINE_COLOR : "silver",
		UI_SELECTED_COLOR : "336600",
		UI_RELATED_COLOR : "660033",
		UI_RELATED_EQUAL_COLOR : "669900"	
	}

};


_F_pipeline.view.pipelineView = function(executionId){
	this.executionId = executionId;	
}

_F_pipeline.view.pipelineView.prototype = {
	getId: function(){
		return this.executionId +"_view";
	},
	getUI:function(){	
		return this.getPipelineUI();
	},
	getPipelineUI:function(){
		var UI_HEIGHT = "";
		var UI_WIDTH =  "";					
		var execution = _F_pipeline.getExecution(this.executionId);
		var UI_ID = execution.getId() +"pipeline_box";		
		var box = _F_pipeline.ui.createBox(UI_ID, execution.getDisplayName(),_F_pipeline.view.constants.UI_PIPELINE_COLOR,UI_HEIGHT, UI_WIDTH, _F_pipeline.constants.CSS_THUMBNAIL, _F_pipeline.constants.CSS_THUMBNAIL_BOX);
		var canvas = _F_pipeline.ui.getBoxCanvas(box);	
		var table = _F_pipeline.ui.table(0,5,0,"");
		canvas.appendChild(table);		
		table.id=UI_ID +"processtable";
		table.align="center";
		var processes = execution.getProcesses();
		var length = processes.length;
		for (var i = 0 ; i < length; i++){			
			this.getProcessUI(processes[i], table);
			if (i < length - 1){
				var tr = _F_pipeline.ui.tr(table)			
				var td = _F_pipeline.ui.td(tr)
				td.colSpan="10";
				td.align = "center";
				td.style.padding="30px";				
				_F_pipeline.ui.img(td,null, "move_down.gif");
			}
		}
		return box;	
	},
	getProcessUI: function(process, table){				
		var params = process.getParams();
		var paramInitialValue = process.getParamInitialValues();
		var outputs = process.getOutputs();
		var inputs = process.getInputs();
		var paramsSize = params.length;
		var outputSize = outputs.length;
		var inputSize = inputs.length;
		
		var isPipelineRendered = false;
		for (var i = 0 ; i < paramsSize; i++){			
			var tr = _F_pipeline.ui.tr(table)			
			var td = _F_pipeline.ui.td(tr)
			td.appendChild(this.getParamInputUI(paramInitialValue[i], process));			
			if (!isPipelineRendered){			
				isPipelineRendered = true;
				td = _F_pipeline.ui.td(tr);
				td.rowSpan = paramsSize + outputSize;
				td.valign="middle";
				_F_pipeline.ui.img(td,null, "move_right.gif");
				
				td = _F_pipeline.ui.td(tr);
				td.rowSpan = paramsSize + outputSize;
				td.width="50";
				td.height="100%";
				
				
				td.appendChild(this.getProcessBoxUI(process));
				
				td = _F_pipeline.ui.td(tr);
				td.rowSpan = paramsSize + outputSize;
				td.valign="middle";
				_F_pipeline.ui.img(td,null, "move_right.gif");
			}			
			td = _F_pipeline.ui.td(tr);
			td.appendChild(this.getParamOutputUI(params[i], process));			
		}
		
		
		var size = inputSize > outputSize ? inputSize : outputSize;
		
		for (var i = 0 ; i < size; i++){
			var tr = _F_pipeline.ui.tr(table)
			
			// before
			var td = _F_pipeline.ui.td(tr)
			if (i < inputSize){
				td.appendChild(this.getInputUI(inputs[i], process));
			}
			
			if (!isPipelineRendered){
				isPipelineRendered = true;
				
				td = _F_pipeline.ui.td(tr);
				td.rowSpan = paramsSize + outputSize;
				td.valign="middle";
				_F_pipeline.ui.img(td,null, "move_right.gif");
				
				td = _F_pipeline.ui.td(tr);
				td.rowSpan = paramsSize + outputSize;
				td.width="50";
				td.height="100%";
				td.appendChild(this.getProcessBoxUI(process));
				
				td = _F_pipeline.ui.td(tr);
				td.rowSpan = paramsSize + outputSize;
				td.valign="middle";
				_F_pipeline.ui.img(td,null, "move_right.gif");
			}
			td = _F_pipeline.ui.td(tr);						
			if (i < outputSize){
				td.appendChild(this.getOutputUI(outputs[i],process));
			}
		}				
	},
	getProcessBoxUI: function(process){
		var UI_ID = process.getId();
		var UI_HEIGHT = "";
		var UI_WIDTH = "";		
		
		var processBox = _F_pipeline.ui.createBoxWithShadow(UI_ID,process.getDisplayName(), _F_pipeline.view.constants.UI_PROCESS_COLOR, UI_HEIGHT, UI_WIDTH, _F_pipeline.constants.CSS_THUMBNAIL,  _F_pipeline.constants.CSS_THUMBNAIL_BOX );
		var traces = process.getTraces();
		var canvas = _F_pipeline.ui.getBoxCanvas(processBox);	
		for (var j = 0 ; j < traces.length; j++){	
			var trace = traces[j];				
			canvas.appendChild(this.getTraceUI(traces[j], process));
			if (j < traces.length -1)	
				_F_pipeline.ui.div(canvas).style.height="5px";
		}
		return processBox;
	},
	getTraceUI:function(trace, process){
		var traceBox = _F_pipeline.ui.createBox(trace.getId(),trace.getDisplayName(), _F_pipeline.view.constants.UI_TRACE_COLOR, "", "", _F_pipeline.constants.CSS_THUMBNAIL, _F_pipeline.constants.CSS_THUMBNAIL_BOX );
		traceBox.style.cursor = "pointer";	
				
		var _self = this;
		var DLG_ID =this.getId()+ "_dlg";		

		xAddEventListener(traceBox, "mouseOver", function(){_self.traceClick(trace)});
		xAddEventListener(traceBox, "mouseOut", function(){_self.resetHighlight(); _self.updateHighlight()});
		xAddEventListener(traceBox, "click", function(){			
			_self.traceClick(trace);
			var resolver = trace.getResolver();
			_self.restoreHighlight = function(){_self.traceClick(resolver());};						
			_F_pipeline.ui.createDialog(DLG_ID,resolver);
			_F_pipeline.ui.showDialog(DLG_ID);			
		});
		return traceBox;
	},
	getParamInputUI:function(param, process){
		var UI_HEIGHT = 20;	
		var UI_WIDTH =  "";
		var UI_ID = param.getId();
		var DLG_ID =this.getId()+ "_dlg";
		var obj = _F_pipeline.ui.createBoxWithShadow(UI_ID, param.getDisplayName(), _F_pipeline.view.constants.UI_PARAM_INPUT_COLOR, UI_HEIGHT, UI_WIDTH, _F_pipeline.constants.CSS_THUMBNAIL, _F_pipeline.constants.CSS_THUMBNAIL_BOX);
		obj.style.cursor = "pointer";		
		
		var _self = this;
		
		xAddEventListener(obj, "mouseOver", function(){_self.paramClick(param)});
		xAddEventListener(obj, "mouseOut", function(){_self.resetHighlight(); _self.updateHighlight()});			
		xAddEventListener(obj, "click", function(){
			var resolver = param.getResolver();			
			_self.paramClick(param);
			_self.restoreHighlight = function(){_self.paramClick(resolver());};			
			_F_pipeline.ui.createDialog(DLG_ID,resolver);
			_F_pipeline.ui.showDialog(DLG_ID);			
		});	
		
		return obj;
	},
	getParamOutputUI:function(param, process){
		var UI_HEIGHT = 20;	
		var UI_WIDTH =  "";
		var  UI_ID = param.getId();	
		var DLG_ID =this.getId()+ "_dlg";
		var obj = _F_pipeline.ui.createBoxWithShadow(UI_ID, param.getDisplayName(),_F_pipeline.view.constants.UI_PARAM_OUTPUT_COLOR, UI_HEIGHT, UI_WIDTH, _F_pipeline.constants.CSS_THUMBNAIL, _F_pipeline.constants.CSS_THUMBNAIL_BOX);
		obj.style.cursor = "pointer";
		var _self = this;	
		
		xAddEventListener(obj, "mouseOver", function(){_self.paramClick(param)});
		xAddEventListener(obj, "mouseOut", function(){_self.resetHighlight(); _self.updateHighlight()});		
		xAddEventListener(obj, "click", function(){
			var resolver = param.getResolver();				
			_self.paramClick(param);
			_self.restoreHighlight = function(){_self.paramClick(resolver());};		
			_F_pipeline.ui.createDialog(DLG_ID,resolver);
			_F_pipeline.ui.showDialog(DLG_ID);			
		
		});		
		return obj;
	},
	getOutputUI:function(output, process){
		var UI_HEIGHT = 30;
		var UI_WIDTH =  "";
		
		var UI_ID = output.getId();
		var DLG_ID =this.getId()+ "_dlg";
		var box = _F_pipeline.ui.createBoxWithShadow(UI_ID, output.getDisplayName(), _F_pipeline.view.constants.UI_OUTPUT_COLOR, UI_HEIGHT,UI_WIDTH, _F_pipeline.constants.CSS_THUMBNAIL, _F_pipeline.constants.CSS_THUMBNAIL_BOX);
		box.style.cursor = "pointer";
		var _self = this;
		
		xAddEventListener(box, "mouseOver", function(){_self.outputClick(output)});
		xAddEventListener(box, "mouseOut", function(){_self.resetHighlight(); _self.updateHighlight()});
		xAddEventListener(box, "click", function(){
			var resolver = output.getResolver();				
			_self.outputClick(output);
			_self.restoreHighlight = function(){_self.outputClick(resolver());}	
			_F_pipeline.ui.createDialog(DLG_ID,resolver);
			_F_pipeline.ui.showDialog(DLG_ID);			
		
		});
				
		return box;
	},	
	getInputUI:function(input, process){
		var UI_HEIGHT = 30;
		var UI_WIDTH =  "";		
		var UI_ID = input.getId();
		var DLG_ID =this.getId()+ "_dlg";
		var box = _F_pipeline.ui.createBoxWithShadow(UI_ID, input.getDisplayName(), _F_pipeline.view.constants.UI_INPUT_COLOR, UI_HEIGHT,UI_WIDTH, _F_pipeline.constants.CSS_THUMBNAIL, _F_pipeline.constants.CSS_THUMBNAIL_BOX);
		box.style.cursor = "pointer";
		var _self = this;
		xAddEventListener(box, "mouseOver", function(){_self.inputClick(input)});
		xAddEventListener(box, "mouseOut", function(){_self.resetHighlight(); _self.updateHighlight()});

		xAddEventListener(box, "click", function(){
			var resolver = input.getResolver();		
			_self.inputClick(input);
			_self.restoreHighlight = function(){_self.inputClick(resolver());}	
			_F_pipeline.ui.createDialog(DLG_ID,resolver);
			_F_pipeline.ui.showDialog(DLG_ID);			
		
		});		
		return box;
	},
	resetHighlight:function(){
		var execution = _F_pipeline.getExecution(this.executionId);
		var plength = execution.processes.length;
		
		for (var h = 0 ; h < plength; h++){
			var length = execution.processes[h].outputs.length;
			for (var i = 0; i< length; i++){
				var output = execution.processes[h].outputs[i];
				_F_pipeline.ui.changeBoxColor(output.getId(), _F_pipeline.view.constants.UI_OUTPUT_COLOR);		
			}
			
			length = execution.processes[h].inputs.length;
			for (var i = 0; i< length; i++){
				var input = execution.processes[h].inputs[i];
				_F_pipeline.ui.changeBoxColor(input.getId(), _F_pipeline.view.constants.UI_INPUT_COLOR);		
			}
			length = execution.processes[h].params.length;
			for (var i = 0; i< length; i++){
				var param = execution.processes[h].params[i];
				_F_pipeline.ui.changeBoxColor(param.getId(), (param.initialValue ? _F_pipeline.view.constants.UI_PARAM_INPUT_COLOR : _F_pipeline.view.constants.UI_PARAM_OUTPUT_COLOR));					
			}
			length = execution.processes[h].paramsBefore.length;
			for (var i = 0; i< length; i++){
				var param = execution.processes[h].paramsBefore[i];
				_F_pipeline.ui.changeBoxColor(param.getId(), (param.initialValue ? _F_pipeline.view.constants.UI_PARAM_INPUT_COLOR : _F_pipeline.view.constants.UI_PARAM_OUTPUT_COLOR));					
			}
			length = execution.processes[h].traces.length;
			for (var i = 0; i< length; i++){
				var trace = execution.processes[h].traces[i];
				_F_pipeline.ui.changeBoxColor(trace.getId(), _F_pipeline.view.constants.UI_TRACE_COLOR);					
			}
		}
	},
	paramClick:function(param){
		this.resetHighlight();
		_F_pipeline.ui.changeBoxColor(param.getId(), _F_pipeline.view.constants.UI_SELECTED_COLOR);
		if (param.getProcess().getExecution){
			var execution = param.getProcess().getExecution();
			var processes= execution.getProcesses();
			var length = processes.length;
			for (var i = 0; i< length; i++){
				var process = processes[i];
				var paramsIn = process.getParamInitialValues();
				var plength = paramsIn.length;
				for (var j = 0; j< plength; j++){
					if (paramsIn[j] == param)
						continue;
					if (paramsIn[j].getName() == param.getName())
						_F_pipeline.ui.changeBoxColor(paramsIn[j].getId(),paramsIn[j].getContent() == param.getContent()?  _F_pipeline.view.constants.UI_RELATED_EQUAL_COLOR : _F_pipeline.view.constants.UI_RELATED_COLOR);	
				}				
				var paramsOut = process.getParams();
				plength = paramsOut.length;
				for (var j = 0; j< plength; j++){
					if (paramsOut[j] == param)
						continue;
					if (paramsOut[j].getName() == param.getName())
						_F_pipeline.ui.changeBoxColor(paramsOut[j].getId(), paramsOut[j].getContent() == param.getContent()?  _F_pipeline.view.constants.UI_RELATED_EQUAL_COLOR : _F_pipeline.view.constants.UI_RELATED_COLOR);	
				}										
			}
		}		
		
	},
	outputClick:function(output){
		this.resetHighlight();		
		_F_pipeline.ui.changeBoxColor(output.getId(), _F_pipeline.view.constants.UI_SELECTED_COLOR);
		if (output.getProcess().getExecution){
			var execution = output.getProcess().getExecution();
			var processes= execution.getProcesses();
			var length = processes.length;
			for (var i = 0; i< length; i++){
				var process = processes[i];
				
				var inputs = process.getInputs();
				var plength = inputs.length;
				for (var j = 0; j< plength; j++){
					if (inputs[j].getLabel() == output.getLabel())
						_F_pipeline.ui.changeBoxColor(inputs[j].getId(), _F_pipeline.view.constants.UI_RELATED_EQUAL_COLOR);	
				}
			}
		}		
	},
	traceClick:function(trace){
		this.resetHighlight();
		_F_pipeline.ui.changeBoxColor(trace.getId(), _F_pipeline.view.constants.UI_SELECTED_COLOR);		
	},
	inputClick:function(input){
		this.resetHighlight();		
		_F_pipeline.ui.changeBoxColor(input.getId(), _F_pipeline.view.constants.UI_SELECTED_COLOR);		
		if (input.getProcess().getExecution){
			var execution = input.getProcess().getExecution();
			var processes= execution.getProcesses();
			var length = processes.length;
			for (var i = 0; i< length; i++){
				var process = processes[i];				
				var outputs = process.getOutputs();
				var plength = outputs.length;
				for (var j = 0; j< plength; j++){					
					if (outputs[j].getLabel() == input.getLabel())
						_F_pipeline.ui.changeBoxColor(outputs[j].getId(), _F_pipeline.view.constants.UI_RELATED_EQUAL_COLOR);	
				}				
				var inputs = process.getInputs();
				plength = inputs.length;
				for (var j = 0; j< plength; j++){
					if (inputs[j] == input)
						continue;
					if (inputs[j].getLabel() == input.getLabel())
						_F_pipeline.ui.changeBoxColor(inputs[j].getId(), _F_pipeline.view.constants.UI_RELATED_EQUAL_COLOR);	
				}										
			}
		}		
	},
	update: function(dialog){		
		dialog.setContent(this.getUI());				
		dialog.setTitle(_F_pipeline.getExecution(this.executionId).getName());
		this.updateHighlight();
	},
	updateHighlight: function(dialog){				
		if (this.restoreHighlight)
			this.restoreHighlight();		
	}
}

_F_pipeline.view.toolbar = function(executionId, name, loader){	
	this.executionId = executionId;
	this.name = name;
	this.loader = loader;
	this.loaded = false;
	if  (_F_pipeline.getExecution(executionId) != null)
		this.load();
}
_F_pipeline.view.toolbar.prototype = {
	getUI: function(){			
		var viewId = this.getId();
		var div = _F_pipeline.ui.div(null, this.getId());
		_F_pipeline.ui.text(div, "DEBUG MODE (" + this.name+"): ");
		var _self = this;
		_F_pipeline.ui.textWithOnclick(div, "Pipeline View", function(){
			if (!_self.loaded){
				_self.load();								
			}				
			DOCKING_MANAGER.dock('left',viewId);		
			_F_pipeline.ui.showDialog(viewId);			
		});
		return div ;
	},
	getId: function(){
		return this.executionId;
	}, 
		
	load: function(){
		if (!this.loaded){
			if (this.loader != null)
				this.loader();
				
			var viewId = this.getId();
			var pipelineView = _F_pipeline.view.views[viewId];
			if (pipelineView == null){
				pipelineView = new _F_pipeline.view.pipelineView(this.executionId);
				_F_pipeline.view.views[viewId] = pipelineView;
			}		
			_F_pipeline.ui.createDialog(viewId, function(){ return pipelineView;});		
			
			this.loaded = true;
		}	
	}	
}

_F_pipeline.executions = {};
_F_pipeline.view.views = {};

_F_pipeline.getExecution = function(id){
	return _F_pipeline.executions[id];
}

_F_pipeline.attach = function(fragment, executionId, loader){	
	var toolbar = new _F_pipeline.view.toolbar(executionId, fragment.title, loader);	
	fragment.addEventListener("fragment.load", function(){	
		$(fragment.id + "debugViewContainer").innerHTML="";
		$(fragment.id +"debugViewContainer").appendChild(toolbar.getUI());
		_F_pipeline.ui.updateDialogs();
	});
}

fragment.prototype.oldRenderURI= fragment.prototype.renderURI;
fragment.prototype.renderURI = function(params){
	var p = this.oldRenderURI(params);
	if (p.indexOf("?") != -1)
		p = p + "&";
	else 
		p = p + "?";
		
	p = p + "frag-debug=fragment";
	
	return p;

}