/*
 @licstart  The following is the entire license notice for the JavaScript code in this file.

 The MIT License (MIT)

 Copyright (C) 1997-2020 by Dimitri van Heesch

 Permission is hereby granted, free of charge, to any person obtaining a copy of this software
 and associated documentation files (the "Software"), to deal in the Software without restriction,
 including without limitation the rights to use, copy, modify, merge, publish, distribute,
 sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
 furnished to do so, subject to the following conditions:

 The above copyright notice and this permission notice shall be included in all copies or
 substantial portions of the Software.

 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
 BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
 DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

 @licend  The above is the entire license notice for the JavaScript code in this file
 */
function initMenu(relPath,treeview) {

  const SHOW_DELAY = 250;  // 250ms delay before showing
  const HIDE_DELAY = 500;  // 500ms delay before hiding
  const SLIDE_DELAY = 250; // 250ms slide up/down delay
  const WHEEL_STEP = 30;   // 30 pixel per mouse wheel tick
  const ARROW_STEP = 5;    // 5 pixel when hovering arrow up/down
  const ARROW_POLL_INTERVAL = 20; // 20ms per arrow up/down check
  const MOBILE_WIDTH = 768; // switch point for mobile/desktop mode

  // Helper function for slideDown animation
  function slideDown(element, duration, callback) {
    if (element.dataset.animating) return;
    element.dataset.animating = 'true';

    element.style.removeProperty('display');
    let display = window.getComputedStyle(element).display;
    if (display === 'none') display = 'block';
    element.style.display = display;
    const height = element.offsetHeight;
    element.style.overflow = 'hidden';
    element.style.height = 0;
    element.offsetHeight; // force reflow
    element.style.transitionProperty = 'height';
    element.style.transitionDuration = duration + 'ms';
    element.style.height = height + 'px';
    window.setTimeout(() => {
      element.style.removeProperty('height');
      element.style.removeProperty('overflow');
      element.style.removeProperty('transition-duration');
      element.style.removeProperty('transition-property');
      delete element.dataset.animating;
      if (callback) callback();
    }, duration);
  }

  // Helper function for slideUp animation
  function slideUp(element, duration, callback) {
    if (element.dataset.animating) return;
    element.dataset.animating = 'true';

    element.style.transitionProperty = 'height';
    element.style.transitionDuration = duration + 'ms';
    element.style.height = element.offsetHeight + 'px';
    element.offsetHeight; // force reflow
    element.style.overflow = 'hidden';
    element.style.height = 0;
    window.setTimeout(() => {
      element.style.display = 'none';
      element.style.removeProperty('height');
      element.style.removeProperty('overflow');
      element.style.removeProperty('transition-duration');
      element.style.removeProperty('transition-property');
      delete element.dataset.animating;
      if (callback) callback();
    }, duration);
  }

  // Helper to create the menu tree structure
  function makeTree(data,relPath,topLevel=false) {
    let result='';
    if ('children' in data) {
      if (!topLevel) {
        result+='<ul>';
      }
      for (let i in data.children) {
        let url;
        const link = data.children[i].url;
        if (link.substring(0,1)=='^') {
          url = link.substring(1);
        } else {
          url = relPath+link;
        }
        result+='<li><a href="'+url+'">'+
                                data.children[i].text+'</a>'+
                                makeTree(data.children[i],relPath)+'</li>';
      }
      if (!topLevel) {
        result+='</ul>';
      }
    }
    return result;
  }

  const mainNav = document.getElementById('main-nav');
  if (mainNav && mainNav.children.length > 0) {
    const firstChild = mainNav.children[0];
    firstChild.insertAdjacentHTML('afterbegin', makeTree(menudata, relPath, true));
  }

  const searchBoxPos2 = document.getElementById('searchBoxPos2');
  let searchBoxContents = searchBoxPos2 ? searchBoxPos2.innerHTML : '';
  const mainMenuState = document.getElementById('main-menu-state');
  let prevWidth = 0;

  const initResizableIfExists = function() {
    if (typeof initResizableFunc === 'function') initResizableFunc(treeview);
  }

  // Dropdown menu functionality to replace smartmenus
  let closeAllDropdowns = null; // Will be set by initDropdownMenu

  const isMobile = () => window.innerWidth < MOBILE_WIDTH;

  if (mainMenuState) {
    const mainMenu = document.getElementById('main-menu');
    const searchBoxPos1 = document.getElementById('searchBoxPos1');

    // animate mobile main menu
    mainMenuState.addEventListener('change', function() {
      if (this.checked) {
        slideDown(mainMenu, SLIDE_DELAY, () => {
          mainMenu.style.display = 'block';
          initResizableIfExists();
        });
      } else {
        slideUp(mainMenu, SLIDE_DELAY, () => {
          mainMenu.style.display = 'none';
        });
      }
    });

    // set default menu visibility
    const resetState = function() {
      const newWidth = window.innerWidth;
      if (newWidth !== prevWidth) {
        // Close all open dropdown menus when switching between mobile/desktop modes
        if (closeAllDropdowns) {
          closeAllDropdowns();
        }

        if (newWidth < MOBILE_WIDTH) {
          mainMenuState.checked = false;
          mainMenu.style.display = 'none';
          if (searchBoxPos2) {
            searchBoxPos2.innerHTML = '';
            searchBoxPos2.style.display = 'none';
          }
          if (searchBoxPos1) {
            searchBoxPos1.innerHTML = searchBoxContents;
            searchBoxPos1.style.display = '';
          }
        } else {
          mainMenu.style.display = '';
          if (searchBoxPos1) {
            searchBoxPos1.innerHTML = '';
            searchBoxPos1.style.display = 'none';
          }
          if (searchBoxPos2) {
            searchBoxPos2.innerHTML = searchBoxContents;
            searchBoxPos2.style.display = '';
          }
        }
        if (typeof searchBox !== 'undefined') {
          searchBox.CloseResultsWindow();
        }
        prevWidth = newWidth;
      }
    }

    if (document.readyState === 'loading') {
      document.addEventListener('DOMContentLoaded', function() {
        resetState();
        initResizableIfExists();
      });
    } else {
      resetState();
      initResizableIfExists();
    }
    window.addEventListener('resize', resetState);
  } else {
    initResizableIfExists();
  }

  function initDropdownMenu() {
    const mainMenu = document.getElementById('main-menu');
    if (!mainMenu) return;

    const menuItems = mainMenu.querySelectorAll('li');

    // Helper function to position nested submenu with viewport checking
    function positionNestedSubmenu(submenu, link) {
      const viewport = {
        height: window.innerHeight,
        scrollY: window.scrollY
      };

      // Set initial position - top aligned with parent (next to arrow)
      submenu.style.top = '0';
      if (isMobile()) {
        submenu.style.marginLeft = 0;
      } else {
        submenu.style.marginLeft = link.offsetWidth + 'px';
      }

      // Get submenu dimensions and position
      const submenuRect = submenu.getBoundingClientRect();
      const submenuHeight = submenuRect.height;
      const submenuTop = submenuRect.top;
      const submenuBottom = submenuRect.bottom+1; // add space for border

      // Check if submenu fits in viewport
      const fitsAbove = submenuTop >= 0;
      const fitsBelow = submenuBottom <= viewport.height;

      if (!fitsAbove || !fitsBelow) {
        // Submenu doesn't fit - try to adjust position
        // Overflows bottom, try to shift up
        const overflow = submenuBottom - viewport.height;
        const newTop = Math.max(0, submenuTop-overflow)-submenuTop;
        submenu.style.top = newTop + 'px';

        // Re-check after adjustment
        const adjustedRect = submenu.getBoundingClientRect();
        if (adjustedRect.height > viewport.height) {
          // Still doesn't fit - enable scrolling
          enableSubmenuScrolling(submenu, link);
        }
      }
    }

    // Helper function to enable scrolling for tall submenus
    function enableSubmenuScrolling(submenu, link) {
      // Check if scroll arrows already exist
      if (submenu.dataset.scrollEnabled) return;

      submenu.dataset.scrollEnabled = 'true';

      const viewport = {
        height: window.innerHeight,
        scrollY: window.scrollY
      };

      // Position submenu to fill available viewport space
      const parentRect = link.getBoundingClientRect();
      const availableHeight = viewport.height - 2; // Leave some margin

      submenu.style.maxHeight = availableHeight + 'px';
      submenu.style.overflow = 'hidden';
      submenu.style.position = 'absolute';

      // Create scroll arrows
      const scrollUpArrow = document.createElement('div');
      scrollUpArrow.className = 'submenu-scroll-arrow submenu-scroll-up';
      scrollUpArrow.innerHTML = '<span class="scroll-up-arrow"></span>';//'<span>▲</span>';
      scrollUpArrow.style.cssText = 'position:absolute;top:0;left:0;right:0;height:30px;background:transparent;text-align:center;line-height:30px;color:#fff;cursor:pointer;z-index:1000;display:none;';

      const scrollDownArrow = document.createElement('div');
      scrollDownArrow.className = 'submenu-scroll-arrow submenu-scroll-down';
      scrollDownArrow.innerHTML = '<span class="scroll-down-arrow"></span>';
      scrollDownArrow.style.cssText = 'position:absolute;bottom:0;left:0;right:0;height:30px;background:transparent;text-align:center;line-height:30px;color:#fff;cursor:pointer;z-index:1000;';

      // Create wrapper for submenu content
      const scrollWrapper = document.createElement('div');
      scrollWrapper.className = 'submenu-scroll-wrapper';
      scrollWrapper.style.cssText = 'height:100vh;overflow:hidden;position:relative;';

      // Move submenu children to wrapper
      while (submenu.firstChild) {
        scrollWrapper.appendChild(submenu.firstChild);
      }

      submenu.appendChild(scrollUpArrow);
      submenu.appendChild(scrollWrapper);
      submenu.appendChild(scrollDownArrow);

      let scrollPosition = 0;
      let scrollInterval = null;

      function updateScrollArrows() {
        const maxScroll = scrollWrapper.scrollHeight - availableHeight;
        scrollUpArrow.style.display = scrollPosition > 0 ? 'block' : 'none';
        scrollDownArrow.style.display = scrollPosition < maxScroll ? 'block' : 'none';
      }

      function startScrolling(direction) {
        if (scrollInterval) return;

        scrollInterval = setInterval(() => {
          const maxScroll = scrollWrapper.scrollHeight - availableHeight;

          if (direction === 'up') {
            scrollPosition = Math.max(0, scrollPosition - ARROW_STEP);
          } else {
            scrollPosition = Math.min(maxScroll, scrollPosition + ARROW_STEP);
          }

          scrollWrapper.scrollTop = scrollPosition;
          updateScrollArrows();

          if ((direction === 'up' && scrollPosition === 0) ||
              (direction === 'down' && scrollPosition === maxScroll)) {
            stopScrolling();
          }
        }, ARROW_POLL_INTERVAL);
      }

      function stopScrolling() {
        if (scrollInterval) {
          clearInterval(scrollInterval);
          scrollInterval = null;
        }
      }

      scrollUpArrow.addEventListener('mouseenter', () => startScrolling('up'));
      scrollUpArrow.addEventListener('mouseleave', stopScrolling);
      scrollDownArrow.addEventListener('mouseenter', () => startScrolling('down'));
      scrollDownArrow.addEventListener('mouseleave', stopScrolling);

      function wheelEvent(e) {
        e.preventDefault();
        e.stopPropagation();

        const maxScroll = scrollWrapper.scrollHeight - availableHeight;
        const wheelDelta = e.deltaY;
        const scrollAmount = wheelDelta > 0 ? WHEEL_STEP : -WHEEL_STEP; // Scroll 30px per wheel tick

        scrollPosition = Math.max(0, Math.min(maxScroll, scrollPosition + scrollAmount));
        scrollWrapper.scrollTop = scrollPosition;
        updateScrollArrows();
      }

      // Add mouse wheel scrolling support
      scrollWrapper.addEventListener('wheel', (e) => wheelEvent(e));

      // Also add wheel event to submenu itself to catch events
      submenu.addEventListener('wheel', function(e) {
        // Only handle if scrolling is enabled
        if (submenu.dataset.scrollEnabled) {
          wheelEvent(e);
        }
      });

      // Initial arrow state
      updateScrollArrows();
    }

    // Helper function to clean up scroll arrows
    function disableSubmenuScrolling(submenu) {
      if (!submenu.dataset.scrollEnabled) return;

      delete submenu.dataset.scrollEnabled;

      // Find and remove scroll elements
      const scrollArrows = submenu.querySelectorAll('.submenu-scroll-arrow');
      const scrollWrapper = submenu.querySelector('.submenu-scroll-wrapper');

      if (scrollWrapper) {
        // Move children back to submenu
        while (scrollWrapper.firstChild) {
          submenu.appendChild(scrollWrapper.firstChild);
        }
        scrollWrapper.remove();
      }

      scrollArrows.forEach(arrow => arrow.remove());

      // Reset styles
      submenu.style.maxHeight = '';
      submenu.style.overflow = '';
    }

    menuItems.forEach(item => {
      const submenu = item.querySelector('ul');
      if (submenu) {
        const link = item.querySelector('a');
        if (link) {
          // Add class and ARIA attributes for accessibility
          link.classList.add('has-submenu');
          link.setAttribute('aria-haspopup', 'true');
          link.setAttribute('aria-expanded', 'false');

          // Add sub-arrow indicator
          const span = document.createElement('span');
          span.classList.add('sub-arrow');
          link.append(span);

          // Calculate nesting level for z-index
          // Root menu (main-menu) is level 200 (above the search box at 102),
          // first submenus are level 201, etc.
          let nestingLevel = 200;
          let currentElement = item.parentElement;
          while (currentElement && currentElement.id !== 'main-menu') {
            if (currentElement.tagName === 'UL') {
              nestingLevel++;
            }
            currentElement = currentElement.parentElement;
          }

          // Apply z-index based on nesting level
          // This ensures child menus with shadows appear above parent menus
          submenu.style.zIndex = nestingLevel + 1;

          // Check if this is a level 2+ submenu (nested within another dropdown)
          const isNestedSubmenu = item.parentElement && item.parentElement.id !== 'main-menu';

          // Timeout management for smooth menu navigation
          let showTimeout = null;
          let hideTimeout = null;

          // Desktop: show on hover
          item.addEventListener('mouseenter', function() {
            if (!isMobile()) {
              // Clear any pending hide timeout
              if (hideTimeout) {
                clearTimeout(hideTimeout);
                hideTimeout = null;
              }

              // Set show timeout
              showTimeout = setTimeout(() => {
                // Hide all sibling menus at the same level before showing this one
                const parentElement = item.parentElement;
                if (parentElement) {
                  const siblings = parentElement.querySelectorAll(':scope > li');
                  siblings.forEach(sibling => {
                    if (sibling !== item) {
                      const siblingSubmenu = sibling.querySelector('ul');
                      const siblingLink = sibling.querySelector('a');
                      if (siblingSubmenu && siblingLink) {
                        siblingSubmenu.style.display = 'none';
                        siblingLink.setAttribute('aria-expanded', 'false');
                        disableSubmenuScrolling(siblingSubmenu);
                      }
                    }
                  });
                }

                submenu.style.display = 'block';
                // Only apply positioning for nested submenus (level 2+)
                if (isNestedSubmenu) {
                  positionNestedSubmenu(submenu, link);
                }
                link.setAttribute('aria-expanded', 'true');
                showTimeout = null;
              }, SHOW_DELAY);
            }
          });

          item.addEventListener('mouseleave', function() {
            if (!isMobile()) {
              // Clear any pending show timeout
              if (showTimeout) {
                clearTimeout(showTimeout);
                showTimeout = null;
              }

              // Set hide timeout
              hideTimeout = setTimeout(() => {
                submenu.style.display = 'none';
                link.setAttribute('aria-expanded', 'false');
                // Clean up scrolling if enabled
                disableSubmenuScrolling(submenu);
                hideTimeout = null;
              }, HIDE_DELAY);
            }
          });

          if (isMobile() && isNestedSubmenu) {
            positionNestedSubmenu(submenu, link);
          }

          function toggleMenu() {
            const isExpanded = link.getAttribute('aria-expanded') === 'true';
            if (isExpanded) {
              slideUp(submenu, SLIDE_DELAY, () => {
                submenu.style.display = 'none';
                link.setAttribute('aria-expanded', 'false');
                link.classList.remove('highlighted')
                disableSubmenuScrolling(submenu);
              });
            } else {
              slideDown(submenu, SLIDE_DELAY, () => {
                submenu.style.display = 'block';
                link.classList.add('highlighted')
                link.setAttribute('aria-expanded', 'true');
              });
            }
          }

          // Mobile/Touch: toggle on click
          link.addEventListener('click', function(e) {
            if (isMobile()) {
              e.preventDefault();
              toggleMenu();
            }
          });

          // Keyboard navigation
          link.addEventListener('keydown', function(e) {
            if (e.key === 'Enter' || e.key === ' ') {
              e.preventDefault();
              toggleMenu();
            } else if (e.key === 'Escape') {
              submenu.style.display = 'none';
              link.setAttribute('aria-expanded', 'false');
              disableSubmenuScrolling(submenu);
              link.focus();
            }
          });
        }
      }
    });

    // Helper function to close all open dropdown menus
    closeAllDropdowns = function() {
      menuItems.forEach(item => {
        const submenu = item.querySelector('ul');
        const link = item.querySelector('a.has-submenu');
        if (submenu && link) {
          disableSubmenuScrolling(submenu);
          submenu.style.display = 'none';
          submenu.style.marginLeft = 0;
          link.setAttribute('aria-expanded', 'false');
          link.classList.remove('highlighted');
        }
      });
    };

    // Close all dropdown menus when clicking a link (navigation to new page or anchor)
    const allLinks = mainMenu.querySelectorAll('a');
    allLinks.forEach(link => {
      link.addEventListener('click', function() {
        // Close dropdowns when navigating (unless it's a has-submenu link in mobile mode)
        if (!link.classList.contains('has-submenu') || !isMobile()) {
          if (closeAllDropdowns) {
            closeAllDropdowns();
          }
        }
      });
    });
  }

  // Initialize dropdown menu behavior
  initDropdownMenu();

  // Close all open menus when browser back button is pressed
  window.addEventListener('popstate', function() {
    if (closeAllDropdowns) {
      closeAllDropdowns();
    }
  });
}

/* @license-end */
