

var __aspxMIIdSuffix = "_DXI";
var __aspxMMIdSuffix = "_DXM";

ASPxClientMenuItemInfo = _aspxCreateClass(null, {
	constructor: function(menu, indexPath){
        this.clientHeight = 0;
        this.clientWidth = 0;
        this.clientTop = 0;
        this.clientLeft = 0;
        this.offsetHeight = 0;
        this.offsetWidth = 0;
        this.offsetTop = 0;
        this.offsetLeft = __aspxAbsoluteRightPosition;
        
        var imageElement = (indexPath != "") ? menu.GetItemImageCell(indexPath) : null;
        if(imageElement != null){
            this.clientWidth += imageElement.clientWidth;
            this.offsetWidth += imageElement.offsetWidth;
            if(this.clientLeft == 0) 
                this.clientLeft = _aspxGetClientLeft(imageElement);
            if(this.offsetLeft > imageElement.offsetLeft)
                this.offsetLeft = imageElement.offsetLeft;
        }
        var indentElement = (indexPath != "") ? menu.GetItemIndentCell(indexPath) : null;
        if(indentElement != null){
            this.clientWidth += indentElement.clientWidth;
            this.offsetWidth += indentElement.offsetWidth;
        }
        var textElement = (indexPath != "") ? menu.GetItemTextCell(indexPath) : null;
        if(textElement != null){ 
            this.clientWidth += textElement.clientWidth;
            this.offsetWidth += textElement.offsetWidth;
            if(this.clientLeft == 0) 
                this.clientLeft = _aspxGetClientLeft(textElement);
            if(this.offsetLeft > textElement.offsetLeft)
                this.offsetLeft = textElement.offsetLeft;

            this.clientHeight = textElement.clientHeight;
            this.clientTop = _aspxGetClientTop(textElement);
            this.offsetHeight += textElement.offsetHeight;
            this.offsetTop = textElement.offsetTop;
        }
        var popOutImageElement = (indexPath != "") ? menu.GetItemPopOutImageCell(indexPath) : null;
        if(popOutImageElement != null){
            this.clientWidth += popOutImageElement.clientWidth;
            this.offsetWidth += popOutImageElement.offsetWidth;
            if(this.clientLeft == 0) 
                this.clientLeft = _aspxGetClientLeft(popOutImageElement);
            if(this.offsetLeft > popOutImageElement.offsetLeft)
                this.offsetLeft = popOutImageElement.offsetLeft;
        }
    }
});
ASPxClientMenuBase = _aspxCreateClass(ASPxClientControl, {
	constructor: function(name){
		this.constructor.prototype.constructor.call(this, name);

        this.allowSelectItem = false;
        this.allowCheckItems = false;
        this.appearAfter = 300;
        this.animationDelay = 30;
        this.animationMaxDelay = 400;
        this.disappearAfter = 500;
        this.enableAnimation = true;
        this.checkedItems = new Array();
        this.itemCheckedGroups = new Array();
        this.lockHoverEvents = false;
        this.popupToLeft = false;
        this.popupCount = 0;
        this.rootItem = null;
        
        this.rootSubMenuFIXOffset = 0;
        this.rootSubMenuFIYOffset = 0;
        this.rootSubMenuLIXOffset = 0;
        this.rootSubMenuLIYOffset = 0;
        this.rootSubMenuXOffset = 0;
        this.rootSubMenuYOffset = 0;
        this.subMenuFIXOffset = 0;
        this.subMenuFIYOffset = 0;
        this.subMenuLIXOffset = 0;
        this.subMenuLIYOffset = 0;
        this.subMenuXOffset = 0;
        this.subMenuYOffset = 0;
        this.ItemClick = new ASPxClientEvent();
        this.ItemMouseOver = new ASPxClientEvent();
        this.ItemMouseOut = new ASPxClientEvent();
        this.PopUp = new ASPxClientEvent();
        this.CloseUp = new ASPxClientEvent();
        
        aspxGetMenuCollection().Add(this);
    },
    InlineInitialize: function(){
        this.InitializeEnabledAndVisible();
        this.InitializeCheckedItems();
        this.InitializeSelectedItem();
    },
	InitializeEnabledAndVisible: function(){
	    if(this.rootItem == null) return;
	    
        this.rootItem.InitializeEnabled();
        this.rootItem.InitializeVisible();
	},
	
    GetMenuElement: function(indexPath){
        return _aspxGetElementById(this.name + __aspxMMIdSuffix + indexPath + "_");
    },
    GetMenuIFrameElement: function(indexPath){
        var level = this.GetMenuLevel(indexPath);
        return _aspxGetElementById(this.name + "_DXMIF" + level);
    },
    GetMenuBorderCorrectorElement: function(indexPath){
        return _aspxGetElementById(this.name + "_DXMBC" + indexPath + "_");
    },
    GetMenuMainCell: function(element){
        return this.GetMenuMainTable(element).rows[0].cells[0];
    },
    GetMenuMainTable: function(element){
        var indexPath = this.GetIndexPathById(element.id, true);
        var shadowTable = _aspxGetElementById(this.name + "_DXMST" + indexPath + "_");
        return shadowTable != null ? shadowTable : element;
    },    
    GetMouseEventItemElement: function(indexPath) {
        var itemElement = null;
        itemElement = this.GetItemTextCell(indexPath);
        if (itemElement == null)
            itemElement = this.GetItemImageCell(indexPath);
        return itemElement;
    },
    
    GetItemElement: function(indexPath){
        return _aspxGetElementById(this.name + __aspxMIIdSuffix + indexPath + "_");
    },
    GetItemTemplateCell: function(indexPath){
        return _aspxGetElementById(this.name + __aspxMIIdSuffix + indexPath + "_ITC");
    },
    GetItemImageCell: function(indexPath){
        return _aspxGetElementById(this.name + __aspxMIIdSuffix + indexPath + "_I");
    },
    GetItemIndentCell: function(indexPath){
        return _aspxGetElementById(this.name + __aspxMIIdSuffix + indexPath + "_N");
    },
    GetItemTextCell: function(indexPath){
        return _aspxGetElementById(this.name + __aspxMIIdSuffix + indexPath + "_T");
    },
    GetItemPopOutImageCell: function(indexPath){
        return _aspxGetElementById(this.name + __aspxMIIdSuffix + indexPath + "_P");
    },
    
    GetSelectedItemInputElement: function(){
        return _aspxGetElementById(this.name + "SI");
    },
    GetCheckedItemsInputElement: function(){
        return _aspxGetElementById(this.name + "CI");
    },
        
    GetSubMenuXPosition: function(indexPath, menuElement){
        var position = 0;
        var element = null;
        var imageElement = this.GetItemImageCell(indexPath);
        var textElement = this.GetItemTextCell(indexPath);
        var popOutImageElement = this.GetItemPopOutImageCell(indexPath);
        var imagePos = _aspxGetAbsoluteX(imageElement);
        var textPos = _aspxGetAbsoluteX(textElement);
        var popOutImagePos = _aspxGetAbsoluteX(popOutImageElement);
        
        if(imageElement != null || textElement != null || popOutImageElement != null){
            if(this.IsVertical(indexPath)){
                position = __aspxAbsoluteLeftPosition;
                if(imageElement != null && position < imagePos){
                    position = imagePos;
                    element = imageElement;
                }
                if(textElement != null && position < textPos){
                    position = textPos;
                    element = textElement;
                }
                if(popOutImageElement != null && position < popOutImagePos){
                    position = popOutImagePos;
                    element = popOutImageElement;
                }
                position = _aspxGetAbsoluteX(element) + element.clientWidth;
            }
            else{
                position = __aspxAbsoluteRightPosition;
                if(imageElement != null && position > imagePos){
                    position = imagePos;
                    element = imageElement; 
                }
                if(textElement != null && position > textPos){
                    position = textPos;
                    element = textElement;
                }
                if(popOutImageElement != null && position > popOutImagePos){
                    position = popOutImagePos;
                    element = popOutImageElement;
                }
            }
            if (element != null && _aspxIsExistsAbsolutePosParent(element))
                position -= _aspxGetIEDocumentClientOffset(true);
        }
        return position;
    },
    GetSubMenuYPosition: function(indexPath, menuElement){
        var position = 0;
        var element = this.GetItemTextCell(indexPath);
        if(element == null)
            element = this.GetItemImageCell(indexPath);
        if(element != null){
            if(this.IsVertical(indexPath)){
                position = _aspxGetAbsoluteY(element);
            }
            else{
                if(__aspxNS || __aspxOpera9)
                    position = _aspxGetAbsoluteY(element) + element.offsetHeight - _aspxGetClientTop(element);
                else if(__aspxSafari)
                    position = _aspxGetAbsoluteY(element) + element.offsetHeight + element.offsetTop - _aspxGetClientTop(element);
                else
                    position = _aspxGetAbsoluteY(element) + element.clientHeight + _aspxGetClientTop(element);
            }
            if (_aspxIsExistsAbsolutePosParent(element))
                position -= _aspxGetIEDocumentClientOffset(false);
        }
        return position;
    },
    GetClientSubMenuXPosition: function(element, x, indexPath){
        var itemInfo = new ASPxClientMenuItemInfo(this, indexPath);
        var itemWidth = itemInfo.clientWidth;
        var itemOffsetWidth = itemInfo.offsetWidth;
        var menuWidth = this.GetMenuMainCell(element).offsetWidth;
        var bodyWidth = _aspxGetDocumentClientWidth();
        
        if(this.IsVertical(indexPath)){
            var left = x - _aspxGetDocumentScrollLeft();
            var right = left + menuWidth;
            var toLeftX = x - menuWidth - itemWidth;
            var toLeftLeft = left - menuWidth - itemWidth;
            var toLeftRight = right - menuWidth - itemWidth;
            if(this.popupToLeft){
                if(toLeftLeft < 0 && toLeftLeft < bodyWidth - right){
                    this.popupToLeft = false;
                    return x;
                }
                else
                    return toLeftX;
            }
            else{
                if(bodyWidth - right < 0 && bodyWidth - right < toLeftLeft){
                    this.popupToLeft = true;
                    return toLeftX;
                }
                else
                    return x;
            }
        }
        else{
            var left = x - _aspxGetDocumentScrollLeft();
            var right = left + menuWidth;
            var toLeftX = x - menuWidth + itemOffsetWidth;
            var toLeftLeft = left - menuWidth + itemOffsetWidth;
            var toLeftRight = right - menuWidth + itemOffsetWidth;
            if(this.popupToLeft){
                if(toLeftLeft < 0 && toLeftLeft < bodyWidth - right){
                    this.popupToLeft = false;
                    return x;
                }
                else
                    return toLeftX;
            }
            else{
                if(bodyWidth - right < 0 && bodyWidth - right < toLeftLeft){
                    this.popupToLeft = true;
                    return toLeftX;
                 }
                 else
                    return x;
            }
        }
    },
    GetClientSubMenuYPosition: function(element, y, indexPath){
        var itemInfo = new ASPxClientMenuItemInfo(this, indexPath);
        var itemHeight = itemInfo.clientHeight;
        var itemOffsetHeight = itemInfo.offsetHeight;
        var menuHeight = this.GetMenuMainCell(element).offsetHeight;
        
        var top = y - _aspxGetDocumentScrollTop();
        var bottom = top + menuHeight;
        var bodyHeight = _aspxGetDocumentClientHeight();
            
        if(this.IsVertical(indexPath)){
            menuHeight -= itemOffsetHeight - itemHeight;
            if(bottom > bodyHeight && top - menuHeight + itemHeight > bodyHeight - bottom)
                return y - menuHeight + itemHeight;
        }
        else{
            if(bottom > bodyHeight && top - menuHeight - itemHeight > bodyHeight - bottom)
                return y - menuHeight - itemHeight;
        }
        return y;
    },
        
    HasChildren: function(indexPath){
        return (this.GetMenuElement(indexPath) != null);
    },
    IsVertical: function(indexPath){
        return true;
    },
    IsRootItem: function(indexPath){
        return this.GetMenuLevel(indexPath) <= 1;
    },
    IsParentElementPositionStatic: function(indexPath){
        return this.IsRootItem(indexPath);
    },
    
    GetItemIndexPath: function(indexes){
        return aspxGetMenuCollection().GetItemIndexPath(indexes);
    },
    GetItemIndexes: function(indexPath){
        return aspxGetMenuCollection().GetItemIndexes(indexPath);
    },
    GetItemIndexPathById: function(id){
        return aspxGetMenuCollection().GetIndexPathById(id, false);
    },
    GetMenuIndexPathById: function(id){
        return aspxGetMenuCollection().GetIndexPathById(id, true);
    },
    GetIndexPathById: function(id, checkMenu){
        var indexPath = this.GetItemIndexPathById(id);
        if(indexPath == "" && checkMenu) 
            indexPath = this.GetMenuIndexPathById(id);
        return indexPath;
    },
    GetMenuLevel: function(indexPath){
        return aspxGetMenuCollection().GetMenuLevel(indexPath);
    },
    
    GetParentIndexPath: function(indexPath){
        var indexes = this.GetItemIndexes(indexPath);
        indexes.length --;
        return (indexes.length > 0) ? this.GetItemIndexPath(indexes) : ""; 
    },
    IsLastElement: function(element){
        return _aspxIsExists(element) && (!_aspxIsExists(element.nextSibling) || !_aspxIsExists(element.nextSibling.tagName));
    },
    IsLastItem: function(indexPath){
        if(this.IsVertical(indexPath)){
            var itemElement = this.GetItemElement(indexPath);
            return this.IsLastElement(itemElement);
        }    
        else{
            var imageCell = this.GetItemImageCell(indexPath);
            if(this.IsLastElement(imageCell))
                return true;
            var textCell = this.GetItemTextCell(indexPath);
            if(this.IsLastElement(textCell))
                return true;
            var popOutImageCell = this.GetItemPopOutImageCell(indexPath);
            if(this.IsLastElement(popOutImageCell))
                return true;
            return false;
        }
    },
    IsFirstElement: function(element){
        return _aspxIsExists(element) && (!_aspxIsExists(element.previousSibling) || !_aspxIsExists(element.previousSibling.tagName));
    },
    IsFirstItem: function(indexPath){
        if(this.IsVertical(indexPath)){
            var itemElement = this.GetItemElement(indexPath);
            return this.IsFirstElement(itemElement);
        }    
        else{
            var imageCell = this.GetItemImageCell(indexPath);
            if(this.IsFirstElement(imageCell))
                return true;
            var textCell = this.GetItemTextCell(indexPath);
            if(this.IsFirstElement(textCell))
                return true;
            var popOutImageCell = this.GetItemPopOutImageCell(indexPath);
            if(this.IsFirstElement(popOutImageCell))
                return true;
            return false;
        }
    },
    GetClientSubMenuPos:function(element, indexPath, pos, isXPos){
        if (!_aspxGetIsValidPosition(pos)){
            pos = isXPos ? this.GetSubMenuXPosition(indexPath, element) : 
                this.GetSubMenuYPosition(indexPath, element);
            if(__aspxSafari){
                if(!this.IsParentElementPositionStatic(indexPath))
                    pos -= isXPos ? document.body.offsetLeft : document.body.offsetTop;
            }    
        }
        
        var clientPos = isXPos ? this.GetClientSubMenuXPosition(element, pos, indexPath) :
            this.GetClientSubMenuYPosition(element, pos, indexPath);
        var isInverted = pos != clientPos;
        var offset = isXPos ? this.GetSubMenuXOffset(indexPath) : this.GetSubMenuYOffset(indexPath);
        clientPos += isInverted ? - offset : offset;
		clientPos -= _aspxGetPositionElementOffset(this.GetMainElement(), isXPos);
        return new _aspxPopupPosition(clientPos, isInverted);
    },
    GetSubMenuXOffset: function(indexPath){
        if(indexPath == "")
            return 0;
        else if(this.IsRootItem(indexPath)){
            if(this.IsFirstItem(indexPath))
                return this.rootSubMenuFIXOffset;
            else if(this.IsLastItem(indexPath))
                return this.rootSubMenuLIXOffset;
            else
                return this.rootSubMenuXOffset;
        }
        else{
            if(this.IsFirstItem(indexPath))
                return this.subMenuFIXOffset;
            else if(this.IsLastItem(indexPath))
                return this.subMenuLIXOffset;
            else
                return this.subMenuXOffset;
        }
    },
    GetSubMenuYOffset: function(indexPath){
        if(indexPath == "")
            return 0;
        else if(this.IsRootItem(indexPath)){
            if(this.IsFirstItem(indexPath))
                return this.rootSubMenuFIYOffset;
            else if(this.IsLastItem(indexPath))
                return this.rootSubMenuLIYOffset;
            else
                return this.rootSubMenuYOffset;
        }
        else{
            if(this.IsFirstItem(indexPath))
                return this.subMenuFIYOffset;
            else if(this.IsLastItem(indexPath))
                return this.subMenuLIYOffset;
            else
                return this.subMenuYOffset;
        }
    },
    
    ClearAppearTimer: function(){
        aspxGetMenuCollection().ClearAppearTimer();
    },
    ClearDisappearTimer: function(){
        aspxGetMenuCollection().ClearDisappearTimer();
    },
    IsAppearTimerActive: function(){
        return aspxGetMenuCollection().IsAppearTimerActive();
    },
    IsDisappearTimerActive: function(){
        return aspxGetMenuCollection().IsDisappearTimerActive();
    },
    SetAppearTimer: function(indexPath){
        aspxGetMenuCollection().SetAppearTimer(this.name, indexPath, this.appearAfter);
    },
    SetDisappearTimer: function(){
        aspxGetMenuCollection().SetDisappearTimer(this.name, this.disappearAfter);
    },
    
    DoItemClick: function(indexPath, hasItemLink, htmlEvent){
        var processOnServer = this.RaiseItemClick(indexPath, htmlEvent);
        if(processOnServer && !hasItemLink)
            this.SendPostBack("CLICK:" + indexPath);
        else{
            this.ClearDisappearTimer();
            this.ClearAppearTimer();
            if(!this.HasChildren(indexPath))
                aspxGetMenuCollection().DoHidePopupMenus(null, -1, this.name, false, "");
            else if(this.IsItemEnabled(indexPath))
                this.ShowSubMenu(indexPath);
        }
    },
    DoShowPopupMenu: function(element, x, y, indexPath){
        if(__aspxNS)
            _aspxSetStylePosition(element, -1000, -1000);
        _aspxSetElementDisplay(element, true);

        if(this.popupCount == 0) this.popupToLeft = false;
        var horizontalPopupPosition = this.GetClientSubMenuPos(element, indexPath, x, true);
        var verticalPopupPosition = this.GetClientSubMenuPos(element, indexPath, y, false);
        var clientX = horizontalPopupPosition.position;
        var clientY = verticalPopupPosition.position;
        var toTheLeft = horizontalPopupPosition.isInverted;
        var toTheTop = verticalPopupPosition.isInverted;

        if (this.enableAnimation){
            this.StartAnimation(element, indexPath, horizontalPopupPosition, verticalPopupPosition);
        }
        else{
            _aspxSetStylePosition(element, clientX, clientY);
            _aspxSetElementVisibility(element, true);
            
            this.DoShowPopupMenuIFrame(element, clientX, clientY, __aspxInvalidDimension, __aspxInvalidDimension, indexPath);
            this.DoShowPopupMenuBorderCorrector(element, clientX, clientY, indexPath, toTheLeft, toTheTop);
        }
        aspxGetMenuCollection().RegisterVisiblePopupMenu(this.name, element.id);
        this.popupCount ++;
        
        this.RaisePopUp(indexPath);
    },
    DoShowPopupMenuIFrame: function(element, x, y, width, height, indexPath){    
        if (!this.renderIFrameForPopupElements) return;
        
        var iFrame = element.overflowElement;
        if(!_aspxIsExists(iFrame)){
            iFrame = this.GetMenuIFrameElement(indexPath);
            element.overflowElement = iFrame;
        }
        if(_aspxIsExists(iFrame)){
            var cell = this.GetMenuMainCell(element);
            if (width < 0)
                width = cell.offsetWidth;
            if (height < 0)
                height = cell.offsetHeight;
            _aspxSetStyleSize(iFrame, width, height);
            _aspxSetStylePosition(iFrame, x, y);
            _aspxSetElementDisplay(iFrame, true);
        }
    },
    DoShowPopupMenuBorderCorrector: function(element, x, y, indexPath, toTheLeft, toTheTop){
        var borderCorrectorElement = this.GetMenuBorderCorrectorElement(indexPath);
        if(_aspxIsExists(borderCorrectorElement)){
            var itemInfo = new ASPxClientMenuItemInfo(this, indexPath);
            var menuXOffset = _aspxGetClientLeft(this.GetMenuMainCell(element));
            var menuYOffset = _aspxGetClientTop(this.GetMenuMainCell(element));
            var menuClientWidth = this.GetMenuMainCell(element).clientWidth;
            var menuClientHeight = this.GetMenuMainCell(element).clientHeight;
            var width = 0, height = 0, left = 0, top = 0;
            if(this.IsVertical(indexPath)){
                var commonClientHeight = itemInfo.clientHeight < menuClientHeight ? itemInfo.clientHeight : menuClientHeight;
                width = menuXOffset;
                height = commonClientHeight + itemInfo.clientTop - menuYOffset;
                left = toTheLeft ? x + menuClientWidth + menuXOffset : x;
                top = toTheTop ? y + menuClientHeight - height + menuYOffset : y + menuYOffset;
            }
            else{
                var commonClientWidth = itemInfo.clientWidth < menuClientWidth ? itemInfo.clientWidth : menuClientWidth;
                width = commonClientWidth + itemInfo.clientLeft - menuXOffset;
                height = menuYOffset;
                left = toTheLeft ? x + menuClientWidth - width + menuXOffset : x + menuXOffset;
                top = toTheTop ? y + menuClientHeight + menuYOffset : y;
                if(__aspxSafari && itemInfo.offsetLeft > 0)
                    width += itemInfo.clientLeft;
            }
            _aspxSetStyleSize(borderCorrectorElement, width, height);
            _aspxSetStylePosition(borderCorrectorElement, left, top);
            _aspxSetElementVisibility(borderCorrectorElement, true);
            _aspxSetElementDisplay(borderCorrectorElement, true);
            
            element.borderCorrectorElement = borderCorrectorElement;
        }
    },
    DoHidePopupMenu: function(evt, element){
        this.DoHidePopupMenuBorderCorrector(element);
        this.DoHidePopupMenuIFrame(element);

        _aspxStopAnimation(element);
        
        _aspxSetElementVisibility(element, false);
        _aspxSetElementDisplay(element, false);        

        this.CancelSubMenuItemHoverItem(element);
        aspxGetMenuCollection().UnregisterVisiblePopupMenu(this.name, element.id);
        this.popupCount --;

        var indexPath = this.GetIndexPathById(element.id, true);
        this.RaiseCloseUp(indexPath);
    },
    DoHidePopupMenuIFrame: function(element){
        if (!this.renderIFrameForPopupElements) return;

        var iFrame = element.overflowElement;
        if(_aspxIsExists(iFrame))
            _aspxSetElementDisplay(iFrame, false);        
    },
    DoHidePopupMenuBorderCorrector: function(element){
        var borderCorrectorElement = element.borderCorrectorElement;
        if(_aspxIsExists(borderCorrectorElement)){
            _aspxSetElementVisibility(borderCorrectorElement, false);
            _aspxSetElementDisplay(borderCorrectorElement, false);
            element.borderCorrectorElement = null;
        }
    },

    SetHoverElement: function(element){
        this.lockHoverEvents = true;
        aspxGetStateController().SetCurrentHoverElementBySrcElement(element);
        this.lockHoverEvents = false;
    },
    ApplySubMenuItemHoverItem: function(element, hoverItem, hoverElement){
        if(_aspxGetElementDisplay(element) && !_aspxIsExists(element.hoverItem)){
        
            var newHoverItem = hoverItem.Clone();
            element.hoverItem = newHoverItem;
            element.hoverElement = hoverElement;
            newHoverItem.Apply(hoverElement);
        }
    },
    CancelSubMenuItemHoverItem: function(element){
        if(_aspxIsExists(element.hoverItem)){
            element.hoverItem.Cancel(element.hoverElement);
            element.hoverItem = null;
            element.hoverElement = null;
        }
    },
    ShowSubMenu: function(indexPath){
        var element = this.GetMenuElement(indexPath);
        if(element != null){
            var level = this.GetMenuLevel(indexPath);
            aspxGetMenuCollection().DoHidePopupMenus(null, level - 1, this.name, false,  element.id);

            if (!_aspxGetElementDisplay(element))
                this.DoShowPopupMenu(element, __aspxInvalidPosition, __aspxInvalidPosition, indexPath);
        }    
        this.ClearAppearTimer();
    },
    
    SelectItem: function(indexPath){
        var element = this.GetItemTextCell(indexPath);
        if(element == null)
            element = this.GetItemImageCell(indexPath);
        if(element != null)
            aspxGetStateController().SelectElementBySrcElement(element);
    },
    DeselectItem: function(indexPath){
        var element = this.GetItemTextCell(indexPath);
        if(element == null)
            element = this.GetItemImageCell(indexPath);
        if(element != null){
            var hoverItem = null;
            var hoverElement = null;
            var menuElement = this.GetMenuElement(indexPath);
            if (menuElement != null && _aspxIsExists(menuElement.hoverItem)){
                hoverItem = menuElement.hoverItem;
                hoverElement = menuElement.hoverElement;
                this.CancelSubMenuItemHoverItem(menuElement);
            }
            aspxGetStateController().DeselectElementBySrcElement(element);
            if(menuElement != null && hoverItem != null)
                this.ApplySubMenuItemHoverItem(menuElement, hoverItem, hoverElement);
        }
    },
    InitializeSelectedItem: function(){
        if(!this.allowSelectItem) return;
    
        var inputElement = this.GetSelectedItemInputElement();
        if(inputElement != null)
            this.SelectItem(inputElement.value);
    },
    SetSelectedItemInternal: function(indexPath, modifyHotTrackSelection){
        if(modifyHotTrackSelection)
            this.SetHoverElement(null);
        var inputElement = this.GetSelectedItemInputElement();
        if(inputElement != null){
            this.DeselectItem(inputElement.value);
            inputElement.value = indexPath;
            this.SelectItem(inputElement.value);
        }
        if(modifyHotTrackSelection){
            var element = this.GetItemTextCell(indexPath);
            if(element == null)
                element = this.GetItemImageCell(indexPath);
            if(element != null) 
                this.SetHoverElement(element);
        }
    },
    InitializeCheckedItems: function(){
        if(!this.allowCheckItems) return;
        
        var inputElement = this.GetCheckedItemsInputElement();
        if(inputElement != null){
            var indexPathes = inputElement.value.split(";");
            for(var i = 0; i < indexPathes.length; i ++){
                if(indexPathes[i] != ""){
                    _aspxArrayPush(this.checkedItems, indexPathes[i]);
                    this.SelectItem(indexPathes[i]);
                }
            }
        }
    },
    ChangeCheckedItem: function(indexPath){
        this.SetHoverElement(null);
        
        var inputElement = this.GetCheckedItemsInputElement();
        if(inputElement != null){
            var itemsGroup = this.GetItemsGroup(indexPath);
            if(itemsGroup != null){
                if(itemsGroup.length > 1){
                    if(!this.IsCheckedItem(indexPath)){
                        for(var i = 0; i < itemsGroup.length; i ++){
                            if(itemsGroup[i] == indexPath) continue;
                            if(this.IsCheckedItem(itemsGroup[i])){
                                _aspxArrayRemove(this.checkedItems, itemsGroup[i]);
                                this.DeselectItem(itemsGroup[i]);
                            }
                        }
                        this.SelectItem(indexPath);
                        _aspxArrayPush(this.checkedItems, indexPath);
                    }
                }
                else{
                    if(this.IsCheckedItem(indexPath)){
                        _aspxArrayRemove(this.checkedItems, indexPath);
                        this.DeselectItem(indexPath);
                    }
                    else{
                        this.SelectItem(indexPath);
                        _aspxArrayPush(this.checkedItems, indexPath);
                    }
                }
                this.UpdateCheckedInputElement(inputElement);
            }
        }
        
        var element = this.GetItemTextCell(indexPath);
        if(element == null)
            element = this.GetItemImageCell(indexPath);
        if(element != null) 
            this.SetHoverElement(element);
    },
    GetItemsGroup: function(indexPath){
        for(var i = 0; i < this.itemCheckedGroups.length; i ++){
            if(_aspxArrayIndexOf(this.itemCheckedGroups[i], indexPath) > -1)
                return this.itemCheckedGroups[i];
        }
        return null;
    },
    IsCheckedItem: function(indexPath){
        return _aspxArrayIndexOf(this.checkedItems, indexPath) > -1;
    },
    UpdateCheckedInputElement: function(inputElement){
        var state = "";
        for(var i = 0; i < this.checkedItems.length; i ++){
            state += this.checkedItems[i];
            if(i < this.checkedItems.length - 1)
                state += ";";
        }
        inputElement.value = state;
    },
    
    GetAnimationVerticalDirection: function(indexPath, popupPosition){
        var verticalDirection = (this.IsRootItem(indexPath) && !this.IsVertical(indexPath)) ? -1 : 0;
        if (popupPosition.isInverted) verticalDirection *= -1;
        return verticalDirection;
    },
    GetAnimationHorizontalDirection: function(indexPath, popupPosition){
        var horizontalDirection = (this.IsRootItem(indexPath) && !this.IsVertical(indexPath)) ? 0 : -1;
        if (popupPosition.isInverted) horizontalDirection *= -1;
        return horizontalDirection;
    },
    StartAnimation: function(animationDivElement, indexPath, horizontalPopupPosition, verticalPopupPosition){
        var element = this.GetMenuMainTable(animationDivElement);

        var clientX = horizontalPopupPosition.position;
        var clientY = verticalPopupPosition.position;
      
        _aspxInitAnimationDiv(animationDivElement, clientX, clientY, "aspxMATimer(\"" + this.name + "\", " + "\"" + indexPath + "\")", "");
      
        var verticalDirection = this.GetAnimationVerticalDirection(indexPath, verticalPopupPosition);
        var horizontalDirection = this.GetAnimationHorizontalDirection(indexPath, horizontalPopupPosition);
        var yPos = verticalDirection * element.offsetWidth;
        var xPos = horizontalDirection * element.offsetHeight;
      
        _aspxSetStylePosition(element, xPos, yPos);
        
        _aspxSetElementVisibility(animationDivElement, true);
        this.DoShowPopupMenuIFrame(animationDivElement, clientX, clientY, 0, 0, indexPath);
        this.DoShowPopupMenuBorderCorrector(animationDivElement, clientX, clientY, indexPath, 
            horizontalPopupPosition.isInverted, verticalPopupPosition.isInverted);

        animationDivElement.timerID = window.setTimeout(animationDivElement.onTimerString, this.animationDelay);
    },
    OnAnimationTimer: function(indexPath){
        var animationDivElement = this.GetMenuElement(indexPath);
        if(_aspxIsExists(animationDivElement)){
            var element = this.GetMenuMainTable(animationDivElement);
            var mainCell = this.GetMenuMainCell(element);   
            var iframeElement = this.GetMenuIFrameElement(indexPath);
        
            _aspxOnAnimationTimer(animationDivElement, element, mainCell, iframeElement, this.animationDelay, this.animationMaxDelay, __aspxMenuAnimationAccelerator);
        }
    },
    
    OnItemClick: function(indexPath, evt){
        var isLinkClicked = (_aspxGetParentByTagName(_aspxGetEventSource(evt), "A") != null);
        var element = this.GetItemTextCell(indexPath);
        if(element == null)
            element = this.GetItemImageCell(indexPath);
        var linkElement = (element != null) ? _aspxGetChildByTagName(element, "A", 0) : null;

        if(this.allowSelectItem)
            this.SetSelectedItemInternal(indexPath, true); 
        if(this.allowCheckItems)
            this.ChangeCheckedItem(indexPath); 
        this.DoItemClick(indexPath, isLinkClicked || (linkElement != null), evt);
        
        if(!isLinkClicked && linkElement != null) 
            _aspxNavigateUrl(linkElement.href, linkElement.target);
    },
    OnAfterItemOver: function(hoverItem, hoverElement){
        if(hoverItem.name == "" || this.lockHoverEvents) return;

        this.ClearDisappearTimer();
        this.ClearAppearTimer();

        var indexPath = this.GetMenuIndexPathById(hoverItem.name, false);
        if(indexPath == ""){
            indexPath = this.GetIndexPathById(hoverItem.name, true);
            var level = this.GetMenuLevel(indexPath);
            var menuElement = this.GetMenuElement(indexPath);
            var id = (menuElement != null) ? menuElement.id : "";
            aspxGetMenuCollection().DoHidePopupMenus(null, level - 1, this.name, false, id);

            if(hoverItem.enabled){
                this.SetAppearTimer(indexPath);
                this.RaiseItemMouseOver(indexPath);
            }
        }
    },
    OnBeforeItemOver: function(hoverItem, hoverElement){
        if (__aspxNS && _aspxIsExists(hoverElement.offsetParent) && 
                hoverElement.offsetParent.style.borderCollapse == "collapse") {
            hoverElement.offsetParent.style.borderCollapse = "separate";
            hoverElement.offsetParent.style.borderCollapse = "collapse";
        }

        var indexPath = this.GetItemIndexPathById(hoverItem.name);
        var element = this.GetMenuElement(indexPath);
        if(_aspxIsExists(element)) this.CancelSubMenuItemHoverItem(element);  
    },
    OnItemOverTimer: function(indexPath){
        if(this.IsAppearTimerActive()){
            this.ClearAppearTimer();
            if(this.GetItemImageCell(indexPath) != null || this.GetItemIndentCell(indexPath) != null ||
                this.GetItemTextCell(indexPath) != null || this.GetItemPopOutImageCell(indexPath) != null){
                this.ShowSubMenu(indexPath);
            }
        }
    },
    OnBeforeItemDisabled: function(disabledItem, disabledElement){
        this.ClearAppearTimer();
        var indexPath = this.GetIndexPathById(disabledElement.id, false);
        if(indexPath != ""){
            var element = this.GetMenuElement(indexPath);
            if(element != null) this.DoHidePopupMenu(null, element);
        }
    },
    OnAfterItemOut: function(hoverItem, hoverElement, newHoverElement){
        if(hoverItem.name == "" || this.lockHoverEvents) return;
        if(hoverItem.IsChildElement(newHoverElement)) return;
        
        var indexPath = this.GetItemIndexPathById(hoverItem.name);
        var element = this.GetMenuElement(indexPath);
        
        this.ClearDisappearTimer();
        this.ClearAppearTimer();
        if(element == null || !_aspxGetIsParent(element, newHoverElement)) 
            this.SetDisappearTimer();
        
        if(element != null) 
            this.ApplySubMenuItemHoverItem(element, hoverItem, hoverElement);
            
        if(indexPath != "")
            this.RaiseItemMouseOut(indexPath);
    },
    OnItemOutTimer: function(){
        if(this.IsDisappearTimerActive()){
            this.ClearDisappearTimer();
            if(aspxGetMenuCollection().CheckFocusedElement())
                this.SetDisappearTimer();
            else
                aspxGetMenuCollection().DoHidePopupMenus(null, 0, this.name, true, "");
        }
    },
    // API
    CreateItems: function(itemsProperties){
        var itemType = this.GetClientItemType();
        this.rootItem = new itemType(this, null, 0, "");
        this.rootItem.CreateItems(itemsProperties);
    },
    GetClientItemType: function(){
        return ASPxClientMenuItem;
    },
    GetItemByIndexPath: function(indexPath){
        var item = this.rootItem;
        if(indexPath != "" && item != null){
            var indexes = this.GetItemIndexes(indexPath);
            for(var i = 0; i < indexes.length; i ++)
                item = item.GetItem(indexes[i]);
        }
        return item;
    },
    CheckSelectedItem: function(indexPath){
        var selectedItem = this.GetSelectedItem();
        if(selectedItem != null && selectedItem.GetIndexPath() == indexPath)
            this.SetSelectedItem(null);
    },
    SetItemChecked: function(indexPath, checked){
        var inputElement = this.GetCheckedItemsInputElement();
        if(inputElement != null){
            var itemsGroup = this.GetItemsGroup(indexPath);
            if(itemsGroup != null){
                if(!checked && this.IsCheckedItem(indexPath)){
                    _aspxArrayRemove(this.checkedItems, indexPath);
                    this.DeselectItem(indexPath);
                }
                else if(checked && !this.IsCheckedItem(indexPath)){
                    if(itemsGroup.length > 1){
                        for(var i = 0; i < itemsGroup.length; i ++){
                            if(itemsGroup[i] == indexPath) continue;
                            if(this.IsCheckedItem(itemsGroup[i])){
                                _aspxArrayRemove(this.checkedItems, itemsGroup[i]);
                                this.DeselectItem(itemsGroup[i]);
                            }
                        }
                    }
                    this.SelectItem(indexPath);
                    _aspxArrayPush(this.checkedItems, indexPath);
                }
                this.UpdateCheckedInputElement(inputElement);
            }
        }
    },
	ChangeEnabledAttributes: function(indexPath, method, styleMethod){
	    var itemElement = this.IsVertical(indexPath) ? this.GetItemElement(indexPath) : null;
        if(_aspxIsExists(itemElement))
            method(itemElement, "onclick");
        var templateElement = this.GetItemTemplateCell(indexPath);
        if(_aspxIsExists(templateElement))
            method(templateElement, "onclick");
        var imageElement = this.GetItemImageCell(indexPath);
        if(_aspxIsExists(imageElement)){
            method(imageElement, "onclick");
            styleMethod(imageElement, "cursor");
   	        var link = _aspxGetChildByTagName(imageElement, "A", 0);
   	        if(link != null){
   	            method(link, "onclick");
   	            method(link, "href");
            }
        }
        var textElement = this.GetItemTextCell(indexPath);
        if(_aspxIsExists(textElement)){
            method(textElement, "onclick");
            styleMethod(textElement, "cursor");
   	        var link = _aspxGetChildByTagName(textElement, "A", 0);
   	        if(link != null){
   	            method(link, "onclick");
   	            method(link, "href");
            }
   	        link = _aspxGetChildByTagName(textElement, "A", 1);
   	        if(link != null){
   	            method(link, "onclick");
   	            method(link, "href");
            }
        }
        var popOutImageElement = this.GetItemPopOutImageCell(indexPath);
        if(_aspxIsExists(popOutImageElement)){
            method(popOutImageElement, "onclick");
            styleMethod(popOutImageElement, "cursor");
        }
        var indentElement = this.GetItemIndentCell(indexPath);
        if(_aspxIsExists(indentElement)){
            method(indentElement, "onclick");
            styleMethod(indentElement, "cursor");
        }
	},
    IsItemEnabled: function(indexPath){
        var item = this.GetItemByIndexPath(indexPath);
        return (item != null) ? item.GetEnabled() : true;
    },
	SetItemEnabled: function(indexPath, enabled, initialization){
	    if(indexPath == "" || !this.GetItemByIndexPath(indexPath).enabled) return;

        if(!initialization || !enabled)
            this.ChangeItemEnabledStateItems(indexPath, enabled);
        this.ChangeItemEnabledAttributes(indexPath, enabled);
	},
	ChangeItemEnabledStateItems: function(indexPath, enabled){
	    var element = this.GetItemTextCell(indexPath);
	    if(element == null)
	        element = this.GetItemImageCell(indexPath);
	    if(element != null)
            aspxGetStateController().SetElementEnabled(element, enabled);
	},
	ChangeItemEnabledAttributes: function(indexPath, enabled){
	    var element = this.GetItemTextCell(indexPath);
	    if(element == null)
	        element = this.GetItemImageCell(indexPath);
	    if(element != null){
	        element.enabled = enabled;
	        if(!enabled)
	            this.CheckSelectedItem(indexPath);
	        this.ChangeEnabledAttributes(indexPath, _aspxChangeAttributesMethod(enabled), 
	            _aspxChangeStyleAttributesMethod(enabled));
	    }
	},
	GetItemImageUrl: function(indexPath){
        var element = this.GetItemImageCell(indexPath);
        if(element != null){
	        var img = _aspxGetChildByTagName(element, "IMG", 0);
	        if(img != null)
	            return img.src;
        }
        element = this.GetItemTextCell(indexPath);
        if(element != null){
	        var img = _aspxGetChildByTagName(element, "IMG", 0);
	        if(img != null)
	            return img.src;
        }
        return "";
	},
	SetItemImageUrl: function(indexPath, url){
        var element = this.GetItemImageCell(indexPath);
        if(element != null){
	        var img = _aspxGetChildByTagName(element, "IMG", 0);
	        if(img != null)
	            img.src = url;
        }
        element = this.GetItemTextCell(indexPath);
        if(element != null){
	        var img = _aspxGetChildByTagName(element, "IMG", 0);
	        if(img != null)
	            img.src = url;
        }
	},
	GetItemNavigateUrl: function(indexPath){
	    var element = this.GetItemTextCell(indexPath);
	    if(element != null){
	        var link = _aspxGetChildByTagName(element, "A", 0);
	        if(link != null)
	            return link.href;
	    }
	    element = this.GetItemImageCell(indexPath);
	    if(element != null){
	        var link = _aspxGetChildByTagName(element, "A", 0);
	        if(link != null)
	            return link.href;
	    }
	    return "";
	},
	SetItemNavigateUrl: function(indexPath, url){
	    var element = this.GetItemTextCell(indexPath);
	    if(element != null){
	        var link = _aspxGetChildByTagName(element, "A", 0);
	        if(link != null)
	            link.href = url;
	        link = _aspxGetChildByTagName(element, "A", 1);
	        if(link != null)
	            link.href = url;
	    }
	    element = this.GetItemImageCell(indexPath);
	    if(element != null){
	        var link = _aspxGetChildByTagName(element, "A", 0);
	        if(link != null)
	            link.href = url;
	    }
	},
	GetItemText: function(indexPath){
	    var element = this.GetItemTextCell(indexPath);
	    if(element != null){
	        var textNode = _aspxGetChildTextNode(element, 0);
	        if(textNode != null)
	            return textNode.nodeValue;
	    }
	    return "";
	},
	SetItemText: function(indexPath, text){
	    var element = this.GetItemTextCell(indexPath);
	    if(element != null){
	        var textNode = _aspxGetChildTextNode(element, 0);
	        if(textNode != null)
	            textNode.nodeValue = text;
	    }
	},
	SetItemVisible: function(indexPath, visible){
	    if(indexPath == "" || !this.GetItemByIndexPath(indexPath).visible) return;
	    
	    if(!visible)
            this.CheckSelectedItem(indexPath);
            
	    var element = null;
	    if(this.IsVertical(indexPath)){
	        element = this.GetItemElement(indexPath);
	        if(element != null)
	            _aspxSetElementDisplay(element, visible);
	    }
	    else{
	        element = this.GetItemTemplateCell(indexPath);
	        if(element != null)
	            _aspxSetElementDisplay(element, visible);
	        element = this.GetItemImageCell(indexPath);
	        if(element != null)
	            _aspxSetElementDisplay(element, visible);
	        element = this.GetItemTextCell(indexPath);
	        if(element != null)
	            _aspxSetElementDisplay(element, visible);
	        element = this.GetItemPopOutImageCell(indexPath);
	        if(element != null)
	            _aspxSetElementDisplay(element, visible);
	    }
        this.SetIndentsVisiblility(indexPath);
        this.SetSeparatorsVisiblility(indexPath);
	},
	SetIndentsVisiblility: function(indexPath){
	    var parent = this.GetItemByIndexPath(indexPath).parent;
        for(var i = 0; i < parent.GetItemCount(); i++){
            var item = parent.GetItem(i);
            var separatorVisible = item.GetVisible() && this.HasNextVisibleItems(parent, i);
            var element = this.GetItemIndentElement(item.GetIndexPath());
            if(element != null) _aspxSetElementDisplay(element, separatorVisible);
        }
	},
	SetSeparatorsVisiblility: function(indexPath){
	    var parent = this.GetItemByIndexPath(indexPath).parent;
        for(var i = 0; i < parent.GetItemCount(); i++){
            var item = parent.GetItem(i);
            var separatorVisible = item.GetVisible() && this.HasPrevVisibleItems(parent, i);
            var element = this.GetItemSeparatorElement(item.GetIndexPath());
            if(element != null) _aspxSetElementDisplay(element, separatorVisible);
            element = this.GetItemSeparatorIndentElement(item.GetIndexPath());
            if(element != null) _aspxSetElementDisplay(element, separatorVisible);
        }
	},
	HasNextVisibleItems: function(parent, index){
        for(var i = index + 1; i < parent.GetItemCount(); i++){
            if(parent.GetItem(i).GetVisible())
                return true;
        }
        return false;
	},
	HasPrevVisibleItems: function(parent, index){
        for(var i = index - 1; i >= 0; i--){
            if(parent.GetItem(i).GetVisible())
                return true;
        }
        return false;
	},

    GetItemIndentElement: function(indexPath){
        return _aspxGetElementById(this.name + __aspxMIIdSuffix + indexPath + "_II");
    },
    GetItemSeparatorElement: function(indexPath){
        return _aspxGetElementById(this.name + __aspxMIIdSuffix + indexPath + "_IS");
    },
    GetItemSeparatorIndentElement: function(indexPath){
        return _aspxGetElementById(this.name + __aspxMIIdSuffix + indexPath + "_ISI");
    },
    
    RaiseItemClick: function(indexPath, htmlEvent){
        var processOnServer = this.autoPostBack || this.IsServerEventAssigned("ItemClick");
        if(!this.ItemClick.IsEmpty()){
            var item = this.GetItemByIndexPath(indexPath);
            var htmlElement = this.GetMouseEventItemElement(indexPath);
            var args = new ASPxClientMenuItemClickEventArgs(processOnServer, item, htmlElement, htmlEvent);
            this.ItemClick.FireEvent(this, args);
            processOnServer = args.processOnServer;
        }
        return processOnServer;
    },    
    RaiseItemMouseOver: function(indexPath){
        if(!this.ItemMouseOver.IsEmpty()){
            var item = this.GetItemByIndexPath(indexPath);
            var htmlElement = this.GetMouseEventItemElement(indexPath);
            var args = new ASPxClientMenuItemMouseEventArgs(item, htmlElement);
            this.ItemMouseOver.FireEvent(this, args);
        }
    },
    RaiseItemMouseOut: function(indexPath){
        if(!this.ItemMouseOut.IsEmpty()){
            var item = this.GetItemByIndexPath(indexPath);
            var htmlElement = this.GetMouseEventItemElement(indexPath);
            var args = new ASPxClientMenuItemMouseEventArgs(item, htmlElement);
            this.ItemMouseOut.FireEvent(this, args);
        }
    },
    RaisePopUp: function(indexPath){
        var item = this.GetItemByIndexPath(indexPath);
        if(!this.PopUp.IsEmpty()){
            var args = new ASPxClientMenuItemEventArgs(false, item);
            this.PopUp.FireEvent(this, args);
        }
    },
    RaiseCloseUp: function(indexPath){
        var item = this.GetItemByIndexPath(indexPath);
        if(!this.CloseUp.IsEmpty()){
            var args = new ASPxClientMenuItemEventArgs(false, item);
            this.CloseUp.FireEvent(this, args);
        }
    },
    GetItemCount: function(){
        return (this.rootItem != null) ? this.rootItem.GetItemCount() : 0;
    },
    GetItem: function(index){
        return (this.rootItem != null) ? this.rootItem.GetItem(index) : null;
    },
    GetItemByName: function(name){
        return (this.rootItem != null) ? this.rootItem.GetItemByName(name) : null;
    },
	GetSelectedItem: function(){
        var inputElement = this.GetSelectedItemInputElement();
        if(inputElement != null && inputElement.value != "")
            return this.GetItemByIndexPath(inputElement.value);
        return null;
	},
	SetSelectedItem: function(item){
	    var indexPath = (item != null) ? item.GetIndexPath() : "";
	    this.SetSelectedItemInternal(indexPath, false);
	}
});
ASPxClientMenuBase.GetMenuCollection = function(){
    return aspxGetMenuCollection();
}
ASPxClientMenuCollection = _aspxCreateClass(ASPxClientControlCollection, {
	constructor: function(){
		this.constructor.prototype.constructor.call(this);
        
        this.appearTimerID = -1;
        this.disappearTimerID = -1;
        this.visibleSubMenusMenuName = "";
        this.visibleSubMenuIds = new Array();
        this.overXPos = -1;
		this.overYPos = -1;
    },
    RegisterVisiblePopupMenu: function(name, id){
        _aspxArrayPush(this.visibleSubMenuIds, id);
        this.visibleSubMenusMenuName = name;
    },
    UnregisterVisiblePopupMenu: function(name, id){
        _aspxArrayRemove(this.visibleSubMenuIds, id);
        if(this.visibleSubMenuIds.length == 0)
            this.visibleSubMenusMenuName = "";
    },

    GetMenu: function(id){
        return this.Get(this.GetMenuName(id));
    },
    GetMenuName: function(id){
        var pos = id.lastIndexOf(__aspxMMIdSuffix);
        if(pos == -1) 
            pos = id.lastIndexOf(__aspxMIIdSuffix);
        if(pos > -1) 
            return id.substring(0, pos);
        return id;
    },
    GetMenuLevel: function(indexPath){
        if(indexPath == "")
            return 0;
        else{
            var indexes = this.GetItemIndexes(indexPath);
            return indexes.length;
        }
    },
    GetMenuLevelById: function(id, isMenu){    
        var indexPath = this.GetIndexPathById(id, isMenu);
        return this.GetMenuLevel(indexPath);
    },
    GetIndexPathById: function(id, isMenu){
        var idSuffix = isMenu ? __aspxMMIdSuffix : __aspxMIIdSuffix;
        var pos = id.lastIndexOf(idSuffix);
        if(pos > -1){
            id = id.substring(pos + idSuffix.length);
            pos = id.lastIndexOf("_");
            if(pos > -1) 
                return id.substring(0, pos);
        }
        return "";
    },
    GetItemIndexPath: function(indexes){
        var indexPath = "";
        for(var i = 0; i < indexes.length; i ++){
            indexPath += indexes[i];
            if(i < indexes.length - 1)
                indexPath += __aspxItemIndexSeparator;
        }
        return indexPath;
    },
    GetItemIndexes: function(indexPath){
        var indexes = indexPath.split(__aspxItemIndexSeparator);
        for(var i = 0; i < indexes.length; i ++)
            indexes[i] = parseInt(indexes[i]);
        return indexes;
    },
    ClearAppearTimer: function(){
        this.appearTimerID = _aspxClearTimer(this.appearTimerID);
    },
    ClearDisappearTimer: function(){
        this.disappearTimerID = _aspxClearTimer(this.disappearTimerID);
    },
    IsAppearTimerActive: function(){
        return this.appearTimerID > -1;
    },
    IsDisappearTimerActive: function(){
        return this.disappearTimerID > -1;
    },
    SetAppearTimer: function(name, indexPath, timeout){
        this.appearTimerID = _aspxSetTimeout("aspxMIMOverTimer(\"" + name + "\", \"" + indexPath + "\")", timeout);
    },
    SetDisappearTimer: function(name, timeout){
        this.disappearTimerID = _aspxSetTimeout("aspxMIMOutTimer(\"" + name + "\")", timeout);
    },
    
    GetMouseDownMenuLevel: function(evt){
        var srcElement = _aspxGetEventSource(evt);
        if(this.visibleSubMenusMenuName != ""){
            var element = _aspxGetParentById(srcElement, this.visibleSubMenusMenuName);
            if(element != null) return 1;
        }
        for(var i = 0; i < this.visibleSubMenuIds.length; i ++){
            var element = _aspxGetParentById(srcElement, this.visibleSubMenuIds[i]);
            if(element != null)
                return this.GetMenuLevelById(this.visibleSubMenuIds[i], true) + 1;
        }
        return -1;
    },
    CheckFocusedElement: function(){
        try{
            if(document.activeElement != null){
                for(var i = 0; i < this.visibleSubMenuIds.length; i ++){
                    var menuElement = _aspxGetElementById(this.visibleSubMenuIds[i]);
                    if(menuElement != null && _aspxGetIsParent(menuElement, document.activeElement)){
                        var tag = document.activeElement.tagName.toUpperCase();
                        if (!__aspxIE || tag == "INPUT" ||tag == "TEXTAREA" || tag == "SELECT")
                            return true;                
                    }
                }
            }
	    }
	    catch(e){
	    }
        return false;
    },
    DoHidePopupMenus: function(evt, level, name, leavePopups, exceptId){
        for(var i = this.visibleSubMenuIds.length - 1; i >=0 ; i --){
            var menu = this.GetMenu(this.visibleSubMenuIds[i]);
            if(menu != null){
                var menuLevel = this.GetMenuLevelById(this.visibleSubMenuIds[i], true);
                if((!leavePopups || menuLevel > 0) && exceptId != this.visibleSubMenuIds[i]){
                    if(menuLevel > level || (menu.name != name && name != "")){
                        var element = _aspxGetElementById(this.visibleSubMenuIds[i]);
                        if(element != null)
                            menu.DoHidePopupMenu(evt, element);
                    }
                }
            }
        }
    },
    DoShowAtCurrentPos: function(name, indexPath){
        var pc = this.Get(name);
        var element = pc.GetMainElement();
        if(pc != null && !_aspxGetElementDisplay(element))
            pc.DoShowPopupMenu(element, this.overXPos, this.overYPos, indexPath);
    },
    SaveCurrentMouseOverPos: function(evt){
        this.overXPos = _aspxGetEventX(evt);
        this.overYPos = _aspxGetEventY(evt);
    },
    
    OnMouseDown: function(evt){
        var menuLevel = this.GetMouseDownMenuLevel(evt);
        this.DoHidePopupMenus(evt, menuLevel, "", false, "");
    },
    HideAll: function(){
        this.DoHidePopupMenus(null, -1, "", false, "");
    }
});

var __aspxMCollection = null;
function aspxGetMenuCollection(){
    if(__aspxMCollection == null)
        __aspxMCollection = new ASPxClientMenuCollection();
    return __aspxMCollection;
}
ASPxClientMenuItem = _aspxCreateClass(null, {
	constructor: function(menu, parent, index, name){
	    this.menu = menu;
	    this.parent = parent;
        this.index = index;
        this.name = name;
        
        this.enabled = true;
        this.clientEnabled = true;
        this.visible = true;
        this.clientVisible = true;
        this.items = []; 
        this.indexPath = null; 
    },
    CreateItems: function(itemsProperties){
        var itemType = this.menu.GetClientItemType();
        for(var i = 0; i < itemsProperties.length; i ++){
            var itemName = _aspxIsExists(itemsProperties[i][0]) ? itemsProperties[i][0] : "";
            var item = new itemType(this.menu, this, i, itemName);
            if(_aspxIsExists(itemsProperties[i][1]))
                item.enabled = itemsProperties[i][1];
            if(_aspxIsExists(itemsProperties[i][2]))                
                item.clientEnabled = itemsProperties[i][2];
            if(_aspxIsExists(itemsProperties[i][3]))
                item.visible = itemsProperties[i][3];
            if(_aspxIsExists(itemsProperties[i][4]))
                item.clientVisible = itemsProperties[i][4];
            _aspxArrayPush(this.items, item);
            item.CreateItems(itemsProperties[i][5]);
        }
    },
    GetIndexPath: function(){
        if(this.indexPath == null){
            this.indexPath = "";
            var item = this;
            while(item.parent != null){
                this.indexPath = (this.indexPath != "") ? item.index.toString() + __aspxItemIndexSeparator + this.indexPath : item.index.toString();
                item = item.parent;
            }
        }
        return this.indexPath;
    },
    GetItemCount: function(){
        return this.items.length;
    },
    GetItem: function(index){
        return (0 <= index && index < this.items.length) ? this.items[index] : null;
    },
    GetItemByName: function(name){
        for(var i = 0; i < this.items.length; i ++)
            if(this.items[i].name == name) return this.items[i];
        for(var i = 0; i < this.items.length; i ++){
            var item = this.items[i].GetItemByName(name);
            if(item != null) return item;
        }
        return null;
    },
	GetChecked: function(){
	    var indexPath = this.GetIndexPath();
	    return this.menu.IsCheckedItem(indexPath);
	},
	SetChecked: function(value){
	    var indexPath = this.GetIndexPath();
	    this.menu.SetItemChecked(indexPath, value);
	},
	GetEnabled: function(){
        return this.enabled && this.clientEnabled;
	},
	SetEnabled: function(value){
        if (this.clientEnabled != value) {
            this.clientEnabled = value;
	        this.menu.SetItemEnabled(this.GetIndexPath(), value, false);
	    }
	},
	InitializeEnabled: function(){
	    this.menu.SetItemEnabled(this.GetIndexPath(), this.clientEnabled, true);
	    for(var i = 0; i < this.items.length; i++)
	        this.items[i].InitializeEnabled();
	},
	GetImageUrl: function(){
	    var indexPath = this.GetIndexPath();
	    return this.menu.GetItemImageUrl(indexPath);
	},
	SetImageUrl: function(value){
	    var indexPath = this.GetIndexPath();
	    this.menu.SetItemImageUrl(indexPath, value);
	},
	GetNavigateUrl: function(){
	    var indexPath = this.GetIndexPath();
	    return this.menu.GetItemNavigateUrl(indexPath);
	},
	SetNavigateUrl: function(value){
	    var indexPath = this.GetIndexPath();
	    this.menu.SetItemNavigateUrl(indexPath, value);
	},
	GetText: function(){
	    var indexPath = this.GetIndexPath();
	    return this.menu.GetItemText(indexPath);
	},
	SetText: function(value){
	    var indexPath = this.GetIndexPath();
	    this.menu.SetItemText(indexPath, value);
	},
	GetVisible: function(){
	    return this.visible && this.clientVisible;
	},
	SetVisible: function(value){
        if (this.clientVisible != value) {
            this.clientVisible = value;
	        this.menu.SetItemVisible(this.GetIndexPath(), value);
	    }
	},
	InitializeVisible: function(){
	    this.menu.SetItemVisible(this.GetIndexPath(), this.clientVisible);
	    for(var i = 0; i < this.items.length; i++)
	        this.items[i].InitializeVisible();
	}
});
ASPxClientMenu = _aspxCreateClass(ASPxClientMenuBase, {
	constructor: function(name){
		this.constructor.prototype.constructor.call(this, name);
        this.isVertical = false;
    },

    IsVertical: function(indexPath){
        return this.isVertical || (indexPath.indexOf(__aspxItemIndexSeparator) > -1);
    }
});
ASPxClientMenuItemEventArgs = _aspxCreateClass(ASPxClientProcessingModeEventArgs, {
    constructor: function(processOnServer, item) {
        this.constructor.prototype.constructor.call(this, processOnServer);
        this.item = item;
    }
});
ASPxClientMenuItemMouseEventArgs = _aspxCreateClass(ASPxClientEventArgs, {
    constructor: function(item, htmlElement) {
        this.constructor.prototype.constructor.call(this);
        this.item = item;
        this.htmlElement = htmlElement;
    }
});
ASPxClientMenuItemClickEventArgs = _aspxCreateClass(ASPxClientMenuItemEventArgs, {
    constructor: function(processOnServer, item, htmlElement, htmlEvent) {
        this.constructor.prototype.constructor.call(this, processOnServer, item);
        this.htmlElement = htmlElement;
        this.htmlEvent = htmlEvent;        
    }
});

function aspxMIClick(evt, name, indexPath){
    var menu = aspxGetMenuCollection().Get(name);
    if(menu != null) menu.OnItemClick(indexPath, evt);
    if(!__aspxNS)
        evt.cancelBubble = true;
    return true;
}
function aspxAMIMOver(source, args){
    var menu = aspxGetMenuCollection().GetMenu(args.item.name);
    if(menu != null) menu.OnAfterItemOver(args.item, args.element);
}
function aspxBMIMOver(source, args){
    var menu = aspxGetMenuCollection().GetMenu(args.item.name);
    if(menu != null) menu.OnBeforeItemOver(args.item, args.element);
}
function aspxMIMOverTimer(name, indexPath){
    var menu = aspxGetMenuCollection().Get(name);
    if(menu != null) menu.OnItemOverTimer(indexPath);
}
function aspxBIDisabled(source, args){
    var menu = aspxGetMenuCollection().GetMenu(args.item.name);
    if(menu != null) menu.OnBeforeItemDisabled(args.item, args.element);
}
function aspxAMIMOut(source, args){
    var menu = aspxGetMenuCollection().GetMenu(args.item.name);
    if(menu != null) menu.OnAfterItemOut(args.item, args.element, args.toElement);
}
function aspxMIMOutTimer(name){
    var menu = aspxGetMenuCollection().Get(name);
    if(menu != null) menu.OnItemOutTimer();
}
function aspxMContextMenu(evt){
    return _aspxCancelBubble(evt);
}

_aspxAttachEventToElement(window, "load", aspxMenuWindowOnLoad);
function aspxMenuWindowOnLoad(evt){
    aspxAddAfterSetHoverState(aspxAMIMOver);
    aspxAddAfterClearHoverState(aspxAMIMOut);
    aspxAddBeforeSetHoverState(aspxBMIMOver);
    aspxAddBeforeDisabled(aspxBIDisabled);
}
_aspxAttachEventToDocument("mousedown", aspxMenuDocumentMouseDown);
function aspxMenuDocumentMouseDown(evt){
    return aspxGetMenuCollection().OnMouseDown(evt);	
}

function aspxMATimer(name, indexPath){
    var menu = aspxGetMenuCollection().Get(name);
    if(menu != null) menu.OnAnimationTimer(indexPath);
}