// Generated by CoffeeScript 1.6.1
(function() {

  $(function() {
    if (!window.$$contents) {
      window.$$contents = {};
    }
    return $.fn.extend({
      loading: function(takeFocus) {
        this.$_loading = $("<div class='loading-animation' tabindex='0'><span class='sr'>" + gettext("Loading content") + "</span></div>");
        $(this).after(this.$_loading);
        if (takeFocus) {
          DiscussionUtil.makeFocusTrap(this.$_loading);
          return this.$_loading.focus();
        }
      },
      loaded: function() {
        return this.$_loading.remove();
      }
    });
  });

  this.DiscussionUtil = (function() {

    function DiscussionUtil() {}

    DiscussionUtil.wmdEditors = {};

    DiscussionUtil.getTemplate = function(id) {
      return $("script#" + id).html();
    };

    DiscussionUtil.setUser = function(user) {
      return this.user = user;
    };

    DiscussionUtil.getUser = function() {
      return this.user;
    };

    DiscussionUtil.loadRoles = function(roles) {
      return this.roleIds = roles;
    };

    DiscussionUtil.loadRolesFromContainer = function() {
      return this.loadRoles($("#discussion-container").data("roles"));
    };

    DiscussionUtil.isStaff = function(user_id) {
      var staff, _ref;
      if (user_id == null) {
        user_id = (_ref = this.user) != null ? _ref.id : void 0;
      }
      staff = _.union(this.roleIds['Moderator'], this.roleIds['Administrator']);
      return _.include(staff, parseInt(user_id));
    };

    DiscussionUtil.isTA = function(user_id) {
      var ta, _ref;
      if (user_id == null) {
        user_id = (_ref = this.user) != null ? _ref.id : void 0;
      }
      ta = _.union(this.roleIds['Community TA']);
      return _.include(ta, parseInt(user_id));
    };

    DiscussionUtil.isPrivilegedUser = function(user_id) {
      return this.isStaff(user_id) || this.isTA(user_id);
    };

    DiscussionUtil.bulkUpdateContentInfo = function(infos) {
      var id, info, _results;
      _results = [];
      for (id in infos) {
        info = infos[id];
        _results.push(Content.getContent(id).updateInfo(info));
      }
      return _results;
    };

    DiscussionUtil.generateDiscussionLink = function(cls, txt, handler) {
      return $("<a>").addClass("discussion-link").attr("href", "javascript:void(0)").addClass(cls).html(txt).click(function() {
        return handler(this);
      });
    };

    DiscussionUtil.urlFor = function(name, param, param1, param2) {
      return {
        follow_discussion: "/courses/" + $$course_id + "/discussion/" + param + "/follow",
        unfollow_discussion: "/courses/" + $$course_id + "/discussion/" + param + "/unfollow",
        create_thread: "/courses/" + $$course_id + "/discussion/" + param + "/threads/create",
        update_thread: "/courses/" + $$course_id + "/discussion/threads/" + param + "/update",
        create_comment: "/courses/" + $$course_id + "/discussion/threads/" + param + "/reply",
        delete_thread: "/courses/" + $$course_id + "/discussion/threads/" + param + "/delete",
        flagAbuse_thread: "/courses/" + $$course_id + "/discussion/threads/" + param + "/flagAbuse",
        unFlagAbuse_thread: "/courses/" + $$course_id + "/discussion/threads/" + param + "/unFlagAbuse",
        flagAbuse_comment: "/courses/" + $$course_id + "/discussion/comments/" + param + "/flagAbuse",
        unFlagAbuse_comment: "/courses/" + $$course_id + "/discussion/comments/" + param + "/unFlagAbuse",
        upvote_thread: "/courses/" + $$course_id + "/discussion/threads/" + param + "/upvote",
        downvote_thread: "/courses/" + $$course_id + "/discussion/threads/" + param + "/downvote",
        pin_thread: "/courses/" + $$course_id + "/discussion/threads/" + param + "/pin",
        un_pin_thread: "/courses/" + $$course_id + "/discussion/threads/" + param + "/unpin",
        undo_vote_for_thread: "/courses/" + $$course_id + "/discussion/threads/" + param + "/unvote",
        follow_thread: "/courses/" + $$course_id + "/discussion/threads/" + param + "/follow",
        unfollow_thread: "/courses/" + $$course_id + "/discussion/threads/" + param + "/unfollow",
        update_comment: "/courses/" + $$course_id + "/discussion/comments/" + param + "/update",
        endorse_comment: "/courses/" + $$course_id + "/discussion/comments/" + param + "/endorse",
        create_sub_comment: "/courses/" + $$course_id + "/discussion/comments/" + param + "/reply",
        delete_comment: "/courses/" + $$course_id + "/discussion/comments/" + param + "/delete",
        upvote_comment: "/courses/" + $$course_id + "/discussion/comments/" + param + "/upvote",
        downvote_comment: "/courses/" + $$course_id + "/discussion/comments/" + param + "/downvote",
        undo_vote_for_comment: "/courses/" + $$course_id + "/discussion/comments/" + param + "/unvote",
        upload: "/courses/" + $$course_id + "/discussion/upload",
        users: "/courses/" + $$course_id + "/discussion/users",
        search: "/courses/" + $$course_id + "/discussion/forum/search",
        retrieve_discussion: "/courses/" + $$course_id + "/discussion/forum/" + param + "/inline",
        retrieve_single_thread: "/courses/" + $$course_id + "/discussion/forum/" + param + "/threads/" + param1,
        openclose_thread: "/courses/" + $$course_id + "/discussion/threads/" + param + "/close",
        permanent_link_thread: "/courses/" + $$course_id + "/discussion/forum/" + param + "/threads/" + param1,
        permanent_link_comment: "/courses/" + $$course_id + "/discussion/forum/" + param + "/threads/" + param1 + "#" + param2,
        user_profile: "/courses/" + $$course_id + "/discussion/forum/users/" + param,
        followed_threads: "/courses/" + $$course_id + "/discussion/forum/users/" + param + "/followed",
        threads: "/courses/" + $$course_id + "/discussion/forum",
        "enable_notifications": "/notification_prefs/enable/",
        "disable_notifications": "/notification_prefs/disable/",
        "notifications_status": "/notification_prefs/status/"
      }[name];
    };

    DiscussionUtil.ignoreEnterKey = function(event) {
      if (event.which === 13) {
        return event.preventDefault();
      }
    };

    DiscussionUtil.activateOnSpace = function(event, func) {
      if (event.which === 32) {
        event.preventDefault();
        return func(event);
      }
    };

    DiscussionUtil.makeFocusTrap = function(elem) {
      return elem.keydown(function(event) {
        if (event.which === 9) {
          return event.preventDefault();
        }
      });
    };

    DiscussionUtil.discussionAlert = function(header, body) {
      var alertDiv, alertTrigger;
      if ($("#discussion-alert").length === 0) {
        alertDiv = $("<div class='modal' role='alertdialog' id='discussion-alert' aria-describedby='discussion-alert-message'/>").css("display", "none");
        alertDiv.html("<div class='inner-wrapper discussion-alert-wrapper'>" + "  <button class='close-modal dismiss' aria-hidden='true'><i class='icon-remove'></i></button>" + "  <header><h2/><hr/></header>" + "  <p id='discussion-alert-message'/>" + "  <hr/>" + "  <button class='dismiss'>" + gettext("OK") + "</button>" + "</div>");
        this.makeFocusTrap(alertDiv.find("button"));
        alertTrigger = $("<a href='#discussion-alert' id='discussion-alert-trigger'/>").css("display", "none");
        alertTrigger.leanModal({
          closeButton: "#discussion-alert .dismiss",
          overlay: 1,
          top: 200
        });
        $("body").append(alertDiv).append(alertTrigger);
      }
      $("#discussion-alert header h2").html(header);
      $("#discussion-alert p").html(body);
      $("#discussion-alert-trigger").click();
      return $("#discussion-alert button").focus();
    };

    DiscussionUtil.safeAjax = function(params) {
      var $elem, request,
        _this = this;
      $elem = params.$elem;
      if ($elem && $elem.attr("disabled")) {
        return;
      }
      params["url"] = URI(params["url"]).addSearch({
        ajax: 1
      });
      params["beforeSend"] = function() {
        if ($elem) {
          $elem.attr("disabled", "disabled");
        }
        if (params["$loading"]) {
          if (params["loadingCallback"] != null) {
            return params["loadingCallback"].apply(params["$loading"]);
          } else {
            return params["$loading"].loading(params["takeFocus"]);
          }
        }
      };
      if (!params["error"]) {
        params["error"] = function() {
          return _this.discussionAlert(gettext("Sorry"), gettext("We had some trouble processing your request. Please ensure you have copied any unsaved work and then reload the page."));
        };
      }
      request = $.ajax(params).always(function() {
        if ($elem) {
          $elem.removeAttr("disabled");
        }
        if (params["$loading"]) {
          if (params["loadedCallback"] != null) {
            return params["loadedCallback"].apply(params["$loading"]);
          } else {
            return params["$loading"].loaded();
          }
        }
      });
      return request;
    };

    DiscussionUtil.updateWithUndo = function(model, updates, safeAjaxParams, errorMsg) {
      var undo,
        _this = this;
      if (errorMsg) {
        safeAjaxParams.error = function() {
          return _this.discussionAlert(gettext("Sorry"), errorMsg);
        };
      }
      undo = _.pick(model.attributes, _.keys(updates));
      model.set(updates);
      return this.safeAjax(safeAjaxParams).fail(function() {
        return model.set(undo);
      });
    };

    DiscussionUtil.bindLocalEvents = function($local, eventsHandler) {
      var event, eventSelector, handler, selector, _ref, _results;
      _results = [];
      for (eventSelector in eventsHandler) {
        handler = eventsHandler[eventSelector];
        _ref = eventSelector.split(' '), event = _ref[0], selector = _ref[1];
        _results.push($local(selector).unbind(event)[event](handler));
      }
      return _results;
    };

    DiscussionUtil.formErrorHandler = function(errorsField) {
      return function(xhr, textStatus, error) {
        var makeErrorElem, response, _i, _len, _ref, _results;
        makeErrorElem = function(message) {
          return $("<li>").addClass("post-error").html(message);
        };
        errorsField.empty().show();
        if (xhr.status === 400) {
          response = JSON.parse(xhr.responseText);
          if ((response.errors != null) && response.errors.length > 0) {
            _ref = response.errors;
            _results = [];
            for (_i = 0, _len = _ref.length; _i < _len; _i++) {
              error = _ref[_i];
              _results.push(errorsField.append(makeErrorElem(error)));
            }
            return _results;
          }
        } else {
          return errorsField.append(makeErrorElem(gettext("We had some trouble processing your request. Please try again.")));
        }
      };
    };

    DiscussionUtil.clearFormErrors = function(errorsField) {
      return errorsField.empty();
    };

    DiscussionUtil.postMathJaxProcessor = function(text) {
      var RE_DISPLAYMATH, RE_INLINEMATH;
      RE_INLINEMATH = /^\$([^\$]*)\$/g;
      RE_DISPLAYMATH = /^\$\$([^\$]*)\$\$/g;
      return this.processEachMathAndCode(text, function(s, type) {
        if (type === 'display') {
          return s.replace(RE_DISPLAYMATH, function($0, $1) {
            return "\\[" + $1 + "\\]";
          });
        } else if (type === 'inline') {
          return s.replace(RE_INLINEMATH, function($0, $1) {
            return "\\(" + $1 + "\\)";
          });
        } else {
          return s;
        }
      });
    };

    DiscussionUtil.makeWmdEditor = function($content, $local, cls_identifier) {
      var appended_id, editor, elem, id, imageUploadUrl, placeholder, _processor;
      elem = $local("." + cls_identifier);
      placeholder = elem.data('placeholder');
      id = elem.attr("data-id");
      appended_id = "-" + cls_identifier + "-" + id;
      imageUploadUrl = this.urlFor('upload');
      _processor = function(_this) {
        return function(text) {
          return _this.postMathJaxProcessor(text);
        };
      };
      editor = Markdown.makeWmdEditor(elem, appended_id, imageUploadUrl, _processor(this));
      this.wmdEditors["" + cls_identifier + "-" + id] = editor;
      if (placeholder != null) {
        elem.find("#wmd-input" + appended_id).attr('placeholder', placeholder);
      }
      return editor;
    };

    DiscussionUtil.getWmdEditor = function($content, $local, cls_identifier) {
      var elem, id;
      elem = $local("." + cls_identifier);
      id = elem.attr("data-id");
      return this.wmdEditors["" + cls_identifier + "-" + id];
    };

    DiscussionUtil.getWmdInput = function($content, $local, cls_identifier) {
      var elem, id;
      elem = $local("." + cls_identifier);
      id = elem.attr("data-id");
      return $local("#wmd-input-" + cls_identifier + "-" + id);
    };

    DiscussionUtil.getWmdContent = function($content, $local, cls_identifier) {
      return this.getWmdInput($content, $local, cls_identifier).val();
    };

    DiscussionUtil.setWmdContent = function($content, $local, cls_identifier, text) {
      this.getWmdInput($content, $local, cls_identifier).val(text);
      return this.getWmdEditor($content, $local, cls_identifier).refreshPreview();
    };

    DiscussionUtil.processEachMathAndCode = function(text, processor) {
      var $div, ESCAPED_BACKSLASH, ESCAPED_DOLLAR, RE_DISPLAYMATH, RE_INLINEMATH, cnt, codeArchive, processedText;
      codeArchive = [];
      RE_DISPLAYMATH = /^([^\$]*?)\$\$([^\$]*?)\$\$(.*)$/m;
      RE_INLINEMATH = /^([^\$]*?)\$([^\$]+?)\$(.*)$/m;
      ESCAPED_DOLLAR = '@@ESCAPED_D@@';
      ESCAPED_BACKSLASH = '@@ESCAPED_B@@';
      processedText = "";
      $div = $("<div>").html(text);
      $div.find("code").each(function(index, code) {
        codeArchive.push($(code).html());
        return $(code).html(codeArchive.length - 1);
      });
      text = $div.html();
      text = text.replace(/\\\$/g, ESCAPED_DOLLAR);
      while (true) {
        if (RE_INLINEMATH.test(text)) {
          text = text.replace(RE_INLINEMATH, function($0, $1, $2, $3) {
            processedText += $1 + processor("$" + $2 + "$", 'inline');
            return $3;
          });
        } else if (RE_DISPLAYMATH.test(text)) {
          text = text.replace(RE_DISPLAYMATH, function($0, $1, $2, $3) {
            processedText = processor("$$" + $2 + "$$", 'display') + processedText;
            processedText = $1 + processedText;
            return $3;
          });
        } else {
          processedText += text;
          break;
        }
      }
      text = processedText;
      text = text.replace(new RegExp(ESCAPED_DOLLAR, 'g'), '\\$');
      text = text.replace(/\\\\\\\\/g, ESCAPED_BACKSLASH);
      text = text.replace(/\\begin\{([a-z]*\*?)\}([\s\S]*?)\\end\{\1\}/img, function($0, $1, $2) {
        return processor(("\\begin{" + $1 + "}") + $2 + ("\\end{" + $1 + "}"));
      });
      text = text.replace(new RegExp(ESCAPED_BACKSLASH, 'g'), '\\\\\\\\');
      $div = $("<div>").html(text);
      cnt = 0;
      $div.find("code").each(function(index, code) {
        $(code).html(processor(codeArchive[cnt], 'code'));
        return cnt += 1;
      });
      text = $div.html();
      return text;
    };

    DiscussionUtil.unescapeHighlightTag = function(text) {
      return text.replace(/\&lt\;highlight\&gt\;/g, "<span class='search-highlight'>").replace(/\&lt\;\/highlight\&gt\;/g, "</span>");
    };

    DiscussionUtil.stripHighlight = function(text) {
      return text.replace(/\&(amp\;)?lt\;highlight\&(amp\;)?gt\;/g, "").replace(/\&(amp\;)?lt\;\/highlight\&(amp\;)?gt\;/g, "");
    };

    DiscussionUtil.stripLatexHighlight = function(text) {
      return this.processEachMathAndCode(text, this.stripHighlight);
    };

    DiscussionUtil.markdownWithHighlight = function(text) {
      var converter;
      text = text.replace(/^\&gt\;/gm, ">");
      converter = Markdown.getMathCompatibleConverter();
      text = this.unescapeHighlightTag(this.stripLatexHighlight(converter.makeHtml(text)));
      return text.replace(/^>/gm, "&gt;");
    };

    DiscussionUtil.abbreviateString = function(text, minLength) {
      if (text.length < minLength) {
        return text;
      } else {
        while (minLength < text.length && text[minLength] !== ' ') {
          minLength++;
        }
        return text.substr(0, minLength) + gettext('…');
      }
    };

    DiscussionUtil.abbreviateHTML = function(html, minLength) {
      var $result, imagesToReplace, truncated_text;
      truncated_text = jQuery.truncate(html, {
        length: minLength,
        noBreaks: true,
        ellipsis: gettext('…')
      });
      $result = $("<div>" + truncated_text + "</div>");
      imagesToReplace = $result.find("img:not(:first)");
      if (imagesToReplace.length > 0) {
        $result.append("<p><em>Some images in this post have been omitted</em></p>");
      }
      imagesToReplace.replaceWith("<em>image omitted</em>");
      return $result.html();
    };

    DiscussionUtil.getPaginationParams = function(curPage, numPages, pageUrlFunc) {
      var delta, maxPage, minPage, pageInfo, params;
      delta = 2;
      minPage = Math.max(curPage - delta, 1);
      maxPage = Math.min(curPage + delta, numPages);
      pageInfo = function(pageNum) {
        return {
          number: pageNum,
          url: pageUrlFunc(pageNum)
        };
      };
      return params = {
        page: curPage,
        lowPages: _.range(minPage, curPage).map(pageInfo),
        highPages: _.range(curPage + 1, maxPage + 1).map(pageInfo),
        previous: curPage > 1 ? pageInfo(curPage - 1) : null,
        next: curPage < numPages ? pageInfo(curPage + 1) : null,
        leftdots: minPage > 2,
        rightdots: maxPage < numPages - 1,
        first: minPage > 1 ? pageInfo(1) : null,
        last: maxPage < numPages ? pageInfo(numPages) : null
      };
    };

    return DiscussionUtil;

  }).call(this);

}).call(this);
