/**
  Switcher Plugin
  - swaps between 'item' passed in using fade effect
**/
(function($) {

	$.fn.slidingtree=function(options){
		return this.each(function(){			
			if(this._st) return;
			else this._st = plugin_counter;
			var params = $.extend(true, {}, $.fn.slidingtree.defaults, options);
			H[plugin_counter] = {container:this, params:params, items:[]};
			$.slidingtree.setup(plugin_counter);
			plugin_counter ++;

		});
	};
	
	//the default config vars
	$.fn.slidingtree.defaults = { after_function:false, 
	                              active_class:'active', 
	                              end_hide_check_level:"auto", 
	                              node:'li', 
	                              branch:'ul', 
	                              click_trigger:'a', 
	                              speed:'slow'
	                              };
	//the over riden stuff
	$.slidingtree = {
		hash:{}, //the hash used to store all the configs & targets
		/**
     * - loop over everything and give it the right level
     * - hide all but the default level
		 */
		setup:function(index){
		  if(H[index].params.end_hide_check_level == "auto") H[index].params.end_hide_check_level= $.slidingtree.find_depth(index, H[index].container, 0);
		  $.slidingtree.traverse(index,H[index].container, 0, H[index].params.end_hide_check_level);
		  $.slidingtree.triggers(index);
	  },
	  /**
	   * find the depth of the tree and returns the total overall depth -1 (so the leafs at the end are never manipulated by this code)
	   */
	  find_depth:function(index, branch, level){
      H[index].params.end_hide_check_level = level;
      jQ(branch).children(H[index].params.node).each(function(){        
	      jQ(this).children(H[index].params.branch).each(function(){
	        return $.slidingtree.find_depth(index,this,level+1);
	      });	        
	    });
	    return H[index].params.end_hide_check_level -1;
	  },
	  /**
	   * - Loop over the nodes (li) of the branch (ul) passed in
	   * - add node class & level counter on to each leaf thats above the level threshold 
	   *    - the level threshold is used so the end leafs at the lowest level in the tree are never hidden - ie the links to the page
	   * - if the first a it finds does not have a 'active_class' param on it then that branch is hidden 
	   * - if any of this branches(ul) nodes(li) has branchs(ul) then call this function again passing in new level 
	   */
	  traverse:function(index, branch, level, end_level){	
	    jQ(branch).children(H[index].params.node).each(function(){
	      if(!jQ(this).hasClass('node') && level <= H[index].params.end_hide_check_level) jQ(this).addClass('node').addClass('node-'+level);
	      
        if(!jQ(this).find("a:first").hasClass(H[index].params.active_class) && level <= end_level) jQ(this).children(H[index].params.branch).slideUp(H[index].params.speed);
        else jQ(this).children(H[index].params.branch).slideDown(H[index].params.speed);
        jQ(this).find("a:first").attr('rel',level); 
        
	      jQ(this).children(H[index].params.branch).each(function(){
	        return $.slidingtree.traverse(index,this, level+1, end_level);
	      });	        
	    });
	    return;
	  },
	  hide_and_show:function(index){
	    
	  },
	  triggers:function(index){
	    jQ(H[index].container).find(H[index].params.click_trigger).click(function(){
	      // this is a base level item, no sliding, just return true so the page link is followed
        if(!jQ(this).parent().hasClass('node')) return true; 
        else{             
          //find the top node in this tree;
          var current_level = jQ(this).attr('rel'), 
              current_node = jQ(this).parent();                    
          //remove all active classes                 
          jQ(H[index].container).find('.'+H[index].params.active_class).removeClass(H[index].params.active_class);
          //find the right nodes to add active class onto -- so everything above where clicked
          for(var i = current_level; i>=0; i--){
            jQ(current_node).children('a:first').addClass('active');
            if(jQ(current_node).parent().parent().hasClass('node')) current_node = jQ(current_node).parent().parent();
          }
          $.slidingtree.traverse(index,H[index].container, 0, H[index].params.end_hide_check_level+1); //plus one on this so id hides end nodes
        }
      
	      return false;
	    });
	    
	  } 
	  
	};
	var H=$.slidingtree.hash,	jQ = jQuery; ie6=$.browser.msie&&($.browser.version == "6.0"), plugin_counter=0;
})(jQuery);
