﻿var menuManager;

function InitaliseContextMenuManager(blockDefaultMenu) {
    menuManager = new ContextMenuManager(blockDefaultMenu);
}

function ContextMenuManager(blockDefaultMenu) {
    document.oncontextmenu = _contextMenu_contextmenu;
    document.onmousedown = _contextMenu_mousedown;
    document.onmouseover = _contextMenu_mouseover;
    if (window.frameElement) {
        window.frameElement.onblur = _contextMenu_mousedown;
    }
    window.onblur = _contextMenu_mousedown;
    document.onblur = _contextMenu_mousedown;
    if (blockDefaultMenu == true) {
        this.blockDefaultMenu = true;
    } else {
        this.blockDefaultMenu = false;
    }
    this.tagCollection = new Array();
}
ContextMenuManager.prototype.activeElement = null;
ContextMenuManager.prototype.blockDefaultMenu = false;
ContextMenuManager.prototype.attachEventListener = _contextMenu_attachEventListener;
ContextMenuManager.prototype.cancel = _contextMenu_cancel;
ContextMenuManager.prototype.checkScroll = _contextMenu_checkScroll;
ContextMenuManager.prototype.createDetached = _contextMenu_createDetached;
ContextMenuManager.prototype.createByContainer = _contextMenu_createByContainer;
ContextMenuManager.prototype.createByTag = _contextMenu_createByTag;
ContextMenuManager.prototype.detach = _contextMenu_detach;
ContextMenuManager.prototype.elementOffset = _contextMenu_elementOffset
ContextMenuManager.prototype.elementSize = _contextMenu_elementSize;
ContextMenuManager.prototype.findCursor = _contextMenu_findCursor;
ContextMenuManager.prototype.findElement = _contextMenu_findElement;
ContextMenuManager.prototype.hide = _contextMenu_hide;
ContextMenuManager.prototype.hideChild = _contextMenu_hideChild;
ContextMenuManager.prototype.itemClick = _contextMenu_itemClick;
ContextMenuManager.prototype.maxMenuHeight = 0;
ContextMenuManager.prototype.updateCursor = _contextMenu_updateCursor;
ContextMenuManager.prototype.underlayAdd = _contextMenu_underlayAdd;
ContextMenuManager.prototype.underlayRemove = _contextMenu_underlayRemove;
ContextMenuManager.prototype.show = _contextMenu_show;
ContextMenuManager.prototype.showChild = _contextMenu_showChild;
ContextMenuManager.prototype.windowOffset = _contextMenu_windowOffset;
ContextMenuManager.prototype.windowSize = _contextMenu_windowSize;

ContextMenuManager.prototype.RemoveChild = function(el) {
    var tagName = el.tagName;
    if (!tagName) { tagName = 'TEXT'; }
    var fragName = 'Fragment' + tagName.toUpperCase();
    if (!this[fragName]) {
        this[fragName] = document.createDocumentFragment()
    }
    this[fragName].appendChild(el);
    while (el.childNodes.length > 0) {
        this.RemoveChild(el.childNodes[0]);
    }
    if (el.style) {
        if (el.style.cssText) {
            el.style.cssText = '';
        }
    }
    if (el.className) { el.className = ''; };
    if (el.removeAttribute) {
        el.removeAttribute('className');
        el.removeAttribute('class');
        el.removeAttribute('id');
        el.removeAttribute('menuItem');
        el.removeAttribute('href');
        el.removeAttribute('iframe');
    }
    if (el.style) {
        el.style.cssText = '';
    }
    //if (el.clearAttributes) { el.clearAttributes(); }
}

ContextMenuManager.prototype.getElement = function(tagName) {
    var el;
    var fragName = 'Fragment' + tagName.toUpperCase();
    if (!this[fragName]) {
        el = document.createElement(tagName);
    }
    else {
        if (this[fragName].hasChildNodes()) {
            el = this[fragName].childNodes[0];
            el.className = '';
            if (el.removeAttribute) {
                el.removeAttribute('className');
                el.removeAttribute('class');
                el.removeAttribute('id');
                el.removeAttribute('menuItem');
                el.removeAttribute('href');
                el.removeAttribute('iframe');
            }
            if (el.style) {
                el.style.cssText = '';
            }
            //el.clearAttributes();          
        }
        else {
            el = document.createElement(tagName);
        }
    }
    return el;
}

function _contextMenu_show(sourceElement, cursor, AttachedContainer, offsetX, offsetY) {
    //window.ContensisUtility.DeleteOrphans('ContextMenu');
    if (this.eventListeners) {
        for (i = 0; i < this.eventListeners.length; i++) {
            if (this.eventListeners[i]) {
                if (this.eventListeners[i].menuShow) {
                    this.eventListeners[i].menuShow(this)
                }
            }
        }
    }

    if (this.isCallback == true) {
        this.items = new contensisMenuItemCollection(this);
        this.callback(sourceElement, this)
    }

    // removed from menu items.generate

    var menuElement = this.items.generate(document.body);
    menuElement.style.zIndex = 10000
    menuManager.activeElement = menuElement;
    menuManager.activeMenu = this
    if (cursor) {
        cursor = menuManager.updateCursor(cursor, menuManager.activeElement);
    }
    if (AttachedContainer) {

        var MenuHeight = menuElement.offsetHeight
        var containerpos = window.ContensisControlsNamespace.Utilities.FindElementPosition(AttachedContainer)
        var WindowSize = menuManager.windowSize();
        cursor = containerpos
        if ((containerpos[1] + AttachedContainer.offsetHeight + MenuHeight) > WindowSize[1]) {
            //deed to put it above the element....
            cursor[1] = (containerpos[1] - MenuHeight)
        } else {
            cursor[1] = (containerpos[1] + AttachedContainer.offsetHeight)
        }

    }

    if (offsetX) {
        cursor[0] = cursor[0] + offsetX;
    }
    if (offsetY) {
        cursor[1] = cursor[1] + offsetY;
    }
    menuManager.checkScroll(menuManager.activeElement);
    if (cursor[0] > -1) {
        menuElement.style.left = cursor[0] + 'px';
        menuElement.style.top = cursor[1] + 'px';
    }
    menuElement.iframe = menuManager.underlayAdd(menuElement)
    //    alert(this.menuElement.outerHTML);
    this.visible = true
    //As this.menuElement had been removed I needed it in some scenarios.
    return menuElement
}

function _contextMenu_attachEventListener(listener) {
    if (listener) {
        this.eventListeners[this.eventListeners.length] = listener;
    }
}

function _contextMenu_cancel(evt) {
    if (evt == null) {
        evt = window.event
    }
    evt.cancelBubble = true;
    return false;
}
function _contextMenu_checkScroll(el) {
    var elSize = menuManager.elementSize(el);
    var winSize = menuManager.windowSize();

    el.style.height = '';
    el.style.marginTop = '';
    el.style.overflowY = '';
    if (this.scrollButtons != null) {
        this.scrollButtons = null;
    }
    if (elSize[1] > (winSize[1] - 1)) {
        el.style.height = (winSize[1] - 2) + 'px';
        el.style.overflowY = 'hidden';
        this.scrollButtons = new contensisMenuScrollButtons(el, (winSize[1] - 2), el.scrollHeight)
    }
}
function _contextMenu_createDetached() {
    var menu = new Object;
    menu.eventListeners = new Array();
    menu.addEventListener = menuManager.attachEventListener;
    menu.container = null;
    menu.detach = menuManager.detach;
    menu.hide = menuManager.hide;
    menu.level = 1;
    menu.items = new contensisMenuItemCollection(menu);
    menu.show = menuManager.show;
    menu.isCallback = false;
    return menu;
}
function _contextMenu_createByContainer(container, callback) {
    var el;
    var menu = new Object;
    menu.eventListeners = new Array();
    menu.addEventListener = menuManager.attachEventListener;
    if (typeof (container) == 'string') {
        el = document.getElementById(container);
        if (el == null || typeof (el) != 'object') {
            alert('The container element \'' + container + '\' could not be found.')
            return null;
        }
    } else {
        el = container;
        if (el == null || typeof (el) != 'object') {
            alert('The container element is invalid.')
            return null;
        }
    }
    if (el.hasContextMenu) {
        alert('The selected container already has a context menu assigned to it.')
        return null;
    }
    menu.container = el;
    menu.detach = menuManager.detach;
    menu.hide = menuManager.hide;
    menu.items = new contensisMenuItemCollection(menu);
    menu.level = 1;
    menu.show = menuManager.show;
    menu.container.contextMenu = menu;
    menu.container.hasContextMenu = true;
    if (callback == null) {
        menu.isCallback = false;
    } else {
        menu.callback = callback;
        menu.isCallback = true;
    }
    return menu;
}
function _contextMenu_createByTag(tagType, callback) {
    var menu = new Object;
    menu.eventListeners = new Array();
    menu.addEventListener = menuManager.attachEventListener;
    menu.container = tagType.toLowerCase();
    menu.detach = menuManager.detachByTag;
    menu.hide = menuManager.hide;
    menu.items = new contensisMenuItemCollection(menu);
    menu.level = 1;
    menu.show = menuManager.show;
    menuManager.tagCollection[menuManager.tagCollection.length] = menu;
    if (callback == null) {
        menu.isCallback = false;
    } else {
        menu.callback = callback;
        menu.isCallback = true;
    }
    return menu;
}
function _contextMenu_contextmenu(evt) {
    if (evt == null) { evt = window.event }
    menuManager.hide();

    var sourceEl = srcElement(evt);
    var contextMenu
    if (menuManager.tagCollection.length > 0) {
        contextMenu = menuManager.findElement(sourceEl);
    } else {
        contextMenu = null
    }
    if (contextMenu != null) {
        contextMenu.show(sourceEl, menuManager.findCursor(evt));
        return false;
    } else {
        if (menuManager.blockDefaultMenu) {
            return false;
        }
    }
    return true;
}
function _contextMenu_detach() {
    this.container.contextMenu = null;
    this.container.hasContextMenu = null;
}
function _contextMenu_detachByTag() {
    this.container.contextMenu = null;
    this.container.hasContextMenu = null;
}
function _contextMenu_elementOffset(el) {
    var offsetX = 0;
    var offsetY = 0;
    /*
    if (el.parentNode != null && el.tagName != 'BODY') {
    while (el.parentNode.tagName != 'BODY') {
    if (el.parentNode.tagName == 'DIV' && el.parentNode.className.indexOf('system_contextMenu')>-1) {
    offsetX = offsetX + el.parentNode.offsetLeft;
    offsetY = offsetY + el.parentNode.offsetTop + 1;
    }
    el = el.parentNode;
    }
    }
    */
    while (el.offsetParent) {
        offsetX = offsetX + el.offsetParent.offsetLeft;
        offsetY = offsetY + el.offsetParent.offsetTop;
        el = el.offsetParent;
    }
    return [offsetX, offsetY]
}
function _contextMenu_elementSize(el) {
    return [el.offsetWidth, el.offsetHeight];
}
function _contextMenu_findCursor(evt) {
    var XY = new Array();
    XY[0] = null;
    XY[1] = null;
    if (evt.pageX) {
        XY[0] = evt.pageX;
        XY[1] = evt.pageY;
    } else {
        if (evt.clientX) {
            XY[0] = evt.clientX + (document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft);
            XY[1] = evt.clientY + (document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop);
        }
    }
    return XY;
}
function _contextMenu_findElement(src) {
    var el = src;
    while (el != null && el.tagName != null) {
        var srcTag = el.tagName.toLowerCase();
        for (i = 0; i < menuManager.tagCollection.length; i++) {
            if (menuManager.tagCollection[i].container == srcTag) {
                return menuManager.tagCollection[i];
            }
        }
        el = el.parentNode;
    }
    var el = src;
    while (el != null) {
        if (el.hasContextMenu) {
            return el.contextMenu;
        }
        el = el.parentNode;
    }
}
function _contextMenu_hide() {
    //return;
    if (menuManager.activeElement != null) {
        if (menuManager.activeElement.parentNode != null) {
            if (this.eventListeners) {
                for (i = 0; i < this.eventListeners.length; i++) {
                    if (this.eventListeners[i]) {
                        if (this.eventListeners[i].menuHide) {
                            this.eventListeners[i].menuHide(this)
                        }
                    }
                }
            } else {
                if (menuManager.activeMenu.eventListeners) {
                    for (i = 0; i < menuManager.activeMenu.eventListeners.length; i++) {
                        if (menuManager.activeMenu.eventListeners[i]) {
                            if (menuManager.activeMenu.eventListeners[i].menuHide) {
                                menuManager.activeMenu.eventListeners[i].menuHide(this)
                            }
                        }
                    }
                }
            }
            //Clear Circular references...
            var elementList = menuManager.activeElement.getElementsByTagName("li");
            for (i = 0; i < elementList.length; i++) {
                el = elementList[i];
                if (el.menuItem) {
                    //clear expando props
                    el.onmouseout = null;
                    el.onmouseover = null;
                    el.oncontextmenu = null;
                    el.onmousedown = null;
                    el.onclick = null;
                    el.menuItem = null
                }
            }
            elementList = null
            menuManager.underlayRemove(menuManager.activeElement.iframe);
            menuManager.RemoveChild(menuManager.activeElement);
            //menuManager.activeElement.parentNode.removeChild(menuManager.activeElement);
            menuManager.activeElement.iframe = null
            menuManager.activeElement = null
            menuManager.activeMenu = null;
        }
    }
    this.visible = false
}
function _contextMenu_hideChild(id) {
    try {
        var el = document.getElementById(id);
        if (el != null) {
            menuManager.underlayRemove(el.childNodes[1].iframe);
            el.childNodes[1].iframe = null;
            el.childNodes[1].style.left = '';
            el.menuItem.timeOut = 0;
        }
    } catch (e) {
    }
}
function _contextMenu_itemClick(evt) {
    var menuItem;
    if (evt == null) {
        evt = window.event
    }
    var parentEl = srcElement(evt);

    while (parentEl.parentNode != null && parentEl.tagName.toLowerCase() != 'li') {
        parentEl = parentEl.parentNode
    }
    if (parentEl.tagName.toLowerCase() == 'li') {
        menuItem = parentEl.menuItem
        if (menuItem.hasChildren() == true) {
            if (menuItem.timeOut != 0) {
                window.clearTimeout(menuItem.timeOut);
                menuItem.timeOut = 0;
                menuItem.timeOutType == ''
            }
            menuManager.showChild(parentEl.id, [(parentEl.parentNode.offsetWidth - 1), parentEl.offsetTop])
        } else {
            var callBack = menuItem.callBack;
            try {
                if (menuItem.parent) {
                    menuItem.parent.hide();
                }
            } catch (e) { }
            menuManager.hide();
            if (callBack != null) {
                var work = new String();
                work = 'menuItem.name'
                for (i = 0; i < menuItem.callBackArgs.length; i++) {
                    work = work + ', menuItem.callBackArgs[' + i + ']'
                }
                eval('callBack(' + work + ')')
            }
        }
    }
    evt.cancelBubble = true;
    return false;
}
function _contextMenu_mousedown(evt) {
    if (evt == null) {
        evt = window.event;
    }
    if (!document.all && evt.button == 2) {
        return _contextMenu_contextmenu(evt);
    }
    menuManager.hide();
}
function _contextMenu_mouseover(evt) {
    if (evt == null) {
        evt = window.event;
    }
}
//AttachedContainer this is an element the menu if offseting from...
//eg a button that the menu appears above or below.

function _contextMenu_showChild(id, position) {
    try {
        var el = document.getElementById(id);
        position = menuManager.updateCursor(position, el.childNodes[1], [el.parentNode.offsetWidth, el.offsetHeight]);
        if (el != null) {
            el.childNodes[1].style.left = position[0] + 'px';
            el.childNodes[1].style.top = position[1] + 'px';
            el.menuItem.timeOut = 0;
            menuManager.checkScroll(el.childNodes[1]);
            if (el.childNodes[1].iframe == null) {
                el.childNodes[1].iframe = menuManager.underlayAdd(el.childNodes[1])
            }
        }
    } catch (e) {
    }
}
function _contextMenu_underlayAdd(element) {
    //only for ie6 !
    //This needs improving when we extend our browser caps.
    if (window.ContensisControlsNamespace.Browser.IsIE) {
        if (!window.ContensisControlsNamespace.Browser.IsIE7OrAbove) {
            //return;
            var iframe = menuManager.getElement('iframe');
            iframe.style.display = "none"
            element.parentNode.appendChild(iframe);
            iframe.style.position = "absolute";

            iframe.style.top = element.style.top;
            iframe.style.left = element.style.left;
            iframe.style.width = element.offsetWidth;
            iframe.style.height = element.offsetHeight;
            iframe.style.border = 'none';
            if (element.style.zIndex <= iframe.style.zIndex) {
                element.style.zIndex = iframe.style.zIndex + 1
            }
            iframe.style.display = "block"

            return iframe;
        }
    }
}

function _contextMenu_underlayRemove(iframe) {
    if (iframe == null) {
        return;
    }
    if (iframe && iframe.parentNode) {
        menuManager.RemoveChild(iframe);
        //iframe.parentNode.removeChild(iframe);
    }
}
function _contextMenu_updateCursor(cursor, el, containerOffset) {
    var windowSize = menuManager.windowSize()
    var windowOffset = menuManager.windowOffset();
    var elOffset = menuManager.elementOffset(el);
    var elSize = menuManager.elementSize(el);

    // Check vertical position
    if ((windowSize[1] + windowOffset[1]) < ((cursor[1] + elOffset[1]) + elSize[1])) {
        cursor[1] = (cursor[1] - elSize[1]) + 3;
        if (containerOffset != null) {
            cursor[1] = cursor[1] + containerOffset[1];
        }
        if (windowOffset[1] > (cursor[1] + elOffset[1])) {
            cursor[1] = windowOffset[1] - elOffset[1];
        }
    }

    //Check horizontal position
    if ((windowSize[0] + windowOffset[0]) < ((cursor[0] + elOffset[0]) + elSize[0])) {
        cursor[0] = cursor[0] - elSize[0];
        if (containerOffset != null) {
            cursor[0] = cursor[0] - containerOffset[0] + 2;
        }
    }

    return cursor;
}
function _contextMenu_windowOffset() {
    var scrOfX = 0, scrOfY = 0;
    if (typeof (window.pageYOffset) == 'number') {
        scrOfY = window.pageYOffset;
        scrOfX = window.pageXOffset;
    } else if (document.body && (document.body.scrollLeft || document.body.scrollTop)) {
        scrOfY = document.body.scrollTop;
        scrOfX = document.body.scrollLeft;
    } else if (document.documentElement && (document.documentElement.scrollLeft || document.documentElement.scrollTop)) {
        scrOfY = document.documentElement.scrollTop;
        scrOfX = document.documentElement.scrollLeft;
    }
    return [scrOfX, scrOfY];
}
function _contextMenu_windowSize() {
    var winWidth = 0, winHeight = 0;
    if (typeof (window.innerWidth) == 'number') {
        winWidth = window.innerWidth;
        winHeight = window.innerHeight;
    } else if (document.documentElement && (document.documentElement.clientWidth || document.documentElement.clientHeight)) {
        winWidth = document.documentElement.clientWidth;
        winHeight = document.documentElement.clientHeight;
    } else if (document.body && (document.body.clientWidth || document.body.clientHeight)) {
        winWidth = document.body.clientWidth;
        winHeight = document.body.clientHeight;
    }
    return [winWidth, winHeight];
}

//  *********************************************************
//  ***              Context menu item object             ***
//  *********************************************************
function contensisMenuItem(name, callBackFunction, parent) {
    this.callBack = callBackFunction;
    this.callBackArgs = new Array();
    this.enabled = true;
    this.items = new contensisMenuItemCollection(this);
    this.level = 2;
    this.name = name;
    //this.parent = parent;
}
contensisMenuItem.prototype.callBack = null;
contensisMenuItem.prototype.callBackArgs = null;
contensisMenuItem.prototype.cssClass = null;
contensisMenuItem.prototype.generate = _menuItem_generate;
contensisMenuItem.prototype.hasChildren = _menuItem_hasChildren;
contensisMenuItem.prototype.name = new String();
contensisMenuItem.prototype.onmousedown = _menuItem_onmousedown;
contensisMenuItem.prototype.onmouseout = _menuItem_onmouseout;
contensisMenuItem.prototype.onmouseover = _menuItem_onmouseover;
contensisMenuItem.prototype.selected = false;
contensisMenuItem.prototype.separator = false;
contensisMenuItem.prototype.timeOut = 0;
contensisMenuItem.prototype.timeOutType = '';
//  *********************************************************
//  ***            Context menu item functions            ***
//  *********************************************************
function _menuItem_generate(Parent) {
    var li = menuManager.getElement('li');
    Parent.appendChild(li);
    var span = menuManager.getElement('span');
    var a = menuManager.getElement('a');

    li.appendChild(a);
    a.appendChild(span);

    //Circular reference....
    li.menuItem = this;
    li.id = generateID();
    this.HtmlID = li.id
    if (this.separator == true) {
        a.className = 'separator';
        window.ContensisUtility.setInnerHTML(span, '&nbsp');
    } else {
        a.className = 'item';
        window.ContensisUtility.setInnerHTML(span, this.name);
        if (this.imageSource != null && this.imageSource != '') {
            if (window.location.protocol == 'https:') {
                a.style.backgroundImage = 'url(' + window.location.protocol + '//' + window.location.host + this.imageSource + ')';
            }
            else {
                a.style.backgroundImage = 'url(' + this.imageSource + ')';
            }
        }
        if (this.selected) {
            li.className = (li.className + ' selected').replace(/^\s/, '');
        }
        if (this.enabled) {
            li.onmouseout = _menuItem_onmouseout;
            li.onmouseover = _menuItem_onmouseover;
            a.href = "#"
            li.oncontextmenu = menuManager.cancel;
            li.onmousedown = menuManager.cancel;
            li.onclick = menuManager.itemClick;
        } else {
            li.className = (li.className + ' disabled').replace(/^\s/, '');
        }
        li.menuItem.HasGenerated = false;
        if (this.hasChildren() == true) {
            if (this.enabled) {
                span.className = (span.className + ' group').replace(/^\s/, '');
            } else {
                span.className = (span.className + ' groupDisabled').replace(/^\s/, '');
            }
            //this.items.generate(li);            
        } else {
            if (this.callBack == null) {
                return null;
            }
        }
    }
    li = null
    span = null
    a = null
}
function _menuItem_hasChildren() {
    return (this.items.count() > 0);
}
function _menuItem_onmousedown(evt) {
    return false;
}
function _menuItem_onmouseout(evt) {
    if (evt == null) { evt = window.event; }
    var li = document.getElementById(this.menuItem.HtmlID);
    var a = li.getElementsByTagName('a')[0];
    a.className = 'item';
    if (this.menuItem.timeOut != 0 && this.menuItem.timeOutType == 'show') {
        window.clearTimeout(this.menuItem.timeOut);
        this.menuItem.timeOut = 0;
    }
    if (this.menuItem.hasChildren() == true && this.childNodes[1].style.left != '') {
        this.menuItem.timeOut = window.setTimeout('menuManager.hideChild(\'' + this.id + '\')', 500)
        this.menuItem.timeOutType = 'hide';
    }
    return false;
}
function _menuItem_onmouseover(evt) {
    if (evt == null) {
        evt = window.event;
    }
    var li = document.getElementById(this.menuItem.HtmlID);
    if (!li.menuItem.HasGenerated) {
        if (li.menuItem.hasChildren()) {
            li.menuItem.items.generate(li);
        }
    }
    li.menuItem.HasGenerated = true;

    var a = li.getElementsByTagName('a')[0];
    a.className = 'item item-hover';
    if (this.menuItem.timeOut != 0 && this.menuItem.timeOutType == 'hide') {
        window.clearTimeout(this.menuItem.timeOut);
        this.menuItem.timeOut = 0;
    }
    if (this.menuItem.hasChildren() == true && this.childNodes[1].style.left == '') {
        this.menuItem.timeOut = window.setTimeout('menuManager.showChild(\'' + this.id + '\',[' + (this.parentNode.offsetWidth - 1) + ',' + this.offsetTop + '])', 500)
        this.menuItem.timeOutType = 'show';
    }
    return false;
}

//  *********************************************************
//  ***         Context menu item collection object       ***
//  *********************************************************
function contensisMenuItemCollection(parent) {
    //this.parent = parent;

    /*
    possible leak
    var divUp = document.createElement('div', 'ContextMenu');
    var aUp = document.createElement('a', 'ContextMenu');
    var divDown = document.createElement('div', 'ContextMenu');
    var aDown = document.createElement('a', 'ContextMenu');

    divUp.className = 'scroll up'    
    aUp.href = '#';
    aUp.title = 'Scroll Up';
    aUp.innerHTML = '&nbsp;';
    divUp.appendChild(aUp);
    divDown.className = 'scroll down'
    aDown.href = '#';
    aDown.title = 'Scroll Down';
    aDown.innerHTML = '&nbsp;';
    divDown.appendChild(aDown);
    this.scrollUpElement = divUp;
    this.scrollDownElement = divDown;
    */
    this._innerList = new Array();
}
contensisMenuItemCollection.prototype.add = _menuItemCollection_add;
contensisMenuItemCollection.prototype.contains = _menuItemCollection_contains;
contensisMenuItemCollection.prototype.count = _menuItemCollection_count;
contensisMenuItemCollection.prototype.generate = _menuItemCollection_generate;
contensisMenuItemCollection.prototype.item = _menuItemCollection_item;
contensisMenuItemCollection.prototype.itemByIndex = _menuItemCollection_itemByName;
contensisMenuItemCollection.prototype.parent = null;
contensisMenuItemCollection.prototype.remove = _menuItemCollection_remove;
contensisMenuItemCollection.prototype.scrollUpElement = null;
contensisMenuItemCollection.prototype.scrollDownElement = null;
//  *********************************************************
//  ***       Context menu item collection functions      ***
//  *********************************************************
function _menuItemCollection_add(name, callBackFunction, imageSource, enabled, separator, selected) {
    //    if (this.parent.level > 2) {
    //        alert('Menu\'s are limited to a depth of two levels.');
    //        return null;
    //    }    
    if (typeof (name) != 'string') {
        alert('Please supply a string name for each menu item.');
        return null;
    }
    if (name.length == 0) {
        alert('The menu item name cannot be a zero length.');
        return null;
    }
    if (this.contains(name)) {
        alert('A menu item with the name \'' + name + '\' has already been added to the collection.');
        return null;
    }
    var item = new contensisMenuItem(name, callBackFunction, this.parent);
    if (enabled == false) {
        item.enabled = false;
    }
    if (selected == true) {
        item.selected = true;
    }
    if (separator == true) {
        item.separator = true;
    } else {
        item.separator = false;
    }
    item.imageSource = imageSource;

    if (arguments.length > 6) {
        for (var i = 6; i < arguments.length; i++) {
            item.callBackArgs[i - 6] = arguments[i];
        }
    }
    this._innerList[this._innerList.length] = item;
    return item;
}
function _menuItemCollection_contains(name) {
    for (var i = 0; i < this._innerList.length; i++) {
        if (this._innerList[i].name.toLowerCase() == name.toLowerCase()) {
            return true;
        }
    }
    return false;
}
function _menuItemCollection_count() {
    return this._innerList.length;
}
function _menuItemCollection_generate(ParentElement) {
    //Note ordering to prevent memory leak
    var container = menuManager.getElement('div');
    ParentElement.appendChild(container);

    //if (this.parent.level>1) {
    container.style.position = 'absolute';
    //}
    container.className = "system_contextMenu";

    var ul = menuManager.getElement('ul');
    container.appendChild(ul)

    for (var i = 0; i < this._innerList.length; i++) {
        this._innerList[i].generate(ul);
    }


    return container;
}
function _menuItemCollection_item(index) {
    return this._innerList[index];
}
function _menuItemCollection_itemByName(name) {
    for (var i = 0; i < this._innerList.length; i++) {
        if (this._innerList[i].name.toLowerCase() == name.toLowerCase()) {
            return _innerList[i];
        }
    }
    return false;
}
function _menuItemCollection_remove(index) {
    this._innerList.splice(index, 1);
}

//  *********************************************************
//  ***            Context menu scroll buttons            ***
//  *********************************************************
function contensisMenuScrollButtons(menuElement, currentHeight, totalHeight) {
    if (!menuElement.id) {
        menuElement.id = generateID();
    }
    this.element = menuElement;
    this.currentHeight = currentHeight;
    this.totalHeight = totalHeight;
    var elOffsets = menuManager.elementOffset(menuElement.childNodes[0])

    var upButton = menuManager.getElement('div');
    var upLink = menuManager.getElement('a');
    if (upLink.innerHTML != '&nbsp;') {
        window.ContensisUtility.setInnerHTML(upLink, '&nbsp;');
    }
    upButton.appendChild(upLink);
    menuElement.appendChild(upButton);

    upLink.id = menuElement.id + '_UpLink';
    upLink.href = '#';
    upLink.className = 'up';
    upLink.style.width = (menuElement.offsetWidth - 2) + 'px';

    upButton.id = menuElement.id + '_UpButton';
    upButton.className = 'system_contextScroll';
    upButton.style.left = '0px';
    upButton.style.top = '0px';
    upButton.style.display = 'none';
    upButton.controller = this;

    upButton.onmousedown = contensisMenuScrollButtons_scrollUp;
    upButton.onmouseover = contensisMenuScrollButtons_scrollUp;
    upButton.onmouseup = contensisMenuScrollButtons_scrollUp;
    upButton.onmouseout = contensisMenuScrollButtons_scrollStop;
    upButton.onclick = new Function('evt', 'contensisMenuScrollButtons_scrollUp(); if (evt == null) {evt = window.event}; evt.cancelBubble = true; return false');

    var downButton = menuManager.getElement('div');
    var downLink = menuManager.getElement('a');
    if (downLink.innerHTML != '&nbsp;') {
        window.ContensisUtility.setInnerHTML(downLink, '&nbsp;');
    }
    downButton.appendChild(downLink);
    menuElement.appendChild(downButton);

    downLink.id = menuElement.id + '_DownLink';
    downLink.href = '#';
    downLink.className = 'down';
    downLink.style.width = (menuElement.offsetWidth - 2) + 'px';

    downButton.id = menuElement.id + '_DownButton';
    downButton.className = 'system_contextScroll';
    downButton.style.left = '0px';
    downButton.style.top = (menuElement.offsetHeight - downButton.offsetHeight) + 'px';

    downButton.style.display = '';
    downButton.controller = this;

    downButton.onmouseover = contensisMenuScrollButtons_scrollDown;
    downButton.onmousedown = contensisMenuScrollButtons_scrollDown;
    downButton.onmouseout = contensisMenuScrollButtons_scrollStop;
    downButton.onclick = new Function('evt', 'contensisMenuScrollButtons_scrollDown(); if (evt == null) {evt = window.event}; evt.cancelBubble = true; return false;');

    this.downButton = downButton;
    this.upButton = upButton;
    this.interval = 0;
    this.change = 0;
}

function contensisMenuScrollButtons_doScroll(id, change) {
    el = document.getElementById(id);

    if (el == null) {
        return false;
    }
    if (!el.controller) { return false; }
    el.controller.change += change;
    if (el.controller.change >= 0) {
        if (el.controller.mouseDown == false) {
            el.controller.upButton.style.display = 'none';
        }
    } else {
        el.controller.upButton.style.display = '';
    }
    if ((el.controller.currentHeight - el.controller.change) >= el.controller.totalHeight) {
        if (el.controller.mouseDown == false) {
            el.controller.downButton.style.display = 'none';
        }
    } else {
        el.controller.downButton.style.display = '';
    }
    if ((el.controller.currentHeight - el.controller.change) >= el.controller.totalHeight) {
        el.controller.change = el.controller.currentHeight - el.controller.totalHeight;
        el.controller.element.childNodes[0].style.marginTop = el.controller.change;
        window.clearInterval(el.controller.interval);
        el.controller.interval = 0;
        return false;
    }
    if (el.controller.change >= 0) {
        el.controller.change = 0;
        el.controller.element.childNodes[0].style.marginTop = el.controller.change;
        window.clearInterval(el.controller.interval);
        el.controller.interval = 0;
        return false;
    }
    el.controller.element.childNodes[0].style.marginTop = el.controller.change + 'px';
}
function contensisMenuScrollButtons_scrollDown(evt) {
    if (evt == null) { evt = window.event }
    var el = srcElement(evt).parentNode;  
    var interval = 10;
    var change = 1;
    if (!el.controller) { return false; }
    el.controller.mouseDown = false;
    if (evt.button == 1) {
        interval = 1;
        change = 2;
        el.controller.mouseDown = true;
    }
    if (el.controller.interval != 0) {
        window.clearInterval(el.controller.interval);
    }
    el.controller.interval = window.setInterval('contensisMenuScrollButtons_doScroll(\'' + el.id + '\', -' + change + ')', interval)
    //evt.cancelBubble = true;
    return false;
}
function contensisMenuScrollButtons_scrollStop(evt) {
    if (evt == null) { evt = window.event }
    var el = srcElement(evt).parentNode;  
    if (!el.controller) { return false; }
    if (el.controller.interval != 0) {
        window.clearInterval(el.controller.interval)
    }
}
function contensisMenuScrollButtons_scrollUp(evt) {
    if (evt == null) { evt = window.event }
    var el = srcElement(evt).parentNode;  
    var interval = 20;
    var change = 1;
    if (!el.controller) { return false; }
    el.controller.mouseDown = false;
    if (evt.button == 1) {
        interval = 1;
        change = 2;
        el.controller.mouseDown = true;
    }
    if (el.controller.interval != 0) {
        window.clearInterval(el.controller.interval);
    }
    el.controller.interval = window.setInterval('contensisMenuScrollButtons_doScroll(\'' + el.id + '\', ' + change + ')', interval)
    //evt.cancelBubble = true;
    return false;
}

function srcElement(evt) {
    var targ;
    if (evt.target) {
        targ = evt.target
    } else {
        if (evt.srcElement) {
            targ = evt.srcElement;
        }
        if (targ.nodeType == 3) {
            targ = targ.parentNode;
        }
    }
    return targ;
}

function generateID() {
    var randomID;
    var unique = false;

    while (!unique) {
        randomID = "MI_" + Math.floor(Math.random() * 1000001);
        if (!document.getElementById(randomID)) {
            unique = true;
        }
    }
    return randomID;
}

InitaliseContextMenuManager(false);
