/* Example: absoluteUrl(“../subfolder1/divaspari.md”, “images/forest-fire.jpg”) == “../subfolder1/images/forest-fire.jpg”

*/

function absoluteUrl(base, relative) {

// console.debug(base, relative);
if (relative.startsWith("http") || relative.startsWith("file")) {
    return relative;
}
if (relative.startsWith("/") && !base.startsWith("http") && !base.startsWith("file")) {
    return relative;
}
var stack = base.toString().split("/"),
    parts = relative.split("/");
stack.pop(); // remove current file name (or empty string)
             // (omit if "base" is the current folder without trailing slash)
for (var i=0; i<parts.length; i++) {
    if (parts[i] == ".")
        continue;
    if (parts[i] == "..")
        stack.pop();
    else
        stack.push(parts[i]);
}
return stack.join("/");

}

// WHen you include html from one page within another, you need to fix image urls, anchor urls etc.. function fixIncludedHtml(url, html, newLevelForH1) {

// We want to use jquery to parse html, but without loading images. Hence this.
// Tip from: https://stackoverflow.com/questions/15113910/jquery-parse-html-without-loading-images
var virtualDocument = document.implementation.createHTMLDocument('virtual');
var jqueryElement = $(html, virtualDocument);

// console.debug(jqueryElement.html());
// Remove some tags.
jqueryElement.find("script").remove();
jqueryElement.find("footer").remove();
jqueryElement.find("#disqus_thread").remove();
jqueryElement.find("#toc").remove();
jqueryElement.find("#toc_header").remove();
jqueryElement.find(".back-to-top").remove();
// console.debug(jqueryElement.html());

// Deal with includes within includes. Do this before fixing images urls etc.. because there may be images within the newly included html.
jqueryElement.find('.js_include').each(function() {
    if (newLevelForH1 < 1) {
        console.error("Ignoring invalid newLevelForH1: %d, using 6", newLevelForH1);
        newLevelForH1 = 6;
    }
    var jsIncludeElement = $(this);
    var includedPageNewLevelForH2 = parseInt(jsIncludeJqueryElement.attr("newLevelForH1"));
    if (includedPageNewLevelForH2 == undefined) {
        includedPageNewLevelForH2 = 6;
    }
    includedPageNewLevelForH2 = Math.min(6, ((includedPageNewLevelForH2 - 2) + newLevelForH1));
    fillJsInclude($(this), includedPageNewLevelForH2);
});

/*
Fix headers in the included html so as to not mess up the table of contents 
of the including page.
Adjusting the heading levels to retain substructure seems more complicated -
getting the heading "under" which jsIncludeJqueryElement falls seems non-trivial.
 */
var headers = jqueryElement.find(":header");
if (headers.length > 0) {
    var id_prefix = headers[0].id;
    headers.replaceWith(function() {
        var headerElement = $(this);
        // console.debug(headerElement);
        var hLevel = parseInt(headerElement.prop("tagName").substring(1));
        var hLevelNew = Math.min(6, newLevelForH1 - 1 + hLevel);
        var newId = id_prefix + "_" + headerElement[0].id;
        return $("<h" + hLevelNew +" id='" + newId + "'/>").append(headerElement.contents());
    });
}

// Fix image urls.
jqueryElement.find("img").each(function() {
    // console.log(absoluteUrl(url, $(this).attr("src")));
    // console.log($(this).attr("src"))
    $(this).attr("src", absoluteUrl(url, $(this).attr("src")));
    // console.log($(this).attr("src"))
});

// Fix links.
jqueryElement.find("a").each(function() {
    // console.debug($(this).html());
    var href = $(this).attr("href");
    if (href.startsWith("#")) {
        var headers = jqueryElement.find(":header");
        var new_href = href;
        if (headers.length > 0) {
            var id_prefix = headers[0].id;
            new_href = id_prefix + "_" + href.substr(1);
            // console.debug(new_href, id_prefix, href);
            jqueryElement.find(href).each(function () {
                $(this).attr("id", new_href.substr(1));
            });
        }
        $(this).attr("href", new_href);
    } else {
        $(this).attr("href", absoluteUrl(url, href));
    }
});

return jqueryElement;

}

function fillJsInclude(jsIncludeJqueryElement, includedPageNewLevelForH1) {

var includedPageUrl = jsIncludeJqueryElement.attr("url").replace(".md", ".html");
if (includedPageNewLevelForH1 == undefined) {
    includedPageNewLevelForH1 = parseInt(jsIncludeJqueryElement.attr("newLevelForH1"));
}
if (includedPageNewLevelForH1 == undefined) {
    includedPageNewLevelForH1 = 6;
}
$.ajax(includedPageUrl,{
    success: function(responseHtml) {
        // We want to use jquery to parse html, but without loading images. Hence this.
        // Tip from: https://stackoverflow.com/questions/15113910/jquery-parse-html-without-loading-images
        var virtualDocument = document.implementation.createHTMLDocument('virtual');

        var titleElements = $(responseHtml, virtualDocument).find(".post-title-main");
        var title = "";
        if (titleElements.length > 0) {
            // console.debug(titleElements[0]);
            title = titleElements[0].textContent;
        }

        var contentElements = $(responseHtml, virtualDocument).find(".post-content");
        // console.log(contentElements);
        if (contentElements.length == 0) {
            console.warn("Could not get \"post-content\" class element.");
            console.log(responseHtml);
        } else {
            // We don't want multiple post-content divs, hence we replace with an included-post-content div.
            var elementToInclude = $("<div class='included-post-content'/>")
            var titleHtml = "";
            if (jsIncludeJqueryElement.attr("includeTitle")) {
                titleHtml = "<h1 id='" + title + "'>" + title + "</h1>" +
                "<a class='btn btn-default' href='" + absoluteUrl(document.location, includedPageUrl) + "'>See separately</a>";
            }
            elementToInclude.html(titleHtml + contentElements[0].innerHTML);
            var contentElement = fixIncludedHtml(includedPageUrl, elementToInclude, includedPageNewLevelForH1);
            jsIncludeJqueryElement.html(contentElement);
            fillAudioEmbeds();
            fillVideoEmbeds();
            updateToc();
        }
    },
    error: function(xhr, error){
        var titleHtml = "";
        var title = "Missing page.";
        if (jsIncludeJqueryElement.attr("includeTitle")) {
            titleHtml = "<h1 id='" + title + "'>" + title + "</h1>";
        }
        jsIncludeJqueryElement.html(titleHtml + "Could not get: " + includedPageUrl + " See debug messages in console for details.");
        console.debug(xhr); console.debug(error);
    }
});

}

// Process includes of the form: // <div class=“js_include” url=“index.md”/> $( document ).ready(function() {

$('.js_include').each(function() {
    console.debug("Inserting include for " + $(this).html());
    var jsIncludeJqueryElement = $(this);
    // The actual filling happens in a separate thread!
    fillJsInclude(jsIncludeJqueryElement);
});

});