//
// BEGIN: our editor page javascript
//

function editorReady(bindHeartbeat) {
    $.get("/questions/ticks", function(txt) {
        $("#post-editor-hidden").append("<input type='hidden' name='bullet' value='" + txt + "' />");
    });
    if ($("#show-editor-button").length == 0)
        initPostEditor(bindHeartbeat);
}

function initPostEditor(bindHeartbeat) {
        
    setupFormValidation('#post-form', null, function(form) {
        setConfirmUnload(null); // Unbind the onbeforeunload handler to allow proper submission..
        form.submit();
    });
    
    var jWmd = $("#wmd-input");
    jWmd.not(".processed").TextAreaResizer();
    jWmd.typeWatch( { highlight:false, wait:5000, captureLength: 5, callback:styleCode } );
    jWmd.rules("add", { required: true, minlength: 15 });
    
    if ($("#title").length > 0)  
        $("#title").rules("add", { required: true, minlength: 15 });
    
    Attacklab.wmdBase();
    Attacklab.Util.startEditor();	    

    if (bindHeartbeat) jWmd.keypress(heartbeat.start);

    // once a new post is entered, bind a handler to prevent form loss via accidential navigation..
    jWmd.keypress(initNavPrevention);
        
    initPostLoginValidation();
}

function initPostLoginValidation() {
    // if the user is registered, none of these fields are present, so bail!
    if ($("#openid_identifier").length == 0) return;
    
    $.validator.addMethod("alturl", 
      function (value) { 
      return /((^https?:\/\/)?.{2,}\.\w{2,4}\/?|^$)/.test(value); }, 
      "Enter a valid URL.");
    
    $("#openid_identifier").rules("add", { alturl: true });
    
    // if anon participation is off, these fields aren't present..
    if ($("#display-name").length == 0) return;
    
    $.validator.addMethod("validUserName",
      function(value, element) {
      return this.optional(element) || /^[\w\-\s\d'\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+$/.test(value); },
      "Can only contain A-Z, 0-9, spaces, and hyphens.");        
    $.validator.addMethod("oidalt", 
      function(value) {
      return (value.length > 2) || ($("#openid_identifier").val().length > 0); },
      function() {
      return "<br>" + ($("#name_req_err").text() ? $("#name_req_err").text() : "Required if you're not using an OpenID"); });

    $("#display-name").rules("add", { validUserName: true, oidalt: true, minlength: 2, maxlength: 30 });
    $("#email").rules("add", { email: true, oidalt: true });                
    $("#home-page").rules("add", { alturl: true });
}

function initNavPrevention(eventArgs) {
    if (eventArgs.which == "undefined") return; // this happens due to the keypress event being fired upon first binding..
    $("#wmd-input").unbind("keypress", initNavPrevention);
    setConfirmUnload("You have started writing or editing a post.");
}

//
// END: our editor page javascript
//

// BEGIN: jquery.typewatch.js
(function(jQuery) {
    jQuery.fn.typeWatch = function(o) {
        var options = jQuery.extend({
            wait: 750,
            callback: function() { },
            highlight: true,
            captureLength: 2
        }, o);

        function checkElement(timer, override) {
            var elTxt = jQuery(timer.el).val();

            if ((elTxt.length > options.captureLength && elTxt.toUpperCase() != timer.text)
			|| (override && elTxt.length > options.captureLength)) {
                timer.text = elTxt.toUpperCase();
                timer.cb(elTxt);
            }
        };

        function watchElement(elem) {
            if (elem.type.toUpperCase() == "TEXT" || elem.nodeName.toUpperCase() == "TEXTAREA") {
                var timer = {
                    timer: null,
                    text: jQuery(elem).val().toUpperCase(),
                    cb: options.callback,
                    el: elem,
                    wait: options.wait
                };

                if (options.highlight) {
                    jQuery(elem).focus(
						function() {
						    this.select();
						});
                }

                var startWatch = function(evt) {
                    var timerWait = timer.wait;
                    var overrideBool = false;

                    if (evt.keyCode == 13 && this.type.toUpperCase() == "TEXT") {
                        timerWait = 1;
                        overrideBool = true;
                    }

                    var timerCallbackFx = function() {
                        checkElement(timer, overrideBool)
                    }

                    clearTimeout(timer.timer);
                    timer.timer = setTimeout(timerCallbackFx, timerWait);

                };

                jQuery(elem).keydown(startWatch);
            }
        };

        return this.each(function(index) {
            watchElement(this);
        });

    };

})(jQuery);

// BEGIN: jquery.textarearesizer.js
(function($) {
    var textarea, staticOffset;
    var iLastMousePos = 0;
    var iMin = 32;
    var grip;
    $.fn.TextAreaResizer = function() {
        return this.each(function() {
            textarea = $(this).addClass('processed'), staticOffset = null;
            $(this).parent().append($('<div class="grippie"></div>').bind("mousedown", { el: this }, startDrag));
            var grippie = $('div.grippie', $(this).parent())[0];
            grippie.style.marginRight = (grippie.offsetWidth - $(this)[0].offsetWidth) + 'px';

        });
    };
    function startDrag(e) {
        textarea = $(e.data.el);
        textarea.blur();
        iLastMousePos = mousePosition(e).y;
        staticOffset = textarea.height() - iLastMousePos;
        textarea.css('opacity', 0.25);
        $(document).mousemove(performDrag).mouseup(endDrag);
        return false;
    }

    function performDrag(e) {
        var iThisMousePos = mousePosition(e).y;
        var iMousePos = staticOffset + iThisMousePos;
        if (iLastMousePos >= (iThisMousePos)) {
            iMousePos -= 5;
        }
        iLastMousePos = iThisMousePos;
        iMousePos = Math.max(iMin, iMousePos);
        textarea.height(iMousePos + 'px');
        if (iMousePos < iMin) {
            endDrag(e);
        }
        return false;
    }

    function endDrag(e) {
        $(document).unbind('mousemove', performDrag).unbind('mouseup', endDrag);
        textarea.css('opacity', 1);
        textarea.focus();
        textarea = null;
        staticOffset = null;
        iLastMousePos = 0;
    }

    function mousePosition(e) {
        return { x: e.clientX + document.documentElement.scrollLeft, y: e.clientY + document.documentElement.scrollTop };
    };
})(jQuery);

// BEGIN: new-activity-heartbeat
var heartbeat = function() {

    var timeout = 1000 * 60;
    var questionId;
    var bindCount = 0;
    var hasBeenNotified = false;
    
    return {
        
        start: function(eventArgs) {
            if (eventArgs.which == "undefined") return; // this happens due to the keypress event being fired upon first binding..
            if (bindCount++ > 0) return; // prevent multiple bindings..
            $("#wmd-input").unbind("keypress", heartbeat.start);
            questionId = location.href.match(/\/questions\/(\d+)/i)[1];
            setTimeout(heartbeat.ping, timeout);
        },

        ping: function() {
            var answerIds = ""; // Pass a space-delimited string of all answer ids currently on the page

            $("div.answer").each(function() {
                answerIds += this.id.substring("answer-".length) + " ";
            });

            $.post("/posts/" + questionId + "/new-activity-heartbeat", { "answerIds": answerIds }, heartbeat.result, "json");
        },

        result: function(data) {
            var rebindHeartbeat = true;
            if (data && !hasBeenNotified) {
                if (data.NoPosting) {
                    var msg = "This question has been " + data.Msg + " - no more answers will be accepted.";
                    notify.show(msg);
                    hasBeenNotified = true;
                    disableSubmitButton("#post-form");
                    setConfirmUnload(null);
                    rebindHeartbeat = false;
                } 
                else if (data.Result) { // Server returns true when there are more answers
                    var msg = data.Count + " new answer" + (data.Count == 1 ? " has" : "s have") + " been posted - "
                    msg += '<a onclick="heartbeat.update()">load new answers.</a>';
                    notify.show(msg);
                    hasBeenNotified = true;
                }
            }
            if (rebindHeartbeat)
                setTimeout(heartbeat.ping, timeout);
        },

        update: function() {
            var divIdsToAdd = [];

            // For now (naively), fetch the entire page again..
            $.get("/questions/" + questionId, function(html) {
                var jHtml = $(html);

                jHtml.find("div.answer").each(function() {
                    var id = this.id.substring("answer-".length);
                    if ($("#answer-" + id).length == 0) {
                        divIdsToAdd.push(this.id);
                    }
                });

                if (divIdsToAdd.length > 0) {
                    var selector = "#" + divIdsToAdd.join(",#");
                    var divs = jHtml.find(selector);
                    var appendAfter = $("div.answer:last");

                    if (appendAfter.length == 0)
                        appendAfter = $("#answers-header");

                    divs.hide();
                    appendAfter.after(divs);
                    divs.fadeIn("slow");
                    // Update answer count..
                    var totalAnswers = $("div.answer").length;
                    $("#subheader h2").text(totalAnswers + " Answer" + (totalAnswers > 1 ? "s" : ""));

                    // Rebind all click handlers on page..
                    vote.init(questionId);
                    comments.init();
                }

                notify.close();
                hasBeenNotified = false;
            }, "html");
        }


    };

} ();