// Used for loading via main.js
var commentScript = false;
var multiCommentPage = false;

// Global page state.
var postid = decodeURIComponent(document.location.href.replace(/^https?:\/\/.*?\//, "/"));
var get_cgi = "/comment_get.cgi";
var post_cgi = "/comment_post.cgi";

// This is where we decide which pages will allow comments.
if(postid.match(/^\/Blog\//)) commentScript = true;
if(postid.match(/^\/Thoughts\//)) commentScript = true;

// Ajax request variables/state.
var xhr = null;
var pending = false;

function initComments()
{
    // A multiple-comment-area page is defined by the presence of a span with the class 'end'.
    // Note that through interaction with the page, these elements can all be removed, but 'multiCommentPage' will
    // already have been set by then.
    var spans = document.getElementsByClassName("end");
    for(var i = 0; i < spans.length; i++)
    {
        if(spans[i].nodeName.match(/^span$/i))
        {
            multiCommentPage = true;
            var showLink = document.createElement("a");
            showLink.href = "";
            showLink.onclick = requestComments;
            showLink.innerHTML = "Show Comments";
            spans[i].appendChild(showLink);
        }
    }

    // A single-comment-area page needs a 'comment_attach' element.
    if(!multiCommentPage && document.getElementById("comment_attach"))
    {
        var showLink = document.createElement("a");
        showLink.href = "";
        showLink.onclick = requestComments;
        showLink.innerHTML = "Show Comments";
        document.getElementById("comment_attach").appendChild(showLink);
    }
}

function showCommentForm(subid){
    if(!subid) subid = 0;
    var form = document.createElement("div");
    form.id = "comment_post_form";
    form.className = "comment_post_form";
    form.innerHTML = "\
        <input type='text' id='name" + subid + "'/>\
        <label for='name'>Name</label><br/>\
        <input type='text' id='email" + subid + "'/>\
        <label for='email'>Email (optional)</label><br/>\
        <input type='text' id='website" + subid + "'/>\
        <label for='website'>Website (optional)</label><br/><br/>\
        <label for='comment'>Comment:</label><br/>\
        <textarea id='comment_" + subid + "'></textarea><br/>\
        <input type='button' id='post_comment" + subid + "' value='Submit Comment'/>\
        <a href='' id='cancel_comment" + subid + "'>Cancel</a>\
    ";
    form.style.display = "none";
    var oldForm = document.getElementById("comment_post_form");
    if(oldForm)
    {
        oldForm.parentNode.replaceChild(form, oldForm);
    }
    else
    {
        document.body.appendChild(form);
    }
    document.getElementById("cancel_comment" + subid).onclick = function(){return cancelComment(subid)};
    document.getElementById("post_comment" + subid).onclick = function(){return postComment(subid)};
    document.getElementById("comment_post_form").style.display = "";
    document.getElementById("name" + subid).focus();
    return false;
}

function requestCommentsCallback()
{
    if(xhr.readyState != 4 /* COMPLETED */)
        return;
    if(xhr.status == 404)
        buildComments(null, xhr.subid);
    else if(xhr.status == 200)
        buildComments(xhr.responseText, xhr.subid);
    else
        alert(xhr.status + ": " + xhr.responseText);
    pending = false;
}

// e is an event object created by an onclick handler. Alternatively, 'e' is an arbitrary object with a 'target'
// property set to an element that could have had an onclick handler.
function requestComments(e)
{
    // If we're in the middle of something, wait for that to finish and then try again.
    if(pending)
    {
        setTimeout(function(){requestComments(e)}, 250);
        return false;
    }

    // For multi-comment-section pages, we want to look up the name of the section we're in when we request comments.
    // This is the first numeric value in the most closely preceeding 'h4' tag to our target element, which is 
    // admittedly very heuristic seeming, but the editing format allows it.

    // In the first case, our target is a link inside an 'end' span, which marks the end of a section.
    // In the second case, our target is a fake target indicating a paragraph wrapping a comment posting form.

    var target_p;
    var subid = "";
    if(e.target.parentNode.className == "end" || e.target.nodeName.match(/^p$/i))
    {
        var current = e.target;
        if(e.target.parentNode.className == "end")
        {
            current = e.target.parentNode.parentNode;
        }
        target_p = current;

        // Find the closest preceeding h4.
        while(!current.nodeName.match(/h4/i))
        {
            current = current.previousSibling;
            if(!current) break;
        }
        if(current)
        {
            // We allow decimal identifiers.
            subid = current.innerHTML.match(/(\d+(\.\d+)?)/);
            if(subid.length) subid = subid[0];

            // Then we'll set the id of the paragraph holding our target, so we can look it up easily.
            target_p.id = "comment_p_" + subid;
            target_p.className = "comment_p";
        }
    }

    // We now know if we need a subid for this request, and so we can make the request.
    var path = get_cgi + "?postid=" + postid;
    xhr = new XMLHttpRequest();
    if(subid)
    {
        xhr.subid = subid; // To look this up when we get our response.
        path += encodeURIComponent("#" + subid);
    }
    xhr.open("GET", path);
    xhr.onreadystatechange = requestCommentsCallback;
    pending = true;
    xhr.send();
    return false; // Shouldn't follow any clicked links.
}

function buildComments(commentHTML, subid)
{
    // We'll be destroying any comment form for this subid, so we'll need to mark it as so.

    // Figure out where we'll need to stick these comments.
    var attachmentPoint = null;
    if(multiCommentPage)
    {
        attachmentPoint = document.getElementById("comment_p_" + subid);
    }
    else
    {
        attachmentPoint = document.getElementById("comment_attach");
    }

    var innerHTML = "<h1>Comments</h1>";
    if(commentHTML == null)
    {
        innerHTML += "<div class=\"no_comments\">No comments on this post yet.<div/>";
    }
    else
    {
       innerHTML += commentHTML;
    }

    attachmentPoint.innerHTML = innerHTML;

    var postLink = document.createElement("a");
    postLink.href = "";
    postLink.onclick = function(){return showCommentForm(subid)};
    postLink.id = "post_comment_link" + subid;
    postLink.classname = "post_comment_link";
    postLink.innerHTML = "Post Comment";

    attachmentPoint.appendChild(postLink);

    if(!document.getElementsByClassName)
    {
        return;
    }

    // Format dates.
    var dates = attachmentPoint.getElementsByClassName("comment_date");
    for(var i = 0; i < dates.length; i++)
    {
        // Converts to the user's time zone.
        var d = new Date();
        d.setTime(parseInt(dates[i].innerHTML) * 1000);
        var time = d.getHours();
        var minutes = d.getMinutes();
        if(minutes < 10)
            minutes = "0" + minutes;
        if(time > 12)
            time = (time - 12) + ":" + minutes + "PM";
        else
            time = time + ":" + minutes + "AM";
        dates[i].innerHTML = d.toLocaleDateString() + ", " + time;
    }
}

// Controls.
function cancelComment(subid){
    if(document.getElementById("comment" + subid).value != "")
    {
        if(confirm("Are you sure you want to discard this comment?"))
        {
            document.getElementById("comment" + subid).value = "";
            document.getElementById("comment_post_form").style.display = "none";
        }
    }
    else
        document.getElementById("comment_post_form").style.display = "none";
    return false;
}

function postCommentCallback(){
    var req_comments = false;
    if(xhr.readyState != 4 /* COMPLETED */)
    {
        return;
    }
    else if(xhr.status == 200)
    {
        document.getElementById("comment" + xhr.subid).value = "";
        document.getElementById("comment_post_form").style.display = "none";
        req_comments = true;
    }
    else
    {
        alert("Error: " + xhr.responseText);
    }
    pending = false;
    if(req_comments)
    {
        requestComments({"target": document.getElementById("comment_p_" + xhr.subid)});
    }
}

function postComment(subid){
    if(pending)
    {
        setTimeout(function(){postComment(subid)}, 250);
        return false;
    }

    var body = "postid=" + encodeURIComponent(postid)
    if(subid)
    {
        body += encodeURIComponent("#" + subid);
    }
    body += "&name=" + encodeURIComponent(document.getElementById("name" + subid).value);
    body += "&email=" + encodeURIComponent(document.getElementById("email" + subid).value);
    body += "&website=" + encodeURIComponent(document.getElementById("website" + subid).value);
    body += "&comment="+ encodeURIComponent(document.getElementById("comment_" + subid).value);
    xhr = new XMLHttpRequest();
    xhr.subid = subid;
    xhr.open("POST", post_cgi);
    xhr.onreadystatechange = postCommentCallback;
    pending = true;
    xhr.send(body);
    return false; // Shouldn't follow any clicked links.
}
