// 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($) {

  function suggest(elem, options) {
    var timer = null;
    var prevVal = null;
    var cache = {};
    var cacheKeys = [];

    var input = $(elem).attr("autocomplete", "off");
    var dropdown = $('<ul style="display: none; position: absolute; z-index: 10000"></ul>')
      .addClass(options.dropdownClass).appendTo(document.body);

    input
      .blur(function() {
        if (timer) clearTimeout(timer);
        setTimeout(function() { dropdown.hide() }, 200);
      })
      .keydown(function(e) {
        if ($.inArray(e.keyCode, [16, 17, 18, 20, 144, 91, 93, 224]) != -1) {
          return; // ignore modifier keys
        }
        if (timer) clearTimeout(timer);
        if ($.inArray(e.keyCode, [38, 40]) != -1 ||
            (dropdown.is(":visible") && (e.keyCode == 27 ||
             ($.inArray(e.keyCode, [9, 13]) != -1 && getSelection())))) {
          switch(e.keyCode) {
            case 38: // up
              moveUp();
              break;
            case 40: // down
              moveDown();
              break;
            case 9:  // tab
            case 13: // return
              commit();
              if (e.keyCode == 9) return true;
              break;
            case 27: // escape
              dropdown.hide();
              break;
          }
          e.preventDefault(); e.stopPropagation();
          return false;
        } else {
          timer = setTimeout(function() { suggest() }, options.delay);
        }
      });

    function suggest(force) {
      var newVal = $.trim(input.val());
      if (force || newVal != prevVal) {
        if (force || newVal.length >= options.minChars) {
          if (options.cache && cache.hasOwnProperty(newVal)) {
            show(cache[newVal].items, cache[newVal].render);
          } else {
            options.callback.apply(elem, [newVal, function(items, render) {
              if (options.cache) {
                if (cacheKeys.length >= options.cacheLimit) {
                  delete cache[cacheKeys.shift()];
                }
                cache[newVal] = {items: items, render: render};
                cacheKeys.push(newVal);
              }
              show(items, render);
            }]);
          }
        } else {
          dropdown.hide();
        }
        prevVal = newVal;
      }
    }

    function show(items, render) {
      if (!items) return;
      if (!items.length) { dropdown.hide(); return; }
      var offset = input.offset();
      dropdown.empty().css({
        top: (offset.top + input.outerHeight()) + "px", left: offset.left + "px",
        minWidth: input.css("width")
      });
      render = render || function(idx, value) { return value; }
      for (var i = 0; i < items.length; i++) {
        var item = $("<li></li>").data("value", items[i]);
        var rendered = render(i, items[i]);
        if (typeof(rendered) == "string") {
          item.text(rendered);
        } else {
          item.append(rendered);
        }
        item.appendTo(dropdown);
      }
      dropdown.slideDown("fast");
      dropdown.children("li").click(function(e) {
        $(this).addClass("selected");
        commit();
      });
    }

    function commit() {
      var sel = getSelection();
      if (sel) {
        prevVal = sel.data("value");
        input.val(prevVal);
        if (options.select) {
          options.select.apply(elem, [prevVal]);
        }
        dropdown.hide();
      }
      if (timer) clearTimeout(timer)
    }

    function getSelection() {
      if (!dropdown.is(":visible")) return null;
      var sel = dropdown.children("li.selected");
      return sel.length ? sel : null;
    }

    function moveDown() {
      if (!dropdown.is(":visible")) suggest(true);
      var sel = getSelection();
      if (sel) sel.removeClass("selected").next().addClass("selected");
      else dropdown.children("li:first-child").addClass("selected");
    }

    function moveUp() {
      if (!dropdown.is(":visible")) suggest(true);
      var sel = getSelection();
      if (sel) sel.removeClass("selected").prev().addClass("selected");
      else dropdown.children("li:last-child").addClass("selected");
    }
  }

  $.fn.suggest = function(callback, options) {
    options = $.extend({
      cache: true,
      cacheLimit: 10,
      callback: callback,
      delay: 250,
      dropdownClass: "suggest-dropdown",
      minChars: 1,
      select: null
    }, options || {});
    return this.each(function() {
      suggest(this, options);
    });
  };

})(jQuery);
