/*
         Copyright(c) 2007 - Frost Innovation AS
         All rights reserved
 */



/* --------------------------------------------------------------------------------------------------------
   Helper class to wrap the AutoCompleter and add up a little bit of "custom action" to it
   -------------------------------------------------------------------------------------------------------- */
Ajax.GaiaAutocompleter = Class.create();
Object.extend(Object.extend(Ajax.GaiaAutocompleter.prototype, Autocompleter.Base.prototype), {
  initialize: function(element, update, options, parentWebControl) {
    this.baseInitialize(element, update, options);
    this.options.asynchronous  = true;
    this.parentWebControl      = parentWebControl;
    this.options.afterUpdateElement = this._onAfterUpdateElement.bind(this);

    this.options.onHide = function(element, update){
      Element.setOpacity(update.id, 0);
      Element.hide(update);
      $A(this.update.childNodes).each(function(el){
        el.parentNode.removeChild(el);
      });
      delete this.actualContentCell;
    }.bind(this);

    this.options.onShow = function(element, update){

      // First the "top" table
      var tblSkin = document.createElement('table');
      Element.addClassName(tblSkin, this.options.className + '_table_window');
      var tblBdy = document.createElement('tbody');
      tblSkin.appendChild(tblBdy);
      var tblRow = document.createElement('tr');
      tblBdy.appendChild(tblRow);
      var cell = document.createElement('td');
      cell.innerHTML = '&nbsp;';
      Element.addClassName(cell, this.options.className + '_nw');
      tblRow.appendChild(cell);
      cell = document.createElement('td');
      cell.innerHTML = '&nbsp;';
      Element.addClassName(cell, this.options.className + '_n');
      tblRow.appendChild(cell);
      cell = document.createElement('td');
      cell.innerHTML = '&nbsp;';
      Element.addClassName(cell, this.options.className + '_ne');
      tblRow.appendChild(cell);
      this.update.appendChild(tblSkin);

      // Then the "mid" table
      tblSkin = document.createElement('table');
      Element.addClassName(tblSkin, this.options.className + '_table_window');
      tblBdy = document.createElement('tbody');
      tblSkin.appendChild(tblBdy);
      tblRow = document.createElement('tr');
      tblBdy.appendChild(tblRow);
      cell = document.createElement('td');
      cell.innerHTML = '&nbsp;';
      Element.addClassName(cell, this.options.className + '_w');
      tblRow.appendChild(cell);
      cell = document.createElement('td');
      Element.addClassName(cell, this.options.className + '_content');
      tblRow.appendChild(cell);
      this.actualContentCell = cell;
      cell = document.createElement('td');
      cell.innerHTML = '&nbsp;';
      Element.addClassName(cell, this.options.className + '_e');
      tblRow.appendChild(cell);
      this.update.appendChild(tblSkin);

      // Then the "bottom" table
      tblSkin = document.createElement('table');
      Element.addClassName(tblSkin, this.options.className + '_table_window');
      tblBdy = document.createElement('tbody');
      tblSkin.appendChild(tblBdy);
      tblRow = document.createElement('tr');
      tblBdy.appendChild(tblRow);
      cell = document.createElement('td');
      cell.innerHTML = '&nbsp;';
      Element.addClassName(cell, this.options.className + '_sw');
      tblRow.appendChild(cell);
      cell = document.createElement('td');
      cell.innerHTML = '&nbsp;';
      Element.addClassName(cell, this.options.className + '_s');
      tblRow.appendChild(cell);
      cell = document.createElement('td');
      cell.innerHTML = '&nbsp;';
      Element.addClassName(cell, this.options.className + '_se');
      tblRow.appendChild(cell);
      this.update.appendChild(tblSkin);

      if(!update.style.position || update.style.position=='absolute') {
        update.style.position = 'absolute';
        Position.clone(element, update, {
          setHeight: false, 
          offsetTop: element.offsetHeight,
          setWidth: false // THOMAS PATCH to let user decide width of element himself...!!
        });
      }
      Element.setOpacity(update.id, 1.0);
      Element.show(update);
    }.bind(this);
  },

  getUpdatedChoices: function() {
    this.parentWebControl._getChoices(this.onFinishedFetching.bind(this));
  },

  onFinishedFetching: function(result) {
    this.updateChoices(result);
  },

  updateChoices: function(choices) {
    if(!this.changed && this.hasFocus) {
      if( !this.actualContentCell ){
        this.options.onShow(this.element, this.update);
      }
      this.actualContentCell.innerHTML = choices;
      Element.cleanWhitespace(this.actualContentCell);
      Element.cleanWhitespace(this.actualContentCell.down());

      if(this.actualContentCell.firstChild && this.actualContentCell.down().childNodes) {
        this.entryCount = 
          this.actualContentCell.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 = 0;
      
      if(this.entryCount==1 && this.options.autoSelect) {
        this.selectEntry();
        this.hide();
      } else {
        this.render();
      }
    }
  },

  getEntry: function(index) {
    return this.actualContentCell.firstChild.childNodes[index];
  },

  _onAfterUpdateElement: function(a,b){
    this.parentWebControl._selectionChanged(b.id);
  }
});







/* ---------------------------------------------------------------------------
   Class basically wrapping the ASP.TextBox WebControl class
   --------------------------------------------------------------------------- */
WebControl.AutoCompleter = function(element, options){
  this.initializeAutoCompleter(element, options);
}

WebControl.AutoCompleter.prototype = Object.extend(new WebControl.TextBox(),{

  // "Constructor"
  initializeAutoCompleter: function(element, options){
    // Calling base class constructor
    this.initialize(element, options);
    
    if( this.options.dropDownButton ) {
      this.options.dropDownButton = $(this.options.dropDownButton);
      Element.observe(this.options.dropDownButton, 'click', this.onShowAll.bind(this));
    }

    // Creating our ScriptAculous AutoCompleter object...!
    this.autoCompleter = new Ajax.GaiaAutocompleter(this.element.id, this.options.renderingDiv, {
      frequency: this.options.frequency,
      minChars:this.options.minimumPrefixLength,
      className:this.options.className
    }, this);
  },

  onShowAll: function(){
    this.element.focus();
    this.autoCompleter.hasFocus = true;
    this.autoCompleter.getUpdatedChoices();
  },

  _getChoices: function(afterCallback){
    Control.callControlMethod.bind(this)('GetAutoCompleteList', [this.autoCompleter.getToken()], function(retVal){
      afterCallback(retVal);
    }.bind(this));
  },

  _selectionChanged: function(id){
    Control.callControlMethod.bind(this)('SelectionChangedMethod', [id], null);
  },

  _getElementPostValue: function(){
    return '&' + this.getCallbackName() + '=' + $F(this.element.id);
  },

  _getElementPostValueEvent: function(){
    return '&' + this.getCallbackName() + '=' + $F(this.element.id) + '&__EVENTTARGET=' + this.getCallbackName();
  }
});

