(function() {
  this.AwardsHandler = (function() {
    const FROM_SENTENCE_REGEX = /(?:, and | and |, )/; //For separating lists produced by ruby's Array#toSentence
    function AwardsHandler() {
      this.aliases = gl.emojiAliases();
      $(document).off('click', '.js-add-award').on('click', '.js-add-award', (function(_this) {
        return function(e) {
          e.stopPropagation();
          e.preventDefault();
          return _this.showEmojiMenu($(e.currentTarget));
        };
      })(this));
      $('html').on('click', function(e) {
        var $target;
        $target = $(e.target);
        if (!$target.closest('.emoji-menu-content').length) {
          $('.js-awards-block.current').removeClass('current');
        }
        if (!$target.closest('.emoji-menu').length) {
          if ($('.emoji-menu').is(':visible')) {
            $('.js-add-award.is-active').removeClass('is-active');
            return $('.emoji-menu').removeClass('is-visible');
          }
        }
      });
      $(document).off('click', '.js-emoji-btn').on('click', '.js-emoji-btn', (function(_this) {
        return function(e) {
          var $target, emoji;
          e.preventDefault();
          $target = $(e.currentTarget);
          emoji = $target.find('.icon').data('emoji');
          $target.closest('.js-awards-block').addClass('current');
          return _this.addAward(_this.getVotesBlock(), _this.getAwardUrl(), emoji);
        };
      })(this));
    }

    AwardsHandler.prototype.showEmojiMenu = function($addBtn) {
      var $holder, $menu, url;
      $menu = $('.emoji-menu');
      if ($addBtn.hasClass('js-note-emoji')) {
        $addBtn.closest('.note').find('.js-awards-block').addClass('current');
      } else {
        $addBtn.closest('.js-awards-block').addClass('current');
      }
      if ($menu.length) {
        $holder = $addBtn.closest('.js-award-holder');
        if ($menu.is('.is-visible')) {
          $addBtn.removeClass('is-active');
          $menu.removeClass('is-visible');
          return $('#emoji_search').blur();
        } else {
          $addBtn.addClass('is-active');
          this.positionMenu($menu, $addBtn);
          $menu.addClass('is-visible');
          return $('#emoji_search').focus();
        }
      } else {
        $addBtn.addClass('is-loading is-active');
        url = this.getAwardMenuUrl();
        return this.createEmojiMenu(url, (function(_this) {
          return function() {
            $addBtn.removeClass('is-loading');
            $menu = $('.emoji-menu');
            _this.positionMenu($menu, $addBtn);
            if (!_this.frequentEmojiBlockRendered) {
              _this.renderFrequentlyUsedBlock();
            }
            return setTimeout(function() {
              $menu.addClass('is-visible');
              $('#emoji_search').focus();
              return _this.setupSearch();
            }, 200);
          };
        })(this));
      }
    };

    AwardsHandler.prototype.createEmojiMenu = function(awardMenuUrl, callback) {
      return $.get(awardMenuUrl, function(response) {
        $('body').append(response);
        return callback();
      });
    };

    AwardsHandler.prototype.positionMenu = function($menu, $addBtn) {
      var css, position;
      position = $addBtn.data('position');
      // The menu could potentially be off-screen or in a hidden overflow element
      // So we position the element absolute in the body
      css = {
        top: ($addBtn.offset().top + $addBtn.outerHeight()) + "px"
      };
      if ((position != null) && position === 'right') {
        css.left = (($addBtn.offset().left - $menu.outerWidth()) + 20) + "px";
        $menu.addClass('is-aligned-right');
      } else {
        css.left = ($addBtn.offset().left) + "px";
        $menu.removeClass('is-aligned-right');
      }
      return $menu.css(css);
    };

    AwardsHandler.prototype.addAward = function(votesBlock, awardUrl, emoji, checkMutuality, callback) {
      if (checkMutuality == null) {
        checkMutuality = true;
      }
      emoji = this.normilizeEmojiName(emoji);
      this.postEmoji(awardUrl, emoji, (function(_this) {
        return function() {
          _this.addAwardToEmojiBar(votesBlock, emoji, checkMutuality);
          return typeof callback === "function" ? callback() : void 0;
        };
      })(this));
      return $('.emoji-menu').removeClass('is-visible');
    };

    AwardsHandler.prototype.addAwardToEmojiBar = function(votesBlock, emoji, checkForMutuality) {
      var $emojiButton, counter;
      if (checkForMutuality == null) {
        checkForMutuality = true;
      }
      if (checkForMutuality) {
        this.checkMutuality(votesBlock, emoji);
      }
      this.addEmojiToFrequentlyUsedList(emoji);
      emoji = this.normilizeEmojiName(emoji);
      $emojiButton = this.findEmojiIcon(votesBlock, emoji).parent();
      if ($emojiButton.length > 0) {
        if (this.isActive($emojiButton)) {
          return this.decrementCounter($emojiButton, emoji);
        } else {
          counter = $emojiButton.find('.js-counter');
          counter.text(parseInt(counter.text()) + 1);
          $emojiButton.addClass('active');
          this.addYouToUserList(votesBlock, emoji);
          return this.animateEmoji($emojiButton);
        }
      } else {
        votesBlock.removeClass('hidden');
        return this.createEmoji(votesBlock, emoji);
      }
    };

    AwardsHandler.prototype.getVotesBlock = function() {
      var currentBlock;
      currentBlock = $('.js-awards-block.current');
      if (currentBlock.length) {
        return currentBlock;
      } else {
        return $('.js-awards-block').eq(0);
      }
    };

    AwardsHandler.prototype.getAwardUrl = function() {
      return this.getVotesBlock().data('award-url');
    };

    AwardsHandler.prototype.checkMutuality = function(votesBlock, emoji) {
      var $emojiButton, awardUrl, isAlreadyVoted, mutualVote;
      awardUrl = this.getAwardUrl();
      if (emoji === 'thumbsup' || emoji === 'thumbsdown') {
        mutualVote = emoji === 'thumbsup' ? 'thumbsdown' : 'thumbsup';
        $emojiButton = votesBlock.find("[data-emoji=" + mutualVote + "]").parent();
        isAlreadyVoted = $emojiButton.hasClass('active');
        if (isAlreadyVoted) {
          this.addAward(votesBlock, awardUrl, mutualVote, false);
        }
      }
    };

    AwardsHandler.prototype.isActive = function($emojiButton) {
      return $emojiButton.hasClass('active');
    };

    AwardsHandler.prototype.decrementCounter = function($emojiButton, emoji) {
      var counter, counterNumber;
      counter = $('.js-counter', $emojiButton);
      counterNumber = parseInt(counter.text(), 10);
      if (counterNumber > 1) {
        counter.text(counterNumber - 1);
        this.removeYouFromUserList($emojiButton, emoji);
      } else if (emoji === 'thumbsup' || emoji === 'thumbsdown') {
        $emojiButton.tooltip('destroy');
        counter.text('0');
        this.removeYouFromUserList($emojiButton, emoji);
        if ($emojiButton.parents('.note').length) {
          this.removeEmoji($emojiButton);
        }
      } else {
        this.removeEmoji($emojiButton);
      }
      return $emojiButton.removeClass('active');
    };

    AwardsHandler.prototype.removeEmoji = function($emojiButton) {
      var $votesBlock;
      $emojiButton.tooltip('destroy');
      $emojiButton.remove();
      $votesBlock = this.getVotesBlock();
      if ($votesBlock.find('.js-emoji-btn').length === 0) {
        return $votesBlock.addClass('hidden');
      }
    };

    AwardsHandler.prototype.getAwardTooltip = function($awardBlock) {
      return $awardBlock.attr('data-original-title') || $awardBlock.attr('data-title') || '';
    };

    AwardsHandler.prototype.toSentence = function(list) {
      if(list.length <= 2){
        return list.join(' and ');
      }
      else{
        return list.slice(0, -1).join(', ') + ', and ' + list[list.length - 1];
      }
    };

    AwardsHandler.prototype.removeYouFromUserList = function($emojiButton, emoji) {
      var authors, awardBlock, newAuthors, originalTitle;
      awardBlock = $emojiButton;
      originalTitle = this.getAwardTooltip(awardBlock);
      authors = originalTitle.split(FROM_SENTENCE_REGEX);
      authors.splice(authors.indexOf('You'), 1);
      return awardBlock
        .closest('.js-emoji-btn')
        .removeData('title')
        .removeAttr('data-title')
        .removeAttr('data-original-title')
        .attr('title', this.toSentence(authors))
        .tooltip('fixTitle');
    };

    AwardsHandler.prototype.addYouToUserList = function(votesBlock, emoji) {
      var awardBlock, origTitle, users;
      awardBlock = this.findEmojiIcon(votesBlock, emoji).parent();
      origTitle = this.getAwardTooltip(awardBlock);
      users = [];
      if (origTitle) {
        users = origTitle.trim().split(FROM_SENTENCE_REGEX);
      }
      users.unshift('You');
      return awardBlock
        .attr('title', this.toSentence(users))
        .tooltip('fixTitle');
    };

    AwardsHandler.prototype.createEmoji_ = function(votesBlock, emoji) {
      var $emojiButton, buttonHtml, emojiCssClass;
      emojiCssClass = this.resolveNameToCssClass(emoji);
      buttonHtml = "<button class='btn award-control js-emoji-btn has-tooltip active' title='You' data-placement='bottom'> <div class='icon emoji-icon " + emojiCssClass + "' data-emoji='" + emoji + "'></div> <span class='award-control-text js-counter'>1</span> </button>";
      $emojiButton = $(buttonHtml);
      $emojiButton.insertBefore(votesBlock.find('.js-award-holder')).find('.emoji-icon').data('emoji', emoji);
      this.animateEmoji($emojiButton);
      $('.award-control').tooltip();
      return votesBlock.removeClass('current');
    };

    AwardsHandler.prototype.animateEmoji = function($emoji) {
      var className = 'pulse animated once short';
      $emoji.addClass(className);

      $emoji.on('webkitAnimationEnd animationEnd', function() {
        $(this).removeClass(className);
      });
    };

    AwardsHandler.prototype.createEmoji = function(votesBlock, emoji) {
      if ($('.emoji-menu').length) {
        return this.createEmoji_(votesBlock, emoji);
      }
      return this.createEmojiMenu(this.getAwardMenuUrl(), (function(_this) {
        return function() {
          return _this.createEmoji_(votesBlock, emoji);
        };
      })(this));
    };

    AwardsHandler.prototype.getAwardMenuUrl = function() {
      return gon.award_menu_url;
    };

    AwardsHandler.prototype.resolveNameToCssClass = function(emoji) {
      var emojiIcon, unicodeName;
      emojiIcon = $(".emoji-menu-content [data-emoji='" + emoji + "']");
      if (emojiIcon.length > 0) {
        unicodeName = emojiIcon.data('unicode-name');
      } else {
        // Find by alias
        unicodeName = $(".emoji-menu-content [data-aliases*=':" + emoji + ":']").data('unicode-name');
      }
      return "emoji-" + unicodeName;
    };

    AwardsHandler.prototype.postEmoji = function(awardUrl, emoji, callback) {
      return $.post(awardUrl, {
        name: emoji
      }, function(data) {
        if (data.ok) {
          return callback();
        }
      });
    };

    AwardsHandler.prototype.findEmojiIcon = function(votesBlock, emoji) {
      return votesBlock.find(".js-emoji-btn [data-emoji='" + emoji + "']");
    };

    AwardsHandler.prototype.scrollToAwards = function() {
      var options;
      options = {
        scrollTop: $('.awards').offset().top - 110
      };
      return $('body, html').animate(options, 200);
    };

    AwardsHandler.prototype.normilizeEmojiName = function(emoji) {
      return this.aliases[emoji] || emoji;
    };

    AwardsHandler.prototype.addEmojiToFrequentlyUsedList = function(emoji) {
      var frequentlyUsedEmojis;
      frequentlyUsedEmojis = this.getFrequentlyUsedEmojis();
      frequentlyUsedEmojis.push(emoji);
      return $.cookie('frequently_used_emojis', frequentlyUsedEmojis.join(','), {
        path: gon.relative_url_root || '/',
        expires: 365
      });
    };

    AwardsHandler.prototype.getFrequentlyUsedEmojis = function() {
      var frequentlyUsedEmojis;
      frequentlyUsedEmojis = ($.cookie('frequently_used_emojis') || '').split(',');
      return _.compact(_.uniq(frequentlyUsedEmojis));
    };

    AwardsHandler.prototype.renderFrequentlyUsedBlock = function() {
      var emoji, frequentlyUsedEmojis, i, len, ul;
      if ($.cookie('frequently_used_emojis')) {
        frequentlyUsedEmojis = this.getFrequentlyUsedEmojis();
        ul = $("<ul class='clearfix emoji-menu-list frequent-emojis'>");
        for (i = 0, len = frequentlyUsedEmojis.length; i < len; i++) {
          emoji = frequentlyUsedEmojis[i];
          $(".emoji-menu-content [data-emoji='" + emoji + "']").closest('li').clone().appendTo(ul);
        }
        $('.emoji-menu-content').prepend(ul).prepend($('<h5>').text('Frequently used'));
      }
      return this.frequentEmojiBlockRendered = true;
    };

    AwardsHandler.prototype.setupSearch = function() {
      return $('input.emoji-search').on('keyup', (function(_this) {
        return function(ev) {
          var found_emojis, h5, term, ul;
          term = $(ev.target).val();
          // Clean previous search results
          $('ul.emoji-menu-search, h5.emoji-search').remove();
          if (term) {
            // Generate a search result block
            h5 = $('<h5 class="emoji-search" />').text('Search results');
            found_emojis = _this.searchEmojis(term).show();
            ul = $('<ul>').addClass('emoji-menu-list emoji-menu-search').append(found_emojis);
            $('.emoji-menu-content ul, .emoji-menu-content h5').hide();
            return $('.emoji-menu-content').append(h5).append(ul);
          } else {
            return $('.emoji-menu-content').children().show();
          }
        };
      })(this));
    };

    AwardsHandler.prototype.searchEmojis = function(term) {
      return $(".emoji-menu-list:not(.frequent-emojis) [data-emoji*='" + term + "']").closest('li').clone();
    };

    return AwardsHandler;

  })();

}).call(this);
