/**
  * The Ajax.CustomAutocompleter class extends the 
  * Scriptaculous Ajax.Autocompleter control so 
  * that the server response can be of any kind. You 
  * need to pass a handler function among the options (responseHandler)
  * responsible to parse the server response and return the HTML <ul>
  * expected by the usual Ajax.Autocompleter. If no function is passed then the
  * server must respond with a <ul> like Ajax.Autocompleter expects.
  *
  * See: http://github.com/madrobby/scriptaculous/wikis/ajax-autocompleter
  */
Ajax.CustomAutocompleter = Class.create(Ajax.Autocompleter, {
  initialize: function(element, update, url, options) {
    this.baseInitialize(element, update, options);
    this.options.minChars      = 3;
    this.options.frequency     = 0.2;
    this.options.asynchronous  = true;
    this.options.onComplete    = this.onComplete.bind(this);
    this.options.defaultParams = this.options.parameters || null;
    this.url                   = url;

    // Add new option for executing self-defined functions
    // between ajax request and before populating the result autocompletion
    // div element
    this.options.responseHandler = this.options.responseHandler || Prototype.K;

    Event.observe(this.update, "mouseout", this.onMouseOut.bindAsEventListener(this));
  },

  /* begin: make AutoCompletion handle a state of "no entry selected" (this.index is -1) */

  onKeyPress: function ($super, event) {
    if (this.active && this.index == -1) {
      if (event.keyCode == Event.KEY_TAB || event.keyCode == Event.KEY_RETURN) {
        this.hide();
        this.active = false;
        return;
      }
    }
    $super(event);
  },

  updateChoices: function ($super, choices) {
    $super(choices);
    this.index = -1;
    this.render();
  },

  markPrevious: function () {
    if (this.index >= 0) {
      this.index--;
    } else {
      this.index = this.entryCount - 1;
    }
    this.getEntry(this.index < 0 ? 0 : this.index).scrollIntoView(true);
  },

  markNext: function () {
    if (++this.index >= this.entryCount) {
      this.index = -1;
    }
    this.getEntry(this.index < 0 ? 0 : this.index).scrollIntoView(false);
  },

  getEntry: function ($super, index) {
    return index < 0 ? null : $super(index);
  },

  updateElement: function ($super, selectedElement) {
    if (selectedElement) {
      $super(selectedElement);
    }
  },

  onMouseOut: function (event) {
    this.index = -1;
    this.render();
  },

  /* end: make AutoCompletion handle a state of "no entry selected" (this.index is -1) */

  onComplete: function(request) {
  	var htmlUL = this.options.responseHandler(request.responseText, this.element);
	if(htmlUL) {
		this.updateChoices(htmlUL);
	}
  }
});


/**
 * JSON Handler for processing responses from the
 * Ajax.CustomAutocompleter class. It converts a JSON respons
 * to the needed '<ul><li>..</li></ul>' format.
 * You can set your custom handler with the 
 * Ajax.CustomAutocompleter attribute
 * 'responseHandler'.
 */
function jsonResponseHandler(respText, elem) {
	var items = eval(respText);
	var ret = "<ul>";
	for(var i = 0; i < items.length; ++i) {
		ret += "<li>" + items[i] + "</li>";
	}
	ret += "</ul>";
	return ret;
}

/*
 * Implements the 'callback' function for the
 * Ajax.CustomAutocompleter class attribute.
 * It adds dynamically other required get parameters
 * for the get request.
 */
function getRequiredParams(element, defaultparams) {

	// Check from which Autocompleter input field this functions is
	// called
	if(element.id == "street") {
		return defaultparams + "&houseNumber=" + $('houseNumber').value + "&zip=" +$('zip').value + "&city=" + $('city').value;
	}
	
	if(element.id == "houseNumber") {
		return defaultparams + "&street=" + $('street').value + "&zip=" +$('zip').value + "&city=" + $('city').value;
	}
	
	if(element.id == "zip") {
		return defaultparams + "&street=" + $('street').value + "&houseNumber=" +$('houseNumber').value + "&city=" + $('city').value;
	}
	
	if(element.id == "city") {
		return defaultparams + "&street=" + $('street').value + "&houseNumber=" +$('houseNumber').value + "&zip=" + $('zip').value;
	}
}

/**
 * Builds the Autocompleter input fields for address fields:
 * - street
 * - houseNumber
 * - zip
 * - city
 *
 * Request for getting autocompletions choices looks like
 * that:
 * http://localhost:8000/base2/completion?function=FUNC&street=xx&houseNumber=xx&zip=xx&city=xx
 * 
 * FUNC can be: getStreets, getHouseNumbers, getZips, getCities
 *
 */
function buildAutocompleter(event, wsUrl) {
	
	// street
	new Ajax.CustomAutocompleter(
		'street',
		'streetAutoCompleteDiv',
		wsUrl,
		{
			responseHandler: jsonResponseHandler,
			method: 'get',
			minChars: 1,
			frequency: 0.4,
			paramName: 'street',
			parameters: 'function=getStreets',
			callback: getRequiredParams
		}
	);
	
	// houseNumber
	new Ajax.CustomAutocompleter(
		'houseNumber',
		'houseNumberAutoCompleteDiv',
		wsUrl,
		{
			responseHandler: jsonResponseHandler,
			method: 'get',
			minChars: 1,
			frequency: 0.6,
			paramName: 'houseNumber',
			parameters: 'function=getHouseNumbers',
			callback: getRequiredParams
		}
	);

	// zip
	new Ajax.CustomAutocompleter(
		'zip',
		'zipAutoCompleteDiv',
		wsUrl,
		{
			responseHandler: jsonResponseHandler,
			method: 'get',
			minChars: 1,
			frequency: 0.5,
			paramName: 'zip',
			parameters: 'function=getZips',
			callback: getRequiredParams
		}
	);

	// city
	new Ajax.CustomAutocompleter(
		'city',
		'cityAutoCompleteDiv',
		wsUrl,
		{
			responseHandler: jsonResponseHandler,
			method: 'get',
			minChars: 1,
			frequency: 0.5,
			paramName: 'city',
			parameters: 'function=getCities',
			callback: getRequiredParams
		}
	);
}