/****************************************************************
** Licensed Materials - Property of IBM
**
** IBM Cognos Products: mdsrv
**
** (C) Copyright IBM Corp. 2008, 2015
**
** US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
*****************************************************************/
//***********************************************************************************************
// Copyright (C) 2008 Cognos ULC, an IBM Company. All rights reserved.
// Cognos (R) is a trademark of Cognos ULC, (formerly Cognos Incorporated).
//
// Component:	Technical View
//***********************************************************************************************

// Declare the LINEAGE namespace

if ( ! LNS )
	var LNS = {};

// Global constants

LNS.oTechnicalView = null;

LNS.arrItemsTypesWithIcon = [];

LNS.arrItemsTypesWithIcon["filter"]				= true;
LNS.arrItemsTypesWithIcon["detailFilter"]		= true;
LNS.arrItemsTypesWithIcon["filterDefinition"]	= true;
LNS.arrItemsTypesWithIcon["summaryFilter"]		= true;
LNS.arrItemsTypesWithIcon["slicerMemberSet"]	= true;

LNS.arrClassIcons = [];

LNS.arrClassIcons["querySubject"]				= "query_subject.gif";
LNS.arrClassIcons["query"]						= "query_subject.gif";
LNS.arrClassIcons["queryItem"]					= "attribute.gif";
LNS.arrClassIcons["dataItem"]					= "attribute.gif";
LNS.arrClassIcons["reportItem"]					= "report_item.gif";
LNS.arrClassIcons["measure"]					= "measure.gif";
LNS.arrClassIcons["dataSource"]					= "data_source.gif";
LNS.arrClassIcons["dimension"]					= "dimension.gif";
LNS.arrClassIcons["hierarchy"]					= "hierarchy.gif";
LNS.arrClassIcons["level"]						= "level.gif";
LNS.arrClassIcons["calculation"]				= "calculation.gif";
LNS.arrClassIcons["filter"]						= "filter.gif";
LNS.arrClassIcons["detailFilter"]				= "filter_embedded.gif";
LNS.arrClassIcons["filterDefinition"]			= "filter_embedded.gif";
LNS.arrClassIcons["summaryFilter"]				= "filter_summary.gif";
LNS.arrClassIcons["slicerMemberSet"]			= "slicer.gif";
LNS.arrClassIcons["queryItemFolder"]			= "folder.gif";

//-------------------------------------------------------------------------------------
// class OnPostPopulate
//-------------------------------------------------------------------------------------

	function OnPostPopulate ( graph, paneManager )
	{
		// Set events

		var timeStart = new Date().getTime();

		var elemGraph	= document.getElementById ( graph.getId() );

		var elemCanvas	= elemGraph.parentNode;

		var nGraphHeight = (UTIL.ElementHelper.setElem( elemGraph )).getClientSize().height;

		// Event callbacks

		//this.OnGraphTimer	= function  ()
		//{
		//	var nGraphHeightNew = (UTIL.ElementHelper.setElem( elemGraph )).getClientSize().height;
		//
		//	// A workaround for FF to respond to graph resize - FF 2.0.0.12 does NOT send the 'resize' event
		//
		//	if ( nGraphHeightNew != nGraphHeight )
		//	{
		//		nGraphHeight = nGraphHeightNew;
		//
		//		paneManager.updateSize ( false );
		//
		//		//--------------------------------------------------------------
		//		// Move all panes' captions and links
		//		//--------------------------------------------------------------
		//
		//		paneManager.OnGraphResize ();
		//	}
		//}

		this.OnGraphResize	= function  ( evt )
		{
			var evtObj	= new CMouseEvent ( evt );

			paneManager.updateSize ( false );

			//--------------------------------------------------------------
			// Move all panes' captions and links
			//--------------------------------------------------------------

			paneManager.OnGraphResize ();
		}

		this.OnGraphScroll	= function  ( evt )
		{
			var evtObj	= new CMouseEvent ( evt );

			paneManager.OnScroll ( evtObj );
		}

//		addEvent( elemCanvas, 'scroll', this.OnGraphScroll, false );

		addEvent( elemGraph, 'scroll', this.OnGraphScroll, false );
		addEvent( elemGraph, 'resize', this.OnGraphResize, true );

		// FireFox resize workaround using timer intervals

		//window.setInterval ( "LNS.oTechnicalView.eventProcessor.OnGraphTimer()", 200 );

		// Any non-generic graph actions are to be done here !

		var gMainObjects = [];

		for ( var i = 0; i < graph.m_nodeList.length; i++)
		{
			var gNode = graph.m_nodeList[ i ];

			// Move the nodes to the correct position

			gNode.move ( gNode.x, gNode.y );

			if ( gNode.modelObject.isMainObject() )
				gMainObjects.push( gNode );
		}

		for (var i = 0; i < gMainObjects.length; i++)
		{
			gMainObjects[i].setTextBold ();
			gMainObjects[i].setBorderStyle ( 'dashed' );
		}

		if ( gMainObjects[0] )
			graph.SelectObject ( gMainObjects[0] );

		// Configure Initial Visible Nodes

		paneManager.setNodesVisibility	();

		// Configure the connections

//		graph.refreshConnections ();
	}

//-------------------------------------------------------------------------------------
// class CTechnicalView
//-------------------------------------------------------------------------------------

function CTechnicalView ( sCanvasId )
{
	// Members

	this.canvasId			= sCanvasId;
	this.bInitialized		= false;
	this.modelData			= null;
	this.GraphCtrl			= null;
	this.paneManager		= null;

	this.propertyPaneQuery	= null;
	this.propertyPaneItem	= null;
	this.propertyManager	= null;

	this.idProgressTimer	= null;
	this.eventProcessor		= null;

	this.bShowActionLinks	= false;
	this.sActionURL			= 'http://www.google.ca';
	this.sActionIcon		= 'action_custom.gif';
	this.sActionIconTooltip	= 'Click to run action...';

	// API

	this.setCurrentDir	= function ( sCurrentDir )
	{
		if ( DG.graphDefaults )
			DG.graphDefaults.sCurrentDir = sCurrentDir;
	}

	this.getCurrentDir	= function ( )
	{
		return DG.graphDefaults.sCurrentDir;
	}

	this.processKeyEvent = function ( keyEvent )
	{
		var bProcessed = false;

		if ( this.GraphCtrl )
		{
			bProcessed = this.GraphCtrl.processKeyEvent( keyEvent );
		}

		return bProcessed;
	} 

	//----------------------------------------------------------------------------
	// Overriding the Graph VIRTUAL METHODs to provide customized behaviour
	//----------------------------------------------------------------------------

	this.getObjectIcon	= function ( modelObject )
	{
		ASSERT( modelObject != null, "getObjectIcon: modelObject is NOT valid !" );

		if ( ! modelObject )
			return 0;

		var sObjClass = modelObject.getObjClass();

		var sIconFile = LNS.arrClassIcons[ sObjClass ];

		// Specific cases

		if ( sObjClass == "dimension" )
		{
			if ( modelObject.getObjSubClass() == "measure" )
				sIconFile	= "measure_dimension.gif";
		}
		else
		if ( sObjClass == "calculation" )
		{
	//		alert( "calcType = " + modelObject.findPropertyValue( "calcType" ) );

			if ( modelObject.findPropertyValue( "calcType" ) == "Named Set" )
				sIconFile	= "named_set.gif";
		}

		ASSERT( sIconFile != null, "getObjectIcon: Icon file for object class '" + sObjClass + "' is NOT found !" );

		var nIconIndex = this.GraphCtrl.getIconIndex ( sIconFile );

		return nIconIndex;
	}

	this.isShowItemIcon	= function ( modelObject )
	{
		ASSERT( modelObject != null, "isShowItemIcon: modelObject is NOT valid !" );

		var bShow = false;

		if ( modelObject != null )
		{
			if ( LNS.arrItemsTypesWithIcon[ modelObject.getObjClass() ] )
			{
//				alert ("isShowItemIcon: show icon for type <" + modelObject.getObjClass() + ">");

				bShow = true;
			}
		}

		return bShow;
	}

	// OnActionClick - virtual callback method. Override it in the controller for a custom action. 

	this.OnActionClick	= function( modelObject )
	{
		var bAction = true;

		if ( bAction )
		{
			if ( this.sActionURL.length > 0 )
			{
				window.open( this.sActionURL );
			}
		}

		return bAction;		
	}

	//----------------------------------------------------------------------------
	//----------------------------------------------------------------------------

	this.Init	=  function ( modelData )
	{
		LNS.oTechnicalView = this;

		if ( this.bInitialized )
			return;

		this.modelData = modelData;

		// Config global diagram settings

		DG.graphDefaults.bShowActionLinks	= this.bShowActionLinks;
		DG.graphDefaults.sActionIcon		= this.sActionIcon;
		DG.graphDefaults.sActionIconTooltip	= this.sActionIconTooltip;

		try
		{
			var timeStart = new Date().getTime();

			// Initialize Graph Panes
			
			this.paneManager	= new CPaneManager ( this.canvasId );

			ASSERT ( this.modelData.getPaneCount() > 0, "Init: No panes to display !!!" );

			if ( this.modelData.getPaneCount() > 0 )
			{
				var nInitialPaneWidth = 100 / this.modelData.getPaneCount();
				
				for ( var i = 0; i < this.modelData.getPaneCount(); i++ )
				{
					var pane = new CPaneInfo ( this.paneManager, this.modelData.getPaneName(i), "expanded", nInitialPaneWidth );

					this.paneManager.addPane ( pane );
				}
			}

			// Initialize Property Pane
			
			this.propertyPaneQuery	= new CPropertyPane( "id_query_property_table" );
			this.propertyPaneItem	= new CPropertyPane( "id_item_property_table" );
			this.propertyManager	= new CPropertyMgr ( this.propertyPaneQuery, this.propertyPaneItem );

			// Initialize Main Graph

			this.GraphCtrl = new DG.CGraphControl( this, this.canvasId, this.propertyManager );

			// Initialize Pane Manager

			this.paneManager.Init ( this.GraphCtrl, 'id_graph_header' );

			this.populateGraph( this.modelData, this.GraphCtrl, this.paneManager );

			this.eventProcessor = new OnPostPopulate ( this.GraphCtrl, this.paneManager );

			this.updateGraphHeader ( 'id_graph_header', this.GraphCtrl, this.paneManager );

			this.paneManager.ExpandPanes ( true );

			//	alertTimeDiff ( timeStart, "CTechnicalView.init" );

			// Debug Diagnostics

			//	var sElemContents = walkChildNodes( document.body, false );
			//	var sElemContents = walkChildNodes( this.GraphCtrl.gdi.id, false );
			//	alert ( sElemContents );
		}
		catch ( err )
		{
			var txt = "Init: Error " + err.description + "\n\n";
			txt += "Click OK to continue.\n\n";
			alert ( txt );
		}
		finally
		{
  			this.bInitialized = true;
		}
	}

	this.populateGraph = function  ( modelData, graph, paneManager )
	{
		// Config Graph

		graph.m_isDragHorzAllowed	= false;

		// Populate Graph

		for ( var i = 0; i < modelData.getObjectCount(); i++ )
		{
			var gNode = new DG.CGraphNode ( modelData.getObject( i ), graph );
			graph.addNode ( gNode );
		}

		// Split the node list into the corresponding pane node lists
		
		paneManager.splitNodes ( graph.m_nodeList );

		//-------------------------------------------------------------------------------------
		// Set Nodes' Initial Layout
		//-------------------------------------------------------------------------------------

		paneManager.Layout ();

		//----------------------------------------------------------------------
		// Add Connections	
		//----------------------------------------------------------------------

		for ( var j = 0; j < modelData.getConnectionCount(); ++j )
		{
			var objLeft		= modelData.getConnectionLeft( j );
			var objRight	= modelData.getConnectionRight( j );

//			alert ( "populateGraph: create connection from " + objLeft + " to " + objRight );

			if ( objLeft && objRight )
			{
				var graphConn = new DG.CGraphConnection ( objLeft, objRight, graph );

				if ( graphConn.isValid )
					graph.addConnection ( graphConn );
			}
		}

		// Painting the graph objects

		graph.paint();
	}

	this.toggleReportPaneState	= function ( idElemLink, cookieMgr )
	{
		var temp = idElemLink;

		var elemLink = document.getElementById( idElemLink );

		var sState = cookieMgr.getCookie( "lineageReportPaneState" );

		if ( sState == "collapsed" )
		{
			elemLink.innerHTML = "REPORT (+)";
			sState = "expanded";
			cookieMgr.setCookie( "lineageReportPaneState", sState );
		}
		else
		{
			elemLink.innerHTML = "REPORT (-)";
			sState = "collapsed";
			cookieMgr.setCookie( "lineageReportPaneState", sState );
		}
	}

	this.toggleModelPaneState	= function( idElemLink, cookieMgr )
	{
		var temp = idElemLink;

		var elemLink = document.getElementById( idElemLink );

		var sState = cookieMgr.getCookie( "lineageModelPaneState" );

		if ( sState == "collapsed" )
		{
			elemLink.innerHTML = "MODEL (+)";
			sState = "expanded";
			cookieMgr.setCookie( "lineageModelPaneState", sState );
		}
		else
		{
			elemLink.innerHTML = "MODEL (-)";
			sState = "collapsed";
			cookieMgr.setCookie( "lineageModelPaneState", sState );
		}
	}

	this.updateGraphHeader	= function  ( headerId, graph, paneManager )
	{
		//----------------------------------------------------------------------------------
		// Create Pane Captions and Buttons
		//----------------------------------------------------------------------------------

		paneManager.createControls	( headerId );
		paneManager.moveControls	();
	}
}