﻿var tree, layerWindow;
//var layersStore, layersRoot;

//  var layersData = {
//    root : []
//  };

var layersGenerated = false;

function showLayersWindow(){
  if(!layersGenerated){
    generateLayers();
  }
  layerWindow.show();
  layerWindow.focus();
}

/// Disable and hide the node and all children and grandchildren of the given node
/// @param {Ext.tree.TreeNode} node The node to utilize
function disableAllChildren(node){
  node.eachChild(function(childNode){
    childNode.eachChild(function(grandchildNode){
      grandchildNode.disable();
      grandchildNode.collapse(true);
    });
    childNode.disable();
    childNode.collapse(true);
  });
  node.disable();
  node.collapse(true);
}

/// Enable and show the node and all children and grandchildren of the given node
/// Useful when changing ToC based on a zoom level
/// @param {Ext.tree.TreeNode} node The node to use
function enableAllChildren(node){
  node.enable();
  node.expand(true);
  node.eachChild(function(childNode){
    childNode.expand(true);
    childNode.enable();
    childNode.eachChild(function(grandchildNode){
      grandchildNode.expand(true);
      grandchildNode.enable();
    });
  });
}

// Changes legend based on current zoom level
//function layerChange(currZoom){
function layerChange(zoomLevelLayerText){
  tree.root.eachChild(function(childNode) {
    // If the current zoom label is the currentNode, enable it else disable it
    if (Ext.util.Format.lowercase(childNode.text).replace(/ /gi,'') == zoomLevelLayerText){
      // The child node is the current zoom level node
      var zoomNode = childNode;
      enableAllChildren(zoomNode);      
      if(zoomNode.hasChildNodes()) {
        // This expands and scrolls to last node and then back to current node to center properly in window
        zoomNode.lastChild.ensureVisible();
        zoomNode.ensureVisible();
      } else {
        zoomNode.ensureVisible();
      }
    } else {
      disableAllChildren(childNode);
    }
  });
}

function generateLayers(){
  tree = new Ext.tree.TreePanel({
      width: 300,
      autoScroll:true,
      animate:true,
      enableDD:false,
      containerScroll: true,
      rootVisible: true,
      frame: true,
      root: {
        text: 'Base Map',
        expanded: true
      },
      loader: {
        dataUrl: 'Legend.ashx',
        listeners: {
          'loadexception': function(treeLoader, node, response) {
            // Error loading, typically a timeout
            tree.getEl().mask('Failed to load. Click refresh on the toolbar to retry.');
          },
          'load' : function(treeLoader, node, response) {
            // Expand the root to preload all images and clean-up
            tree.root.expand(true);
            Ext.Ajax.timeout = 30000;
          },
          'beforeload' : function() {
            // If the timeout is less than 60  seconds, set it to 60 seconds
            if (Ext.Ajax.timeout < 60000) {
              Ext.Ajax.timeout = 60000;
            }
          }
        }
      },
      preloadChildren: true,  
      listeners: {
        'checkchange': function(node, checked){
          
          // If the layer has been turned off and it has a parent, the parent layer must be off too
          if(node.parentNode != null && 
            node.parentNode.ui.checkbox != null &&
            !node.attributes.checked){
            node.parentNode.ui.checkbox.checked = node.attributes.checked;
            node.parentNode.attributes.checked = node.attributes.checked;
          }
          var activeLayers = tree.getChecked('data');
          map.getLayer("baseLayer").setVisibleLayers(activeLayers);
        }
      }      
  });

  layerWindow = new Ext.Window({ 
	  layout: 'fit',
	  header: true,
	  title: 'Map Layers / Legend',
	  closable: true,
    closeAction: 'hide',
    collapsible: true,
    id:'layerWindow',
    width: 300,
    height: 250,
	  plain: false,
	  frame: true,
	  initHidden: true,
	  initCollapsed: true,
	  shadow: true,
	  items: [tree],
	  tools: [{
        id: 'help',
        qtip: 'Help',
        handler: function(event, toolEl, panel){
          window.open('Help/Default.htm', 'new');
	      }
	    },{
	      id: 'refresh',
	      qtip: 'refresh',
	      handler: function(event, toolEl, panel){
	        Ext.Ajax.timeout += 10000;
	        tree.getEl().mask('Loading...');
	        layersGenerated = false;
	        tree.getLoader().load(tree.root, function(){}, tree);
	      }
	  }]
  });
  
  // Position the window in the upper right corner 
  layerWindow.on('show',function(){
    var xOffset = Ext.getCmp('masterViewport').getBox().width - layerWindow.width - 5;
    var yOffset = 42;
    layerWindow.setPosition(
      [parseInt(xOffset),yOffset]
    );
    if(!layersGenerated) {
      tree.getEl().mask('Loading...');
	  }
  });
  
  // When the browser window is resized, check if the layer window flows off the screen
  // If it does, move it back onto the screen
  Ext.EventManager.onWindowResize(function(){
    var layerWindowExtent = layerWindow.getBox().width + layerWindow.getBox().x;
    var viewportExtent = Ext.getCmp('masterViewport').getBox().width;
    if (layerWindowExtent > viewportExtent) {
      layerWindow.fireEvent('show');
    }
  });

  // once the root is loaded, set a listener to it's last grandchild node to cleanup
  tree.getRootNode().on('expand', function(){
    //TODO: Recurse
    if(this.hasChildNodes() && !layersGenerated){
      // Expand all children recursively
      this.lastChild.on('expand', function() { layersTreeLoaded(); }, {single: true});
    } else if (!layersGenerated) {
      // If the layers were NOT generated, collapse the node again
      tree.getRootNode().collapse();
    }
//    if(this.hasChildNodes() && !layersGenerated){
//      // first put a single listener on the child so when it's expanded
//      this.lastChild.on('expand', function(){ 
//        // Set listener on last child to cleanup after expanding the first time
//        this.lastChild.on('expand', function(){
//          console.debug('root-lastgrandchild-expand');
//          layersTreeLoaded();
//        }, this.lastChild, {single: true});
//      }, this.lastChild, {single: true});
//    } else if (!layersGenerated) {
//      // If the layers were NOT generated, collapse the node again
//      tree.getRootNode().collapse();
//    }
  }); 
  
  // Clean-up the component, unmask and set visible layers for zoom level
  function layersTreeLoaded() {
    tree.getEl().unmask();
    layersGenerated = true;
    updateTableOfContents(map.getLevel());       
  }  
}


/// Update the table of contents (Layers TreePanel) based on the current zoom level
/// @param {number} zoomLevel The current zoom level of the map
/// @param {string} (optional) direction The direction to increment/decrement
function updateTableOfContents(zoomLevel, direction) {
  // If the current zoom level has no associated text, we move to the next level up for text
  if (sliderText[zoomLevel] == null) {
    // If we reached 0 without find our label, go the other direction
    if (zoomLevel < 0) {
      updateTableOfContents(++zoomLevel, 'asc');
      return;
    }
    if (direction == 'asc') {
      updateTableOfContents(++zoomLevel, 'asc');
      return;      
    } else {
      updateTableOfContents(--zoomLevel);
      return;      
    }
  } else {
    // Get the slider text at current level with no spaces and in all lowercase so it can be matched to ToC
    var currentLevelText = Ext.util.Format.lowercase(sliderText[zoomLevel]).replace(/ /gi,'');
    layerChange(currentLevelText);
  }  
}
