/**
 * AutoCompleteView
 * @param {object} arg
 * @returns {AutoCompleteView}
 * @property {jQuery} $el テキストボックス
 * @property {array} source 候補として表示するデータ
 * @constructor
 */
var AutoCompleteView = function AutoCompleteView(arg) {
    this.$el = arg.$el;
    this.source = arg.source;

    return this;
};
AutoCompleteView.prototype.initialize = function initialize () {
    var self = this;

    this.$el.autocomplete({
        autoFocus: false,
        minLength: 0,
        select: function (event, ui) {
            if (self.$el.val() !== ui.item.value) {
              self.$el
                .val(ui.item.value)
                .trigger('update')
                .trigger('blur');
            }
        },
        source: function (request, response) {
            var term = zenkakuToHankaku(request.term);
            var escaped = term.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
            if (escaped.length === 0) {
              response(self.source);
              return;
            }

            var regex = new RegExp(escaped, 'i');
            var list =  _(self.source)
                .filter(function (item) {
                    return regex.test(item);
                })
                .value();

            response(list);
        }
    });

    this.$el.on('focus', function () {
      self.doSearch();
    });

    $(window).on('render', function () {
      self.adjust();
    });

    return this;
};
/**
 * ウィジェットの表示位置を調整
 * ex) ブラウザ上でスクロールバーの表示が切り替わったとき, 基点とする要素とずれる場合がある
 */
AutoCompleteView.prototype.adjust = function adjust () {
  this.widget().css({
    left: this.$el.offset().left
  });
};
/**
 * 検索を実行
 */
AutoCompleteView.prototype.doSearch = function doSearch () {
  this.$el.autocomplete('search', this.$el.val())
};
/**
 * 検索ソースを最新化
 * @param source
 */
AutoCompleteView.prototype.update = function update (source) {
  this.source = source;

  if (this.widget().is(':visible')) {
    this.doSearch();
  }
};
/**
 * autocomplete ウィジェットを取得
 * @returns {*}
 */
AutoCompleteView.prototype.widget = function widget () {
  return this.$el.autocomplete('widget');
};
