function fillComments()
{
    // Update the content of each comment
    // Currently of the form
    // <div group ref_id comment_type comment_id comment_val username editable/>
    
    var comments = document.getElementsByTagName('comment');
    
    while (comments.length > 0)
    {
        var ref_id = comments[0].getAttribute("ref_id");
        var comment_id = comments[0].getAttribute("comment_id");
        var username = comments[0].getAttribute("username");
        var comment_type = comments[0].getAttribute("comment_type");
        var comment_val = comments[0].getAttribute("comment_val");
        var editable = comments[0].getAttribute("editable");

        var newnode = makeCommentNode(ref_id, comment_id, username, comment_type, comment_val, editable);

        comments[0].parentNode.replaceChild(newnode, comments[0]);
    }
}

// Turn a node with structure:
// <comment ref_id='' comment_id='' user_id='' username='' comment_type=''>comment_val</comment>
// into html for that comment.
function makeCommentFromXML(currNode)
{
    var ref_id = currNode.getAttribute("ref_id");
    var comment_id = currNode.getAttribute("comment_id");
    var username = currNode.getAttribute("username");
    var comment_type = currNode.getAttribute("comment_type");
    
    // The comment value is in a child text node
    var comment_val = "";
    for (var j = 0; j < currNode.childNodes.length; i++)
    {
        if (currNode.childNodes[j].nodeType == 3)
        {
            // text
            comment_val = currNode.childNodes[j].textContent;
            break;
        }
    }            
    
    var newnode = makeCommentNode(ref_id, comment_id, username, comment_type, comment_val, 1);

    return newnode;
}

function makeCommentNode(ref_id, comment_id, username, comment_type, comment_val, editable)
{
    var children = [
            ["b", {}, username],
            ["text", {}, ": "]
        ];

    var commentContent = convertMarkup(comment_val);
    if (commentContent != null)
    {
        children = children.concat(commentContent); 
    }
    else
    {
        children.push(["text", {}, comment_val]);
    }
    
    var newnode = newElement("div", 
        {"group":"comment", "ref_id":ref_id, "comment_type":comment_type, "comment_id":comment_id, "comment_val":comment_val}, 
        null, 
        children);
    
    if (editable == 1)
    {
        newnode.appendChild(newElement("button", {onmousedown:'editComment(event)'}, "Edit"));
        newnode.appendChild(newElement("text", {}, " "));
        newnode.appendChild(newElement("button", {onmousedown:'deleteComment(event)'}, "Delete"));
    }
    
    return newnode;
}

function addComment(event)
{
    var commentRoot = getGroupRoot(event.target, "comment");
    if (!commentRoot)
        return;
    
    commentRoot.style.display = "none";
    
    var newContent = newElement("fieldset", {"upload":"comment","message":"Adding comment"}, null, [
        ["legend", {}, "Add Comment"],
        ["textarea", {name:'comment', rows:'6', cols:'80', uploadval:'comment_val'}, null],
        ["input", {type:'hidden', uploadval:'ref_id', value:commentRoot.getAttribute('ref_id')}, null],
        ["input", {type:'hidden', uploadval:'comment_type', value:commentRoot.getAttribute('comment_type')}, null],
        ["input", {type:'hidden', uploadval:'action', value:'add'}, null],
        ["button", {onmousedown:'submitComment(event)'}, "submit"],
        ["text", {}, " "],
        ["button", {onmousedown:'cancelComment(event)'}, "cancel"]
        ]);
    commentRoot.parentNode.insertBefore(newContent, commentRoot);
}

function editComment(event)
{
    var commentRoot = getGroupRoot(event.target, "comment");
    if (!commentRoot)
        return;
    
    commentRoot.style.display = "none";
    
    var newContent = newElement("fieldset", {"upload":"comment","message":"Editing comment"}, null, [
        ["legend", {}, "Edit Comment"],
        ["textarea", {name:'comment', rows:'6', cols:'80', uploadval:'comment_val'}, commentRoot.getAttribute('comment_val')],
        ["input", {type:'hidden', uploadval:'ref_id', value:commentRoot.getAttribute('ref_id')}, null],
        ["input", {type:'hidden', uploadval:'comment_type', value:commentRoot.getAttribute('comment_type')}, null],
        ["input", {type:'hidden', uploadval:'comment_id', value:commentRoot.getAttribute('comment_id')}, null],
        ["input", {type:'hidden', uploadval:'action', value:'edit'}, null],
        ["button", {onmousedown:'submitComment(event)'}, "update"],
        ["text", {}, " "],
        ["button", {onmousedown:'cancelComment(event)'}, "cancel"]
        ]);
    commentRoot.parentNode.insertBefore(newContent, commentRoot);
}

function deleteComment(event)
{
    var commentRoot = getGroupRoot(event.target, "comment");
    if (!commentRoot)
        return;
    
    commentRoot.style.display = "none";
    
    var newContent = newElement("fieldset", {"upload":"comment","message":"Deleting comment"}, commentRoot.getAttribute('comment_val'), [
        ["legend", {}, "Delete Comment"],
        ["input", {type:'hidden', uploadval:'ref_id', value:commentRoot.getAttribute('ref_id')}, null],
        ["input", {type:'hidden', uploadval:'comment_type', value:commentRoot.getAttribute('comment_type')}, null],
        ["input", {type:'hidden', uploadval:'comment_id', value:commentRoot.getAttribute('comment_id')}, null],
        ["input", {type:'hidden', uploadval:'comment_val', value:commentRoot.getAttribute('comment_val')}, null],
        ["input", {type:'hidden', uploadval:'action', value:'delete'}, null],
        ["button", {onmousedown:'submitComment(event)'}, "DELETE"],
        ["text", {}, " "],
        ["button", {onmousedown:'cancelComment(event)'}, "cancel"]
        ]);
    commentRoot.parentNode.insertBefore(newContent, commentRoot);
}

function submitComment(event)
{
    var uploadRoot = getUploadRoot(event.target);
    if (!uploadRoot)
        return;
        
    var http_string = "update.php";
    var params = getServerParams(uploadRoot);
    
    // Replace the update node with an updating message
    uploadRoot.innerHTML = "Connecting to server...<legend>" + uploadRoot.getAttribute('message') + "</legend>";
    
    ajax_post(http_string, 
    function(xml) 
    {
        receiveCommentFromServer(uploadRoot, xml);
    }, 
    params);
}

// Receive xml from the server, and apply it to syncNode.
function receiveCommentFromServer(syncNode, xml)
{
    // We have received info from the server, so need to update
    // Expect everything to be wrapped in a "result" element.
    if (xml.nodeName != "result" || xml.childNodes == null)
    {
        alert(xmlToString(xml));
        return;
    }
       
    if (xml.getAttribute('status') != 1)
    {
        newnode = newElement("fieldset", {"upload":"comment"}, 
            xmlToString(xml.firstChild), 
            [
            ["legend", {}, "Server error"],
            ["button", {onmousedown:'cancelForm(event)'}, "Bother."]
            ]);
        syncNode.parentNode.replaceChild(newnode, syncNode);
        return;
    }
    
    var newnode = null;
    
    // Can only cope with a single response
    if (xml.childNodes.length != 1)
    {
        alert('more than one response from server:' + xmlToString(xml));
        return;
    }
    
    var currNode = xml.childNodes[0];
        
    switch (currNode.getAttribute('action'))
    {
    case 'add':
        newnode = makeCommentFromXML(currNode);
        syncNode.nextSibling.style.display = "";
        syncNode.parentNode.replaceChild(newnode, syncNode);
        break;
        
    case 'update':
        newnode = makeCommentFromXML(currNode);
        syncNode.parentNode.removeChild(syncNode.nextSibling);
        syncNode.parentNode.replaceChild(newnode, syncNode);
        break;
        
    case 'delete':
        syncNode.parentNode.removeChild(syncNode.nextSibling);           
        syncNode.parentNode.removeChild(syncNode);           
        break;
    }
}

function cancelComment(event)
{
    // Cancel this action; revert to previous state
    
    var uploadRoot = getUploadRoot(event.target);
    if (!uploadRoot)
        return;
    
    // The form is always the element immediately before the removed element
    if (uploadRoot.nextSibling.style.display == "none")
    {
        uploadRoot.nextSibling.style.display = "";
    }
    uploadRoot.parentNode.removeChild(uploadRoot);
}


