//Made by Szilvássy, Gábor in Winter of 2005
//
//Menu Definition
//  popup = "up"    | "upLeft"    | "upCenter"    | "upRight"   |
//          "right" | "rightDown" | "rightCenter" | "rigthUp"   |
//          "down"  | "downLeft"  | "downCenter"  | "downRight" |
//          "left"  | "leftDown"  | "leftCenter"  | "leftUp"    |
//          "fixed" | "float"


function createMenu(menuImpId, winImpId, classArray, delay)
 {this.id = menuImpId;         //menu implement id
  this.win = winImpId;         //for window event

  /* check criterias */
  if (typeof(menuImpId)!='string') {alert("menu implement id is undefined, check the parameters"); return;}
  if (typeof(winImpId)!='object') {alert("menu implement windows object for mouse coordinate is undefined, check the parameters"); return;}
  if (classArray.length<1) {alert("menu class sources are undefined, check the parameters"); return;}

  /* define defaults */
  this.timerID = null;
  this.interval = (isNaN(delay))?999:delay;

  /* define classes */
  this.on  = new Array(classArray.length-1);
  this.off = new Array(classArray.length-1);
  this.rightClickMenuId = null;
  this.arrowPos = new Array(3);
  this.arrowPos[0] = "top right";
  this.arrowPos[1] = "center right";
  this.arrowPos[2] = "bottom right";
  this.arrowPos[3] = "center left";
  this.arrow = new Array(3);
  for (i=0;i<classArray.length;i++)
    {strArray = classArray[i].split("|");
     if (!strArray[0])
       {this.arrowOn  = (strArray[1]=="true")?1:0;
        this.menuOn   = strArray[2];
        this.itemOn   = strArray[3];
        this.itemBOn  = strArray[4];
        this.arrow[0] = strArray[5];
        this.arrow[1] = strArray[6];
        this.arrow[2] = strArray[7];
        this.arrow[3] = strArray[8];
       }
      else
       {this.off[strArray[0]] = strArray[1];
        this.on[strArray[1]]  = strArray[0];
       }
    }

  /* define menus */
  this.menus = new Array();
  this.curMenuId = null;

  /* define events */
  this.win.clickCalls.push(this.id+".focus('')");
  this.win.clickRCalls.push(this.id+".rightClick()");
  this.win.resizeCalls.push(this.id+".resize()");
  this.win.cancelCalls.push(this.id+".cancel()");

  /* define methods */

  /* init root menus */
  this.init = function (dataArray)
   {/* check criterias */
    if (dataArray.length<1) {alert("menu data sources are undefined, check the parameters"); return;}

    for (i=0;i<dataArray.length;i++)
      {strArray = dataArray[i].split("|");
       this.set('',strArray[0],strArray[1],strArray[2],strArray[3],strArray[4],strArray[5]);
       this.setItems('',strArray[0]);
      }
   }


  /* set menu container */
  this.set = function (itemObj,menuId,typeId,arrowOn,menuOn,itemOn,itemBOn)
   {this.menus[menuId] = new Object;
    submenu = this.menus[menuId];
    submenu.obj = document.getElementById(menuId);
    if (submenu.obj==null) {alert("id="+menuId+"   submenu not exist");return;}
    submenu.type      = typeId;
    submenu.parentId  = (itemObj)?itemObj.parentNode.id:null;
    submenu.dot       = new vec(0, 0);
    submenu.dim       = new vec(0, 0);
    submenu.callerDot = new vec(0, 0);
    submenu.callerDim = new vec(0, 0);
    submenu.resize    = true;

    submenu.typeInd = (submenu.type=="up"    || submenu.type=="upLeft"    || submenu.type=="upCenter"    || submenu.type=="upRight")   ? 0 :
                      (submenu.type=="right" || submenu.type=="rightDown" || submenu.type=="rightCenter" || submenu.type=="rigthUp")   ? 1 :
                      (submenu.type=="down"  || submenu.type=="downLeft"  || submenu.type=="downCenter"  || submenu.type=="downRight") ? 2 :
                      (submenu.type=="left"  || submenu.type=="leftDown"  || submenu.type=="leftCenter"  || submenu.type=="leftUp")    ? 3 : null;
    if (submenu.type!="fixed") submenu.obj.style.position="absolute";

    submenu.arrowOn = (arrowOn==null || arrowOn=="")?this.arrowOn:(arrowOn==true)?1:0;
    submenu.menuOn  = (menuOn==null  || menuOn=="") ?this.menuOn :menuOn;
    submenu.itemOn  = (itemOn==null  || itemOn=="") ?this.itemOn :itemOn;
    submenu.itemBOn = (itemBOn==null || itemBOn=="")?this.itemBOn:itemBOn;

    if (itemObj!=null && itemObj!="") itemObj.onmouseover = new Function(this.id+".setItems(this,'"+menuId+"')");
   }


  /* set menu classes and events */
  this.setItems = function (itemObj,menuId)
   {menu = this.menus[menuId]
    if (!menu.obj.className && menu.menuOn!=null) menu.obj.className = this.off[menu.menuOn];

    /* set menu items classes and events */
    var node = menu.obj.firstChild;
    while (node)
     {if (!node.onclick && !node.onmouseover)                                                //blank menu item
        {if (!node.className && menu.itemBOn!=null) node.className = this.off[menu.itemBOn];
         node.onmouseover = new Function(this.id+".focus(this)");
        }
       else
        {if (!node.className && menu.itemOn!=null) node.className = this.off[menu.itemOn];
         if (!node.onmouseover) node.onmouseover = new Function(this.id+".focus(this)");     //command menu Item
          else                                                                               //submenu item
            {node.onmouseover();
             if (submenu.typeInd!=null && menu.arrowOn && this.arrow[submenu.typeInd])
               {node.style.backgroundImage = "url("+this.arrow[submenu.typeInd]+")";
                node.style.backgroundRepeat = "no-repeat";
                node.style.backgroundPosition = this.arrowPos[submenu.typeInd];
               }
            }
        }

      node.onmouseout = new Function(this.id+".blurDelay(this)");
      node = node.nextSibling;
     }

    /* set caller Item event */
    if (itemObj!=null && itemObj!="")
      {itemObj.onmouseover = new Function(this.id+".show(this,'"+menuId+"')");
       itemObj.onmouseover();
      }
     else if (menu.type=="float") this.rightClickMenuId = menu.obj.id;
     else this.place(itemObj,menu);                                     //fixed root menus
   }


  /* set menu position */
  this.place = function (itemObj,menu)
   {if (menu.type=="float")                                             //rightClick menu
      {menu.callerDot.set(null,null);
       menu.callerDim.set(null,null);
       menu.dot.set(this.win.mouse.x-8, this.win.mouse.y-8);
       menu.dim.set(menu.obj.offsetWidth, menu.obj.offsetHeight);
      }

     else if (menu.type=="fixed" || itemObj==null || itemObj=="")       //fixed or root menu
      {menu.dot.set(0,0);
       menu.dim.set(menu.obj.offsetWidth, menu.obj.offsetHeight);
       var objTrail=menu.obj;
       while(objTrail)
         {menu.dot.x += objTrail.offsetLeft;
          menu.dot.y += objTrail.offsetTop;
          objTrail=objTrail.offsetParent;
         }
      }

     else                                                              //depend menu from parent tag
      {menu.callerDot.set(this.menus[itemObj.parentNode.id].dot.x+itemObj.offsetLeft, this.menus[itemObj.parentNode.id].dot.y+itemObj.offsetTop);
       menu.callerDim.set(itemObj.offsetWidth, itemObj.offsetHeight);
       menu.dot.set(menu.callerDot.x, menu.callerDot.y);
       menu.dim.set(menu.obj.offsetWidth, menu.obj.offsetHeight);

       if (menu.typeInd==1)       menu.dot.x += menu.callerDim.x;
        else if (menu.typeInd==3) menu.dot.x -= menu.dim.x;
        else if (menu.type=="upLeft" || menu.type=="downLeft")     menu.dot.x +=  menu.callerDim.x - menu.dim.x;
        else if (menu.type=="upCenter" || menu.type=="downCenter") menu.dot.x += (menu.callerDim.x - menu.dim.x)/2;

       if (menu.typeInd==0)       menu.dot.y -= menu.dim.y;
        else if (menu.typeInd==2) menu.dot.y += menu.callerDim.y;
        else if (menu.type=="rightUp" || menu.type=="leftUp")         menu.dot.y +=  menu.callerDim.y - menu.dim.y;
        else if (menu.type=="rightCenter" || menu.type=="leftCenter") menu.dot.y += (menu.callerDim.y - menu.dim.y)/2;
      }

    if (menu.type!="fixed")
      {//correct out of the border overlay
       if (menu.typeInd==0 || menu.typeInd==2) menu.callerDot.x = null;
       if (menu.typeInd==1 || menu.typeInd==3) menu.callerDot.y = null;
       this.win.checkBorder(menu.dot, menu.dim, menu.callerDot, menu.callerDim);

       //set the menu coordinate
       menu.obj.style.left = menu.dot.x+"px";
       menu.obj.style.top  = menu.dot.y+"px";
      }

    //set the menu resize
    menu.resize=(menu.type=="float")?true:false;
   }


  /* focus menu */
  this.focus = function(itemObj)
   {if (itemObj) itemObj.className = this.on[itemObj.className];          //highlight
    if (this.timerId) clearTimeout(this.timerId);                         //stop delay hide
    if (itemObj) this.blur(this.menus[itemObj.parentNode.id].obj.id);     //hide up to menu parent
     else this.blur("");                                                  //hide all others
   }


  /* show menu */
  this.show = function(itemObj,menuId)
   {this.focus(itemObj);                                                            //stop delay hide
    this.menus[menuId].obj.className = this.on[this.menus[menuId].obj.className];   //display menu
    if (this.menus[menuId].resize==true) this.place(itemObj,this.menus[menuId]);    //re-position menu
    this.curMenuId = menuId;
   }


  /* hide menu */
  this.blur = function(menuId)
   {curId=this.curMenuId;
    while (curId!=menuId && curId!=null)
       {this.menus[curId].obj.className=this.off[this.menus[curId].obj.className];
        curId=this.menus[curId].parentId;
       }
    this.curMenuId=curId;
   }


  /* delay hide menu */
  this.blurDelay = function(itemObj)
   {if (itemObj) itemObj.className = this.off[itemObj.className];         //lowlight
    this.timerId = setTimeout(this.id+".blur('')", this.interval);        //delay hiding
   }


  /* click menu */
  this.click = function(itemObj,act)
   {if (itemObj) itemObj.className = this.off[itemObj.className];         //lowlight
    this.win.open(act);
   }


  /* right click menu */
  this.rightClick = function()
   {if (this.rightClickMenuId!=null)
      {this.show("",this.rightClickMenuId)
      }
   }


  /* resize menu */
  this.resize = function()
   {this.focus('');
    for (var i in this.menus)
      {if (this.menus[i].type=="fixed") this.place("",this.menus[i]);
        else this.menus[i].resize=true;
      }
   }


  /* cancel menu */
  this.cancel = function()
    {this.focus('');
     this.id = null;
    }
 }