/* =============================================================
 * bootstrap-combobox.js v1.0.0
 * =============================================================
 * Copyright 2012 Daniel Farrell
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * ============================================================ */

!function ($) {

  "use strict"

  var Combobox = function (element, options) {
    this.options = $.extend({}, $.fn.combobox.defaults, options)
    this.$container = this.setup(element)
    this.$element = this.$container.find('input')
    this.$button = this.$container.find('.dropdown-toggle')
    this.$target = this.$container.find('select')
    this.matcher = this.options.matcher || this.matcher
    this.sorter = this.options.sorter || this.sorter
    this.highlighter = this.options.highlighter || this.highlighter
    this.$menu = $(this.options.menu).appendTo('body')
    this.placeholder = this.options.placeholder || this.$target.attr('data-placeholder')
    this.$element.attr('placeholder', this.placeholder)
    this.shown = false
    this.selected = false
    this.refresh()
    this.listen()
  }

  /* NOTE: COMBOBOX EXTENDS BOOTSTRAP-TYPEAHEAD.js
   ========================================== */

  Combobox.prototype = $.extend({}, $.fn.typeahead.Constructor.prototype, {

    constructor:Combobox, setup:function (element) {
      var select = $(element)
        , combobox = $(this.options.template)
      select.before(combobox)
      select.detach()
      combobox.append(select)
      return combobox
    },
    parse:function () {
      var map = {}
        , source = []
        , selected = false
      this.$target.find('option').each(function () {
        var option = $(this)
        map[option.text()] = option.val()
        source.push(option.text())
        if (option.attr('selected')) selected = option.html()
      })
      this.map = map
      if (selected) {
        this.$element.val(selected)
        this.$container.addClass('combobox-selected')
        this.selected = true
      }
      return source
    },
    toggle:function () {
      if (this.$container.hasClass('combobox-selected')) {
        this.clearTarget()
        this.$element.val('').focus()
      } else {
        if (this.shown) {
          this.hide()
        } else {
          this.lookup()
        }
      }
    },
    clearTarget:function () {
      this.$target.val('')
      this.$container.removeClass('combobox-selected')
      this.selected = false
      this.$target.trigger('change')
    },
    refresh:function () {
      this.source = this.parse()
      this.options.items = this.source.length
    }

    // modified typeahead function adding container and target handling
    , select:function () {
      var val = this.$menu.find('.active').attr('data-value')
      this.$element.val(val)
      this.$container.addClass('combobox-selected')
      this.$target.val(this.map[val])
      this.$target.trigger('change')
      this.selected = true
      return this.hide()
    }

    // modified typeahead function removing the blank handling
    , lookup:function (event) {
      var that = this
        , items
        , q

      this.query = this.$element.val()

      items = $.grep(this.source, function (item) {
        if (that.matcher(item)) return item
      })

      items = this.sorter(items)

      if (!items.length) {
        return this.shown ? this.hide() : this
      }

      return this.render(items.slice(0, this.options.items)).show()
    }

    // modified typeahead function adding button handling
    , listen:function () {
      this.$element
        .on('blur', $.proxy(this.blur, this))
        .on('keypress', $.proxy(this.keypress, this))
        .on('keyup', $.proxy(this.keyup, this))

      if ($.browser.webkit || $.browser.msie) {
        this.$element.on('keydown', $.proxy(this.keypress, this))
      }

//      hide menu hack
      this.$button.on('mouseenter', $.proxy(this.addClassOnMouseEnter, this.$button))
        .on('mouseleave', $.proxy(this.addClassOnMouseLeave, this.$button));

      $(window).on('click', $.proxy(this.hideList, this));
//      hide menu hack end


      this.$menu
        .on('click', $.proxy(this.click, this))
        .on('mouseenter', 'li', $.proxy(this.mouseenter, this))

      this.$button
        .on('click', $.proxy(this.toggle, this))
    }

    // modified typeahead function to clear on type and prevent on moving around
    , keyup:function (e) {
      switch (e.keyCode) {
        case 40: // down arrow
        case 39: // right arrow
        case 38: // up arrow
        case 37: // left arrow
        case 36: // home
        case 35: // end
        case 16: // shift
          break

        case 9: // tab
        case 13: // enter
          if (!this.shown) return
          this.select()
          break

        case 27: // escape
          if (!this.shown) return
          this.hide()
          break

        default:
          this.clearTarget()
          this.lookup()
      }

      e.stopPropagation()
      e.preventDefault()
    },

    addClassOnMouseEnter:function (e) {
      console.warn("Enter");
      this.addClass('hover');
    },

    addClassOnMouseLeave:function (e) {
      console.warn("Leave");
      this.removeClass('hover');
    },

    // modified typeahead function to only hide menu if it is visible
    blur:function (e) {
      var that = this
      e.stopPropagation()
      e.preventDefault()
      var val = this.$element.val()
      if (!this.selected && val != "") {
        this.$element.val("")
        this.$target.val("").trigger('change')
      }
      if (this.shown) {
        setTimeout(function () {
          that.hide()
        }, 150)
      }
    },

    /**
     * hide list
     * @param e
     */
    hideList:function (e) {
      if (!this.$button.is(".hover")) {
        var that = this;
        if (this.shown) {
          setTimeout(function () {
            that.hide()
          }, 150)
        }
      }
    }
  })

  /* COMBOBOX PLUGIN DEFINITION
   * =========================== */

  $.fn.combobox = function (option) {
    return this.each(function () {
      var $this = $(this)
        , data = $this.data('combobox')
        , options = typeof option == 'object' && option
      if (!data) $this.data('combobox', (data = new Combobox(this, options)))
      if (typeof option == 'string') data[option]()
    })
  }

  $.fn.combobox.defaults = {
    template:'<div class="combobox-container"><input type="text" autocomplete="off" /><span class="add-on btn dropdown-toggle" data-dropdown="dropdown"><span class="caret"/><span class="combobox-clear"><i class="icon-remove"/></span></span></div>',
    menu:'<ul class="typeahead typeahead-long dropdown-menu"></ul>',
    item:'<li><a href="#"></a></li>', placeholder:null
  }

  $.fn.combobox.Constructor = Combobox

}(window.jQuery);
