function current_page_headers() {
    let result = K.getv([1,2,3,4,5].map(function (o) {
        return "#text h" + o;
    }));
    result = [...result];
    ["kt-part", "kt-chapter"].forEach(function (tag) {
        let elt = K.get("#text " + tag);
        if (elt) {
            result.push(elt);
        }
    });
    return result;
}

function add_navlink_mapping(navlink_map, navlink) {
    let target = K.attr(navlink, "data-target");
    navlink_map[target] = navlink.children[0];
    return navlink_map;
}

function headers_in_text() {
    //const headers = [...K.getv("h1,h2,h3,h4")];
    const headers = current_page_headers();
    //const text_rect = K.get("#text").getBoundingClientRect();
    const text_rect = displayed_text().getBoundingClientRect();
    const top = text_rect.top;
    const bottom = top + text_rect.height;
    let visible = [];
    let invisible = [];
    headers.forEach(function (h) {
        const header_rect = h.getBoundingClientRect();
        const header_bottom = header_rect.bottom;
        if (header_bottom > top && header_bottom < bottom) {
            visible.push(h);
        } else {
            invisible.push(h);
        }
    });
    //console.log("headers_in_text: " + visible.length
    // + " " + invisible.length);
    return [visible, invisible];
}

function open_highlighted_sections(node) {

    //console.log("open_highlighted_sections");
    let parent = node.parentNode;
    while (parent && parent.id != "toc_items") {
        //console.log(parent.id);
        //console.dir(parent);
        //console.log(parent);
        //console.log(parent.children);
        let carets = [...parent.children].filter(function (node) {
            return K.has_class(node, "caret")
                && !K.has_class(node, "caret-down");
        });
        carets.forEach(function (c) {
            c.click();
        });
        //console.log("carets: ")
        //console.log(carets);
        parent = parent.parentNode;
    }
}

function open_visible() {
    //console.log("open_visible");
    let open_sections = visible_toc_sections();
    if (open_sections.length === 1 && !open_sections[0]) {
        return;
    }
    //console.log("open_sections:");
    //console.log(open_sections);
    open_sections.forEach(function (e) {
        //console.log("visible: " + e);
        let section_id = K.attr(e, "id");
        let navlink = K.get(".navlink[data-target=\"" + section_id + "\"]");
        if (navlink) {
            open_highlighted_sections(navlink);
        }
    });
}



var last_visible = [];

//function find_visible_element(node) {
//    [...node.children].forEach(function (o) {



function highlight_headers_in_toc() {
    let navlink_map = {};
    [...K.getv(".navlink")].forEach(
        function (o) { add_navlink_mapping(navlink_map, o); });

    [...K.getv(".highlight")].forEach(function (o) {
        K.remove_class(o, "highlight");
    });

    let [visible, invisible] = headers_in_text();

    /*
      console.log("-");
      console.log("visible: ");
      console.log(visible);
      console.log("visible length: " + visible.length + " " + visible);
      console.log("invisible: ");
      console.log(invisible);
      console.log("invisible length: " + invisible.length + " " + invisible);
      console.log("-");
    */

    let max_level = 0;
    if (visible.length > 0) {
        visible.forEach(function (h) {
            if (h.id) {
                K.add_class(navlink_map[h.id], "highlight");
                //console.log(h);
                max_level = Math.max(max_level, parseInt(K.attr(h, "data-level")));
            }
        });
    }

    //console.log("max_level: ", max_level);
    if (invisible.length > 0) {
        invisible.forEach(function (h) {
            if (h.id) {
                K.remove_class(navlink_map[h.id], "highlight");
            }
        });
    }
    //if (toc_count === 0) {


    /*
      if (visible.length !== 0) {
      //console.log("last visible: " + last_visible);
      //last_visible = visible[visible.length - 1];
      last_visible = visible[0];
      } else {
      //console.log("None visible; setting:")
      //console.log(last_visible);
      //visible = [last_visible];
      }
      console.log("visible");
      console.log(visible);
    */

    //console.log("last_visible:");
    //console.log(last_visible);

    if (visible.length === 0 && last_visible.id && navlink_map[last_visible.id]) {
        // No headers are visible; use the header of the displayed element
        //console.log("setting visiblity of " + last_visible.id);
        K.add_class(navlink_map[last_visible.id], "highlight");
        /*
          last_visible.forEach(function (h) {
          K.add_class(navlink_map[h.id], "highlight");
          });
        */
    }

    if (visible.length !== 0) {
        //console.log("set last visible: " + last_visible.id);
        //last_visible = visible[visible.length - 1];
        last_visible = visible[visible.length - 1];
    }

    open_visible();
}

/*
function update_hash() {
    const first_highlighted_navlink = K.get(".section-title.highlight").parentNode;
    const basename = K.attr(first_highlighted_navlink, "data-page");
    const target = K.attr(first_highlighted_navlink, "data-target");
    window.location.hash = "#" + basename + "#" + target;
}
*/

var navigation_interval = null;

function go_to_section(elt, basename_arg, target_arg, force_reload, on_loaded) {
    const basename = basename_arg || K.attr(elt, "data-page");
    const target = target_arg || (elt ? K.attr(elt, "data-target") : null);
    const parts = window.location.toString().split("#");

    let hash = "#" + basename;
    if (target) {
        hash += "#" + target;
    }

    let basepage = K.get("#_page_" + basename);
    if (!basepage) {
        return;
    }

    if (navigation_interval) {
        clearInterval(navigation_interval);
        navigation_interval = null;
    }

    var retries = 0;
    const max_retries = 100;

    navigation_interval = setInterval(function() {

        if (!K.get("#text") || parts[1] != basename || force_reload) {
            displayed_text().innerHTML = K.get("#_page_" + basename).innerHTML;
            resize_images();

            if (!force_reload) {
                unhighlight_search_targets();
            }
        }
        force_reload = false;
        var target_element = document.getElementById(target);
        if (!target_element) {
            if (++retries > max_retries) {
                clearInterval(navigation_interval);
                navigation_interval = null;
            }
            return;
        }
        clearInterval(navigation_interval);
        navigation_interval = null;
        if (on_loaded) {
            on_loaded();
        }
        let text_div = displayed_text();
        text_div.scrollTop = target_element.offsetTop - text_div.offsetTop;
        remove_toc_highlighting();
        highlight_headers_in_toc();
        set_next_last_button_status();
        set_link_listeners();

        window.location.hash = hash;
        localStorage.setItem("klammertext_location", `${basename}:${target}`);
    }, 10);

    K.get("#help").textContent = "Help";
}

function toggle_caret(node) {
    //console.trace();
    node.parentElement.querySelector(".nested").classList.toggle("active");
    node.classList.toggle("caret-down");
    resize_toc();
}

function add_scrolling_to_text() {
    K.get("#text").addEventListener("scroll", function (event) {
        //event.preventDefault();
        //console.log("scroll " + K.get("#text").scrollTop);
        highlight_headers_in_toc();
        //show_all_highlighted();
    });
}

window.addEventListener("load", function (event) {
    var toggler = document.getElementsByClassName("caret");
    for (i = 0; i < toggler.length; i++) {
        toggler[i].addEventListener("click", function(event) {
            toggle_caret(event.srcElement);
        });
    }

    K.map(".section-number, .section-title-text", function(elt) {
        elt.addEventListener("click", function (event) {
            event.preventDefault();
            buttons_before_search();
            const caret = event.srcElement.parentNode.parentNode.parentNode.firstChild;
            if (caret.nodeName !== "#text") {
                const caret_down = K.has_class(caret, "caret-down");
                if (!caret_down) {
                    toggle_caret(caret);
                }
            }
            go_to_section(elt.parentNode.parentNode);
        });
    });

    add_scrolling_to_text();
    /*
      K.get("#text").addEventListener("scroll", function (event) {
      //event.preventDefault();
      console.log("scroll " + K.get("#text").scrollTop);
      highlight_headers_in_toc();
      //show_all_highlighted();
      });
    */
    //highlight_headers_in_toc();

    //open_visible();


    //show_all_highlighted();
});

