
QuickSearch = function(el, options) {
  // private
  var _keys = {
    escape : 27,
    left : 37,
    up : 38,
    right : 39,
    down : 40,
    enter: 13
  }

  var _this;
  var $_this;
  var _input;
  var $_input;
  var _popup;
  var _results;
  var _cache = new Array();
  var _enabled = true;
  var _ignoreFormSubmit = false;
  var _inputTemp = '';

  var _mouse_is_over = false;
  var _options = {
    'timer': 100,
    'url':'/ro/quicksearch',
    'lang':'ro',
    'insertSuggestion': false,
    'popupStyle':'suggestion',
    'popupTitle':''
  }

  var _params = {
    'type':'places'
  }
  // public
  QuickSearch.prototype = {
    setParams: function(params) {
      $.extend(_params, params);
    },
    setOptions: function(options) {
      _setOptions(options);
    },
    show:function() {
      _showQuickSearch();
    },

    close:function() {
      _closeQuickSearch();
    },

    enable: function() {
      _enabled = true;
    },

    disable: function() {
      _enabled = false;
    },
    clear: function(doClearCache) {
      _clearQuickSearch(doClearCache);
    },
    CLASSNAME:'QuickSearch'
  }
  return _createQuickSearch(el, options);

  function _createQuickSearch(el, options) {
    _setOptions(options);

    _input = document.getElementById(el);
    var parent = _input.parentNode;
    _this = document.createElement('div');
    $_input = $(_input);
    _this.className = 'quicksearch';
    var txtClose = 'Inchideti'
    switch(_options.lang) {
      case 'ro': txtClose = 'Inchide'; break;
      case 'ru': txtClose = 'Закрыть'; break;
      case 'en': txtClose = 'Close'; break;
    }
    var divHtml = '';
    if (_options.popupStyle == 'listOfLinks')
      divHtml = '<span class="results-title">'+_options.popupTitle+'</span>';
    divHtml += '<div class="results"></div>'
    +'<a class="close" title="'+txtClose+'">'+txtClose+'</a>';
    _popup = document.createElement('div');
//    _popup.className = 'popup';
    _popup.innerHTML = divHtml;
    _popup.style.display = 'none';
    $(_popup).css({'top':$_input.height() + 8})
             .addClass('popup').addClass(_options.popupStyle);
    parent.replaceChild(_this, _input);
    _this.appendChild(_input);
    _this.appendChild(_popup);

    $.extend(_this, QuickSearch.prototype);

    $_this = $(_this);

    if (_input.id) {
      _this.id = "quicksearsch-" + _input.id;
    }
    _results = $_this.find('.results')[0];

    _registerEvents();
    _inputTemp = '';
    return _this;
  }

  function _setOptions(options) {
    if (typeof options != 'object' && typeof options != 'array') {
      return;
    }

    for(key in _options) {
      if (typeof options[key] != 'undefined') {
        _options[key] = options[key];
        if (key == 'popupTitle' && _popup != null)
          $(_popup).find('.results-title').html(_options[key]);
      }
    }
  }
    
  function _registerEvents() {
    $_input.bind('keydown', _onKeyDown);
    $_input.bind('keyup', _onKeyUp);
    if (_input.form) {
      var oldOnFormSubmit = _input.form.onsubmit;
      _input.form.onsubmit = null;
      $(_input.form).unbind('submit').bind('submit', function(evt) {
        _onFormSubmit(evt, oldOnFormSubmit);
      });
    }
    $_input.bind('blur', _onBlur);
    $_input.bind('focus', _onFocus);
    $_this.find('.close').bind('click', _closeQuickSearch);
    $_this.bind('onSelectedResult', _clickResult);
  }

  function _registerPopupEvents() {
    $(_popup).find('.item').bind('mouseover', _resultMouseOver);
    $(_popup).bind('mouseenter', _popupMouseEnter);
    $(_popup).bind('mouseleave', _popupMouseLeave);
    $(_popup).find('.item').bind('click', function(evt){
      $_this.trigger('onSelectedResult', evt);
    });
  }

  // _onFormSubmit: cancels form submission if
  // an enter keydown event has been handled by the quicsearch
  function _onFormSubmit(evt, oldOnFormSubmit) {
    if (_ignoreFormSubmit == true) {
      if (typeof evt.preventDefault == "function") {
        evt.preventDefault();
      }
      else {
        evt.returnValue = false;
      }
      _ignoreFormSubmit = false;
    }
    else {
      oldOnFormSubmit(evt, _input.form);
    }
  }

  function _onKeyDown(evt) {
    _ignoreFormSubmit = false;
    switch(evt.keyCode) {
      case _keys.enter:
        if ($(_popup).find('.selected')[0] != undefined) {
          _ignoreFormSubmit = true;
        }
        $_this.trigger('onSelectedResult', evt);
        return;
    }
  }
  
  function _onKeyUp(evt) {
    _ignoreFormSubmit = false;
    switch(evt.keyCode) {
      case _keys.escape:
        _closeQuickSearch();
        return;
      case _keys.up:
        _hoverResult('up');
        return;
      case _keys.down:
        _hoverResult('down');
        return;
      default:
        if (_options.insertSuggestion == true)
          _inputTemp = $_input.val();
        
    }
    
    if (!_enabled) return;
    _makeRequest(_input.value);
  }

  function _onBlur() {
    if (!_mouse_is_over) {
      _closeQuickSearch();
    }
    _this.disable();
  }

  function _onFocus() {
    _this.enable();
  }

  function _makeRequest(search) {
    
    search = $.trim(search);
//    var words = search.split(' ');
//    var lastWord = words[words.length - 1];
//    if (lastWord.length < 3 && words.length != 1) {
//      return;
//    }

    if (search.length > 0 && typeof _cache[search] == 'undefined') {
      _cache[search] = null;
      
      var postParams = new Object();
      postParams['search'] = search;
      for (var key in _params) {
        postParams[key] = _params[key];
      }
//      postParams
//      $.ajax({
//        type: "POST",
//        url: _options.url,
//        data: postParams,
//        success: function(response) {
//          _parseResoponse(search, response);
//        },
//        dataType: 'html'
//      });

      $.post(_options.url, postParams, function(data){_parseResoponse(search, data)}, 'html');

    }
    else {
      _parseResoponse(search, _cache[search]);
    }

  }

  function _parseResoponse(search, response) {
    
    _cache[search] = response;
    if (!response || response.length < 3) {
      _closeQuickSearch();
      return;
    }
    _results.innerHTML = response;
    _showQuickSearch();
    _registerPopupEvents();
    
  }

  function _showQuickSearch(force) {
    if (force === true || _enabled === true)
      $(_popup).show();
  }

  function _closeQuickSearch() {
    $(_popup).find('.selected').each(function(key, el) {
      $(el).removeClass('selected');
    });
    $(_popup).hide();

  }

  // selects and deselects the results in the popup dropdown list
  function _hoverResult(dir) {

    var selItem = $(_popup).find('.selected')[0];
    var items = $(_popup).find('.item');

    if (dir == 'down') {
      if (items.length > 0) {
        _showQuickSearch(true);
      }
      else {
        return;
      }
    }

    var index = 0;

    for (var i = 0; i < items.length; i++) {
      if (items[i] == selItem) {
        index = i;
        break;
      }
    }

    if (selItem) {
      if (dir == 'up') {
        index--;
        if (index >= 0 && items[index]) {
          $(selItem).removeClass('selected');
          $(items[index]).addClass('selected');
          _pasteResultInInput();
        }
        else if (index == -1) {
          $(selItem).removeClass('selected');
          _closeQuickSearch();

          // paste user input
          if (_options.insertSuggestion == true && _inputTemp && _inputTemp.length > 0) {
            $_input.val(_inputTemp);
            _inputTemp = '';
          }
        }
      }
      else if (dir == 'down') {
        index++;
        if (index < items.length && items[index]) {
          $(selItem).removeClass('selected');
          $(items[index]).addClass('selected');
          _pasteResultInInput();
        }
      }
    }
    else {
      $(items[index]).addClass('selected');
      _pasteResultInInput();
    }
  }

  function _pasteResultInInput() {
    if (_options.insertSuggestion != true) return;
    var $selItem = $(_popup).find('.selected a');
    if ($selItem.length != 1) return;
    // copy users input value
    if (typeof _inputTemp == 'undefined' || _inputTemp.length == 0) {
      _inputTemp = $_input.val();
    }
    _input.value = $selItem.html();
  }

  function _resultMouseOver(evt) {
    _mouse_is_over = true;
    var el = evt.currentTarget;
    $(_popup).find('.selected').removeClass('selected');
    $(el).addClass('selected');
  }

  function _popupMouseEnter(evt) {
    _mouse_is_over = true;
  }
  
  function _popupMouseLeave(evt) {
    _mouse_is_over = false;
  }

  // clicks on the result in the popup dropdown list
  function _clickResult() {
    
    var selItem = $(_popup).find('.selected a')[0];
    if (selItem) {
      document.location.href = selItem.href;
    }
  }

  function _clearQuickSearch(forceClear) {
    $_input.attr('value', '');
    _inputTemp = '';
    // force blur instead of triggering it
    if (typeof _input.onblur == 'function') {
      _input.onblur();
    }
    if (forceClear === true) {
      _cache = null;
      _cache = new Array();
      $(_popup).find('.results').empty();
    }
  }

};


AddressQuickSearch = function(el, options) {
  var _keys = {
    escape : 27,
    left : 37,
    up : 38,
    right : 39,
    down : 40,
    enter: 13
  }

  var _this;
  var $_this;
  var _popup;
  var _input;
  var _options;
  var _streets_cache = new Array();

  AddressQuickSearch.prototype = {
    streetName: "",
    streetId: "",

    searchAddress: function (address) {
      var search = _input.value;
      var postParams = new Object();
      if (typeof address != 'undefied' && address) {
        postParams['search'] = address;
        postParams['type'] = 'multiple_search';
      }
      else {
        postParams['search'] = search;
        postParams['type'] = 'pois';
        postParams['street_id'] = _this.streetId;
        postParams['street_name'] = _this.streetName;
      }
      _input.blur();
      _this.disable();
      
//      postParams
      $.post(_options.url, postParams,
        function(response) {
          $_this.trigger('onAddressSearch', response);
          _this.close();
        }, "html");
    },
    CLASSNAME:'AddressQuickSearch'
  }

  return _create(el, options);

  function _create(el, options) {
    _options = options;
    _this = new QuickSearch(el, options);
    $_this = $(_this);
    $.extend(_this, AddressQuickSearch.prototype);
    _popup = $_this.find('.popup')[0];
    _input = $_this.find('input')[0];

    _this.setParams({type:'streets'});
    _registerEvents();
    return _this;
  }


  function _toggleQuicksearchInput(ev)
  {
    if (!ev)
      return;
    var $el = $('#input-search-streets');
    var val = $el.val();
    var default_value = $el.attr('default_value');
    switch (ev.type)
    {
      case 'focus':
        if (val == default_value) {
          $el.val('');
          $el.removeClass("disabled");
        }
        else if (val == "" || val == null){
          $el.addClass("disabled");
        }
        break;
      case 'blur':
        if (val == '' || val == null) {
          $el.val(default_value);
          $el.addClass("disabled");
        }
        else {
          $el.removeClass("disabled");
        }
        break;
    }
  }

  function _registerEvents() {
    $_this.unbind('onSelectedResult').bind('onSelectedResult', _clickResult);
    $(_input).bind('keyup', _onKeyUp);
    $_this.unbind('onSubmit').bind('onSubmit', function(){_this.searchAddress(null)});

    $('#input-search-streets').bind('blur', _toggleQuicksearchInput);
    $('#input-search-streets').bind('focus', _toggleQuicksearchInput);
    
  }

  function _onKeyUp(evt) {

    var value = _input.value;
    if (value == "") {
      _this.streetId = "";
      _this.streetName = "";
      _this.enable();
      return;
    }

    for(var i in _streets_cache) {
      var streetName = _streets_cache[i];

      if (value.lastIndexOf(streetName) != -1) {
        _this.streetId = i;
        _this.streetName = streetName;
        _this.disable();
        return;
      }
    }

    _this.streetId = "";
    _this.streetName = "";
    _this.enable();
  }

  function _clickResult() {
    
    var selItem = $(_popup).find('.selected')[0];
    if (!selItem) {
      $_this.trigger("onSubmit");
      return;
    }
    var streetId = $(selItem).attr('street_id');
    var streetName = $(selItem).attr('street_name');
    if( typeof _streets_cache[streetId] == 'undefined') {
      _streets_cache[streetId] = streetName;
      _this.streetId = streetId;
      _this.streetName = streetName;
    }
    
    $('#input-search-streets').val(streetName + ' ');
    $('#input-search-streets').removeClass('disabled')
    _this.disable();
    _this.close();
  }

}
