/*global ich, Twitch */
(function ($) {

  /**
   * turns the target into a gameselector, displaying the results in the provided
   * target. The results are rendered by the template. Selecting an entry or pressing enter
   * will trigger the function passed as the second parameter, called with the title
   * of the game
   */
  $.fn.gameselector = function (template, opts) {

    opts = $.extend({'loadAsDisabled': (window.PP && !window.PP.channelMetaGame)}, opts);

    return this.each(function () {
      var ele = $(this) ;

      var original = ele.val() ;

      var setInputValue = function (str) {
        ele.val(str) ;
      } ;

      // Keep track of games so we don't submit an invalid meta_game
      ele.data('games', {});
      var gameChanged = false;

      // setup the autocomplete
      var autocomplete = ele.autocomplete({
        minLength: 3,
        delay: 0,
        //  autoFocus: true,

        // Performs the search
        source: function(request, response) {
          Twitch.api.get('/kraken/search/games', {query: request.term }, {version: 5}).done(function(data) {
            response(data.games);
          }).fail(function(data){
            response([]);
          });
        },

        // Triggered when we focus an element - either keyboard or mouse
        focus: function (event, ui) {
          setInputValue(ui.item.name) ;
          return false ;
        },

        // Triggered when we select and item with a mouse click or enter
        select: function (event, ui) {
          setInputValue(ui.item.name) ;
          if (opts.actionFn) {
            opts.actionFn(ui.item.name) ;
          }
          return false ;
        },

        search: function (event, ui) {
          gameChanged = true;
        },

        messages: {
          noResults: '',
          results: function () {}
        }

      });

      var gameselector = {
        isValidGame: function () {
        // Has this game been seen in search?
          return (!gameChanged || !!ele.data('games')[ele.val()] || ele.val() === '');
        }
      };

      autocomplete.data('gameselector', gameselector);

      autocomplete.data('ui-autocomplete')._renderItem = function (ul, item) {

        // correct name of property
        item.boxArt = item.box;
      // Store any result that comes back from search as a valid option
      // for submission
        var games = ele.data('games');
        games[item.name] = true;
        ele.data('games', games);

        item.images = item.images || {};
        item.images = Twitch.defaults(item.images, {
          tiny: 'https://www-cdn.jtvnw.net/images/xarth/gamefilter_all.png'
        });

        // calls the jquery template on our data and inserts it into the
        // list
        return ich['gameselector-game'](item)
                 .data('item.autocomplete', item)
                 .appendTo(ul) ;
      } ;

      autocomplete.data('ui-autocomplete')._cancelSearch = function () {
        if (this.xhr) {
          this.xhr.abort() ;
        }
      } ;

      /**
       * Give a way to trigger a reset
       */
      ele.bind('gameselector.reset', function () {
        setInputValue(original) ;
      }) ;

      /**
       * Triggering this prevents opening the drop down
       */
      ele.bind('gameselector.prevent', function () {
        ele.data('ui-autocomplete')._cancelSearch() ;
      }) ;


      ele.bind('gameselector.enable', function () {
        ele.removeClass('disabled') ;
        ele.attr('disabled', false) ;
        setInputValue(original) ;
      }) ;

      ele.bind('gameselector.disable', function () {
        ele.addClass('disabled') ;
        ele.attr('disabled', true) ;
        setInputValue('') ;
      }) ;

      if (opts.loadAsDisabled) {
        ele.trigger('gameselector.disable') ;
      }

    }) ;
  } ;

})(jQuery);
