var nStyle = new Array;
var hStyle = new Array;
var nLayer = new Array;
var hLayer = new Array;
var nTCode = new Array;

var AnimStep = 0;
var AnimHnd = 0;
var HTHnd = new Array;
var DoFormsTweak = true;

var mFrame;
var cFrame;

var OpenMenus = new Array;
var SelCommand;
var nOM = 0;

var mX;
var mX2;
var mY;
var xOff = 0;

var HideSpeed = 300;

var BV=navigator.appVersion;
BV=parseFloat(BV.indexOf('MSIE')>0?BV.split(';')[1].split(' ')[2]:BV.split(' ')[0]);
var BN=window.navigator.appName;
var IsWin=(navigator.userAgent.indexOf('Windows')!=-1)?true:false;
var OP=(navigator.userAgent.indexOf('Opera')!=-1&&BV>=4)?true:false;
var SM=(BN.indexOf('Netscape')!=-1&&(BV>=5)||OP)?true:false;
var NS=(BN.indexOf('Netscape')!=-1&&!SM)?true:false;
var IE=(BN.indexOf('Explorer')!=-1&&(BV>=4)||SM)?true:false;


    if((!IsWin&&IE)||SM) {
        frames.self = window;
        frames.top = top;
    }

    if(IE)
        xOff = (SM&&!OP)?-9:2;
    cFrame = eval(frames['self']);

    var fx = 0;

    function GetCurCmd(e) {
//IE
//This function will return the current command under the mouse pointer.
//It will return null if the mouse is not over any command.
//------------------------------
//Version 1.5
//
        if(SM)
            var cc = e;
        else
            var cc = mFrame.window.event.srcElement;
        while(cc.id=="") {
            cc = cc.parentElement;
            if(cc==null)
                break;
        }
        return cc;
    }

    function HoverSel(mode, imgLName, imgRName, e) {
//IE
//This is the function called every time the mouse pointer is moved over a command.
//------------------------------
//mode: 0 if the mouse is moving over the command and 1 if is moving away.
//imgLName: Name of the left image object, if any.
//imgRName: Name of the right image object, if any.
//------------------------------
//Version 10.0
//
        var imgL = new Image;
        var imgLRsc = new Image;
        var imgR = new Image;
        var imgRRsc = new Image;
        var nStyle;
        var mc;

        if(mode==0 && OpenMenus[nOM].SelCommand!=null)
            HoverSel(1);

        if(imgLName!="_")
            var imgL = eval("mFrame.document.images['"+imgLName+"']");
        if(imgRName!="_")
            var imgR = eval("mFrame.document.images['"+imgRName+"']");

        if(mode==0) {
            mc = GetCurCmd(e);
            if(nOM>1)
                if(mc==OpenMenus[nOM-1].SelCommand)
                    return false;
            if(OpenMenus[nOM].SelCommand || nOM>1)
                while(!InMenu())
                    Hide();
            if(imgLName!='_') imgLRsc = eval(imgLName+"On");
            if(imgRName!='_') imgRRsc = eval(imgRName+"On");
            OpenMenus[nOM].SelCommand = mc;
            OpenMenus[nOM].SelCommandPar = [imgLName,imgRName,SM?mc.getAttribute("style"):mc.style.cssText];
            if(SM)
                mc.setAttribute("style", GetCStyle(mc.style) + hStyle[mc.id]);
            else
                mc.style.cssText = GetCStyle(mc.style) + hStyle[mc.id];
        } else {
            mc = (mode==1)?OpenMenus[nOM].SelCommand:OpenMenus[nOM].Opener;
            imgLName = (mode==1)?OpenMenus[nOM].SelCommandPar[0]:OpenMenus[nOM].OpenerPar[0];
            imgRName = (mode==1)?OpenMenus[nOM].SelCommandPar[1]:OpenMenus[nOM].OpenerPar[1];
            nStyle = (mode==1)?OpenMenus[nOM].SelCommandPar[2]:OpenMenus[nOM].OpenerPar[2];
            mc.style.background = "";
            if(SM)
                mc.setAttribute("style", nStyle);
            else
                mc.style.cssText = nStyle;
            if(imgLName!='_') imgLRsc = eval(imgLName+"Off");
            if(imgRName!='_') imgRRsc = eval(imgRName+"Off");
            window.status = "";
            OpenMenus[nOM].SelCommand = null;
        }

        if(imgLName!='_') {
            imgL = eval("mFrame.document.images."+imgLName);
            imgL.src = imgLRsc.src;
        }
        if(imgRName!='_') {
            imgR = eval("mFrame.document.images."+imgRName);
            imgR.src = imgRRsc.src;
        }

        return true;
    }

    function NSHoverSel(mode, mc, bcolor) {
//NS
//This is the function called every time the mouse pointer is moved over or away from a command.
//------------------------------
//mode: 0 if the mouse is moving over the command and 1 if is moving away.
//mc: Name of the layer that corresponds to the selected command.
//n: Unique ID that identifies this command. Used to retrieve the data from the nLayer or hLayer array.
//bcolor: Background color of the command. Ignored if the group uses a background image.
//w: Width of the command's layer.
//h: Height of the command's layer.
//------------------------------
//Version 11.0
//
        var n;
        var LayerHTM;
        if(mode==0 && OpenMenus[nOM].SelCommand!=null)
            NSHoverSel(1);

        if(mode==0) {
            mc = mc.parentLayer.layers[mc.name.substr(0, mc.name.indexOf("EH"))];
            n = CBparseInt(mc.name.substr(2));
            if(nOM>1)
                if(mc==OpenMenus[nOM-1].SelCommand)
                    return false;
            while(!InMenu()&&nOM>1)
                Hide();
            LayerHTM = hLayer[n];
            OpenMenus[nOM].SelCommand = mc;
            OpenMenus[nOM].SelCommandPar = mc.bgColor;
            mc.bgColor = bcolor;
        } else {
            mc = (mode==1)?OpenMenus[nOM].SelCommand:OpenMenus[nOM].Opener;
            bcolor = (mode==1)?OpenMenus[nOM].SelCommandPar:OpenMenus[nOM].OpenerPar;
            n = CBparseInt(mc.name.substr(2));
            LayerHTM = nLayer[n];
            if(mc.parentLayer.background.src!="")
                mc.bgColor = null;
            else
                mc.bgColor = bcolor;
            window.status = "";
            OpenMenus[nOM].SelCommand = null;
        }
        mc.clip.width = mc.parentLayer.clip.width - 2;
        mc.document.open();
        mc.document.write(LayerHTM);
        mc.document.close();

        return true;
    }

    function Hide() {
//IE,NS
//This function hides the last opened group and it keeps hiding all the groups until
//no more groups are opened or the mouse is over one of them.
//Also takes care of reseting any highlighted commands.
//------------------------------
//Version 3.5
//
        window.clearTimeout(HTHnd[nOM]);HTHnd[nOM] = 0;
        window.clearTimeout(AnimHnd);AnimHnd = 0;

        if(OpenMenus[nOM].SelCommand!=null) {
            if(IE) HoverSel(1);
            if(NS) NSHoverSel(1);
        }
        if(OpenMenus[nOM].Opener!=null) {
            if(IE) HoverSel(3);
            if(NS) NSHoverSel(3);
        }

        OpenMenus[nOM].visibility = "hidden";
        nOM--;

        if(nOM>0)
            if(!InMenu())
                HTHnd[nOM] = window.setTimeout("Hide()", HideSpeed/4);

        if(nOM==0)
            FormsTweak("visible");
    }

    function ShowMenu(mName, x, y, isCascading) {
//
//IE,NS
//This is the main function to show the menus when a hotspot is triggered or a cascading command is activated.
//------------------------------
//mName: Name of the <div> or <layer> to be shown.
//x: Left position of the menu.
//y: Top position of the menu.
//isCascading: True if the menu has been triggered from a command, and not from a hotspot.
//------------------------------
//Version 14.5
//
        window.clearTimeout(CBparseInt(HTHnd[nOM]));HTHnd[nOM] = 0;
        x = CBparseInt(x);y = CBparseInt(y);

        if(AnimHnd && nOM>0) {
            AnimStep=101;
            Animate();
        }
        if(IE)
            if(SM)
                var Menu = mFrame.document.getElementById(mName);
            else
                var Menu = mFrame.document.all[mName];
        if(NS)
            var Menu = mFrame.document.layers[mName];
        if(!Menu)
            return false;
        if(IE)
            Menu = Menu.style;
        if(Menu==OpenMenus[nOM])
            return false;

        if(!isCascading)
            HideAll();

        Menu.Opener = nOM>0?OpenMenus[nOM].SelCommand:null;
        Menu.OpenerPar = nOM>0?OpenMenus[nOM].SelCommandPar:null;
        Menu.SelCommand = null;
        if(OP) {
            Menu.width = Menu.pixelWidth;
            Menu.height = Menu.pixelHeight;
        }

        var pW = GetWidthHeight()[0] + GetLeftTop()[0];
        var pH = GetWidthHeight()[1] + GetLeftTop()[1];

        if(IE) {
            if(isCascading) {
                x = CBparseInt(OpenMenus[nOM].left) + CBparseInt(OpenMenus[nOM].width) - 6;
                y = y + CBparseInt(OpenMenus[nOM].top) - 5;
                Menu.left = (x+CBparseInt(Menu.width)>pW)?CBparseInt(OpenMenus[nOM].left) - CBparseInt(Menu.width) + 6:x;
                Menu.top =  (y+CBparseInt(Menu.height)>pH)?pH - CBparseInt(Menu.height):y;
            } else {
                Menu.left = (x+CBparseInt(Menu.width)>pW)?pW - CBparseInt(Menu.width):x;
                Menu.top =  (y+CBparseInt(Menu.height)>pH)?pH - CBparseInt(Menu.height):y;
            }
            if(IsWin&&!SM)
                Menu.clip = "rect(0 0 0 0)";
        }
        if(NS) {
            if(isCascading) {
                x = OpenMenus[nOM].left + OpenMenus[nOM].clip.width - 6;
                y = OpenMenus[nOM].top + OpenMenus[nOM].SelCommand.top;
                x = (x+Menu.w>pW)?OpenMenus[nOM].left - Menu.w + 6:x;
                y = (y+Menu.h>pH)?pH - Menu.h:y;
            } else {
                x = (x+Menu.w>pW)?pW - Menu.w:x;
                y = (y+Menu.h>pH)?pH - Menu.h:y;
            }
            Menu.clip.width = 0;
            Menu.clip.height = 0;
            Menu.moveToAbsolute(x,y);
        }
        if(isCascading)
            Menu.zIndex = CBparseInt(OpenMenus[nOM].zIndex) + 1;
        Menu.visibility = "visible";
        OpenMenus[++nOM] = Menu;
        HTHnd[nOM] = 0;
        if((IE&&IsWin&&!SM)||NS)
            AnimHnd = window.setTimeout("Animate()", 10);
        FormsTweak("hidden");

        return true;
    }

    function Animate() {
//IE,NS
//This function is called by ShowMenu every time a new group must be displayed and produces the predefined unfolding effect.
//Currently is disabled for Navigator, because of some weird bugs we found with the clip property of the layers.
//------------------------------
//Version 1.9
//
        var r = '';
        var nw = nh = 0;
        switch(fx) {
            case 1:
                if(IE) r = "0 " + AnimStep + "% " + AnimStep + "% 0";
                if(NS) nw = AnimStep; nh = AnimStep;
                break;
            case 2:
                if(IE) r = "0 100% " + AnimStep + "% 0";
                if(NS) nw = 100; nh = AnimStep;
                break;
            case 3:
                if(IE) r = "0 " + AnimStep + "% 100% 0";
                if(NS) nw = AnimStep; nh = 100;
                break;
            case 0:
                if(IE) r = "0 100% 100% 0";
                if(NS) nw = 100; nh = 100;
                break;
        }
        if(OpenMenus[nOM]) {
            with(OpenMenus[nOM]) {
                if(IE)
                    clip =  "rect(" + r + ")";
                if(NS) {
                    clip.width = w*(nw/100);
                    clip.height = h*(nh/100);
                }
            }
            AnimStep += 20;
            if(AnimStep<=100)
                AnimHnd = window.setTimeout("Animate()",25);
            else {
                window.clearTimeout(AnimHnd);
                AnimStep = 0;
                AnimHnd = 0;
            }
        }
    }

    function InMenu() {
//IE,NS
//This function returns true if the mouse pointer is over the last opened menu.
//------------------------------
//Version 1.6
//
        var m = OpenMenus[nOM];
        if(!m)
            return false;
        if(IE&&!SM)
            SetPointerPos();
        var l = CBparseInt(m.left) + xOff;
        var r = l+(IE?CBparseInt(m.width):m.clip.width) - xOff;
        var t = CBparseInt(m.top) + xOff;
        var b = t+(IE?CBparseInt(m.height):m.clip.height) - xOff;
        return ((mX>=l && mX<=r) && (mY>=t && mY<=b));
    }

    function SetPointerPos(e) {
//IE,NS
//This function sets the mX and mY variables with the current position of the mouse pointer.
//------------------------------
//e: Only used under Navigator, corresponds to the Event object.
//------------------------------
//Version 1.2
//
        if(IE) {
            if(!SM) {
                if(mFrame!=cFrame||event==null)
                    if(mFrame.window.event==null)
                        return;
                    else
                        e = mFrame.window.event;
                else
                    e = event;
            }
            mX = e.clientX + GetLeftTop()[0];
            mY = e.clientY + GetLeftTop()[1];
        }
        if(NS) {
            mX = e.pageX;
            mY = e.pageY;
            mX2 = mX;
        }
    }


    function HideMenus(e) {
//IE,NS
//This function checks if the mouse pointer is on a valid position and if the current menu should be kept visible.
//The function is called every time the mouse pointer is moved over the document area.
//------------------------------
//e: Only used under Navigator, corresponds to the Event object.
//------------------------------
//Version 24.5
//
        if(nOM>0) {
            SetPointerPos(e);
            if(OpenMenus[nOM].SelCommand!=null)
                while(!InMenu() && !HTHnd[nOM]) {
                    HTHnd[nOM] = window.setTimeout("Hide()", HideSpeed);
                    if(nOM==0)
                        break;
                }
        }
    }

    function FormsTweak(state) {
//IE
//This is an undocumented function, which can be used to hide every listbox (or combo) element on a page.
//This can be useful if the menus will be displayed over an area where is a combo box, which is an element that cannot be placed behind the menus and it will always appear over the menus resulting in a very undesirable effect.
//------------------------------
//Version 2.0
//
        if(DoFormsTweak && IE)
            for(var f = 0; f <= (mFrame.document.forms.length - 1); f++)
                for(var e = 0; e <= (mFrame.document.forms[f].elements.length - 1); e++)
                    if(mFrame.document.forms[f].elements[e].type=="select-one")
                        mFrame.document.forms[f].elements[e].style.visibility = state;
    }

    function execURL(url, tframe) {
//IE,NS
//This function is called every time a command is triggered to jump to another page or execute some javascript code.
//------------------------------
//url: Encrypted URL that must be opened or executed.
//tframe: If the url is a document location, tframe is the target frame where this document will be opened.
//------------------------------
//Version 1.1
//
        HideAll();
        window.setTimeout("execURL2('" + url + "', '" + tframe + "')", 100);
    }

    function execURL2(url, tframe) {
//IE,NS
//This function is called every time a command is triggered to jump to another page or execute some javascript code.
//------------------------------
//url: Encrypted URL that must be opened or executed.
//tframe: If the url is a document location, tframe is the target frame where this document will be opened.
//------------------------------
//Version 1.1
//
        var fObj = eval(rStr(tframe));
        url = rStr(url);
        url.indexOf("javascript")!=url.indexOf("vbscript")?eval(url):fObj.location.href = url;
    }

    function rStr(s) {
//IE,NS
//This function is used to decrypt the URL parameter from the triggered command.
//------------------------------
//Version 1.1
//
        s = xrep(s,"\x1E","'");
        s = xrep(s,"\x1D","\x22");
        s = xrep(s,"\x1C",",");
        return s;
    }

    function xrep(s, f, n) {
//IE,NS
//This function looks for any occurrence of the f string and replaces it with the n string.
//------------------------------
//Version 1.0
//
        var tmp = s.split(f);
        return tmp.join(n);
    }

    function hNSCClick(e) {
//NS
//This function executes the selected command's trigger code.
//------------------------------
//Version 1.0
//
        eval(this.TCode);
    }

    function CBparseInt(n) {
//IE,NS
//This function fixes a bug in Navigator's parseInt() function for the Mac.
//------------------------------
//Version 1.3
//
        if(typeof(n)=="number"||typeof(n)=="string")
            return (!IsWin&&!SM?n:parseInt(n))*1;
        return 0;
    }

    function HideAll() {
//IE,NS
//This function will hide all the currently opened menus.
//------------------------------
//Version 1.0
//
        while(nOM>0)
            Hide();
    }

    function GetLeftTop() {
//IE,NS
//This function returns the scroll bars position on the menus frame.
//------------------------------
//Version 2.0
//
        if(IE)
            return [OP?0:SM?mFrame.scrollX:mFrame.document.body.scrollLeft,OP?0:SM?mFrame.scrollY:mFrame.document.body.scrollTop];
        if(NS)
            return [mFrame.pageXOffset,mFrame.pageYOffset];
    }

    function tHideAll() {
//IE,NS
//This function is called when the mouse is moved away from a hotspot to close any opened menu.
//------------------------------
//Version 1.0
//
        HTHnd[nOM] = window.setTimeout("if(!InMenu()&&nOM==1)HideAll(); else HTHnd[nOM]=0;", HideSpeed);
    }

    function GetWidthHeight() {
//IE,NS
//This function returns the width and height of the menus frame.
//------------------------------
//Version 2.0
//
        if(IE&&!SM)
            return [mFrame.document.body.clientWidth,mFrame.document.body.clientHeight];
        if(NS||SM)
            return [mFrame.innerWidth,mFrame.innerHeight];
    }

    function GetCStyle(cmc) {
//IE,SM
//This functions completes the style of command with all the common
//parameters from the original style code.
//------------------------------
//Version 1.0
//
        return "position: absolute; left:" + cmc.left +
               "; top: " + cmc.top +
               "; width: " + (OP?cmc.pixelWidth:cmc.width) +
               "; height: " + (OP?cmc.pixelHeight:cmc.height) + "; ";
    }

    function SetUpEvents() {
//IE,NS
//This function initializes the frame variables and setups the event handling.
//------------------------------
//Version 1.9
//
        onerror = errHandler;
        if(typeof(mFrame)=="undefined")
        mFrame = eval(frames['self']);
        if(typeof(mFrame)=="undefined")
            window.setTimeout("SetUpEvents()",10);
        else {
            if(NS) {
                mFrame.captureEvents(Event.MOUSEMOVE);
                mFrame.onmousemove = HideMenus;
                PrepareEvents();
            }
            if(IE) {
                document.onmousemove = HideMenus;
                mFrame.document.onmousemove = document.onmousemove;
            }
        }
    }

    function errHandler(sMsg,sUrl,sLine) {
//IE,NS
//This function will trap any errors generated by the scripts and filter the unhandled ones.
//------------------------------
//Version 1.0
//
//        if(sMsg.substr(0,16)!="Access is denied"&&sMsg!="Permission denied")
 //           alert("DHTML Menu Builder Java Script Error\n" +
  //                "\nDescription: " + sMsg +
   //               "\nSource: " + sUrl +
    //              "\nLine: "+sLine);
        return true;
    }

    function PrepareEvents() {
//NS
//This function is called right after the menus are rendered.
//It has been designed to attach the OnClick event to the <layer> tag. This is being
//done this way because Navigator does not support a click inline event capturing on
//the layer tag... duh!
//------------------------------
//Version 2.5
//
        for(var l=0; l<mFrame.document.layers.length; l++) {
            var lo = mFrame.document.layers[l];
            lo.w = lo.clip.width;
            lo.h = lo.clip.height;
            for(var sl=0; sl<lo.layers[0].layers.length; sl++) {
                var slo = mFrame.document.layers[l].layers[0].layers[sl];
                if(slo.name.indexOf("EH")>0) {
                    slo.document.onmouseup = hNSCClick;
                    slo.document.TCode = nTCode[slo.name.split("EH")[1]];
                }
            }
        }
    }

    function SPIPreInitialize() {
//SPI - Added to ensure an early hoverover does not cause a script error.
        if(typeof(mFrame)=="undefined")
        mFrame = eval(frames['self']);
        if(typeof(mFrame)=="undefined")
            window.setTimeout("SPIPreInitialize()",10);
    }
    SPIPreInitialize();
