function forEach(elems, fun) {
  Array.prototype.forEach.call(elems, fun);
}

function getPagetoc(){
  return document.getElementsByClassName("pagetoc")[0]
}

function getPagetocElems() {
  return getPagetoc().children;
}

function getHeaders(){
  return document.getElementsByClassName("header")
}

// Un-active everything when you click it
function forPagetocElem(fun) {
  forEach(getPagetocElems(), fun);
}

function getRect(element) {
  return element.getBoundingClientRect();
}

function overflowTop(container, element) {
  return getRect(container).top - getRect(element).top;
}

function overflowBottom(container, element) {
  return getRect(container).bottom - getRect(element).bottom;
}

var activeHref = location.href;

var updateFunction = function (elem = undefined) {
  var id = elem;

  if (!id && location.href != activeHref) {
    activeHref = location.href;
    forPagetocElem(function (el) {
      if (el.href === activeHref) {
        id = el;
      }
    });
  }

  if (!id) {
    var elements = getHeaders();
    let margin = window.innerHeight / 3;

    forEach(elements, function (el, i, arr) {
      if (!id && getRect(el).top >= 0) {
        if (getRect(el).top < margin) {
          id = el;
        } else {
          id = arr[Math.max(0, i - 1)];
        }
      }
      // a very long last section
      // its heading is over the screen
      if (!id && i == arr.length - 1) {
        id = el
      }
    });
  }

  forPagetocElem(function (el) {
    el.classList.remove("active");
  });

  if (!id) return;

  forPagetocElem(function (el) {
    if (id.href.localeCompare(el.href) == 0) {
      el.classList.add("active");
      let pagetoc = getPagetoc();
      if (overflowTop(pagetoc, el) > 0) {
        pagetoc.scrollTop = el.offsetTop;
      }
      if (overflowBottom(pagetoc, el) < 0) {
        pagetoc.scrollTop -= overflowBottom(pagetoc, el);
      }
    }
  });
};

let elements = getHeaders();

if (elements.length > 1) {
  // Populate sidebar on load
  window.addEventListener("load", function () {
    var pagetoc = getPagetoc();
    var elements = getHeaders();
    forEach(elements, function (el) {
      var link = document.createElement("a");
      link.appendChild(document.createTextNode(el.text));
      link.href = el.hash;
      link.classList.add("pagetoc-" + el.parentElement.tagName);
      pagetoc.appendChild(link);
      link.onclick = function () {
        updateFunction(link);
      };
    });
    updateFunction();
  });

  // Handle active elements on scroll
  window.addEventListener("scroll", function () {
    updateFunction();
  });
} else {
  document.getElementsByClassName("sidetoc")[0].remove();
}
