
/**
 * Ajax.Request.abort
 * extend the prototype.js Ajax.Request object so that it supports an abort method
 */
Ajax.Request.prototype.abort = function() {
    // prevent and state change callbacks from being issued
    this.transport.onreadystatechange = Prototype.emptyFunction;
    // abort the XHR
    this.transport.abort();
    // update the request counter
    Ajax.activeRequestCount--;
};

Ajax.FixedAutocompleter = Class.create();
var requestObj = null;

Object.extend(Object.extend(Ajax.FixedAutocompleter.prototype, Autocompleter.Base.prototype), {

initialize: function(element, update, url, options) {
	
	options.onShow = function(element, update){
        Effect.Appear(update,{duration:0.15});
    };
    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;
    this.options.onShow       = this.options.onShow ||
      function(element, update){
        Effect.Appear(update,{duration:0.15});
      };
  },

  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;

    requestObj = new Ajax.Request(this.url, this.options);
  },

  onComplete: function(request) {
    this.updateChoices(request.responseText);
  },
		
	// Page jump fix
	markPrevious: function() {
 		if(this.index > 0) {this.index--;}
 		else {
		  this.index = this.entryCount-1;
		  this.update.scrollTop = this.update.scrollHeight;
 		}
		selection = this.getEntry(this.index);
		selection_top = selection.offsetTop;
		if(selection_top < this.update.scrollTop){
			this.update.scrollTop = this.update.scrollTop-selection.offsetHeight;
		}
	},
 
	markNext: function() {
		if(this.index < this.entryCount-1) {this.index++;}
		else {
			this.index = 0;
			this.update.scrollTop = 0;
		}
		selection = this.getEntry(this.index);
		selection_bottom = selection.offsetTop+selection.offsetHeight;
		if(selection_bottom > this.update.scrollTop+this.update.offsetHeight){
			this.update.scrollTop = this.update.scrollTop+selection.offsetHeight;
	 	}
	},
	
	abort: function() {
		
		if( requestObj && !requestObj._complete ){
			requestObj.abort();
		}
	},
	
	onKeyPress: function(event) {
    if(this.active)
      switch(event.keyCode) {
       case Event.KEY_TAB:
       case Event.KEY_RETURN:
         if (this.index > -1) {
         	this.selectEntry();
       	} else {
       		this.hide();
       	}
         return;
       case Event.KEY_ESC:
         this.hide();
         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.keyCode==Event.KEY_RETURN ||
         (Prototype.Browser.WebKit > 0 && event.keyCode == 0)) return;

    this.changed = true;
    this.hasFocus = true;

    if(this.observer) clearTimeout(this.observer);
      this.observer =
        setTimeout(this.onObserverEvent.bind(this), this.options.frequency*1000);
  },
  
  updateChoices: function(choices) {
  	
    if(!this.changed && this.hasFocus) {
      this.update.innerHTML = choices;
      Element.cleanWhitespace(this.update);
      Element.cleanWhitespace(this.update.down());

      if(this.update.firstChild && this.update.down().childNodes) {
        this.entryCount =
          this.update.down().childNodes.length;
        for (var i = 0; i < this.entryCount; i++) {
          var entry = this.getEntry(i);
          entry.autocompleteIndex = i;
          this.addObservers(entry);
        }
      } else {
        this.entryCount = 0;
      }

      this.stopIndicator();
      this.index = -1;

      if(this.entryCount==1 && this.options.autoSelect) {
        this.selectEntry();
        this.hide();
      } else {
        this.render();
      }
    }
  }
});