
/*******************************************
*
* Menu Class... for multilevel menus
*
*******************************************/
//if(Object.isUndefined(SteveMenu)) { var SteveMenu = { } }

var SteveMenu = Class.create({
  initialize:function() {
    var e = Prototype.emptyFunction;
	this.options = Object.extend({
	  id:'menu',
      itemClassPrefix:'steveMenuItem',
      paneClassPrefix:'steveMenuPane',
	  nodeClassName:'steveMenuNode',
        selectorClass:'steveMenuSelector',
	  isContextMenu:false,
	  menuHideDelay:200,
	  nodeData:null
	}, arguments[0] || { });
	this.timerHash = new Hash();
	this.activatedBy = null;
  },
  buildMenu:function(nodes, depth, paneID, parentName) {
 
    var itemsArray = $A(nodes);

    //sort out the document object so it closes the menu... but only if it is a context menu!!
    $(document).observe('click', this.hideMenu.bind(this));



    var levelContainer = new Element("div",{className:this.options.paneClassPrefix+"_"+depth, id:paneID+"_pane"});

    //add event listeners to levelcontainers to make sure the pane stays open or closed...
	//but only if depth>0 because we want the root pane to stay there no matter what...
	if (depth>0) {
	  levelContainer.observe('Steve.Menu:mouseover',this.paneMouseOver.bind(this)).observe('Steve.Menu:mouseout',this.paneMouseOut.bind(this));
	} else {
      if (this.options.isContextMenu) {
		  levelContainer.observe('Steve.Menu:mouseover',this.paneMouseOver.bind(this)).observe('Steve.Menu:mouseout',this.paneMouseOut.bind(this));
	  } else {
		  levelContainer.observe('Steve.Menu:mouseover',this.paneMouseOver.bind(this));
	  }
  
	}

    //for every node in the array of nodes passed in...
    itemsArray.each(function(node, index) {

      //put item into level container
      var menuItem = new Element("div",{className:this.options.itemClassPrefix+"_"+depth});

      //make the node id reflect its current position
	  node.id=paneID+"_"+node.id;

      //if image then make image, else make label
	  if (node.image) {
		if (node.mouseover_image) {
		  var new_node = Object.extend(new Element("img",{id:node.id, className:node.className+"Image", src:node.image}), {_onleftclick:node.leftclick})
		  .observe('click',this.onClick.bind(this))
		  .observe('mouseover',function(e) { 
		                                     e.element().src=node.mouseover_image;
											 if(parentName!="") {
											   $(parentName).fire("Steve.Menu:childmouseover_image");
											 }
  									       }.bind(this))
		  .observe('mouseout',function(e) {
		                                    e.element().src=node.image;
											if(parentName!="") {
											  $(parentName).fire("Steve.Menu:childmouseout_image");
											}
										  }.bind(this));

        } else {
          var new_node = Object.extend(new Element("img",{id:node.id, className:node.className+"Image", src:node.image}), {_onleftclick:node.leftclick}).observe('click',this.onClick.bind(this));
		}
	  } else {
	    if (node.className) {
	      var new_node = Object.extend(new Element("div",{id:node.id, className:node.className+"Label"}), {_onleftclick:node.leftclick})
		  .observe('click',this.onClick.bind(this)).update(node.label)
		  .observe('mouseover',function(e) {
		                                     e.element().removeClassName(node.className+"Label");
											 e.element().addClassName(node.className+"Label_mouseover");
											 if(parentName!="") {
											   $(parentName).fire("Steve.Menu:childmouseover_label");
											 }
										   }.bind(this))
		  .observe('mouseout',function(e) { 
		                                    e.element().removeClassName(node.className+"Label_mouseover");
											e.element().addClassName(node.className+"Label"); 
											if(parentName!="") {
											  $(parentName).fire("Steve.Menu:childmouseout_label");
											}
										  }.bind(this));

	    } else {
		  var new_node = Object.extend(new Element("div",{id:node.id, className:node.className+"Label"}), {_onleftclick:node.leftclick}).observe('click',this.onClick.bind(this)).update(node.label);
	
		}
	  }

      if (node.children) {
          new_node.observe('mouseover', this.parentItemMouseOver.bind(this));
          new_node.observe('mouseout', this.parentItemMouseOut.bind(this));
		  if(node.mouseover_image) {
		    new_node.observe('Steve.Menu:childmouseout_image', 
			                 function(e) {
							   e.element().src=node.image;
							 }.bind(this));
		    new_node.observe('Steve.Menu:childmouseover_image', 
			                 function(e) {
                               e.element().src=node.mouseover_image;
							 }.bind(this));		  
		  } else if (node.className) {
		    new_node.observe('Steve.Menu:childmouseout_label', 
			                 function(e) {
							   if(e.element().hasClassName(node.className+"Label_mouseover")) {
                                 e.element().removeClassName(node.className+"Label_mouseover");
							     e.element().addClassName(node.className+"Label"); 
							   }
							 }.bind(this));
		    new_node.observe('Steve.Menu:childmouseover_label', 
			                 function(e) {
							   if(e.element().hasClassName(node.className+"Label")) {								 
							     e.element().removeClassName(node.className+"Label"); 
                                 e.element().addClassName(node.className+"Label_mouseover");
							   }
							 }.bind(this));							 
		  }
	  } else {
          new_node.observe('mouseover', this.itemMouseOver.bind(this));
          new_node.observe('mouseout', this.itemMouseOut.bind(this));
	  }


      menuItem.insert(new_node);

	//if there's children then put in the subcontainer and call
      //the function again to build the next branch of the tree,
	  // making sure to adjust the parentsArray
	  
	  
      if(node.children) {
	    menuItem.insert(this.buildMenu(node.children, (depth+1), node.id, new_node.id));
	  }

      levelContainer.insert(menuItem);

    }.bind(this));



    return levelContainer;

  },
  build:function() {

    var rval = this.buildMenu(this.options.nodeData,0,this.options.id+'_root', "");

    if (this.options.isContextMenu==true) {
      $$("."+this.options.selectorClass).invoke('observe', 'contextmenu', function(e){
        e.stop();
        this.showMenu(e);
      }.bind(this));
	}
	
    return rval;
  },
  showMenu:function(e) {
	  
    //set the activatedBy variable for ID of caller
    this.activatedBy = e.element().identify();

    //used for context menu behaviour
	var container = $(this.options.id+'_root_pane');

    //position container
	var x = e.pointerX(),
	    y = e.pointerY(),
	    vpDim = document.viewport.getDimensions(),
		vpOff = document.viewport.getScrollOffsets(),
		elDim = container.getDimensions(),
		elOff = {
			left: ((x + elDim.width + 0) > vpDim.width 
				? (vpDim.width - elDim.width - 0) : x) + 'px',
			top: ((y - vpOff.top + elDim.height) > vpDim.height && (y - vpOff.top) > elDim.height 
				? (y - elDim.height) : y) + 'px'
		};
		container.setStyle(elOff);
	//display positioned container	
	container.setStyle({display:'block'});

  },
  showMenuNonContext:function() {

    var container = $(this.options.id+'_root_pane');
    container.setStyle({display:'block'});

  },
  hideMenu:function(e) {
	if (this.options.isContextMenu) {
	  $(this.options.id+'_root_pane').setStyle({display:'none'});
	}
  },
  showPane:function(key) {
    $(key).setStyle({display:'block'});
  },
  hidePane:function(key) {
    this.timerHash.set(key, setTimeout("document.getElementById('"+key+"').style.display='none';", this.options.menuHideDelay));
  },
  stopHide:function(key) {
    clearTimeout(this.timerHash.get(key));
  },
  itemMouseOver:function(e) {
    e.stop();
	$(e.element().up(1)).fire('Steve.Menu:mouseover');    
  },
  itemMouseOut:function(e) {
    e.stop();  
	$(e.element().up(1)).fire('Steve.Menu:mouseout');
  },
  parentItemMouseOver:function(e) {
    e.stop();
    var key = e.element().identify()+"_pane";
	this.stopHide(key);
	this.showPane(key);
	$(e.element().up(1)).fire('Steve.Menu:mouseover');
  },
  parentItemMouseOut:function(e) {
    e.stop();
    var key = e.element().identify()+"_pane";
	this.hidePane(key);
	$(e.element().up(1)).fire('Steve.Menu:mouseout');
  },
  paneMouseOver:function(e) {
    e.stop();
    var key = e.element().identify();
	this.stopHide(key);
	Event.fire($(e.element().up(1)), 'Steve.Menu:mouseover');
	this.showPane(key);
  },
  paneMouseOut:function(e) {
    e.stop();
    var key = e.element().identify();
	this.hidePane(key);
	Event.fire($(e.element().up(1)), 'Steve.Menu:mouseout');
  },
  onClick:function(e) {
    e.stop();
    if(e.target._onleftclick) {
      e.target._onleftclick(this.activatedBy);
    }
    this.hideMenu();
  }

});

