/**
 * TreePanel
 * * An asyncronously loading gold tree panel
 * * Customizable as to what subtree of the original gold ontology
 * * is displayed
 *
 * * Tree structure that is open persists on page loads by a state cookie system
 * 
 * @author Dwight VanTuyl
 * @param root: GOLD root uri for this tree
 * @param title: string title for panel tab
 */
TreePanel = Ext.extend(Ext.tree.TreePanel, {
  constructor: function(config){
    
    //Initialize config defaults
    if (config == null){config = {};}
    if (!config.title){config.title = '';}
    if (!config.root){config.root = '*';} 
  
    //Modify Configuration to Panel
    c = {
      id: config.title + "-" + gversion,
      title: config.title,
      root: new Ext.tree.AsyncTreeNode({
        text: 'Invisible Root',
        draggable: false,
        id: config.root
      }),
      rootVisible: false,
      loader: new Ext.tree.TreeLoader({
        url: '/gold/' + gversion + 'nodes.json',
        requestMethod: 'GET'
      }),
      listeners: {
      
      	//Clicking on a node links to that gold concept
        click: function(node) {
          window.location = "/gold/" + gversion + "/" + node.id;        
        },
        
        //Expand node event needs to save state info
        expandnode: function(node){
        	this.onExpand(node);
        },
        
        //Collape node event needs to save state info
        collapsenode: function(node){
        	this.onCollapse(node)
        },
        
        //Init tree expand from previous state when the tree panel is shown
        show: function(){
        	this.cp = new Ext.state.CookieProvider();
			this.state = this.cp.get('TreePanelState_' + this.id, new Array() );
			this.restoreState(this.root.getPath());
        }
      }
    };

    TreePanel.superclass.constructor.call(this, c);
  },
 
  //Save current state of the tree to a cookie
  saveState: function(newState) {
		this.state = newState;
		this.cp.set('TreePanelState_' + this.id, this.state);
	},
  
  //Record expanded nodes to state
  onExpand: function(node) {
  	var currentPath = node.getPath();
  	var newState = new Array();
	for (var i = 0; i < this.state.length; ++i) {
		var path = this.state[i];
		if (currentPath.indexOf(path) == -1) {
			// this path does not already exist
			newState.push(path);			
		}
	}
	// now ad the new path
	newState.push(currentPath);
	this.saveState(newState);
  },
  
  //Record collapsed nodes to state
  onCollapse: function(node){
	var closedPath = closedPath = node.getPath();
    var newState = new Array();
	for (var i = 0; i < this.state.length; ++i) {
		var path = this.state[i];
		if (path.indexOf(closedPath) == -1) {
			// this path is not a subpath of the closed path
			newState.push(path);			
		}
	}
	if (newState.length == 0) {
		var parentNode = node.parentNode;
		newState.push((parentNode == null ? this.mytree.pathSeparator : parentNode.getPath()));
	}
	this.saveState(newState);
  },
  
  //Restore previous tree state from cookie
  restoreState: function(defaultPath) {	
	if (this.state.length == 0) {
		var newState = new Array(defaultPath);
		this.saveState(newState);		
		this.expandPath(defaultPath);
		return;
	}
	for (var i = 0; i < this.state.length; ++i) {
		// activate all path strings from the state
		try {
			var path = this.state[i];
		    this.expandPath(path);  		
		} catch(e) {
			// ignore invalid path, seems to be remove in the datamodel
			// TODO fix state at this point
		}
	}	
 }
});