/* Expand Comments version 1.3.1
 *  Copyright 2006 Andrew Rader
 *
 * This file is part of Expand Comments
 *
 * Expand Comments is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.

 * Expand Comments is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Expand Comments; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

/*
 * Called when the link is clicked, handles show/hide stuff
 */
function expandCollapseComments( src ) {
    srcId = src.id;
    appendDiv = document.getElementById( srcId.replace( "expComLink-", "expComDiv-" ) );
    postID = srcId.replace( "expComLink-", "" );

    /* If we need to download the comments */
    if( src.getAttribute( "rel" ) == "get" ) {
        loadingDiv = document.getElementById( srcId.replace( "expComLink-", "expComLoading-" ) );
        loadingDiv.style.display = "";
        url = "?expcom&id=" + srcId.replace( "expComLink-", "" );
        makeAjaxRequest( 'handleExpandReturn', true, url, postID );
        src.setAttribute( "rel", "hide" );
    } else {
        /* otherwise, just show/hide the div */
        if( src.getAttribute( "rel" ) == "hide" ) {
            /* Hide the div */
            appendDiv.style.display = "none";
            src.setAttribute( "rel", "show" );
            if( expcom_exp.indexOf( '$count' ) != -1 ) {
                var divs = appendDiv.getElementsByTagName('div');
                var count = 0;
                for( i = 0; i < divs.length; i++ ) {
                    if( divs[i].id.indexOf( 'expComComment-' ) == 0 ) {
                        count++;
                    }
                }
                src.innerHTML = expcom_exp.replace( '$count', count );
            }
            else {
                src.innerHTML = expcom_exp;
            }
        } else {
            /* Show the div */
            appendDiv.style.display = "";
            src.setAttribute( "rel", "hide" );
            src.innerHTML = expcom_col;
        }
    }
    return false;
}

/*
 * Called from the bottom collapse link
 */
function collapse( src ) {
    srcID = src.id;
    appendDiv = document.getElementById( srcID.replace( "expCollLink-", "expComDiv-" ) );
    expColLink = document.getElementById( srcID.replace( "expCollLink-", "expComLink-" ) );

    appendDiv.style.display = "none";
    expColLink.setAttribute( "rel", "show" );
    if( expcom_exp.indexOf( '$count' ) != -1 ) {
        var divs = appendDiv.getElementsByTagName('div');
        var count = 0;
        for( i = 0; i < divs.length; i++ ) {
            if( divs[i].id.indexOf( 'expComComment-' ) == 0 ) {
                count++;
            }
        }
        expColLink.innerHTML = expcom_exp.replace( '$count', count );
    }
    else {
        expColLink.innerHTML = expcom_exp;
    }

    window.location.hash = srcID.replace( "expCollLink-", "expComComments-" );
    return false;
}

/*
 * Called from the form to submit a comment using AJAX
 */
function submitCommentForm( submitUrl, form, postID ) {
    getUrl = "/?expcom&id=" + postID;

    /* Clear the error */
    var err = document.getElementById( "expcom_ajax_error" );
    if(err) err.parentNode.removeChild(err);

    params = "";
    for( var i = 0; i < form.elements.length; i++ ) {
        switch( form.elements[i].name ) {
            case "author":
                if( form.elements[i].value == "" ) {
                    alertBadForm( form.elements[i], "You must enter a Name" );
                    return;
                }
                params += ( "author=" + form.elements[i].value + "&" );
                break;
            case "email":
                if( form.elements[i].value == "" ) {
                    alertBadForm( form.elements[i], "You must enter an Email" );
                    return;
                }
                var filter  = /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/;
                if( !filter.test( form.elements[i].value ) ) {
                    alertBadForm( form.elements[i], "You must enter a Valid Email" );
                    return;
                }
                params += ( "email=" + form.elements[i].value + "&" );
                break;
            case "url":
                params += ( "url=" + form.elements[i].value + "&" );
                break;
            case "comment":
                if( form.elements[i].value == "" ) {
                    alertBadForm( form.elements[i], "You must enter a Comment" );
                    return;
                }
                params += ( "comment=" + form.elements[i].value + "&" );
                break;
            case "comment_post_ID":
                params += ( "comment_post_ID=" + form.elements[i].value + "&" );
                break;
        }
    }
    
    submit = null;
    inputs = form.getElementsByTagName("input");
    for( var i = 0; i < inputs.length; i++ ) {
        if( inputs[i].type == "submit" ) {
            submit = inputs[i];
            break;
        }
    }

    textarea = form.getElementsByTagName("textarea")[0];

    params = params.substr(0,(params.length - 1));
    makeAjaxPost('handlePostReturn', true, submitUrl, params, getUrl, submit, textarea, postID);
    
    if( textarea != null ) {
        textarea.disabled = true;
    }

    if( submit != null ) {
        submit.disabled = true;
    }

}

/*
 * insertComment will insert a comment to the list of comments
 * before the beforeElement
 */
function insertComment( entry, appendDiv, beforeElement, showEffect ) {
    /* Create the container for this single comment */
    comment = document.createElement( "div" );

    commentIDNode = entry.getElementsByTagName("comment_ID");
    if( commentIDNode.length >0 && commentIDNode[0].firstChild ) {
        comment.id = "expComComment-" + commentIDNode[0].firstChild.data;
    }

    postAuthorNode = entry.getElementsByTagName("post_author");
    if( postAuthorNode.length > 0 && postAuthorNode[0].firstChild 
        && postAuthorNode[0].firstChild.data == 1 ) {
        comment.className = expcom_comtext_author_class;
    }
    else if( i % 2 == 0 ) {
        comment.className = expcom_comtext_even_class;
    }
    else {
        comment.className = expcom_comtext_odd_class;
    }

    /* Create the Author & Link */
    authLinkNode = entry.getElementsByTagName("comment_author_url");
    if( authLinkNode.length > 0 && authLinkNode[0].firstChild ) {
        authLink = authLinkNode[0].firstChild.data;
        authCite = document.createElement( "cite" );
        authCite.innerHTML = authLink;
        authCite.className = expcom_authclass;

        comment.appendChild( authCite );
    }

    says = document.createTextNode( " " + expcom_says + " " );
    comment.appendChild( says );

    approvedNode = entry.getElementsByTagName("comment_approved");
    if( approvedNode.length > 0 && approvedNode[0].firstChild ) {
        approved = approvedNode[0].firstChild.data;
        /* Is this approved? */
        if( approved == "0" ) {
            appr = document.createElement( "em" );
            appr.innerHTML = "Your comment is awaiting moderation.";
            comment.appendChild( appr );
        }
    }

    br = document.createElement( "br" );
    comment.appendChild(br);

    /* Now the Date */
    small = document.createElement( "small" );
    small.className = expcom_dateclass;

    linkNode = entry.getElementsByTagName("comment_link");
    if( linkNode.length > 0 && linkNode[0].firstChild ) {
        link = document.createElement( "a" );
        link.href = linkNode[0].firstChild.data;
        dateNode = entries[i].getElementsByTagName("comment_date");
        if( dateNode.length > 0 && dateNode[0].firstChild ) {
            theDate = dateNode[0].firstChild.data;
        }
        else {
            dateNode = entries[i].getElementsByTagName("comment_date_gmt");
            if( dateNode.length > 0 && dateNode[0].firstChild ) {
                theDate = dateNode[0].firstChild.data;
            }
            else {
                theDate = "";
            }
        }
        timeNode = entry.getElementsByTagName( "comment_time" );
        if( timeNode.length > 0 && timeNode[0].firstChild ) {
            theTime = " at "+timeNode[0].firstChild.data;
        }
        else {
            theTime = "";
        }

        link.innerHTML = theDate + theTime;

        link.title = "";
        small.appendChild( link );
    }
    
    /* Can we edit this comment? */
    canEdit = entry.getElementsByTagName("comment_edit");
    if( canEdit.length > 0 && canEdit[0].firstChild ) {
        space = document.createTextNode( " " );
        small.appendChild( space );

        edit = document.createElement("a");
        edit.href = canEdit[0].firstChild.data;
        edit.innerHTML = "edit";
        small.appendChild( edit );
    }

    comment.appendChild( small );

    /* Now the Comment Body */
    entryNode = entry.getElementsByTagName( "comment_content" );
    if( entryNode.length > 0 && entryNode[0].firstChild ) {
        text = document.createElement( "div" );
        text.className = expcom_comcontentclass;

        text.innerHTML = entryNode[0].firstChild.data;
        comment.appendChild( text );
    }
            
    /* Insert the comment block */
    if( showEffect ) {
        fadeEffect = new fx.Opacity( comment, {duration: 1000} );
        fadeEffect.setOpacity( 0 );

        appendDiv.insertBefore( comment, beforeElement );

        fadeEffect.custom(0,1);
    }
    else {
        appendDiv.insertBefore( comment, beforeElement );
    }
}

/*
 * removeComment - given the id number of the comment and post,
 * this will remove the comment from the DOM
 */
function removeComment( commentID, postID ) {
    commentsDiv = document.getElementById( "expComDiv-" + postID );
    comment = document.getElementById( "expComComment-" + commentID );
    commentsDiv.removeChild( comment );
}

/*
 * handleExpandReturn - called after the expand link is pressed and the
 * AJAX function has finished
 * This will insert all of the comments into the div
 */
function handleExpandReturn( retVal, postID ) {
    /* The XML Doc */
    xmlDoc = retVal.documentElement;

    if( postID >= 0 ) {
        appendDiv = document.getElementById( "expComDiv-" + postID );

        collapseLinkDiv = document.getElementById( "expCollLinkDiv-" + postID );

        /* Loop through the entries from the XML */
        entries = xmlDoc.getElementsByTagName( "comment" );
        for( i = 0; i < entries.length; i++ ) {
            insertComment( entries[i], appendDiv, collapseLinkDiv, false );
        }

        appendDiv.style.display = "";
    }

    newcommentform = document.getElementById(appendDiv.id.replace("expComDiv-","expcom-newform-"));
    if( newcommentform ) {
        newcommentform.style.display = "";
    }

    loadingDiv = document.getElementById( "expComLoading-" + postID );
    loadingDiv.style.display = "none";

    appendLink = document.getElementById(appendDiv.id.replace("expComDiv-","expComLink-"));
    appendLink.innerHTML = expcom_col;

    if( expcom_jump ) {
        window.location.hash = "expComComments-" + postID;
    }
}

/*
 * handePostReturn - this is called when the post request has completed.
 * Once the comment has been submitted, it will update the comments
 */
function handlePostReturn( retVal, getUrl, submit, textarea, postID ) {
    makeAjaxRequest( 'handleCommentSubmitted', true, getUrl, submit, textarea, postID );
}

/*
 * handleCommentSubmitted - Now that the comment is submitted,
 * update the comment list, and disable the form items
 * This will insert / remove comments based on what currently exists
 * versus what is returned from the server
 */
function handleCommentSubmitted( retVal, submit, textarea, postID ) {
    xmlDoc = retVal.documentElement;

    commentsDiv = document.getElementById( "expComDiv-" + postID );

    /* Create an array of the comment elements */
    commentIDs = new Array();

    /* And fill the array */
    subDivs = commentsDiv.getElementsByTagName( "div" );
    for( i = 0; i < subDivs.length; i++ ) {
        if( subDivs[i].id.indexOf( "expComComment-" ) == 0 ) {
            commentIDs.push( subDivs[i].id.replace("expComComment-", "") );
        }
    }

    /* Loop through the entries from the XML */
    entries = xmlDoc.getElementsByTagName( "comment" );
    for( i = 0; i < entries.length; i++ ) {
        entry = entries[i];
        entryIDNode = entry.getElementsByTagName( "comment_ID" );
        if( entryIDNode.length > 0 && entryIDNode[0].firstChild ) {
            entryID = entryIDNode[0].firstChild.data;
            matched = false;
            for( k = 0; k < commentIDs.length; k++ ) {
                if( commentIDs[k] == entryID ) {
                    commentIDs.splice(k ,1);
                    matched = true;
                    break;
                }
            }
            if( !matched ) {
                /* This is a new comment, so we must add it. First find the element
                * That will go after this comment, then insert the new comment
                */
                insertBeforeID = null;
                for( probe = commentIDs.length - 1; probe >= 0; probe++ ) {
                    if( commentIDs[probe] < entryID ) {
                        break;
                    }

                    insertBeforeID = commentIDs[probe];
                }

                if( insertBeforeID != null ) {
                    insertBeforeElement = document.getElementById( "expComComment-" + insertBeforeID );
                }
                else {
                    insertBeforeElement = document.getElementById( "expCollLinkDiv-" + postID );
                }

                insertComment( entry, commentsDiv, insertBeforeElement, expcom_moo_fx );
            }
        }
    }

    /* Now if there are any comments left, it means they were removed
     * by the server, so lets remove them from the list
     */

    for( r = 0; r < commentIDs.length; r++ ) {
        removeComment( commentIDs[r], postID );
    }

    refreshEvenOdd( postID );

    disableForm( textarea, submit, 15 );
}

/*
 * disableForm - disable the textarea and submit items for the number
 * of seconds
 */
function disableForm( textarea, submit, seconds ) {
    if( textarea != null ) {
        if( seconds > 0 ) {
            textarea.value = "You must wait " + seconds + " seconds";
        }
        else {
            textarea.value = "";
            textarea.disabled = false;
        }
    }

    if( seconds == 0 && submit != null ) {
        submit.disabled = false;
    }

    seconds--;
    secs = seconds + "";
    if( seconds >= 0 ) {
        setTimeout( 'disableForm( textarea, submit, secs )', 1000 );
    }
}

/*
 * refreshEvenOdd - this goes through all of the comments in a post
 * and re-calculates the even/odd class name
 */
function refreshEvenOdd( postID ) {
    commentsDiv = document.getElementById( "expComDiv-" + postID );

    divs = commentsDiv.getElementsByTagName( "div" );

    counter = 0;
    for( i = 0; i < divs.length; i++ ) {
        if( divs[i].id.indexOf( "expComComment-" ) == 0 ) {
            counter++;
            if( divs[i].className != expcom_comtext_author_class ) {
                if( counter % 2 == 0 ) {
                    divs[i].className = expcom_comtext_odd_class;
                }
                else {
                    divs[i].className = expcom_comtext_even_class;
                }
            }
        }
    }
}

/*
 * alertBadForm - modify the form to show that it is malformed
 */
function alertBadForm( el, msg ) {
    var error = document.createElement( "div" );
    error.id = "expcom_ajax_error";
    error.style.color = "#f08080";
    var errMsg = document.createTextNode( msg );
    error.appendChild( errMsg );
    el.parentNode.insertBefore( error,el );
}
