(function($){
  $.behaveAsSelect = function(el, options) {
    // To avoid scope issues, use 'base' instead of 'this'
    // to reference this class from internal events and functions.
    var base = this;

    // Access to jQuery and DOM versions of element
    base.$el = $(el);
    base.el = el;

    base.clear_search_timeout = null;

    // Add a reverse reference to the DOM object
    base.$el.data("behaveAsSelect", base);

    // Find the currently highlighted list item
    base.current_list_item = function () {
      return base.$dropdown.find('.' + base.options.highlight).first();
    };

    // Highlight new item when navigating with arrows
    base.new_list_item = function () {
      var $current_list_item = base.current_list_item(),
          direction = (base.event.keyCode == 38) ? 'prev' : 'next',
          $new_list_item = $current_list_item[direction]().first();

      if ($current_list_item.length > 0 && $new_list_item.length > 0) {
        base.change_current_item_to($new_list_item);
        return $new_list_item;
      }
      return null;
    };

    // Add highlight class to element
    base.change_current_item_to = function ($el) {
      base.remove_current_item();
      $el.addClass(base.options.highlight)
    };

    // Remove highlight class from all li's inside dropdown
    base.remove_current_item = function () {
      base.$dropdown.find('li').removeClass(base.options.highlight);
    };

    // Find the first matching list item
    base.find_first_matching_list_item = function () {      
      var $list_item = base.$dropdown.find('a:ci_begins('+base.$input.val()+')').first();
       if($list_item.length > 0) {
        base.change_current_item_to($list_item.parent());
        base.$dropdown.scrollTop(base.$dropdown.scrollTop() + $list_item.position().top);
      }
    };
    
    // Changes the window.location.href
    base.change_window_href = function () {
      base.event.preventDefault();
      var $current_list_item = base.current_list_item();
      
      if ($current_list_item.length > 0) {
        var href = $current_list_item.find('a').attr('href');
        
        if(href.indexOf('http:') == -1) {
          window.location.href = window.location.href + '/' + href;
        } else {
          window.location.href = href
        }
        
      }
    };

    // Allows for navigation with arrow keys
    base.arrow_navigation = function () {
      base.event.preventDefault();      
      var $new_list_item = base.new_list_item();
      
      if ($new_list_item) {
        new_list_item_position = $new_list_item.position().top + $new_list_item.outerHeight();

        if (new_list_item_position < $new_list_item.outerHeight()) {          
          base.$dropdown.scrollTop(base.$dropdown.scrollTop() + new_list_item_position - $new_list_item.outerHeight());          
        } else if (new_list_item_position > base.$dropdown.height() - 5) {
          base.$dropdown.scrollTop(base.$dropdown.scrollTop() + new_list_item_position - base.$dropdown.height() + 5);          
        }        
      }  
    };

    // Searches for entered text and starts timeout
    base.search_dropdown_list = function () {
      clearTimeout(base.clear_string_timeout);
      
      if (base.$input.val().length > 0) {
        base.find_first_matching_list_item();        
        base.clear_string_timeout = setTimeout("jQuery('."+ base.options.input_class+"').val('')",base.options.timeout);
      }
    };

    // Hides the dropdown list
    base.hide_dropdown_list = function () {      
      if(base.$dropdown.data('hover') != true) {
        base.$dropdown.hide();
      }
    };
    
    base.init = function(){        
        base.options = $.extend({},$.behaveAsSelect.defaultOptions, options);        

        base.$dropdown = base.$el.find(base.options.dropdown);
        base.$trigger = base.$el.find(base.options.trigger);
        base.$input = $('<input class="'+base.options.input_class+'" />');

        // CODE FOR INPUT
        base.$input
          .insertAfter(base.$trigger)
          .css(base.options.input_css)
          .blur(function () {
            base.hide_dropdown_list();
          })
          .focus(function () {
            base.$dropdown.show();
          })
          .keyup(function (e) {
            base.event = e;
            if (base.event.keyCode == 13) {
              base.change_window_href(e);
            } else if (base.event.keyCode == 38 || base.event.keyCode == 40 ) {
              base.arrow_navigation(e);
            } else {
              base.search_dropdown_list();              
            }
          });
        
        // CODE FOR DROPDOWN
        base.$dropdown
          .hover(function () {
            $(this).data('hover', true);
          }, function () {
            $(this).data('hover', false);
          }).scroll(function () {
            base.$input.focus();
          })
          .find('li')
          .hover(function () {
            base.change_current_item_to($(this));
            base.$input.focus();
          });

        // CODE FOR TRIGGER
        base.$trigger
          .click(function () {
          if(base.$dropdown.is(':visible')) {                
            base.$dropdown.data('hover', false);
            base.$input.blur();
          } else {
            base.$input.focus();
          }
        });        
        // Put your initialization code here
  
    };

   
    // Run initializer
    base.init();
  };

  $.behaveAsSelect.defaultOptions = {
      create_input: true,
      input_class: 'dropdown_search_value',
      trigger: '.dropdown_trigger',
      dropdown: '.search_select_dropdown',
      highlight: 'current_typed',
      timeout: 500,
      input_css: {
            'position': 'absolute',
            'left': -5000,
            'opacity': 0
          }
  };

  $.fn.behaveAsSelect = function(options){
      return this.each(function(){
          (new $.behaveAsSelect(this, options));
      });
  };

  // add Case insensitive begins selector
  jQuery.expr[':'].ci_begins = function(a,i,m){
       return jQuery(a).text().toUpperCase().indexOf(m[3].toUpperCase())==0;
  };

})(jQuery);

