Element.Events.outerClick = {
  base : 'click',  // attach click event to element
  condition : function(event) {
    event.stopPropagation();  // stop event from bubbling up
    return false;  // never run handler when clicking on element
  },
  onAdd : function(fn) {
    this.getDocument().addEvent('click', fn);
  },
  onRemove : function(fn) {
    this.getDocument().removeEvent('click', fn);
  }
};

var autocomplete = new Class({

  Implements: [Options],

  options: {
    requestTriggerCount: 1,
    requestUrl: null,
    requestVar: null,
    boxId: 'autocomplete',
    boxOffset: { x: 0, y: 0 }
  },

  inputField: null,
  box: null,

  initialize: function(input, options)
  {
    // Optionen setzen
    this.setOptions(options);

    // Properties füllen
    this.input = document.id(input);
    this.input.setProperty('autocomplete', 'off');

    // Box erstellen
    this.box = new Element('div', { id: this.options.boxId });
    this.box.inject(document.body);
    this.hideBox();

    // Events hinzufügen
    this.input.addEvent('keyup', this.requestCompletions.bind(this));
    this.box.addEvent('outerClick', this.outerClickHandler.bind(this));
  },

  outerClickHandler: function(e)
  {
    if(e.target != this.input)
    {
      this.hideBox();
    }
  },

  requestCompletions: function(e)
  {
    if(e.key == 'esc')
    {
      this.hideBox();
      return;
    }

    if(this.input.get('value').length > this.options.requestTriggerCount)
    {
      // Request losschicken
      new Request.HTML({
        'url':       this.options.requestUrl,
        'data':      this.options.requestVar + '=' + this.input.get('value'),
        'onSuccess': this.handleCompletions.bind(this),
        'update':    this.options.boxId
      }).post();
    }
    else
    {
      this.hideBox();
    }
  },

  handleCompletions: function(response)
  {
    if(response.length == 0)
    {
      this.hideBox();
    }
    else
    {
      this.showBox();
    }
  },

  hideBox: function()
  {
    // Position ermitteln und auf die Box anwenden (+ offset werte)
    var position = this.input.getPosition();
    position.y += this.input.getHeight() + this.options.boxOffset.y;
    position.x += this.options.boxOffset.x;
    this.box.setPosition(position);

    // Box ausblenden
    this.box.setStyle('display', 'none');
  },

  showBox: function()
  {
    // Box einblenden
    this.box.setStyle('display', 'block');
  }

});
