/*
  FoldableMenuClass, used for custom menus and playlists
  author: jack@inex.nl
  last update: 15/03/2004
  (c) 2004 Info Pinnacle BV
*/

function FoldableMenuClass(){
  
  // public interface
  this.Init=Init;
  this.BuildMenu=BuildMenu;
  this.SubMenuClick=SubMenuClick;
  this.Next=SelectNextItem;
  this.Previous=SelectPreviousItem;
  this.SelectItem=SelectItem;
  this.GetCurrentItem=GetCurrentItem;
  this.GetItemCount=GetItemCount;
  this.GetItemById=GetItemById;
  this.GetItemIdByValue=GetItemIdByValue;
  this.SetMenuItemHTML=SetMenuItemHTML;
  this.SelectMenuItemByThumb=SelectMenuItemByThumb;
  
  //private variables
  var theTitleArr=new Array();
  var theMenuArray;
  var theMenuDivId="";
  var theObjectName="x";
  var theMenuItemHeight=0;
  var theCurrentItem=0;
  var theCurrentOpenMenu=new Array();
  var thePreviousItem=0;
  var theLastItem;
  var theMenuItemHTML="";
  
  
  function SelectMenuItemByThumb(aSlidenum, aSubstr){
    var sel=-1;
    for(var i=0;i<theMenuArray.length;i++){
      if(theMenuArray[i][ITEM_THUMBNAIL].indexOf(aSubstr)>-1){
        var tmpStr=theMenuArray[i][ITEM_THUMBNAIL].toLowerCase();
        var p=tmpStr.indexOf(aSubstr)+aSubstr.length;
        var tmp=parseInt(theMenuArray[i][ITEM_THUMBNAIL].substr(p).replace(".jpg",""));
        if(aSlidenum>=tmp) sel=i;
      }
    }
    //status="slide:" + aSlidenum +" sel:" + sel + " cur:"+theCurrentItem;
    if(sel>-1 && theMenuArray[sel][ITEM_ID]!=theCurrentItem)SelectItem(theMenuArray[sel][ITEM_ID],false);
  }
  
  //initiate object
  function Init(aMenuDivId, aObjectName, aMenuArray, aMenuItemHeight){
    theMenuArray=aMenuArray;
    theLastItem=findLastItem(theMenuArray);
    theMenuDivId=aMenuDivId;
    theObjectName=aObjectName;
    theMenuItemHeight=aMenuItemHeight;
  }
  
  // find last valid id in the list (searches in submenus too)
  function findLastItem(aArray){for(var i=aArray.length-1;i>=0;i--)if(aArray[i][ITEM_TYPE]=="submenu")return findLastItem(aArray[i][ITEM_SUBMENU]); else return aArray[i][ITEM_ID];}
  
  //returns id of currently selected item
  function GetCurrentItem(){ return theCurrentItem; }
  
  //return number of items in menu
  function GetItemCount(){ return theLastItem; }
  
  // return a menuitem, specified by aId
  function GetItemById(aId){ return getMenuItemById(aId, theMenuArray); }
  
  //return a menu id, specified by aValue [ITEM_ITEMID]
  function GetItemIdByValue(aValue){ return getMenuItemByValue(aValue, theMenuArray)[0]; }
    
  //select previous item in menu
  function SelectPreviousItem(aFlag){while(SelectItem(--theCurrentItem,aFlag)=="submenu");}
  
  //select next item in menu
  function SelectNextItem(aFlag){while(SelectItem(++theCurrentItem,aFlag)=="submenu");}
  
  //selects an item in the menu, set status, (un)folds submenus when necessairly, and raises an event that a new item is selected
  function SelectItem(aId,aFlag){
    if(aId==undefined || theMenuArray.length==0)return null;
    theCurrentItem=aId
    // check boundaries
    if(theCurrentItem>theLastItem)theCurrentItem=1;
    if(theCurrentItem<1)theCurrentItem=theLastItem;
    
    //get menu item, specified by aId
    var myMenuArray=getMenuItemById(theCurrentItem,theMenuArray);
    
    // check if item is in a closed submenu, and if so, open it
    if(myMenuArray[ITEM_PARENTID]>0)
      if(getMenuItemById(myMenuArray[ITEM_PARENTID],theMenuArray)[ITEM_STATUS]=="closed")
        SubMenuClick(myMenuArray[ITEM_PARENTID]);

    // close all other submenus in 'parent' level (only ancestors may be open)
    while(theCurrentOpenMenu.length>0){
      if(theCurrentOpenMenu[theCurrentOpenMenu.length-1][0]!=myMenuArray[ITEM_PARENTID]){
        SubMenuClick(theCurrentOpenMenu.pop()[0]);
      }else break;
    }
      
    //if this item is a submenu, open it if closed. 
    if(myMenuArray[ITEM_TYPE]=="submenu"){
      if(myMenuArray[ITEM_STATUS]=="closed")SubMenuClick(theCurrentItem);
    }else if(thePreviousItem>=0){         
    
      // if its not a submenu, reset status of previous selected item  
      if(thePreviousItem>0){
        var myObj2=HTMLUtil.GetElement(theObjectName+'_MenuItem_'+thePreviousItem+'_Div');
        myObj2.className=getDefaultClassName(myObj2.className);
      }

      // activate new item
      var myObj=HTMLUtil.GetElement(theObjectName+'_MenuItem_'+theCurrentItem+'_Div');
      thePreviousItem=theCurrentItem;
      myObj.className=myObj.className+"-on"; 
      if(aFlag)theEventHandler.Raise(theObjectName,"MENUCHANGE",theCurrentItem);//myMenuArray);
    }
  
    //if(!aFlag)theEventHandler.Raise(theObjectName,"MENUCHANGE",'');
    //return the type of item that just have been processed
    return  myMenuArray[ITEM_TYPE];
  }


  function SetMenuItemHTML(aValue){
    theMenuItemHTML=aValue;  
  }
  
  //(re)build the menu
  function BuildMenu(){
    var output=BuildMenuLayer(1,0,theMenuArray);
    try{HTMLUtil.GetElement(theMenuDivId).innerHTML=output;}catch(e){}
  }
  
  //recursive function for building the menu
  //(might be better to replace it with some sort of redirect to a global function witch then defines/paints a menuitem)
  function BuildMenuLayer(aLayer, aId, aMenuArray){
    var retval="";
    for(var i=0;i<aMenuArray.length;i++){
      if(aMenuArray[i][ITEM_TYPE]=="submenu"){
        retval+='<div class="'+theObjectName+'-MenuSubClass-'+aLayer+'" id="'+theObjectName+'_SubMenuItem_'+aMenuArray[i][ITEM_ID]+'_Div" style="height:'+theMenuItemHeight+'px;">\n';
        retval+='<div class="'+theObjectName+'-MenuSubItemClass-'+aLayer+'" id="'+theObjectName+'_MenuItem_'+aMenuArray[i][ITEM_ID]+'_Div" style="height:'+theMenuItemHeight+'px;" ';
        retval+='onclick="'+theObjectName+'.SelectItem('+aMenuArray[i][ITEM_ID]+',true);">'+aMenuArray[i][ITEM_CAPTION]+'</div>\n';
        retval+=BuildMenuLayer(aLayer+1, aMenuArray[i][ITEM_ID], aMenuArray[i][ITEM_SUBMENU])+'</div>\n';
      }else{
        if(theMenuItemHTML!=""){
          var myItem=new String(theMenuItemHTML);
          myItem=myItem.replace(new RegExp(/@@__CAPTION/g),aMenuArray[i][ITEM_CAPTION]);
          myItem=myItem.replace(new RegExp(/@@__LAYER/g),aLayer);
          myItem=myItem.replace(new RegExp(/@@__ID/gi),aMenuArray[i][ITEM_ID]);
          myItem=myItem.replace(new RegExp(/@@__ITEMID/g),aMenuArray[i][ITEM_ITEMID]);
          var myTitle=new String(aMenuArray[i][ITEM_TITLE]).split("@@__BR__@@");
          myItem=myItem.replace(new RegExp(/@@__TITLE_1/g),myTitle[0]);
          myItem=myItem.replace(new RegExp(/@@__TITLE_2/g),myTitle[1]);
          myItem=myItem.replace(new RegExp(/@@__TITLE_3/g),myTitle[2]);
          myItem=myItem.replace(new RegExp(/@@__TITLE_4/g),myTitle[3]);
          myItem=myItem.replace(new RegExp(/@@__THUMBNAIL/g),aMenuArray[i][ITEM_THUMBNAIL]);
          retval+=myItem;
        }else{
          retval+='<div class="'+theObjectName+'-MenuItemClass-'+aLayer+'" id="'+theObjectName+'_MenuItem_'+aMenuArray[i][ITEM_ID]+'_Div" style="height:'+theMenuItemHeight+'px;" ';
          retval+=' onclick="'+theObjectName+'.SelectItem('+aMenuArray[i][ITEM_ID]+',true);">';
          if(aMenuArray[i].length>ITEM_THUMBNAIL) retval+='<table width="100%" cellpadding="0" cellspacing="0" align="right"><tr><td><td align="right"><img height="'+theMenuItemHeight+'" src="'+aMenuArray[i][ITEM_THUMBNAIL]+'"/></td></tr></table>';
          retval+=aMenuArray[i][ITEM_CAPTION];
          retval+='</div>\n';
          //alert(myItem+"\n\n"+retval);
        }
      }
    }
    return retval;
  }
  
  //internal recursive lookup for menuitem in menuarray by id
  function getMenuItemById(aId,aArray){
    var retval=false;
    for(var i=0;i<aArray.length;i++)
      if(aArray[i][ITEM_ID]==aId) return aArray[i];
     
    for(var i=0;i<aArray.length;i++)
      if(aArray[i][ITEM_TYPE]=="submenu"){
        retval=getMenuItemById(aId,aArray[i][ITEM_SUBMENU]);
        if(retval!=false)break;
      }
    return retval;
  }
  
  //internal recursive lookup for menuitem in menuarray by value
  function getMenuItemByValue(aValue,aArray){
    var retval=false;
    for(var i=0;i<aArray.length;i++)
      if(aArray[i][ITEM_ITEMID]==aValue) return aArray[i];
    for(var i=0;i<aArray.length;i++)
      if(aArray[i][ITEM_TYPE]=="submenu"){
        retval=getMenuItemByValue(aValue,aArray[i][ITEM_SUBMENU]);
        if(retval!=false)break;
      }
    return retval;
  }
  
  //a submenuitem is clicked, repaint the menu with new submenu open unfold/fold sother submenus  if neccesairly
  function SubMenuClick(aId){
    var myMenuArray=getMenuItemById(aId,theMenuArray);
    var myLength=myMenuArray[ITEM_SUBMENU].length;
    var myObj=HTMLUtil.GetElement(theObjectName+'_SubMenuItem_'+aId+'_Div');
    if(myMenuArray[ITEM_STATUS]=="closed"){  
      
      //unfold submenus from parent level to level of new submenu
      while(theCurrentOpenMenu.length>0){
        if(theCurrentOpenMenu[theCurrentOpenMenu.length-1][0]!=myMenuArray[ITEM_PARENTID]){
          SubMenuClick(theCurrentOpenMenu.pop()[0]);
        }else break;
      }
      theCurrentOpenMenu.push(new Array(myMenuArray[ITEM_ID],myMenuArray[ITEM_PARENTID]));
      UnFoldMenu(aId,myMenuArray);
      if(myMenuArray[ITEM_PARENTID]>0)UnfoldParent(myMenuArray[ITEM_PARENTID],myLength);
      myObj.style.pixelHeight=(theMenuItemHeight*(myLength+1));
    }else{
      
      //fold submenus for parents peers and its siblings
      FoldMenu(aId,myMenuArray);
      FoldChild(aId);
      if(myMenuArray[ITEM_PARENTID]>0)FoldParent(myMenuArray[ITEM_PARENTID],myLength);
      myObj.style.pixelHeight=theMenuItemHeight;
    }
  }
  
  //return value off the classname without exensions defining its state
  function getDefaultClassName(aName){
    var myClassName=new String(aName);
    if(myClassName.substr(myClassName.length-3,myClassName.length)=="-on")
        myClassName=myClassName.substr(0,myClassName.length-3);
    return myClassName;
  }
  
  //fold a menu
  function FoldMenu(aId,aSubMenuArray){
    if(aSubMenuArray[ITEM_STATUS]=="open"){
      var myObj=HTMLUtil.GetElement(theObjectName+'_MenuItem_'+aId+'_Div');
      aSubMenuArray[ITEM_STATUS]="closed";
      myObj.className=getDefaultClassName(myObj.className);
      myObj.innerHTML=aSubMenuArray[ITEM_CAPTION];
    }
  }
  
  //unfold a menu
  function UnFoldMenu(aId,aSubMenuArray){
    if(aSubMenuArray[ITEM_STATUS]=="closed"){
      var myObj=HTMLUtil.GetElement(theObjectName+'_MenuItem_'+aId+'_Div');
      aSubMenuArray[ITEM_STATUS]="open";
      myObj.className+="-on";
      myObj.innerHTML=aSubMenuArray[ITEM_CAPTION];
    }
  }
  
  //fold child
  function FoldChild(aId){
    var myMenuArray=getMenuItemById(aId,theMenuArray);
    for(var i=0;i<myMenuArray[ITEM_SUBMENU].length;i++)
      if(myMenuArray[ITEM_SUBMENU][i][ITEM_TYPE]=="submenu")
        if(myMenuArray[ITEM_SUBMENU][i][ITEM_STATUS]=="open") 
          SubMenuClick(myMenuArray[ITEM_SUBMENU][i][ITEM_ID]);
  }
  
  //unfold parent
  function UnfoldParent(aId,aLength){
    var myMenuArray=getMenuItemById(aId,theMenuArray);
    if(aLength>0){
      var myObj=HTMLUtil.GetElement(theObjectName+'_SubMenuItem_'+aId+'_Div');
      myObj.style.pixelHeight+=theMenuItemHeight*aLength;
      if(myMenuArray[ITEM_PARENTID]>0)UnfoldParent(myMenuArray[ITEM_PARENTID],aLength);
    }
  }

  //fold parent
  function FoldParent(aId,aLength){
    var myMenuArray=getMenuItemById(aId,theMenuArray);
    if(aLength>0){
      var myObj=HTMLUtil.GetElement(theObjectName+'_SubMenuItem_'+aId+'_Div');
      myObj.style.pixelHeight-=theMenuItemHeight*aLength;
      if(myMenuArray[ITEM_PARENTID]>0)FoldParent(myMenuArray[ITEM_PARENTID],aLength);
    }
  }
  
}