Autocompleter.Json = Class.create(Autocompleter.Base, {
  initialize: function(element, update, lookupFunction, options, onSelectFunction) {
    options = options || {};
    this.baseInitialize(element, update, options);
    this.lookupFunction = lookupFunction;
    this.onSelectFunction = onSelectFunction;
    this.options.choices = options.choices || 10;
    this.options.onShow = function(element, update) {
      if(!update.style.position || update.style.position=='absolute') {
        update.style.position = 'absolute';
        try {
          var widthSet;
          if (update.style.width) {
             widthSet = update.style.width;
          }
          update.clonePosition(element, {setHeight: false, offsetTop: element.offsetHeight});
          if (widthSet) {
            update.style.width = widthSet;
          }
        } catch(e) {
        }
      }
      Effect.Appear(update,{duration: 0.15});
    };
  },

  getUpdatedChoices: function() {
    this.lookupFunction(this.getToken(), this.updateJsonChoices.bind(this));
  },

  updateJsonChoices: function(choices) {
    this.updateChoices('<ul>' + choices.slice(0, this.options.choices).map(this.jsonChoiceToListChoice.bind(this)).join('') + '</ul>');
  },

  jsonChoiceToListChoice: function(choice, mark) {
    return '<li>' + choice.escapeHTML().gsub(new RegExp(this.getToken(), 'i'), '<strong>#{0}</strong>') + '</li>';
  },

  markPrevious: function() {
    if (this.index > 0) {
      this.index--;
    } else {
        this.index = this.entryCount - 1;
    }

    var selection = this.getEntry(this.index);
    var 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;
    }

    var selection = this.getEntry(this.index);
    var selection_bottom = selection.offsetTop + selection.offsetHeight;
    if (selection_bottom > this.update.scrollTop + this.update.offsetHeight) {
      this.update.scrollTop = this.update.scrollTop + selection.offsetHeight;
    }
  },

  selectEntry: function() {
	this.active = false;
	this.updateElement(this.getCurrentEntry());
	if (typeof this.onSelectFunction != 'undefined') {
	  this.onSelectFunction();
	}
  }
});
