/*******************************************************************************
 * Copyright (c) 2008 IBM Corporation
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
dojo.provide("org.eclipse.cosmos.provisional.dr.ps.components.widget.GraphResponseTreeViewer");

dojo.require("org.eclipse.cosmos.provisional.dr.ps.components.utility.common");
dojo.require("dijit.form.ComboBox");
dojo.require("dijit.layout.LayoutContainer");
dojo.require("dijit.layout.SplitContainer");
dojo.require("dijit.layout.ContentPane");


dojo.declare(
	
	////////////////////////////////////////////////////////////////////////////////////
	// Summary: The graph response tree viewer is an alternative view for displaying
	// a CMDBf graph response.  The view is divided into two sections: a graphical 
	// section displays a visual overview of the response and a tree structure displays
	// a logical structure.
	//
	// Author: Ali Mehregani 
	////////////////////////////////////////////////////////////////////////////////////
	"org.eclipse.cosmos.provisional.dr.ps.components.widget.GraphResponseTreeViewer",
	
	// superclass 	
	[dijit._Widget, dijit._Templated, dijit._Container, dijit.form], 
	

	// member variables/functions
	{
		widgetId: "",
		_message: dojo.i18n.getLocalization("nls.org.eclipse.cosmos.provisional.dr.ps.components", "widget"),
		titleGL: " ",
		titleLL: " ",
		titleDetailsViewer: " ",	
        detailsViewer:null,
        widgetsInTemplate: true,		// The html layout of the page is in GraphResponseView.html
		globalParams: "",				// so that all classes can get to the initQueryHandler
		splitContainerHeight: "",		// The height of the split container
		utility: new org.eclipse.cosmos.provisional.dr.ps.components.utility.BasicUtility(),

		// set member variable templatePath to where the template html is		
		templatePath:dojo.moduleUrl("org.eclipse.cosmos.provisional.dr.ps.components.widget", "html/GraphResponseTreeViewer.html"),
	
		
		///////////////////
		// METHOD create 
		///////////////////	
		create: function(params, srcNodeRef) 
		{		
			globalParams = params;						
			
		    // Destroy any widgets left from previous creations
			this.destroy();
			this.inherited("create", arguments);
		},  // end create

		
		////////////////////////////////
		// METHOD postMixInProperties //
		////////////////////////////////		
		postMixInProperties: function()
		{			
			this.inherited("postMixInProperties", arguments);
		}, //end postMixInProperties
				
		
		///////////////////////
		// METHOD postCreate //
		///////////////////////						
		postCreate: function()
		{
			this.inherited("postCreate", arguments);						
		},  // end create METHOD
		
		
		
		///////////////////////
		// METHOD destroy	 //
		///////////////////////								
		destroy:function()
		{			
			this.utility.destroyWidgets(
				[this.widgetId + "logicalLayout"]);
				 
			this.inherited("destroy", arguments);
		} // end Destroy		
	}
);


dojo.declare
(
	////////////////////////////////////////////////////////////
	// Super class shared by the graphical and logical layout //
	////////////////////////////////////////////////////////////
	"org.eclipse.cosmos.provisional.dr.ps.components.widget.LogicalLayout",
	
	
	////////////////
	// superclass //
	////////////////	
	[dijit._Widget], 
	
	
	////////////////////////////////
	// member variables/functions //
	////////////////////////////////	
	{		
		utility: new org.eclipse.cosmos.provisional.dr.ps.components.utility.BasicUtility(),
		ownerObject: null,
		topic: "org.eclipse.cosmos.provisional.dr.ps.components.widget.RecordSelection",
		
		/////////////////////////
		// METHOD processInput //
		/////////////////////////	
		processInput: function(postData, handlerMethod)
		{			
			var _self = this;
			dojo.rawXhrPost
			(
				{
			    	url: globalParams.initQueryHandler,
			    	handleAs: "json-comment-optional",
			    	postData: postData,
			    	handle: function(response, ioArgs)
			    	{
						handlerMethod(_self.ownerObject, response, ioArgs);
			    	}
				}
			);
		}, // end of processInput
	
	
		////////////////////////
		// METHOD sendRequest //
		////////////////////////		
		sendRequest: function(owner, handlerMethod) 
		{				
			this.ownerObject = owner;
			var postData = null;
			
			if (globalParams.contextMap)
			{

				if (globalParams.contextMap.queryResponse)
				{
					postData = 	globalParams.initQueryHandler + 
								"&queryResponse=" + escape(globalParams.contextMap.queryResponse);
				}
				
				// Check if this is a response saved in the history
				else if ((globalParams.contextMap.historyId) && (globalParams.contextMap.uuid))
				{
					postData = 	globalParams.initQueryHandler +
								"&uuid=" + globalParams.contextMap.uuid[0] + 
								"&historyId=" + globalParams.contextMap.historyId;
				}
				
				this.processInput(postData, handlerMethod);
			}
			
			// Used for testing purposes
			else if (typeof(globalParams.queryResponse) != 'undefined')
			{						
				if (globalParams.queryResponse.length <= 0)
				{					
					postData = "";
					this.processInput(postData, handlerMethod);
				}	
						
				var _self = this;
		        dojo.xhrGet({
		            url: globalParams.queryResponse,
		            load: function (data,ioArgs)
		            {		        				        	
		        		postData = globalParams.initQueryHandler + 
						"&queryResponse=" + escape(data);
		        		
		        		_self.processInput(postData, handlerMethod);
		            },
		            error: function (data,ioArgs)
		            {
		        		console.debug("Error :");
		        		console.debug(data);
		            }            
		         });				
			}
		
		}, // end of sendRequest
		
		
		removeElement: function(id)
		{
			var element = dojo.byId(id);
			if (element)
			{
				element.parentNode.removeChild(element);
			}
		},
		
		
		showProgress: function(parentId, idSuffix, progressMessage)
		{
			var divElement = dojo.byId(parentId);
			
			// Create the image
			var imgElement = document.createElement("img");			
			imgElement.setAttribute("id", "progressImage" + idSuffix);
			imgElement.setAttribute("src", dojo.moduleUrl("dojox","off/resources/roller.gif").uri);											
			divElement.appendChild(imgElement);
			
			// Create the text beside the image
			var fontElement = document.createElement("font");			
			fontElement.setAttribute("id", "progressLabel" + idSuffix);
			fontElement.setAttribute("style", "font-weight: bold");
			fontElement.textContent = " " + progressMessage;			
			divElement.appendChild(fontElement);				
		},
		showMessage: function(parentId, idSuffix, progressMessage)
		{
			var divElement = dojo.byId(parentId);
					
			// Create the text beside the image
			var fontElement = document.createElement("font");			
			fontElement.setAttribute("id", "progressLabel" + idSuffix);
			fontElement.setAttribute("style", "font-weight: bold");
			fontElement.textContent = " " + progressMessage;			
			divElement.appendChild(fontElement);				
		},
		
		destroyProgress: function(idSuffix)
		{
			this.removeElement("progressImage" + idSuffix);
			this.removeElement("progressLabel" + idSuffix);
		}
	}
);


dojo.declare
(
	///////////
	// class //
	///////////	
	"org.eclipse.cosmos.provisional.dr.ps.components.widget.QueryLogicalLayout",
	
	
	////////////////
	// superclass //
	////////////////	
	[dijit._Widget, org.eclipse.cosmos.provisional.dr.ps.components.widget.LogicalLayout], 
	
	
	////////////////////////////////
	// member variables/functions //
	////////////////////////////////	
	{
		propertyAttachPoint: "",
		myParams : "",
		_message: dojo.i18n.getLocalization("nls.org.eclipse.cosmos.provisional.dr.ps.components", "widget"),
				
		
		///////////////////
		// METHOD create //
		///////////////////		
		create: function(params, srcNodeRef) 
		{		
			this.destroy();		
			this.inherited("create", arguments);
			this.showProgress("logicalTree", "02", this._message.GRAPH_RESPONSE_GENERATING_TREE);
			
			var handlerMethod = this.processRequest;
			this.sendRequest(this, handlerMethod);			
			dojo.publish("org.eclipse.cosmos.provisional.dr.ps.components.utility.UIContext", [this]);				        
		},// end create METHOD

		setUIContext: function(obj){
	  		this.UIContext = obj;
		},					
		
		processRequest: function(owner, response, ioArgs)
		{	
			// Destroy the progress image
			owner.destroyProgress("02");
			
			//check if the response has empty itms
			if ((response.items) && (response.items.length > 0)){
				
				// Create the store for the response tree
				var treeStore = new dojo.data.ItemFileReadStore ({data: response});			
				
				// Create the tree
				var element = document.getElementById("logicalTree");
				
				// Create an inner class to override the getIconClass method
				// of the dijit tree
				dojo.declare(
						// class
						"org.eclipse.cosmos.provisional.dr.ps.components.widget.LogicalTreeStructure",
	
						// superclass	
						[dijit.Tree],
						
						// member variables/functions
						{
							getIconClass: function(/*dojo.data.Item*/ item)
							{						
								return item == null || typeof(item.type) == 'undefined' ? "" : item.type + "Icon";
							}
						}
					);		
	
					
		        var responseTree = new org.eclipse.cosmos.provisional.dr.ps.components.widget.LogicalTreeStructure(
	    	    	   { 
	    	    		   id: "queryLogicalTreeStructure",
	    	    		   owner: owner, 
						   _message: owner._message,
						   propertiesAttachPoint: owner.propertyAttachPoint,
	    	    		   store: treeStore,
	    	    		   labelAttr: "label",
	    	    		   childrenAttr: ["elements", "records"],
	    	    		   query: {type:"*Template"},
	    	    		   widgetId: "queryResponseTree"
	    	    	   }, 
	    	    	   element);	 
					   
				// Attach a subscription method to the tree so that it's notified
		        // of node selections.
		        dojo.subscribe("queryLogicalTreeStructure", responseTree, owner.processSelection);
			}
			else if (response._error_){	
				//need to decode string messages
				var detail = unescape(response.detail);
				var message = unescape(response.message);
				rExp = /\+/gi;
				response.detail=detail.replace(rExp, " ");				
				response.message=message.replace(rExp, " ");
				dojo.publish("org.eclipse.cosmos.provisional.dr.ps.components.utility.ErrorHandler", [{message:response, prompt:true, severity:1}]);				 
				owner.showMessage("logicalTree", "02", owner._message.NO_DATA_FOUND);				
			}			
			else{
				owner.showMessage("logicalTree", "02", owner._message.NO_DATA_FOUND);				
			}
		},
		
		
		// Method: processSelection
		// Summary: This method is invoked when there is a node selection in the
		// logical tree structure.  The method publishes a topic that is used by
		// the properties view to render the attributes of the selected item.
		processSelection: function(selectedTreeNode)
		{	 	    	 	
			var owner = this.owner;			
	 	    var properties = new Array();
			var isRelationship = false;
			
			var selectedItem = selectedTreeNode.item;
			
			// Item/Relationship is selected
			if (selectedItem.type == 'item' || (isRelationship = (selectedItem.type == 'relationship')))
			{
				// Display source and target if this is a relationship
				if (isRelationship)
				{
					if (typeof(selectedItem.source) != 'undefined')
					{
						properties[properties.length] = [this._message.COLSOURCE, selectedItem.source];
					}
					
					if (typeof(selectedItem.target) != 'undefined')
					{
						properties[properties.length] = [this._message.COLTARGET, selectedItem.target];
					}
				}	
				
				// Instance IDs
				if (typeof(selectedItem.instanceId) != 'undefined') 
				{
					var instanceIds = selectedItem.instanceId;
					var totalLength = properties.length + instanceIds.length
					for (var i = properties.length; i < totalLength; i++) 
					{				
						var inx = i - properties.length;		
						properties[i] = [this._message.GRAPH_RESPONSE_INSTANCE_ID, 
										"MDR ID: " + instanceIds[inx].mdrId + "<br/>" + 
										"Local ID: " + instanceIds[inx].localId];						
					}
				}
				
				// Additional record types
				if (typeof(selectedItem.additionalRecords) != 'undefined')
				{
					var additionalRecords = selectedItem.additionalRecords;
					var totalLength = properties.length + additionalRecords.length
					for (i = properties.length; i < totalLength; i++) 
					{
						var inx = i - properties.length;
						properties[i] = [this._message.GRAPH_RESPONSE_ADDITIONAL_RECORD, 
										"Namespace: " + [inx].namespace + "<br/>" + 
										"Local Name: " + additionalRecords[inx].localName];						
					}
				}			
			}
			// Record is selected
			else if (selectedItem.type == 'record')
			{				
				if (typeof(selectedItem.value) != 'undefined')
				{
					properties[properties.length] = [this._message.GRAPH_RESPONSE_RECORD_VALUE, this.owner.UIContext.xmlFormatter.format(selectedItem.value[0])];
				}
				
				if (typeof(selectedItem.lastModified) != 'undefined')
				{
					properties[properties.length] = [this._message.COLLASTMODIFIED, selectedItem.lastModified];
				}
				
				if (typeof(selectedItem.snapId) != 'undefined')
				{
					properties[properties.length] = [this._message.COLSNAPSHOTID, selectedItem.snapId];
				}
				
				if (typeof(selectedItem.baseId) != 'undefined')
				{
					properties[properties.length] = [this._message.COLBASELINEID, selectedItem.baseId];
				}
				
				dojo.publish(this.topic, selectedItem);
			}
						
			var cloneMap = new Object();
	 	    dojo.mixin(cloneMap, selectedTreeNode);	 	    			
	 	    cloneMap.nodeClass = this.attachPoint + " " + cloneMap.nodeClass;
	 	    cloneMap.store = properties;
			
			dojo.publish(this.propertiesAttachPoint, [{contextMap:cloneMap}]);
		},		
		///////////////////////
		// METHOD postCreate //
		///////////////////////					
		postCreate: function()
		{		
			this.propertyAttachPoint = globalParams.propertyAttachPoint;
			this.inherited("postCreate", arguments);
		},  // end create METHOD		
		
		
		// Method: destroy
		// Summary: Invoked to destroy this widget
		destroy: function()
		{
			dojo.unsubscribe("queryLogicalTreeStructure"); 		
			this.utility.destroyWidgets(["queryLogicalTreeStructure"]);	
			this.inherited("destroy", arguments);	
		}
	
	}
);