class Sidebar {
  constructor(element) {
    this.element = element;
    this.activeLink = null;

    this.element.addEventListener('click', (e) => {
      // If we click a navigation, close the hamburger menu
      if (e.target.tagName == 'A' && this.element.classList.contains('sidebar-toggle')) {
        this.element.classList.remove('sidebar-toggle');
        let button = hamburgerToggle.firstElementChild;
        button.textContent = 'menu';

        // Scroll a little up to actually see the header
        // Note: this is generally around ~55px
        // A proper solution is getComputedStyle but it can be slow
        // Instead let's just rely on this quirk and call it a day
        // This has to be done after the browser actually processes
        // the section movement
        setTimeout(() => window.scrollBy(0, -100), 75);
      }
    });
  }

  createCollapsableSections() {
    let toc = this.element.querySelector('ul');
    if (!toc) {
      return
    }
    let allReferences = toc.querySelectorAll('a.reference.internal:not([href="#"])');

    for (let ref of allReferences) {

      let next = ref.nextElementSibling;

      if (next && next.tagName === "UL") {

        let icon = document.createElement('span');
        icon.className = 'material-icons collapsible-arrow expanded';
        icon.innerText = 'expand_more';

        if (next.parentElement.tagName == "LI") {
          next.parentElement.classList.add('no-list-style')
        }

        icon.addEventListener('click', () => {
          if (icon.classList.contains('expanded')) {
            this.collapseSection(icon);
          } else {
            this.expandSection(icon);
          }
        })

        ref.classList.add('ref-internal-padding')
        ref.parentNode.insertBefore(icon, ref);
      }
    }
  }

  resize() {
    let rect = this.element.getBoundingClientRect();
    this.element.style.height = `calc(100vh - 1em - ${rect.top + document.body.offsetTop}px)`;
  }

  collapseSection(icon) {
    icon.classList.remove('expanded');
    icon.classList.add('collapsed');
    let children = icon.nextElementSibling.nextElementSibling;
    // <arrow><heading>
    // --> <square><children>
    setTimeout(() => children.style.display = "none", 75)
  }

  expandSection(icon) {
    icon.classList.remove('collapse');
    icon.classList.add('expanded');
    let children = icon.nextElementSibling.nextElementSibling;
    setTimeout(() => children.style.display = "block", 75)
  }

  setActiveLink(section) {
    if (this.activeLink) {
      this.activeLink.parentElement.classList.remove('active');
    }
    if (section) {
      this.activeLink = document.querySelector(`#sidebar a[href="#${section.id}"]`);
      if (this.activeLink) {
        let headingChildren = this.activeLink.parentElement.parentElement;
        let heading = headingChildren.previousElementSibling.previousElementSibling;

        if (heading && headingChildren.style.display === 'none') {
          this.activeLink = heading;
        }
        this.activeLink.parentElement.classList.add('active');
      }
    }
  }

}

function getCurrentSection() {
  let currentSection;
  if (window.scrollY + window.innerHeight > bottomHeightThreshold) {
    currentSection = sections[sections.length - 1];
  }
  else {
    if (sections) {
      sections.forEach(section => {
        let rect = section.getBoundingClientRect();
        if (rect.top + document.body.offsetTop < 1) {
          currentSection = section;
        }
      });
    }
  }
  return currentSection;
}

document.addEventListener('DOMContentLoaded', () => {
  sidebar = new Sidebar(document.getElementById('sidebar'));
  sidebar.resize();
  sidebar.createCollapsableSections();

  window.addEventListener('scroll', () => {
    sidebar.setActiveLink(getCurrentSection());
    sidebar.resize();
  });
});