Event.observe(window, 'load', function () {
    const $top = $('top');
    const $mainMenu = $('mainMenu');
    const topHeight = $top.getHeight();
    const $extrasMenu = $mainMenu.down('.extras');
    const $extrasMenuList = $('module-dropdown');
    const $languageSwitcher = $top.down('.language-switch');
    const $avatarPicture = $top.down('.user-avatar');
    const $objectTypeGroup = $mainMenu.down('.object-type-group');
    const $objectTypeGroupList = $('object-type-group-dropdown');
    const $globalSearch = $('globalSearch');
    // 0 = Always show all object type groups, 1 = always show the 'object type group' dropdown, 2 = responsive.
    const menuType = +'[{$objectTypeGroupsAsDropDown}]';
    let objectTypeGroupDropdown;
    
    if ($languageSwitcher) {
        new DropDown($languageSwitcher, $languageSwitcher.down('ul'));
    }
    
    new DropDown($avatarPicture, $avatarPicture.down('ul'), { keepX: true });
    
    if ($objectTypeGroup && $objectTypeGroupList) {
        objectTypeGroupDropdown = new DropDown($objectTypeGroup, $objectTypeGroupList);
    
        $objectTypeGroupList.on('click', 'a', function () {
            $objectTypeGroup.fire('popup:close');
        });
    
        if ($objectTypeGroupList.down('.active')) {
            $objectTypeGroup.addClassName('active');
        }
    }
    
    const openDropDown = function ($dropDown) {
        $dropDown
            .setStyle({
                top:     (topHeight - 8) + 'px',
                opacity: 0,
                display: null
            })
            .removeClassName('hide');
    
        new Effect.Morph($dropDown, {
            style:    'opacity: 1; top: ' + (topHeight - 4) + 'px',
            duration: 0.2
        });
    };
    
    const closeDropDown = function ($dropDown) {
        new Effect.Morph($dropDown, {
            style:       'opacity: 0; top: ' + (topHeight - 8) + 'px',
            duration:    0.2,
            afterFinish: function () {
                $dropDown.addClassName('hide');
            }
        });
    };
    
    $mainMenu.select('li a').invoke('on', 'click', function (ev) {
        var $li = ev.findElement('a').up('li');
        $mainMenu.select('li').invoke('removeClassName', 'active');
        $li.addClassName('active');
        
        if (!$li.hasClassName('extras') && $extrasMenuList.visible()) {
            $extrasMenuList.fire('menu:close');
        }
    });
    
    if ($extrasMenu && $extrasMenuList) {
        $extrasMenuList.close_all_childs = function () {
            // Hides all childs
            $$('#module-dropdown ul.moduleChilds').each(function (ele) {
                ele.hide();
                ele.previous().removeClassName('active');
            });
        };
        
        $extrasMenuList.show_childs = function (p_childID) {
            this.close_all_childs();
            
            var leftPosi = parseInt($(p_childID).previous().getWidth());
            
            // Position of the Child Tab.
            $(p_childID).setStyle({
                top:  $(p_childID).previous().offsetTop + 'px',
                left: leftPosi + 'px'
            });
            
            // Show childs.
            $(p_childID).previous().addClassName('active');
            $(p_childID).show();
        };
        
        $extrasMenu.on('click', function (e) {
            e.preventDefault();
            
            if (!$extrasMenuList.visible()) {
                if ($extrasMenuList.innerHTML.blank()) {
                    new Ajax.Updater(
                        'module-dropdown',
                        '?call=modules&ajax=1',
                        {
                            method:      'POST',
                            evalScripts: true,
                            onComplete:  function () {
                                $extrasMenuList.fire('menu:open');
                            }
                        }
                    );
                } else {
                    $extrasMenuList.fire('menu:open');
                    
                    // Hides all childs.
                    $extrasMenuList.close_all_childs();
                }
            } else {
                $extrasMenuList.fire('menu:close');
                $extrasMenuList.close_all_childs();
            }
        });
    
        $extrasMenuList.on('menu:open', function () {
            openDropDown($extrasMenuList.setStyle('left:' + $extrasMenu.offsetLeft + 'px'));
        });
    
        $extrasMenuList.on('menu:close', function () {
            closeDropDown($extrasMenuList);
        });
    }
    
    if (dragBar) {
        var dragBarObj = new dragBar({
            dragContainer:  'draggableBar',
            leftContainer:  'menuTreeOn',
            rightContainer: 'contentArea',
            moveInfoBox:    true,
            defaultWidth:   '[{$menu_width}]'
        });
        
        dragBarObj.callback_save = function () {
            new Ajax.Request('?call=menu&ajax=1&func=save_menu_width', {
                parameters: {
                    menu_width: $('menuTreeOn').getWidth()
                },
                method:     'post'
            });
        };
    }
    
    // Hide various dropdowns if the user clicks anywhere else.
    document.body.on('click', function(ev) {
        if ($extrasMenuList && !Element.up(ev.target, '#module-dropdown') && !Element.up(ev.target, '.extras') && !ev.target.matches('.extras')) {
            $extrasMenuList.fire('menu:close');
            if ($extrasMenuList.hasOwnProperty('close_all_childs')) {
                $extrasMenuList.close_all_childs();
            }
        }
    });
    
    // Create a global listener to set tooltips to all icon buttons.
    $('body').on('update:tooltips', function () {
        Tips.hideAll();
        
        $$('[data-tooltip]').each(function ($el) {
            new Tip($el, $el.readAttribute('title').replaceAll(/\n/g, '<br />'), {
                stem:              false,
                style:             'darkgrey',
                positionByElement: true,
                offsetX:           0,
                offsetY:           4,
                onBeforeShow:      function () {
                    $el.writeAttribute('data-title', $el.readAttribute('title'));
                    $el.removeAttribute('title');
                },
                onAfterHide:       function () {
                    if (!$el.hasAttribute('title') && !$el.readAttribute('data-title').blank()) {
                        $el.writeAttribute('title', $el.readAttribute('data-title'));
                    }
                }
            });
        });
    });
    
    // @see ID-9008 Implement responsive menu.
    const menuResize = function (initial) {
        if (menuType === 0) {
            // If the object type group should never be collapsed, we only need to remove the 'object type group' menu item.
            $objectTypeGroup.addClassName('hide')
            return;
        }
        
        if (menuType === 1) {
            // If the object type group should be collapsed, we'll simply do that.
            $mainMenu.addClassName('collapsed');
            return;
        }
        
        const isSmall = $globalSearch.getWidth() < 150;
        const currentWidth = $top.getWidth();
        
        // Here we save the 'collapse threshold' - we use the size of the global size to identify the switch.
        if ($mainMenu.retrieve('collapse-threshold', 0) === 0 && isSmall) {
            // We calculate a custom threshold by using the right client rect of the avatar picture + the global search width delta (because it was probably squished).
            let calculatedThreshold = $avatarPicture.getBoundingClientRect().right + (150 - $globalSearch.getWidth());
            
            // The small calculation should help when i-doit was opened on a small screen and then expanded.
            $mainMenu.store('collapse-threshold', Math.max(currentWidth, calculatedThreshold));
        }
        
        const collapseThreshold = $mainMenu.retrieve('collapse-threshold', 0);
        
        // If the 'collapse threshold' is set and it the current screen width drops below it, we 'collapse' the main menu.
        if (collapseThreshold && currentWidth < collapseThreshold) {
            $mainMenu.addClassName('collapsed');
            
            if ($objectTypeGroup) {
                $objectTypeGroup.removeClassName('hide');
            }
        } else {
            $mainMenu.removeClassName('collapsed');
            
            if ($objectTypeGroup) {
                $objectTypeGroup.addClassName('hide');
            }
            
            if (objectTypeGroupDropdown) {
                objectTypeGroupDropdown.closeDropDown();
            }
        }
    }
    
    Event.observe(window, 'resize', menuResize);
    
    // Write tooltips after 0.5 seconds (just in case of some slow code or ajax).
    setTimeout(function () {
        $('body').fire('update:tooltips');
    }, 500);
    
    // @see ID-9153 Trigger the 'menu resize' callback with a delay, if the 'automatic' option is selected.
    setTimeout(function () {
        menuResize();
    }, menuType === 2 ? 250 : 0);
});
