(function($) {

  var pluginName = "typeahead_search";

  var defaultOptions = {
  };

  var methods = {
    initialize: function (opts, sources) {

      return this.each(function() {
        var options = $.extend({}, defaultOptions, opts);
        var $this = $(this);
        $this.data(pluginName, {options: options});

        var $inputGroup = $('<div class="input-group" />');
        var $btnSpan = $("<span class='input-group-btn' />");
        var $btn = $("<button class='btn btn-default' type='button' />").append($("<span />").addClass("glyphicon glyphicon-search"));

        $btnSpan.append($btn);

        $this.after($inputGroup);
        $this.detach();
        $inputGroup.append($this);
        $inputGroup.append($btnSpan);

        $this.typeahead(opts, sources);

        $btn.on("click", function(evt) {
          privateMethods.search($this);
        });

        $this
            .on("typeahead:change", function(evt, value) {
              privateMethods.change($this, value);
            })
            .on("typeahead:select", function(evt, value) {
              privateMethods.select($this, value);
            })
            .on("typeahead:autocomplete", function(evt, value) {
              privateMethods.autocomplete($this, value);
            })
            .on("keydown", function(evt) {
              if (evt.keyCode == 13) {
                evt.preventDefault();
                privateMethods.search($this);
              }
            });
      });
    },

    val: function() {
      if (this.length) {
        return $(this[0]).typeahead("val");
      } else {
        return null;
      }
    }
  };

  var privateMethods = {
    change: function($this, value) {

    },

    select: function($this, item) {
      $this.trigger("typeahead_search:selected", item);
    },

    autocomplete: function($this, item) {
      $this.trigger("typeahead_search:selected", item);
    },

    search: function($this) {
      var options = privateMethods.options($this);
      var input = $this.typeahead("val");

      if (input.length && options.searchUrl && options.searchUrl.length) {
        $.get({
          url: options.searchUrl,
          data: {query: input},
          dataType: 'html',
          success: function(data) {
            $(options.resultsContainer).empty().append(data);
          }
        })
      }

      $this.typeahead("close");
    },

    options: function($this) {
      return $this.data(pluginName).options;
    }
  };

  $.fn[pluginName] = function (method) {
    if (methods[method]) {
      return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
    } else if (typeof method === 'object' || ! method) {
      return methods.initialize.apply(this, arguments);
    } else {
      $.error('Method ' +  method + ' does not exist on jQuery.' + pluginName);
    }
  };

})(jQuery);