/**
 * Publication ontology related javascript module.  It has necessary function 
 * to build high interactive, scalable Tree Component in conjunction with Ajax 
 * and JSON.  It also support caching mechanism for persisting tree component's 
 * nodes.
 *
 * @author Veeresh D.
 * @date March 2008
 */

var pubLevel = 0, pubStr
var pubNodeImg, pubNodeLink;
var pubNodesChildren = new Array();
var pubParentNodeLabels = new Array();
var pubTreeImagesDir = "images/treeImages/";
var keyStringLabel = "";

var treePub =
{
    /**
    Adds a node into the tree data structure.  After adding nodes, actual rendering or
    graphical preperation of tree in the browser will be done along with necessary 
    events over every nodes
    
    @param nodeId Uniqud id the child node
    @param nodeParentId Parent id of the node. It is used as a query parameter to fetch its children nodes
    @param nodeValue Name of the node
    @param nodeLevel Level or depth of the child node from the root node of the tree
    @param nodeType Type of node, either parent or child
    @param nodeTocId TOC Id of the node in the database.  It is used as a query parameter to fetch its articles
    @param lastNode 
    */
    pubAddNode: function(nodeId, nodeParentId, nodeValue, nodeLevel, nodeType, nodeTocId, lastNode, nodeLabel)
    {         
	    treePub.pubAppendChildNode();
	    pubLevel++;

	    pubNodeImg = pubTreeImagesDir + "folder.gif";
	    pubNodeLink = pubTreeImagesDir + "plus.gif";

	    if (nodeId == null)					
		    nodeId = pubLevel;              //Unique Node ID
	    if (nodeParentId == null)
		    nodeParentId = "0";				//Node's Parent ID
	    if (nodeValue == null)
		    nodeValue = "Node" + nodeId;	//Node name
		if (nodeLevel == null)
		    nodeLevel = "0";        		//Depth from parent
	    if (nodeType == null)
		    nodeType = "1";					//Type of node (1= Parent, 0= Child)
        
        if(nodeParentId != "")
	    {
		    var divs = document.getElementById("pubDiv" + nodeParentId);
		    pubStr = "<DIV id=pubDiv" + nodeId + " style=\"position: relative;\">";
            
		    if ( nodeLevel > 0 )
		    {
			    for (i = 0; i < nodeLevel-1; i++)
				    pubStr += "<img src=" + pubTreeImagesDir + "line.gif />";							
		    }
		    if (pubNodesChildren[nodeParentId] == null)
			    pubNodesChildren[nodeParentId] = "";
    		
		    pubNodesChildren[nodeParentId] += "" + nodeId + ",";	//To keep track all its children
    		
		    keyStringLabel = nodeValue ;
    		var treeNodeLabel = nodeValue;
    		nodeValue = nodeValue.replace("<font color=saxblue>","").replace("</font>","")
		    if ( nodeLevel == 2)
		    {
			    pubParentNodeLabels[nodeId] = nodeValue;
		    }
		    if ( nodeLevel == 3)
		    {
			    pubParentNodeLabels[nodeId] = pubParentNodeLabels[nodeParentId] + ", " + nodeValue;
			    keyStringLabel = pubParentNodeLabels[nodeParentId] + ", " + nodeValue;			
		    }
		    if ( nodeLevel == 4)
		    {
			    keyStringLabel = pubParentNodeLabels[nodeParentId] + " " + nodeValue;			
		    }
    		
		    if (nodeType == 0)	
			    pubNodeImg = pubTreeImagesDir + "page.gif";
		    if (lastNode == null)	
			    lastNode = 0;				//For button add
    		
		    pubNodeLink = treePub.pubDefineLinkType(nodeType, lastNode);
    		
		    if (nodeId==1)
		    {
			    pubNodeImg = pubTreeImagesDir + "globe.gif";	//Root most element
			    nodeValue = "Ontology Forest";
			    pubNodeLink = pubTreeImagesDir + "nolines_plus.gif";
		    }
		    pubStr += "<img class=clickPtr onclick=\"treePub.pubCheckNode(" + nodeId +")\" id=pubimg" + nodeId;
		    pubStr += " name=imgname" + nodeParentId +" src=\"" + pubNodeLink + "\"/>";
    		
    		var nodeToolTip = nodeValue;
		    
		    //pubStr += "<a href=\"#\" onclick=\"treePub.pubCheckNode(" + nodeId + "),treePub.pubGetPublicationResults('" + nodeTocId + "','" + keyStringLabel + "')\" title='" + nodeToolTip + "'>";		
    		pubStr += "<A href=?publication=" + validateDataItem("", nodeTocId) + "&label=" + escape(keyStringLabel) + " onclick=\"return treePub.pubCheckNode(" + nodeId + "),treePub.pubGetPublicationResults('" + nodeTocId + "','" + keyStringLabel + "')\" title='" + nodeToolTip + "'>";
	
		    pubStr += "<img src=\"" + pubNodeImg + "\" title='" + nodeToolTip + "'/>";	//Either Folder or Item icon
		    //pubStr += treeNodeLabel + "(" + (nodeLabel + "").fontcolor("firebrick") + ")";								//Node name/value
		    pubStr += treeNodeLabel;								//Node name/value
		    pubStr += "</a></DIV>";		
    		
		    if ( getBrowserName() == "Safari" || getBrowserName() == "Mozilla" )
		        divs.innerHTML += pubStr;
		    else
		        divs.insertAdjacentHTML("afterEnd", pubStr);
		    //if ( divs == null ) alert("found null");    		
	    }
    },
    
    /**
    Supporting method to get the set of articles

    @param subjectNodeName TOC id of the node to fetch all of its articles
    */
    pubGetPublicationResults: function(pubNodeId, pubNodeRootLabel)
    {
        treePub.pubGetNodeArticles(pubNodeId, pubNodeRootLabel);	
        latestSearchResultFunCall = "treePub.pubGetNodeArticles('" + pubNodeId + "','" + pubNodeRootLabel + "')";       
        return false;
    },
    
    /**
    Defines the type of link associated with parent and its children node.
    Depends on the type of node, it generates a image just below its parent
    or children nodes( like Plus, Last plus, last node)

    @param nType Node type, 1 for parent and 0 for children/leaf node
    @param ln Binary state of last node.  0 for last node, and not 0 for not last node
    */
    pubDefineLinkType: function(nType, ln)
    {
	    var ret;
	    switch(Number(nType))
	    {
		    case 0:
					    ret = (ln==0)? "joinbottom.gif" : "join.gif";
					    break;
		    case 1:
					    ret = (ln==0)? "plusbottom.gif" : "plus.gif";
					    break;				
	    }
	    return (pubTreeImagesDir + ret);
    },
    
    /**
    It Checks the status of the node, based on it, it either opens or closes the
    parent node.  It may also need to manage security accesses and data caching 
    mechanism tasks

    @param j Identifier of the node
    */
    pubCheckNode: function(j)
    {
        var nodeIname;
	    nodeIname = getURIFileName(document.getElementById("pubimg" + j).src);
	    if ( isSameString(nodeIname, "nolines_plus.gif") || isSameString(nodeIname, "plus.gif") || isSameString(nodeIname,"plusbottom.gif"))
	    {
		    if ( pubNodesChildren[j]== null)
		    {
			    treePub.pubGetChildrenNodes(j);
			    var img = document.getElementById("pubimg" + j);
			    img.src = (pubTreeImagesDir + "minus.gif");
		    }
		    else
		    {
			    treePub.pubOpenParent(j);	//If Node has already been loaded
		    }
	    }
	    else
		    treePub.pubCloseParent(j);
    },
    
    /**
    Expands or opens the parent node of the tree

    @param k Identifier of the parent node
    */
    pubOpenParent: function(k)
    {
	    if( pubNodesChildren[k] != null)
	    {
		    var cnode;
		    
		    if ( document.getElementById("pubimg" + k) )
    	        document.getElementById("pubimg" + k).src = (treeImagesDir + "minus.gif");
    	        
		    var childrenIds = new Array();
		    childrenIds = pubNodesChildren[k].split(",");   /* Using the persisted nodes */

		    for(var i=0;i<childrenIds.length-1;i++)
		    {
			    cnode = document.getElementById("pubDiv" + childrenIds[i]);
			    cnode.style.display = '';
			    treePub.pubOpenParent(childrenIds[i]);
		    }
	    }
    },
    
    /**
    Closes the parent node of the tree

    @param l Identifier of the parent node
    */
    pubCloseParent: function(l)
    {	
	    if (pubNodesChildren[l] != null)
	    {
		    var cnode;
		    var img = document.getElementById("pubimg" + l);
		    img.src = pubTreeImagesDir + "plus.gif";

		    var childrenIds = new Array();
		    childrenIds = pubNodesChildren[l].split(",");

		    for (var i = 0; i < childrenIds.length - 1; i++)
		    {
			    cnode = document.getElementById("pubDiv" + childrenIds[i]);
			    cnode.style.display = "none";
			    treePub.pubCloseParent(childrenIds[i]);
		    }
	    }
    },
    
    /**
    Get the children nodes from the server dynamically

    @param rid Parent id of the node
    */
    pubGetChildrenNodes: function(rid)
    {
	    var ajaxRequest = zXmlHttp.createRequest();
    	showNotification('pubTreeNote', 'Loading...', 0);
    	
	    ajaxRequest.onreadystatechange = function()
	    {
		    if(ajaxRequest.readyState == 4)
		    {
			    if (ajaxRequest.status == 200)
			    {
				    treePub.pubsRenderJSONTreeArrays(ajaxRequest.responseText);									
			    }
			    else
			    {
				    showFallBackNotification('leftPanelPublicationTreeBoxDiv',"Unable to get server response.", "treePub.getPubTreeInitData()");
				    hideNotification('pubTreeNote');				    
			    }
		    }
	    }
	    ajaxRequest.open("GET", ROOT_DB_URL + "ontology.action?parentNodeId=" + rid + "&ontologyType=publications" + ((loginStatus == false) ? "" : "&nullParam=" + new Date()), true);	//Struts class source
	    ajaxRequest.send(null);
    },
    
    /**
    Render/Retrive the children meta data of tree and adds/updates the tree component

    @param myJSONtext JSON data object containing children meta data of tree
    */
    pubsRenderJSONTreeArrays: function(myJSONtext)
    {
	    var myObject = eval('(' + myJSONtext + ')');
	    var lnode = 0;
    	
    	if ( myObject.ontologyNode.length == 0 )
	    {
	        hideNotification('pubTreeNote');
		    showFallBackNotification('leftPanelPublicationTreeBoxDiv',"Unable to get server response.", "treePub.getPubTreeInitData()");
			return ;
	    }
	    
	    if ( getBrowserName() == "Safari" || getBrowserName() == "Mozilla" )
	    {
	        for (var i = 0; i < myObject.ontologyNode.length; i++)
	        {
		        treePub.pubAddNode(myObject.ontologyNode[i].nodeId, myObject.ontologyNode[i].rootId, myObject.ontologyNode[i].name, Number(myObject.ontologyNode[i].displayLevel)-1, myObject.ontologyNode[i].type, myObject.ontologyNode[i].tocID, lnode, myObject.ontologyNode[i].nodeLabel);
		        lnode = 1;
	        }
	    }
	    else
	    {
	        for (var i = myObject.ontologyNode.length - 1; i >= 0; i--)
	        {
	            //alert("nodeLabel=" +  myObject.ontologyNode[i].nodeLabel);
	            treePub.pubAddNode(myObject.ontologyNode[i].nodeId, myObject.ontologyNode[i].rootId, myObject.ontologyNode[i].name, Number(myObject.ontologyNode[i].displayLevel)-1, myObject.ontologyNode[i].type, myObject.ontologyNode[i].tocID, lnode, myObject.ontologyNode[i].nodeLabel);
		        lnode = 1;
	        }
	    }
	    hideNotification('pubTreeNote');
    },
    
    /**
    Get the articles of a selected node of the tree component from the server

    @param nodeTOCId Identifier/TOC id of the tree node
    */
    pubGetNodeArticles: function(pubNodeTOCId, pubNodeRootLabel)
    {
        var ajaxRequest = zXmlHttp.createRequest();
	    showTopNotification();
    	ajaxRequest.onreadystatechange = function()
	    {
		    if(ajaxRequest.readyState == 4)
		    {
			    if (ajaxRequest.status == 200)
			    {	
			        hideTopNotification();
				    global.variables.recentSearchType = "publicationOntologySearch";
			        
			        global.setSaveSearchParams(pubNodeTOCId, "ontologyPublication");
    				var flag = searchResults.renderJSONSearchResults(ajaxRequest.responseText, pubNodeRootLabel, 1);	
    				if ( flag == false )
        		    {
        		        return false;   // Do nothing when no results
        		    }
				    if ( totalArticleResultsFound != 0)
					    initResultPages(totalArticleResultsFound, 10, pubNodeTOCId, "ontology", pubNodeRootLabel);   //Pagination component initialization				
    				
				    historyIsItResultDetails = 1;
	                parityHistory.setInHistory();
			    }
			    else
			    {
				    //showFallBackNotification('leftPanelPublicationTreeBoxDiv',"Unable to get node articles.", "treePub.getPubTreeInitData()");
				    hideTopNotification();//hideNotification('pubTreeNote');
				    alert("Unable to get search results articles for \"" + pubNodeRootLabel + "\". Please try again"); 
				}
		    }
	    }
	    //alert("url=" + ROOT_DB_URL + "search.action?nodeID=" + pubNodeTOCId + "&nodeLabel=" + escape(pubNodeRootLabel) + "&ontologyType=publication");
	    ajaxRequest.open("GET", ROOT_DB_URL + "search.action?nodeID=" + pubNodeTOCId + "&nodeLabel=" + escape(pubNodeRootLabel) + "&ontologyType=publication&nullParam=" + new Date(), true);	//Struts class source
	    ajaxRequest.send(null);
    },
    
    /**
    Re-Initialize the population of whole tree, particularly after login or updating MyComSoc by Saving items
    */
    getPubTreeInitData: function()
    {
        document.getElementById("leftPanelPublicationTreeBoxDiv").innerHTML = "<div id=\"pubDiv1\"></div><BR/>";
        
        pubNodesChildren.length = 0;
        pubParentNodeLabels.length = 0;
        
        treePub.pubAddNode(2, 1,'Publications', 1, 1,'TOC0');
	    treePub.pubGetChildrenNodes(2);
	    if ( getBrowserName() == "Safari" || getBrowserName() == "Mozilla" )
	    {
	        if (document.getElementById("pubDiv2"))
	            document.getElementById("pubDiv2").innerHTML = "";	//To remote root note "Subjects"
	    }
	    else
	    {
	        if (document.getElementById("pubDiv2"))
	            document.getElementById("pubDiv2").style.display = "none";	//To remote root note "Publication"    
	    }
    },
    
    /**
    Create or Adds a new object prototype for appending child node mechanism.
    It will detects the internal object's method, based on status it creates
    this browser level function to add new children nodes to existing tree
    */
    pubAppendChildNode: function()
    {
	    if(typeof HTMLElement!="undefined" && !HTMLElement.prototype.insertAdjacentElement)
	    {
		    HTMLElement.prototype.insertAdjacentElement = function(where,parsedNode)
		    {
			    switch (where)
			    {
				    case 'beforeBegin':
					    this.parentNode.insertBefore(parsedNode,this)
					    break;
				    case 'afterBegin':
					    this.insertBefore(parsedNode,this.firstChild);
					    break;
				    case 'beforeEnd':
					    this.appendChild(parsedNode);
					    break;
				    case 'afterEnd':
					    if (this.nextSibling)
						    this.parentNode.insertBefore(parsedNode,this.nextSibling);
					    else
						    this.parentNode.appendChild(parsedNode);
					    break;
			    }
		    }

		    HTMLElement.prototype.insertAdjacentHTML = function(where,htmlStr)
		    {
			    var r = this.ownerDocument.createRange();
			    r.setStartBefore(this);
			    var parsedHTML = r.createContextualFragment(htmlStr);
			    this.insertAdjacentElement(where,parsedHTML)

		    }

		    HTMLElement.prototype.insertAdjacentText = function(where,txtStr)
		    {
			    var parsedText = document.createTextNode(txtStr)
			    this.insertAdjacentElement(where,parsedText)
		    }
	    }
    }
}



