// JavaScript code for the contextMenuTag
// Daniel Lichtenberger, UCS
// $Revision: 11050 $

function ContextMenu(id) {
    this.id = id;
    this.menuItemIds = new Array();         // array containing all menu item id's
    this.disabledMenuItems = new Array();   // array containing all disabled menu items
    this.elPopup = document.getElementById(this.id + "Popup");
    this.elContent = document.getElementById(this.id + "Content");
    this.timeout = -1;                      // popup is automatically closed after x seconds unless the mouse is over the popup, set to -1 to disable timeout
    this.active = false;
    this.timeoutHandler = null;
}


// opens the context menu at the given coordinates
ContextMenu.prototype.show = function(event, x, y) {
    this.elPopup.style.display = 'block';
    this.updateSeparators();
    var cur = this.elPopup;
    var offsetX = 0;
    var offsetY = 0;
    while (cur.offsetParent) {
        cur = cur.offsetParent;
        offsetX += cur.offsetLeft;
        offsetY += cur.offsetTop;
    }
    //alert("x=" + x + ",y=" + y + ",offsetX=" + offsetX + ",offsetY=" + offsetY);
    x -= offsetX;
    y -= offsetY;
    var width = this.elPopup.scrollWidth;
    var height = this.elPopup.scrollHeight;
    x = Math.max(0, Math.min(x, document.body.clientWidth - width - offsetX - 20));
    y = Math.max(0, Math.min(y, document.body.clientHeight - height - offsetY - 20));
    this.elPopup.style.left = x + "px";
    this.elPopup.style.top = y + "px";// + (document.all ? 22 : -10);
    this.elPopup.style.visibility = 'visible';
}

// event handler, e.g. for 'oncontextmenu'
ContextMenu.prototype.onShow = function(event) {
    if (this.disabledMenuItems.length == this.menuItemIds.length)
        return false;    // don't show our popup if nothing is selected
    var curX = (!document.all) ? event.pageX : event.clientX + ietruebody().scrollLeft;
    var curY = (!document.all) ? event.pageY : event.clientY + ietruebody().scrollTop;

    this.show(event, curX, curY);
    if (this.timeout > 0) {
        this.clearTimeout();
        this.timeoutHandler = window.setTimeout(this.id + ".hideTimeout();", this.timeout * 1000);
    }
    return false;
}

ContextMenu.prototype.onMouseOver = function(event) {
    this.active = true;
}

ContextMenu.prototype.hideTimeout = function() {
    if (!this.active)   this.hide();
}

ContextMenu.prototype.hide = function() {
    this.clearTimeout();
    this.elPopup.style.visibility = 'hidden';
    this.elPopup.style.display = 'none';
}

ContextMenu.prototype.onHide = function(event) {
    if (!event)
        event = window.event;
    var relTarg;
    if (event.relatedTarget)
        relTarg = event.relatedTarget;
    else if (event.toElement)
        relTarg = event.toElement;
    while (relTarg && relTarg != this.elContent && relTarg.nodeName != 'BODY')
        relTarg = relTarg.parentNode;
    if (relTarg == this.elContent) return;
    if (relTarg) {
        this.active = false;
        this.clearTimeout();
        this.timeoutHandler = window.setTimeout(this.id + ".hideTimeout()", 500);
    }
}

// executed when an item is clicked
ContextMenu.prototype.selectItem = function(link) {
    this.hide();
    openContextLink(link);
}

// enables (shows) a menu item
ContextMenu.prototype.enableItem = function(idItem) {
    // remove item from "disabled" list
    var newItems = new Array();
    for (var i=0;i<this.disabledMenuItems.length;i++) {
        if (this.disabledMenuItems[i] != idItem)
            newItems.push(this.disabledMenuItems[i]);
    }
    this.disabledMenuItems = newItems;
}

// disables (hides) a menu item
ContextMenu.prototype.disableItem = function(idItem) {
    // add item to "disabled" list
    if (!this.isItemDisabled(idItem))
        this.disabledMenuItems.push(idItem);
}

ContextMenu.prototype.isItemEnabled = function(idItem) {
    var found = false;
    for (var i=0;i<this.disabledMenuItems.length;i++) {
        if (this.disabledMenuItems[i] == idItem) {
            found = true;
            break;
        }
    }
    return !found;
}

ContextMenu.prototype.isItemDisabled = function(idItem) {
    return !this.isItemEnabled(idItem);
}

// enable all menu items
ContextMenu.prototype.enableAllItems = function() {
    this.disabledMenuItems = new Array();
}

// disable all menu items
ContextMenu.prototype.disableAllItems = function() {
    this.disabledMenuItems = new Array();
    for (var i=0;i<this.menuItemIds.length;i++) {
        this.disabledMenuItems.push(this.menuItemIds[i]);
    }
}

// enables or disables the menu item
ContextMenu.prototype.setItemState = function(idItem, enabled) {
    var menuItem = this.getMenuItem(idItem);
    if (menuItem != null)
        menuItem.style.display = enabled ? "block" : "none";
    if (enabled)
        this.enableItem(idItem);
    else
        this.disableItem(idItem);
}

// enable or disable all items
ContextMenu.prototype.setAllItems = function(enabled) {
    if (enabled)
        this.enableAllItems();
    else
        this.disableAllItems();
    for (var i=0;i<this.menuItemIds.length;i++) {
        this.getMenuItem(this.menuItemIds[i]).style.display = enabled ? "block" : "none";
    }
}

// returns the html element of the given menu item
ContextMenu.prototype.getMenuItem = function(idItem) {
    return document.getElementById(this.id + "_" + idItem);
}

ContextMenu.prototype.openContextLink = function(hrefUrl) {
    if (hrefUrl!=null) {
        if (hrefUrl.substring(0,11)=='javascript:') eval(hrefUrl.substring(11,hrefUrl.length));
        else window.location = hrefUrl;
        //window.status='';
    }
}

ContextMenu.prototype.clearTimeout = function() {
    if (this.timeoutHandler != null) {
        window.clearTimeout(this.timeoutHandler);
        this.timeoutHandler = null;
    }
}

// hides adjacent separators (based on current menu visibility)
ContextMenu.prototype.updateSeparators = function() {
    var visible = 0;
    var separator = null;
    for (var i=0;i<this.menuItemIds.length;i++) {
        var idItem = this.menuItemIds[i];
        if (idItem.indexOf("SEPARATOR") == 0) {
            if (visible == 0) {
                // no visible items between last separator and current separator - hide it
                this.setItemState(idItem, false);
            } else {
                // enable separator when next regular menu item is drawn
                separator = idItem;
                // enable separator until next visible item is processed
                this.setItemState(idItem, false);
            }
            visible = 0;
        } else if (this.isItemEnabled(idItem)) {
            visible++;
            if (separator != null) {
                // enable separator
                this.setItemState(separator, true);
                separator = null;
            }
        }
    }
}

function ietruebody() {
    return (document.compatMode && document.compatMode!="BackCompat")? document.documentElement : document.body;
}

// --------  global functions  -----------------

// closes all context menus.
// @param event     the current event
// @param contextInfoName   the html "name" to find all context menus in a document
function closeAllContextMenus(event, contextInfoName) {
    // process main window
    var contextMenus = document.getElementsByName(contextInfoName);
    for (var j = 0; j < contextMenus.length; j++) {
        // close all "inactive" menues (a context menu becomes inactive
        // when the mouse cursor moves outside the context menu)
        var menuId = contextMenus[j].getAttribute("menuId");
        var cmd =  "if (!" + menuId + ".active) " + menuId + ".hide();";
        eval(cmd);
    }

    // process frames
    for (var i = 0; i < window.frames.length; i++) {
        contextMenus = window.frames[i].document.getElementsByName(contextInfoName);
        for (var j = 0; j < contextMenus.length; j++) {
            // close all "inactive" menues (a context menu becomes inactive
            // when the mouse cursor moves outside the context menu)
            var menuId = contextMenus[j].getAttribute("menuId");
            var menu = "window.frames[" + i + "]." + menuId;
            var cmd =  "if (!" + menu + ".active) " + menu + ".hide();";
            eval(cmd);
        }
    }
}

