/* ---------------------------------------------------------------------------
 * Javascript for AjaxComments Django Application
 * 
 * Author: Michael Shepanski
 * License: Create Commons (Attribution, Noncommercial, Share Alike)
 *          http://creativecommons.org/licenses/by-nc-sa/3.0/us/
 *
 * Requirements:
 *   * jQuery 1.3.2 or newer; (http://jquery.com/)
 *   * jQuery Form Plugin; (http://jquery.malsup.com/form/)
 *   * jQuery MD5 Plugin; (http://plugins.jquery.com/project/md5)
 *   *
 *
 * Instructions:
 *   1. Add ajaxcomments to Python Path and Django's settings.INSTALLED_APPS.
 *
 *   2. Copy or link the ajaxcomments/media directory to your environments
 *      media directory and add the following references to html template
 *      containing Django's Comment application:
 *        * 
 * 
 *   2. Wrap the Django comment Form in a div with the class 'commentForm'.
 *      NOTE: This is used to know which form to alter.  Also, the completed
 *      commentBlock after successful post will be placed before this.
 *      ex: <div class='commentForm'>{% render_comment_form for post %}</div>
 *
 *   3. Update the function 'createCommentBlock()' below to match the HTML
 *      of a completed comment.  You can leave the actual value empty.
 *---------------------------------------------------------------------------- */

$(function() {
    
    var DOMAIN = "http://"+document.domain;                          // Current HTTP Domain
    var DEFAULT_AVATAR = DOMAIN+"/media/images/default_avatar.gif";  // Full URL Required
    // Live Preview Variables
    var commentBusy = false;                      // True when CommentForm is Submitting
    var previewComment = createCommentBlock();    // HTML for Live Preview
    var previousName = "<NONE>";                  // Placeholder for Name/Url Changes
    var previousEmail = "<NONE>";                 // Placeholder for Email Address changes
    var previousMarkupText = "<NONE>";            // Placeholder for MarkupText changes
    
    /*----------------------------------------------------------------------
     * Register the Wysiwym Editor
     *-------------------------------------------------------------------- */
    $('#id_comment').wysiwym(WysiwymMarkdown, 'wysiwymComment');
    $('#id_comment').before($('label[for="id_comment"]'));
    $('#wysiwymComment .wysiwymHeader').css('float', 'right').css('padding-right', '10px');
    
    /*----------------------------------------------------------------------
     * Setup the Live Preview
     *-------------------------------------------------------------------- */
    $('#id_email').bind('blur', function() {
        var email = $('#id_email').val();
        if (email != previousEmail) {
            var gravatar = getGravatarUrl(email);
            previewComment.find('.gravatar span').css('background-image', 'url('+gravatar+')');
            previousEmail = email;
        }
    });
    $('#id_email').triggerHandler('blur');
    // Hide the Button and Display the Preview
    $('.commentForm .submit-preview').remove();
    $('.commentForm').after(previewComment);
    previewComment.show();
    markupPreviewLoop();
    
    /*----------------------------------------------------------------------
     * Register the Comment Form Submit Button
     *-------------------------------------------------------------------- */
    $('.commentForm .submit-post').click(function() {
        var commentForm = $(this).parents('form');
        // Clear any currently displaying errors
        commentForm.find('.error-message').slideUp(300, function() {
            $(this).remove();
            $('.ajaxLoader').find('.error').removeClass('error');
        });
        // Don't Allow Double-Submit
        if (commentBusy) {
            $('.ajaxLoader').html("No need to double submit, I am trying the best I can.");
            return false;
        }
        commentBusy = true;
        // Add Wait Animation & Message
        loadingHtml  = "<div class='ajaxLoader' style='float: right; padding-right: 50px;'>";
        loadingHtml += "  One moment while the comment is posted..";
        loadingHtml += "</div>";
        $(this).before(loadingHtml);
        $('.ajaxLoader').fadeIn(600, function() {
            commentForm.ajaxSubmit({dataType: 'json', success: jsonResponse}); 
        });
        return false;
    });
    
    /*----------------------------------------------------------------------
     * JSON Response
     * Response will always be successful (even with form validation
     * errors).  This function simply performs the post-submit operations
     * then calls the correct success or error function.
     *-------------------------------------------------------------------- */
    function jsonResponse(data) {
        $('.ajaxLoader').fadeOut(600, function() {
            $(this).remove();
            commentBusy = false;
        });
        if (data.success)
            return commentFormSuccess(data);
        return commentFormError(data);
    }
    
    /*----------------------------------------------------------------------
     * Comment Form Submit Error Handler
     *   Loops through each error and appends an error message to it's
     *   corresponding input.
     *-------------------------------------------------------------------- */
    function commentFormError(data) {
        for (var field in data.errors) {
            var message = data.errors[field];
            $('#id_'+field).after("<div class='error-message' style='display: none;'>"+message+"</div>");
            $('#id_'+field).parent().addClass('error');
            $('.error-message').slideDown(300);
        }
    }
    
    /*----------------------------------------------------------------------
     * Comment Form Submit Success Handler
     *   Creates a dummy Comment Block and appends it to the bottom of
     *   the other comments.
     *-------------------------------------------------------------------- */
    function commentFormSuccess(data) {
        var newComment = createCommentBlock();
        // Update the NewComment Name & Date
        var name = $('#id_name').val();
        var url = $('#id_url').val();
        if (url != '')  { name = "<a href='"+url+"'>"+name+"</a>"; }
        newComment.find('.commentName').html(name);
        newComment.find('.commentDate').html('Comment Just Posted');
        // Update the NewComment Avatar
        var email = $('#id_email').val();
        var gravatar = getGravatarUrl(email);
        newComment.find('.gravatar span').css('background-image', 'url('+gravatar+')');
        // Update the NewComment Markup
        var markupText = $('#id_comment').val().escapeHTML();
        var converter = new Showdown.converter();
        var markupHtml = converter.makeHtml(markupText);
        newComment.find('.commentText').html(markupHtml);
        // Finish Up; Display Comment, Clear Form, Display ThankYou
        $('.commentForm').before(newComment);
        newComment.slideDown('300');
        $('#id_comment').val('');
        // TODO: Display ThankYou
    }
    
    /*----------------------------------------------------------------------
     * Creates a New Comment Block
     * NOTE: Edit this return HTML that matches your own comments.
     *-------------------------------------------------------------------- */
    function createCommentBlock() {
        comment  = "<div class='cornerBlock' style='margin-bottom: 10px; display: none;'>";
        comment += "  <div class='cb-header'><span></span></div>";
        comment += "  <div class='cb-content'>";
        comment += "    <div class='blogComment'>";
        comment += "      <div class='gravatar'><span></span></div>";
        comment += "      <div class='commentName'>Live Preview</div>";
        comment += "      <div class='commentDate'>This is a Live Preview</div>";
        comment += "      <div class='commentText'>&nbsp;</div>";
        comment += "      <div class='clear'></div>";
        comment += "    </div>";
        comment += "  </div>";
        comment += "  <div class='cb-footer'><span></span></div>";
        comment += "</div>";
        return $(comment);
    }
    
    /*----------------------------------------------------------------------
     * Returns the URL to the Gravatar Image
     *-------------------------------------------------------------------- */
    function getGravatarUrl(email) {
        gravatar  = "http://www.gravatar.com/avatar.php?size=48"
        gravatar += "&gravatar_id=" + $.md5(email);
        gravatar += "&default=" + DEFAULT_AVATAR;
        return gravatar;
    }
    
    /*----------------------------------------------------------------------
     * Preview Loop - Continiously runs after Preview button clicked
     *-------------------------------------------------------------------- */
    function markupPreviewLoop() {
        // Update the Preview Name
        var name = $('#id_name').val();
        var url = $('#id_url').val();
        if (name == '') { name = "Live Preview"; }
        if (url != '')  { name = "<a href='"+url+"'>"+name+"</a>"; }
        if (name != previousName) {
            previewComment.find('.commentName').html(name);
            previousName = name;
        }
        // Update the Comment Markup
        var markupText = $('#id_comment').val().escapeHTML();
        if (markupText == '') { markupText = "&nbsp;"; }
        if (markupText != previousMarkupText) {
            var converter = new Showdown.converter();
            var markupHtml = converter.makeHtml(markupText);
            previewComment.find('.commentText').html(markupHtml);
            previousMarkupText = markupText;
        }
        setTimeout(markupPreviewLoop, 100);
    }
    
});


/*----------------------------------------------------------------------
 * Additional Javascript Prototypes
 *-------------------------------------------------------------------- */
String.prototype.escapeHTML = function() {                                       
    return(this.replace(/&/g,'&amp;').replace(/>/g,'&gt;').
        replace(/</g,'&lt;').replace(/"/g,'&quot;'));
};