var gtmFlightsAutocompleter = {};
gtmFlightsAutocompleter.Base = Class.create(Autocompleter.Base, {
  onBlur: function(event) {
    this.hide();

    this.hasFocus = false;
    this.active   = false;

    var direction = this.element.identify().replace('Airport', '');
    var isSpace = $F(this.element).strip() === '';

    if (isSpace) {
      $$('body').first().fire('flightsAutocompleter:update',
                              {
                                   direction: direction,
                                   iata: ''
                              });
        return;
      }
      setTimeout(this._initFastIata.bind(this, event), 0);
  },
  _initFastIata: function(event) {
      if ($(this.element).readAttribute('isfirstupdate') == 'false' && !$(this.update).visible() && $F($(this.element)).length == 3 ) {
          var direction = this.element.identify().replace('Airport', '');
          var postBody = Object.toQueryString({query: $F(this.element)});
          var urlParametrs = new Hash({
              action: 'location',
              method: 'autocompleteFastIata',
              direction: direction,
              clearCache: 'true'
          });
          var url = "./flights/?" + urlParametrs.toQueryString();
          new Ajax.Request(url, {
                           postBody: postBody,
                           onSuccess: this._fastInsertIata.bind(this),
                           onException: function(r, e) {console.log(e);},
                           onFailure: function (e, r) {console.log(e);}});
      } else if ($(this.update).visible() && $F(this.element) != $(this.getCurrentEntry()).innerHTML ) {
          this.selectEntry();
          this.active = false;
      } else if (!$(this.update).visible() && $(this.element).readAttribute('isfirstupdate') == 'false') {
        var direction = this.element.identify().replace('Airport', '');
        $$('body').first().fire('flightsAutocompleter:update',
                                {
                                    direction: direction,
                                    iata: ''
                                });
      }
      this.hide();
  },
  _fastInsertIata: function(transport) {
      if (transport.responseText === 'departure_false' || transport.responseText === 'destination_false') {
        var direction = transport.responseText === 'departure_false' ? 'departure' : 'destination';
        this.element.value = 'Incorrect IATA code';
        $$('body').first().fire('flightsAutocompleter:update',
                                {
                                    direction: direction,
                                    iata: ''
                                });
          return;
      }
      var li = new Element('ul').insert(transport.responseText).firstDescendant();

      this._updateElementFastIata(li);

      setTimeout(this.hide.bind(this), 0);
      this.hasFocus = false;
      this.active = false;
  },
  _updateElementFastIata: function(selectedElement) {
    if (this.options.updateElement) {
      this.options.updateElement(selectedElement);
      return;
    }
    var value = '';
    if (this.options.select) {
      var nodes = $(selectedElement).select('.' + this.options.select) || [];
      if(nodes.length>0) value = Element.collectTextNodes(nodes[0], this.options.select);
    } else
      value = Element.collectTextNodesIgnoreClass(selectedElement, 'informal');

    var bounds = this.getTokenBounds();
    if (bounds[0] != -1) {
      var newValue = this.element.value.substr(0, bounds[0]);
      var whitespace = this.element.value.substr(bounds[0]).match(/^\s+/);
      if (whitespace)
        newValue += whitespace[0];
      this.element.value = newValue + value + this.element.value.substr(bounds[1]);
    } else {
      this.element.value = value;
    }
    this.oldElementValue = this.element.value;

    if (this.options.afterUpdateElement)
      this.options.afterUpdateElement(this.element, selectedElement);
  },
  onObserverEvent: function() {
    this.changed = false;
    this.tokenBounds = null;
    if(this.getToken().length>=this.options.minChars) {
      this.getUpdatedChoices();
    } else {
      this.active = false;
      this.hide();
    }
    this.oldElementValue = this.element.value;
  },
  onKeyPress: function(event) {
    if ($F(this.element).strip() === '') {
        $(this.element).writeAttribute('isfirstupdate', 'false');
        var direction = this.element.identify().replace('Airport', '');
        $$('body').first().fire('flightsAutocompleter:update',
                                {
                                    direction: direction,
                                    iata: ''
                                });
        return;
    }

    if(this.active)
      switch(event.keyCode) {
       case Event.KEY_TAB:
       case Event.KEY_RETURN:
         this.selectEntry();
         Event.stop(event);
         this.hide();
         this.active = false;
         return;
       case Event.KEY_ESC:
         this.onPressEsc(event);
         this.active = false;
         Event.stop(event);
         return;
       case Event.KEY_LEFT:
       case Event.KEY_RIGHT:
         return;
       case Event.KEY_UP:
         this.markPrevious();
         this.render();
         Event.stop(event);
         return;
       case Event.KEY_DOWN:
         this.markNext();
         this.render();
         Event.stop(event);
         return;
      }
     else
       if(event.keyCode==Event.KEY_TAB
         || event.ctrlKey
         || event.altKey
         || event.keyCode==Event.KEY_RETURN
         || event.keyCode==Event.KEY_ESC
         || event.keyCode==Event.KEY_LEFT 
         || event.keyCode==Event.KEY_UP
         || event.keyCode==Event.KEY_RIGHT 
         || event.keyCode==Event.KEY_DOWN
         || event.keyCode==Event.KEY_HOME
         || event.keyCode==Event.KEY_END
         || event.keyCode==Event.KEY_PAGEUP
         || event.keyCode==Event.KEY_PAGEDOWN
         || (Prototype.Browser.WebKit > 0 && event.keyCode == 0)) return;
     this._startRequestAutocomplete();

  },
  _startRequestAutocomplete: function(interval) {
    $(this.element).writeAttribute('isfirstupdate', 'false');

    this.changed = true;
    this.hasFocus = true;
    var interval = interval ? interval : this.options.frequency*1000;
    if(this.observer) clearTimeout(this.observer);
      this.observer =
        setTimeout(this.onObserverEvent.bind(this), interval);
  },
  onPressEsc: function(event) {
      this.selectEntry();
      this.hide();
      this.active = false;
      Event.stop(event);
  },
  onClick: function(event) {
  }
});

Ajax.gtmFlightsAutocompleter = Class.create(gtmFlightsAutocompleter.Base, {
  initialize: function(element, update, url, options) {
    this.baseInitialize(element, update, options);
    this.options.asynchronous  = true;
    this.options.onComplete    = this.onComplete.bind(this);
    this.options.defaultParams = this.options.parameters || null;
    this.url                   = url;
  },
  getUpdatedChoices: function() {
    this.startIndicator();

    var entry = encodeURIComponent(this.options.paramName) + '=' +
      encodeURIComponent(this.getToken());

    this.options.parameters = this.options.callback ?
      this.options.callback(this.element, entry) : entry;

    if(this.options.defaultParams)
      this.options.parameters += '&' + this.options.defaultParams;

    new Ajax.Request(this.url, this.options);
  },

  onComplete: function(request) {
    this.updateChoices(request.responseText);
  },
  markPrevious: function() {
    if(this.index > 0) this.index--;
      else this.index = this.entryCount-1;
    this.getEntry(this.index);
  },

  markNext: function() {
    if(this.index < this.entryCount-1) this.index++;
      else this.index = 0;
    this.getEntry(this.index);
  }
});

var Control_Abstract = {
  _uniqueElement: false,
  _createUniqueElement: function() {
      var uniqueElemen = new Element('div').setStyle({display: 'none'});
      this._uniqueElement = $$('body').reduce().insert(uniqueElemen);
      var uniqueElemenname = uniqueElemen.identify();
  }
};


var Autocomplete_Abstract = Class.create({
	  initialize: function() {
	      document.observe('autocompliterFlights:start', this._init.bind(this));
	  },
	  _init: function(event) {
	      this._initElemeStorage();
	      this._initObserver();
	      this._initAutocompletes();

	      this._createUniqueElement();
	  },
	  _clickAutocomplete: function(event) {
	      Event.element(event).select();
	  }
	}, Control_Abstract);

var Flights_Autocomplete = Class.create(Autocomplete_Abstract, {
  _autocompletes: new Hash({}),
  _elemStorage: {
      departureAutocomplete: false,
      destinationAutocomplete: false
  },
  _autocompleteContainer: {
      container:   false,
      input:       false,
      blockResult: false
  },
  _autocomplete: [],
  _initElemeStorage: function() {
      $$('.flightsAutocompletes').each(function(elem) {
          var type = this.getTypeAutocomplete(elem);
          this._elemStorage[type] = new Object();

          Object.extend(this._elemStorage[type],
                        this._autocompleteContainer);

          this._elemStorage[type].container = elem;
          this._elemStorage[type].input = $(elem).select('input').reduce();
          this._elemStorage[type].input.writeAttribute('isfirstupdate', 'false');
          
          this._elemStorage[type].blockResult = $(elem).select('div')
                                                       .reduce();
      }.bind(this));
  },
  getTypeAutocomplete: function(elem) {
      var nameElem = elem.identify();
      if (nameElem == 'flightsDestinationAutocompleteContainer') {
          return 'destinationAutocomplete';
      } else if (nameElem == 'flightsDepartureAutocompleteContainer') {
          return 'departureAutocomplete';
      } else {
          throw new Error('bad id by autocompletes');
      }
  },
  _initObserver: function() {
      $H(this._elemStorage).each(function(elem){
          elem = elem.value;
          if (elem) {
              var input = elem.input;
              $(input).observe('click', this._clickAutocomplete.bind(this));
          }
      }.bind(this));
      document.observe('flightsStorage:changeClient', this._changeClienEvent.bind(this));
  },
  _changeClienEvent: function(event) {
      var name = this._storage.getClientName();
      this.changeClientNameInUrl(name);
  },
  _initAutocompletes: function() {
      $H(this._elemStorage).each(function(elem){
          var typeContainer = elem.key;
          elem = elem.value;

          if (elem) {
              var input = elem.input;
              var blockResult = elem.blockResult;
              var direction = typeContainer.replace('Autocomplete', '');
              this._createAutocomplete(input, blockResult, direction);
          }
      }.bind(this));
  },
  _updateAutocompleter: function(text, li) {
      text.writeAttribute('isfirstupdate', 'true');
      var direction = text.identify().replace('Airport', '');
      var iata = li.identify();

      if (iata.length != 3 || $(text).readAttribute('isnan') == 'true') {
          iata = '';
      }

      $(this._uniqueElement).fire('flightsAutocompleter:update',
                                  {
                                      direction: direction,
                                      iata: iata
                                  });
  },
  _createAutocomplete: function(input, blockResult, direction) {
      var clientName, params, queryParams, queryParamsKey, isSetDeparture;
      params = $H({action:    'location',
                   method: 'autocomplete',
                   direction: direction,
                   clearCache: 'true'}).toQueryString();
      params = '/flights/?' + params;

      queryParams = location.href.toQueryParams();

      queryParamsKey = Object.keys(queryParams);

      var isDirection = queryParamsKey.indexOf(direction);

      if (isDirection != -1) {
          var url = "/flights/?action=location&method=locationTextByIata";
          var postBody = Object.toQueryString({iata: $H(queryParams).get(direction),
                                               direction: direction});
      } else {
          var urlParametrs = new Hash({
              action: 'location',
              method: 'getIataByIp'
          });
          var url = "/flights/?" + urlParametrs.toQueryString();
          var postBody = Object.toQueryString({direction: direction});
      }
      if (true) {
          var responseHendler = this._setIataInInput.bind(this);
          new Ajax.Request(url, {
                                 postBody: postBody,
                                 onSuccess: responseHendler,
                                 onException: function(r, e) {console.log(e);},
                                 onFailure: function (e, r) {console.log(e);}});
      }
      this._autocompletes.set(direction, new Ajax.gtmFlightsAutocompleter($(input),
                $(blockResult),
                params,
                {
                    paramName: 'query',
                    frequency: 0.4,
                    afterUpdateElement: this._updateAutocompleter
                                            .bind(this)
                })
      );
  },
  _setIataInInput: function(transport) {
      var searchResponse, autocomplete, input, direction, iata;
      searchResponse = transport.responseJSON;

      if (!searchResponse || (searchResponse && searchResponse.text == -1)) {
          return;
      }

      direction = searchResponse.direction;
      iata = searchResponse.iata;

      autocomplete = direction + 'Autocomplete';
      input = this._elemStorage[autocomplete].input;
      input.value = searchResponse.text;

      $(this._uniqueElement).fire('flightsAutocompleter:update',
                                  {
                                      direction: direction,
                                      iata: iata
                                  });
  },

  changeClientNameInUrl: function(name) {
      this._autocompletes.each(function(elem) {
        var hash    = elem.value.url.toQueryParams();
        hash.client = this._storage.getClientName();
        elem.value.url = './?' + $H(hash).toQueryString();
      }.bind(this));

      $H(this._elemStorage).each(function(elem){
          elem = elem.value;
          if (elem) {
              var input = elem.input;
              $(input).value = 'Origin';
          }
      }.bind(this));
  }
});

var flightsAutocomplete = new Flights_Autocomplete();

document.observe('dom:loaded', function() {
    $("tripTypeR").onclick = function() {
        $("return_date").style.visibility = "visible";
        $("bottomCalImage").style.visibility = "visible";
    }

    $("tripTypeO").onclick = function() {
        $("return_date").style.visibility = "hidden";
        $("bottomCalImage").style.visibility = "hidden";
    }

    var button = $("search-btn");
    if (button) {
        button.className = button.className.replace("transparent", "");
        button.onclick = function() {
            setTimeout(function() {
	            if (checkLocationElementValue("departureAirport") && checkLocationElementValue("destinationAirport")) {
	                checkClientRedirect();
	            }
            }, 1500);
        }
        button.setAttribute("title", "Search");
    }

    $$('body').first().fire('autocompliterFlights:start');
});

function checkClientRedirect() {
    var checkRedirect;
    new Ajax.Request("/flights/?action=checkRedirect", {
        postBody: $H({
            destination:    $("destinationAirport").value
        }).toQueryString(),
        onSuccess: function (response) {
            if (response.responseText.replace(/^\s+|\s+$/g,"").length > 0) {
                document.forms['searchfrm'].action = response.responseText;
            } else {
                checkLocationElementValue("departureAirport", true);
                checkLocationElementValue("destinationAirport", true);
            }
            document.forms['searchfrm'].submit();
        }
    });
}

function checkLocationElementValue(location, replace) {
    var element = $(location);
    if (element.nodeName.toLowerCase() == "select") {
        return true;
    }
    var regular = /\[[A-Z]{3}\]/;
    if (regular.test(element.value) && !replace) {
        return true;
    }
    if (replace && element.nodeName.toLowerCase() == "input") {
        var index;
        if ((index = element.value.search(regular)) != -1) {
            element.value = element.value.substr(index + 1, 3);
        }
        return true;
    } else if(replace) {
        return true;
    }
    if (location.replace("Airport", "").capitalize) {
        var text = location.replace("Airport", "").capitalize();
    } else {
        var text = location.replace("Airport", "");
    }
    alert("Please enter " + text);
    return false;
}

function createAutocompleter(location) {
    var uid = location + "Airport";
    if ($(uid).nodeName.toLowerCase() == "select") {
        return;
    }
    $(uid).disabled = false;
    $(uid).value = "";
    if ($(uid).getAttribute("primary")) {
        $(uid).value = $(uid).getAttribute("primary");
    } else {
        $(uid).value = "";
    }

    var autocompleteUrl = "/flights/?action=autocomplete&" + location;
    var uid = location + "Airport";

    var aj = "new Ajax.Autocompleter(location+\"Airport\", location+\"Autocomplete\", autocompleteUrl, {paramName: \"query\", checkIATA: true, afterUpdateElement: function (text, li) {}});";
    eval(location + "Ajax = " + aj);
    Event.observe(location + "Airport", "click", function(e) {
        Event.element(e).select();
    });
}

// overload accomodation form
AccommodationFormPage.prototype.fetchProvinceList = AccommodationFormPage.prototype.fetchProvinceList.wrap(function(func, arg){
    if (this.countries.length == 1) func(arg);
    else {
        var value = $("country-list").options[$("country-list").selectedIndex].value;
	    var defaultValue = $("country-list").getAttribute("default")?$("country-list").getAttribute("default"):this.countries[0].getId();
	    this.fetchCityListByCountry((! parseInt(value))?defaultValue:value);
	}
})