/**
 * Revision by Stefano Curtoni
 * add onChange function
 *
 * Autocompleter
 *
 * @version		1.0rc4
 *
 * @license		MIT-style license
 * @author		Harald Kirschner <mail [at] digitarald.de>
 * @copyright	Author
 */
var Autocompleter = {};

Autocompleter.Base = new Class({

  options: {
    minLength: 1,
    useSelection: true,
    markQuery: true,
    inheritWidth: true,
    maxChoices: 10,
    injectChoice: null,
    onSelect: Class.empty,
    onShow: Class.empty,
    onHide: Class.empty,
    onChange:Class.empty,
    customTarget: null,
    className: 'autocompleter-choices',
    zIndex: 42,
    observerOptions: {},
    fxOptions: {},
    overflown: []
  },

  initialize: function(el, options) {
    this.setOptions(options);
    this.element = $(el);

  var idProdotto = $('codArt').getValue();

if (idProdotto != "") {
      $E('#selectSerie').addClass("disabled").disabled = true;
      $E('#selectTileSize').addClass("disabled").disabled = true;
      $E('#selectIntendedUse').addClass("disabled").disabled = true;
      $E('#selectTechnology').addClass("disabled").disabled = true;
  }else{
      $E('#selectSerie').removeClass("disabled").disabled = false;
      $E('#selectTileSize').removeClass("disabled").disabled = false;
      $E('#selectIntendedUse').removeClass("disabled").disabled = false;
      $E('#selectTechnology').removeClass("disabled").disabled = false;
  }

  $('codArt').addEvent('keyup', function(e){



  var idProdotto = $('codArt').getValue();


  if (idProdotto != "") {
      $E('#selectSerie').addClass("disabled").disabled = true;
      $E('#selectTileSize').addClass("disabled").disabled = true;
      $E('#selectIntendedUse').addClass("disabled").disabled = true;
      $E('#selectTechnology').addClass("disabled").disabled = true;
  }else{
      $E('#selectSerie').removeClass("disabled").disabled = false;
      $E('#selectTileSize').removeClass("disabled").disabled = false;
      $E('#selectIntendedUse').removeClass("disabled").disabled = false;
      $E('#selectTechnology').removeClass("disabled").disabled = false;
  }
  });


    this.build();
    this.observer = new Observer(this.element, this.prefetch.bind(this), $merge({
      delay: 400
    }, this.options.observerOptions));
    this.value = this.observer.value;
    this.queryValue = null;
  },

  /**
   * build - Initialize DOM
   *
   * Builds the html structure for choices and appends the events to the element.
   * Override this function to modify the html generation.
   */
  build: function() {

   if ($(this.options.customTarget)) this.choices = this.options.customTarget;
    else {
      this.choices = new Element('ul', {
        'class': this.options.className,
        styles: {zIndex: this.options.zIndex}
      }).injectInside(document.body);
      this.fix = new OverlayFix(this.choices);
    }
    this.fx = this.choices.effect('opacity', $merge({
      wait: false,
      duration: 200
    }, this.options.fxOptions))
      .addEvent('onStart', function() {
        if (this.fx.now) return;
        this.choices.setStyle('display', '');
        this.fix.show();
      }.bind(this))
      .addEvent('onComplete', function() {
        if (this.fx.now) return;
        this.choices.setStyle('display', 'none');
        this.fix.hide();
      }.bind(this)).set(0);
    this.element.setProperty('autocomplete', 'off')
      .addEvent(window.ie ? 'keydown' : 'keypress', this.onCommand.bindWithEvent(this))
      .addEvent('mousedown', this.onCommand.bindWithEvent(this, [true]))
      .addEvent('focus', this.toggleFocus.bind(this, [true]))
      .addEvent('blur', this.toggleFocus.bind(this, [false]))
      .addEvent('trash', this.destroy.bind(this));
  },

  destroy: function() {
    this.choices.remove();
  },

  toggleFocus: function(state) {
    this.focussed = state;
    if (!state) this.hideChoices();
  },

  onCommand: function(e, mouse) {
    if (mouse && this.focussed) this.prefetch();
    if (e.key && !e.shift) switch (e.key) {
      case 'enter':
        if (this.selected && this.visible) {
          this.choiceSelect(this.selected);
          e.stop();
        }
    return;
      case 'up': case 'down':
        if (this.observer.value != (this.value || this.queryValue)) this.prefetch();
        else if (this.queryValue === null) break;
        else if (!this.visible) this.showChoices();
        else {
          this.choiceOver((e.key == 'up')
            ? this.selected.getPrevious() || this.choices.getLast()
            : this.selected.getNext() || this.choices.getFirst() );
          this.setSelection();
        }
        e.stop(); return;
      case 'esc': this.hideChoices(); return;
    }

    this.value = false;
  },

  setSelection: function() {
    if (!this.options.useSelection) return;
    var startLength = this.queryValue.length;
    if (this.element.value.indexOf(this.queryValue) != 0) return;
    var insert = this.selected.inputValue.substr(startLength);
    if (document.getSelection) {
      this.element.value = this.queryValue + insert;
      this.element.selectionStart = startLength;
      this.element.selectionEnd = this.element.value.length;
    } else if (document.selection) {
      var sel = document.selection.createRange();
      sel.text = insert;
      sel.move("character", - insert.length);
      sel.findText(insert);
      sel.select();
    }
    this.value = this.observer.value = this.element.value;
  },

  hideChoices: function() {
    if (!this.visible) return;
    this.visible = this.value = false;
    this.observer.clear();
    this.fx.start(0);
    this.fireEvent('onHide', [this.element, this.choices]);
  },

  showChoices: function() {
    if (this.visible || !this.choices.getFirst()) return;
    this.visible = true;
    var pos = this.element.getCoordinates(this.options.overflown);
    this.choices.setStyles({
      left: pos.left,
      top: pos.bottom
    });
    if (this.options.inheritWidth) this.choices.setStyle('width', pos.width);
    this.fx.start(1);
    this.choiceOver(this.choices.getFirst());
    this.fireEvent('onShow', [this.element, this.choices]);
  },

  prefetch: function() {
    if (this.element.value.length < this.options.minLength) this.hideChoices();
    else if (this.element.value == this.queryValue) this.showChoices();
    else this.query();
  },

  updateChoices: function(choices) {
    this.choices.empty();
    this.selected = null;
    if (!choices || !choices.length) return;
    if (this.options.maxChoices < choices.length) choices.length = this.options.maxChoices;
    choices.each(this.options.injectChoice || function(choice, i){
      var el = new Element('li').setHTML(this.markQueryValue(choice));
      el.inputValue = choice;
      this.addChoiceEvents(el).injectInside(this.choices);
    }, this);
    this.showChoices();
  },

  choiceOver: function(el) {
    if (this.selected) this.selected.removeClass('autocompleter-selected');
    this.selected = el.addClass('autocompleter-selected');
  },

  choiceSelect: function(el) {
    this.observer.value = this.element.value = el.inputValue;
    this.hideChoices();
    this.fireEvent('onSelect', [this.element], 20);
  },

  /**
   * markQueryValue
   *
   * Marks the queried word in the given string with <span class="autocompleter-queried">*</span>
   * Call this i.e. from your custom parseChoices, same for addChoiceEvents
   *
   * @param		{String} Text
   * @return		{String} Text
   */
  markQueryValue: function(txt) {
    return (this.options.markQuery && this.queryValue) ? txt.replace(new RegExp('^(' + this.queryValue.escapeRegExp() + ')', 'i'), '<span class="autocompleter-queried">$1</span>') : txt;
  },

  /**
   * addChoiceEvents
   *
   * Appends the needed event handlers for a choice-entry to the given element.
   *
   * @param		{Element} Choice entry
   * @return		{Element} Choice entry
   */
  addChoiceEvents: function(el) {
    return el.addEvents({
      mouseover: this.choiceOver.bind(this, [el]),
      mousedown: this.choiceSelect.bind(this, [el])
    });
  }
});

Autocompleter.Base.implement(new Events);
Autocompleter.Base.implement(new Options);

Autocompleter.Local = Autocompleter.Base.extend({

  options: {
    minLength: 0,
    filterTokens : null
  },

  initialize: function(el, tokens, options) {
    this.parent(el, options);
    this.tokens = tokens;
    if (this.options.filterTokens) this.filterTokens = this.options.filterTokens.bind(this);
  },

  query: function() {
    this.hideChoices();
    this.queryValue = this.element.value;
    this.updateChoices(this.filterTokens());
  },

  filterTokens: function(token) {
    var regex = new RegExp('^' + this.queryValue.escapeRegExp(), 'i');
    return this.tokens.filter(function(token) {
      return regex.test(token);
    });
  }

});

Autocompleter.Ajax = {};

Autocompleter.Ajax.Base = Autocompleter.Base.extend({

  options: {
    postVar: 'value',
    postData: {},
    ajaxOptions: {},
    onRequest: Class.empty,
    onComplete: Class.empty
  },

  initialize: function(el, url, options) {
    this.parent(el, options);
    this.ajax = new Ajax(url, $merge({
      autoCancel: true
    }, this.options.ajaxOptions));
    this.ajax.addEvent('onComplete', this.queryResponse.bind(this));
    this.ajax.addEvent('onFailure', this.queryResponse.bind(this, [false]));
  },

  query: function(){
    var data = $extend({}, this.options.postData);
    data[this.options.postVar] = this.element.value;
    this.fireEvent('onRequest', [this.element, this.ajax]);
    this.ajax.request(data);
  },

  /**
   * queryResponse - abstract
   *
   * Inherated classes have to extend this function and use this.parent(resp)
   *
   * @param		{String} Response
   */
  queryResponse: function(resp) {
    this.value = this.queryValue = this.element.value;
    this.selected = false;
    this.hideChoices();
    this.fireEvent(resp ? 'onComplete' : 'onFailure', [this.element, this.ajax], 20);
  }

});

Autocompleter.Ajax.Json = Autocompleter.Ajax.Base.extend({

  queryResponse: function(resp) {
    this.parent(resp);
    var choices = Json.evaluate(resp || false);
    if (!choices || !choices.length) return;
    this.updateChoices(choices);
  }

});

Autocompleter.Ajax.Xhtml = Autocompleter.Ajax.Base.extend({

  options: {
    parseChoices: null
  },

  queryResponse: function(resp) {
    this.parent(resp);
    if (!resp) return;
    this.choices.setHTML(resp).getChildren().each(this.options.parseChoices || this.parseChoices, this);
    this.showChoices();
  },

  parseChoices: function(el) {
    var value = el.innerHTML;
    el.inputValue = value;
    el.setHTML(this.markQueryValue(value));
  }

});


var OverlayFix = new Class({

  initialize: function(el) {
    this.element = $(el);
    if (window.ie){
      this.element.addEvent('trash', this.destroy.bind(this));
      this.fix = new Element('iframe', {
        properties: {
          frameborder: '0',
          scrolling: 'no',
          src: 'javascript:false;'
        },
        styles: {
          position: 'absolute',
          border: 'none',
          display: 'none',
          filter: 'progid:DXImageTransform.Microsoft.Alpha(opacity=0)'
        }
      }).injectAfter(this.element);
    }
  },

  show: function() {
    if (this.fix) this.fix.setStyles($extend(
      this.element.getCoordinates(), {
        display: '',
        zIndex: (this.element.getStyle('zIndex') || 1) - 1
      }));
    return this;
  },

  hide: function() {
    if (this.fix) this.fix.setStyle('display', 'none');
    return this;
  },

  destroy: function() {
    this.fix.remove();
  }

});