//Author: Christopher J. Andrews 2002, All copyleft rights reserved.

//
// Scripts for a relative popup box
//
// requires: util.js

//08/01/2003 Made some modifications to add some minor features and to
//add some documentation.
//Note that IMG elements can be passed right in without bothering to use
//the image functionality, so this could be removed.

/*
PopupManager
    -- Class created to manage multiple popup menus

    .singleVisible
        -- If true, only one popup will be visible at a time

    .setLastPopup(nextPopup)
        -- Checks to see if there is only supposed to be one
        open popup and closes the last one opened, if so
*/

var globalPopupManager = newPopupManager();

function PopupManager(){
    this.singleVisible = false;
    this._lastPopup = null;
}

function newPopupManager(){
    var pm = new PopupManager();

    pm.setLastPopup = setLastPopup;

    return pm;
}

//Set the instance of the last popup used
function setLastPopup(nextPopup){
    if (this.singleVisible &&
            (nextPopup != this._lastPopup)){
        if (this._lastPopup != null){
            this._lastPopup.
                showPopup(false, 0, this._lastPopup.divNamePrefix);
        }
    }

    if ((this._lastPopup != null) &&
            this._lastPopup.isVisible() &&
            (nextPopup != this._lastPopup)){
        nextPopup.
            setZIndex(this._lastPopup._z_index + 1, 0, nextPopup.divNamePrefix);
    }

    this._lastPopup = nextPopup;
}

/*
Popup
    newPopup(instanceName, divNamePrefix, backgroundColor) <-- 'constructor'
    .setPositioning(holderInFront, offsetX, offsetY)
        -- sets the positioning of the popup relative to the anchor

    .setCSSClasses(mainCSSClass, popupCSSClass, menuCSSClass)
        -- sets the CSS classes that will be used for the menus, popup,
        and main link

    .addMenu(text, url)
        -- add a menu to be part of a list of popup menus

    .writePopup(mainText, popupText, mainURL)
        or (mainImageURL, popupImageURL, mainURL) if useImageMain and useImagePopup
        -- write out the popup menu HTML into the body of the page; used as
        an inline command in the BODY of the page

    .showPopup(flag, index, divNamePrefix)
        -- force the popup to be shown

    .isVisible()
        -- check to see if the popup is visible

    .setZIndex(z, index, divNamePrefix)
        -- Set the zindex
*/

function Popup(){
    this.pCntr = 0;
    this.divNamePrefix = "";
    this.instanceName = "";
    this.popupCSSClass = "";
    this.textCSSClass = "";
    this.menuCSSClass = "";
    this.bgColor = "";
    this.offsetX = 5;
    this.offsetY = -15;
    this.holderInFront = false;
    //timer and menu vars
    this.mainDelay = 1700;
    this.menuDelay = 1700;
    this.useMainTimer = false;
    this.useMenuTimer = false;
    this.menuIsVertical = true;

    this._timerArray = null;
    this._menus = newArrayList(false);
    this._isMenu = false;
    this._isVisible = false;
    this._z_index = 2;

    //Image vars: set true if passing an image name
    //not really necessary as you can pass in an image HTML element
    this.useImageMain = false;
    this.useImagePopup = false;
    this.netscapeCorrection = 0;
}

//iName: the name of the variable used to refer to this popup
//dNamePrefix: divName that will be used
//tColor: background color of the div tag
function newPopup(iName, dNamePrefix, tColor){
    var p = new Popup();
    p.instanceName = iName;
    p.divNamePrefix = dNamePrefix;
    p.bgColor = tColor;
    p.setPositioning = setPositioning;
    p.setCSSClasses = setCSSClasses;
    p.addMenu = addMenu;
    p.writePopup = writePopup;
    p.showPopup = showPopup;
    p.isVisible = isVisible;
    p.setZIndex = setZIndex;

    p._writeLeadingTag = _writeLeadingTag
    p._doShowPopup = _doShowPopup;
    p._startTimer = _startTimer;
    p._stopTimer = _stopTimer;
    p._writeMenus = _writeMenus;
    p._checkImage = _checkImage;
    return p;
}

//Check to see if the popup is visible
function isVisible(){
    return this._isVisible;
}

function _checkImage(flag, text){
    var result = text;
    if (flag){
        result = "\r\n<IMG SRC=\"" + text + "\" BORDER=0>";
    }
    return result;
}

//text: Text to be displayed in the submenu
//link: The relative or absolute url to be used... javascript:void(0) if empty or null
function addMenu(text, link){
    if ((link == null) || (link == "")){
        link = "javascript:void(0)";
    }
    this._menus.add(text, link);
    this._isMenu = true;
    this.useMenuTimer = true;
    this.useMainTimer = false;
}

//hInFront: Place the div holder in front or after the link. Affects relative positioning.
//offX: x offset
//offY: y offset
function setPositioning(hInFront, offX, offY){
    this.holderInFront = hInFront;
    this.offsetX = offX;
    this.offsetY = offY;
}

//txtClass: main menu style
//ppClass: background popup div style
//menuClass: individual menu text style
function setCSSClasses(txtClass, ppClass, menuClass){
    this.textCSSClass = txtClass;
    this.popupCSSClass = ppClass;
    if ((menuClass != null) && ((menuClass + "") != "undefined")){
        this.menuCSSClass = menuClass;
    }
}

function _writeMenus(index){
    var output = "";
    for (i = 0; i < this._menus.length; i++){

        if ((i == 0) || this.menuIsVertical){
            output += "<P";
            if (this.menuCSSClass != ""){
                output += " class=\"" + this.menuCSSClass + "\"";
            }
            output += ">";
        }

        output += "<A HREF=\"" + this._menus.getItemByIndex(i) + "\"";
        if (this.useMenuTimer){
            output +=
                " onMouseOver=\"" + this.instanceName +
                "._stopTimer(" + index + ")\"";
            output +=
                " onMouseOut=\"" + this.instanceName +
                "._startTimer(" + index + ", " + this.menuDelay + ")\"";
        }

        //Temporarily removed... may be placed back in when I convert the
        //CSS utilities to be menu item specific
        if (this.menuCSSClass != ""){
            output += " class=\"" + this.menuCSSClass + "\"";
        }

        output += ">" +
            this._checkImage(this.useImagePopup, this._menus.getKeyByIndex(i)) +
            "</A>\r\n";

        if (this.menuIsVertical && (i != this._menus.length - 1)){
            output += "</P>";
        }
    }
    myDocWrite(output);
}

//mainText: the text that gets displayed
//popupText: the name of the popup
//mainURL: if not null, the url used for the main link
//anchorTitle: the TITLE attribute for the anchor
function writePopup(mainText, popupText, mainURL, anchorTitle){
    //alert("write popup called");
    //Write the anchor
    var anchorText = "";

    if ((mainURL == null) || (mainURL == "")){
        anchorText = "<A HREF=\"javascript:void(0)\" ";
    } else {
        anchorText = "<A HREF=\"" + mainURL + "\" ";
    }
    if (this.textCSSClass != ""){
        anchorText = anchorText + "CLASS=\"" + this.textCSSClass + "\" ";
    }
    if ((anchorTitle != null) && (anchorTitle != "")){
        anchorText = anchorText + "TITLE=\"" + anchorTitle + "\" ";
    }
    anchorText = anchorText +
        "onMouseOver=\"" + this.instanceName +
        ".showPopup(true," + this.pCntr + ",\'" + this.divNamePrefix + "\')\" ";
    if (this.useMainTimer){
        anchorText +=
            "onMouseOut=\"" + this.instanceName +
            "._startTimer(" + this.pCntr + ", " + this.mainDelay + ")\"";
    } else {
        if (!this._isMenu){
            anchorText +=
                "onMouseOut=\"" + this.instanceName +
                ".showPopup(false," + this.pCntr + ",\'" + this.divNamePrefix + "\')\""
        }
    }
    anchorText += ">" + this._checkImage(this.useImageMain, mainText) + "</A>\r\n";

    //Write the marker image
    var imgText =
        "<IMG SRC=\"/images/blank.gif\" " +
        "NAME=\"" + this.divNamePrefix + this.pCntr +
        "\" ID=\"" + this.divNamePrefix + this.pCntr + "\" " +
        "WIDTH=\"0\" HEIGHT=\"0\" " +
        "STYLE=\"visibility:hidden;position:relative;\">\r\n";
    if (this.holderInFront){
        myDocWrite(imgText + anchorText);
    } else {
        myDocWrite(anchorText + imgText);
    }

    //Write the division
    this._writeLeadingTag(this.divNamePrefix + "Div" + this.pCntr);
    if (!this._isMenu){
        myDocWrite(this._checkImage(this.useImagePopup, popupText));
    } else {
        this._writeMenus(this.pCntr);
    }
    writeTrailingTag();

    //alert(this.divNamePrefix + "   " + this.pCntr);
    //var tImg = document.images[this.divNamePrefix + this.pCntr];
    //alert(tImg);
    //tImg.getRealLeft = getRealLeft;
    //tImg.getRealTop = getRealTop;
    //alert(tImg.name);

    this.showPopup(false, this.pCntr, this.divNamePrefix);
    this.pCntr = this.pCntr + 1;
}

//Changes the z-index of the popup
//z: the new z-index
//index: same as Popup.pCntr; only gets indexed if writePopup is called more than once,
//       usually use zero
//tname: usually the divNamePrefix
function setZIndex(z, index, divPrefix){
    var name = divPrefix + "Div" + index;
    this._z_index = z;

    if (theBrowser.version() == "MS4"){
        //Do nothing
    } else if ((theBrowser.version() == "MS5") ||
            (theBrowser.version() == "N6")){

        var anObj = document.getElementById(name);
        anObj.style.zIndex = this._z_index;

    } else if (theBrowser.version() == "ns") {
        //Do nothing
    }
}

//Shows or hides the popup box
//showBox: show -- true, hide -- false
//index: same as Popup.pCntr; only gets indexed if writePopup is called more than once,
//       usually use zero
//tname: usually the divNamePrefix
function showPopup(showBox, index, tname){
    var name = tname + "Div" + index;
    var spacerName = tname + index;
    this._stopTimer(index);

    this._isVisible = showBox;

    if (showBox){
        globalPopupManager.setLastPopup(this);
    }

    this._doShowPopup(showBox, name, spacerName, this.offsetX, this.offsetY);
}

function _doShowPopup(showBox, name, spacerName, xTrans, yTrans){
    //alert("in doShowPopup");
    if (theBrowser.version() == "too old") {return void(0);}
    var pleft;
    var ttop;
    if (showBox){
        var tImg = document.images[spacerName];
        tImg.getRealLeft = getRealLeft;
        tImg.getRealTop = getRealTop;
        pleft = tImg.getRealLeft() + xTrans;
        ptop = tImg.getRealTop() + yTrans;
    } else {
        pleft = -1250;
        ptop = -1250;
    }
    if (theBrowser.version() == "MS4"){
        var anObj;
        var aStatement = "anObj = document.all." + name + ";"
        eval(aStatement);
        anObj.style.pixelLeft = pleft;
        anObj.style.pixelTop = ptop;
    } else if ((theBrowser.version() == "MS5") ||
            (theBrowser.version() == "N6")){

        var anObj = document.getElementById(name);
        anObj.style.left = pleft + "px";
        anObj.style.top = ptop + "px";
    } else if (theBrowser.version() == "ns") {
        //netscapeCorrection keeps coming up undefined
        //document.layers[name].moveTo(pleft, ptop + this.netscapeCorrection);
        document.layers[name].moveTo(pleft, ptop);
    }
}

function _writeLeadingTag(name){
    if (theBrowser.version() == "too old") {return void(0);}

    var result = "";

    if ((theBrowser.version() == "MS4") ||
        (theBrowser.version() == "MS5") ||
        (theBrowser.version() == "N6")){
            result = "";
            result = "<DIV ID=\"" + name + "\" ";
            if (this.popupCSSClass != ""){
                result = result +
                    "class=\"" + this.popupCSSClass + "\" ";
            }
            result = result +
                "STYLE=\"position:absolute;z-index:" + this._z_index;
            if (this.bgColor != ""){
                result += ";background:" + this.bgColor;
            }
            result = result +
                ";Left:-1000;Top:-1000\">\r\n";
            myDocWrite(result);
    } else {
            result = "";
            result = "<LAYER ID=\"" + name + "\" ";
            if (this.popupCSSClass != ""){
                result = result +
                    "class=\"" + this.popupCSSClass + "\" ";
            }
            result = result +
                "TOP=-1000 LEFT=-1000>\r\n";// Z-INDEX=2
            myDocWrite(result);
    }
}

function writeTrailingTag(){
    if (theBrowser.version() == "too old") {return void(0);}

    var result = "";

    if ((theBrowser.version() == "MS4") ||
            (theBrowser.version() == "MS5") ||
            (theBrowser.version() == "N6")){
        result = "</DIV>\r\n";
        myDocWrite(result);
    } else {
        result = "</LAYER>\r\n";
        myDocWrite(result);
    }
}

function getRealLeft() {
    var xPos = 0;
    if ((theBrowser.version() == "MS4") ||
            (theBrowser.version() == "MS5") ||
            (theBrowser.version() == "N6")){

        xPos = this.offsetLeft;
        tempEl = this.offsetParent;
        while (tempEl != null) {
            xPos += tempEl.offsetLeft;
            tempEl = tempEl.offsetParent;
        }
    } else {//Netscape 4 correction
        xPos = this.x;
    }
    return xPos;
}

function getRealTop() {
    var yPos = 0;
    if ((theBrowser.version() == "MS4") ||
            (theBrowser.version() == "MS5") ||
            (theBrowser.version() == "N6")){

        yPos = this.offsetTop;
        tempEl = this.offsetParent;
        while (tempEl != null) {
            yPos += tempEl.offsetTop;
            tempEl = tempEl.offsetParent;
        }
    } else {//Netscape 4 correction
        yPos = this.y;
    }
    return yPos;
}

function _startTimer(index, delay){
    var timerID = 0;
    timerID = self.setTimeout("this.showPopup(false, "
        + index + ", \'" +  this.divNamePrefix + "\');", delay);
    if (this._timerArray == null){
        this._timerArray = new Array(this.pCntr);
    } else if (this._timerArray.length < this.pCntr){
        var tArray = new Array(this.pCntr);

        for (i = 0; i < this.pCntr; i++){
            tArray[i] = this._timerArray[i];
        }
        this._timerArray = tArray;
    }
    this._timerArray[index] = timerID;
}

function _stopTimer(index){
    if ((this._timerArray != null) &&
            (("" + this._timerArray) != "undefined") &&
            (index < this._timerArray.length) &&
            (this._timerArray[index] != null)){
        self.clearTimeout(this._timerArray[index]);
    }
}