/**
* @author Administrator
* REQUIRED script.aculo.us scriptaculous.js v1.8.1
*/

if(typeof Effect == 'undefined')
  throw("sakenavi.js requires including script.aculo.us' controls.js library");

Ajax.Autocompleter = Class.create( Ajax.Autocompleter, {
  initialize: function ( $super, element, update, url, options ) {
    $super( element, update, url, options );
    this.canSuggest  = true;
    this.operaReturn = false;
    this.txtObserver = null;
    
    // CSSクラスを上書き
    this.update.className = "auto_complete";

    if ( Prototype.Browser.Opera > 0 ) {
      Event.observe( this.element.form,'submit', this.onSubmit.bindAsEventListener( this ));
    }
    
    if ( Prototype.Browser.IE > 0 ) {
      Event.observe( this.element.form,'keyup', this.onKeyup.bindAsEventListener( this ));
    }

    Event.observe( this.element,'focus', this.onFocus.bindAsEventListener( this ));
  },
  
  disableReturnSubmit: function() {
    this.operaReturn = true;
  },

  enableReturnSubmit: function() {
    this.operaReturn = false;
  },

  onSubmit: function(event) {
    if(this.operaReturn) {
      Event.stop(event);
      this.enableReturnSubmit();
    }
  },

  onFocus: function(event) {
    this.txtObserver = 
    setTimeout(this.checkTextChanged.bind(this), 100);
  },

  checkTextChanged: function () {
    if(this.element.value != this.oldElementValue){
      this.executeSuggest();
    }

    if(this.txtObserver) clearTimeout(this.txtObserver);

    this.txtObserver = setTimeout(this.checkTextChanged.bind(this), 500);
  },

  onKeyup: function(event) {
    if (this.active && (event.keyCode==Event.KEY_ESC)) {
      this.hide();
      this.active = false;
      Event.stop(event);
    }
  },
  
  onKeyPress: function(event) {
    try{
      this.canSuggest = true;
      if (this.active) {
        switch (event.keyCode) {
          case Event.KEY_TAB:
          case Event.KEY_RETURN:
            if (Prototype.Browser.Opera > 0 && this.index >= 0) {
              this.disableReturnSubmit();
              setTimeout(this.enableReturnSubmit.bind(this), 1);
            }
            this.selectEntry();
            this.moveToEndCursor();
            Event.stop(event);
          case Event.KEY_ESC:
            this.hide();
            this.active = false;
            Event.stop(event);
            if (Prototype.Browser.Opera > 0) {
              this.element.focus();
            }
            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;
      }
    }
    catch(e){/* エラーは無視する */}
  },

  executeSuggest: function() {
    if(!this.canSuggest) return;
    this.changed = true;
    this.hasFocus = true;

    if(this.observer) clearTimeout(this.observer);
    this.observer = setTimeout(this.onObserverEvent.bind(this), this.options.frequency*1000);
  },
      
  onClick: function($super, event) {
    $super(event);
    this.moveToEndCursor();
  },
  
  moveToEndCursor: function() {
    try {
      if (Prototype.Browser.IE > 0) {
        var range = this.element.createTextRange();
        range.move('character', this.element.value.length);
        range.select();
      }
      else if (Prototype.Browser.Opera > 0) {
        this.element.selectionStart = this.element.textLength;
        this.element.selectionEnd = this.element.textLength;
      }
    }
    catch (e) {/*エラーは無視*/}
  },

  onBlur: function($super, event) {
    if(this.txtObserver)
      clearTimeout(this.txtObserver);
	  $super(event);
  }, 

  markPrevious: function() {
    if(this.index >= 0) 
      this.index--
    else
      this.index = this.entryCount-1;

    if( this.index >= 0 )
      this.getEntry(this.index);
  },

  markNext: function() {
    if(this.index < this.entryCount-1) {
      this.index++
      this.getEntry(this.index);
    }
    else 
      this.index = -1;
  },

  selectEntry: function($super) {
    this.canSuggest = false;
    $super();
  },

  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();
      }
    }
  },

  getToken: function() {
    var bounds = this.getTokenBounds();
    return this.element.value.substring(bounds[0], bounds[1]).gsub(/(　| |\t|\n|\r|\0|\x0B)+/, ' ');
  },
  
  onComplete: function($super, request) {
    request.responseText = decodeURIComponent(request.responseText);
    $super(request);
  }
});