/*  suggest ahead by braudel -a-t- ferrarihaines - dot - com 2008 
    
    usage: just add class="suggest_ahead" to the input needed to
    enable and write appropiate backend code to handle the query and reply
    using json
*/

var suggest = function(spec){
    var a, url, input_id, AJAXres, textbox, search_length;
    
    var sg = {
      init          : function(){
                      this.url        = spec.url;
                      this.input_id    = spec.input_id;
                      this.textbox  = $e(spec.input_id);
                      this.a = new net.CLoader(this.url, 
                                           this.a_response,
                                           null,
                                           null,
                                           null);
      },
      search        : function() {
                      if ( $e(this.input_id).value.length > 2 
                            && (!this.a.readyState 
                                || this.a.readyState == 4 
                                || this.a.readyState == 0)) {

                        this.search_length    = this.textbox.value.length;
                        this.a.loadXMLDoc( this.input_id+'=' + encodeURIComponent( this.last_word() ) );
                      }
      },
      a_response    : function(){
                      if(this.req.responseText != null){
                          AJAXres = JSON.parse(this.req.responseText);
                          if (AJAXres.id && AJAXres.suggestions && AJAXres.suggestions.length){
                            
                            if (inputs[AJAXres.id]){
                                // some init stuff
                                AJAXres.index = 0;
                                inputs[AJAXres.id].AJAXres = AJAXres;
                                inputs[AJAXres.id].refresh();
                            }
                          }
                      }
      },
      select_range : function(start , length ){

            if (this.textbox.createTextRange) {
                var range = this.textbox.createTextRange(); 
                range.moveStart("character", start); 
                range.moveEnd("character", length - this.textbox.value.length);      
                range.select();
                
            } else if (this.textbox.setSelectionRange) {
                this.textbox.setSelectionRange(start, length);
            }     

            this.textbox.focus();      
      },
      refresh        : function(){

                            if (this.textbox.createTextRange || this.textbox.setSelectionRange){
                            
                                //grab last word
                                var vwords    = this.textbox.value.split(/\W+/);
                                        
                                if (vwords[0]){
                                    var lword = vwords.pop();
                                    vwords.push(this.AJAXres.suggestions[this.AJAXres.index]);
                                        
                                    this.textbox.value = vwords.join(' '); 
                                }
                                else {
                                    this.textbox.value = this.AJAXres.suggestions[this.AJAXres.index];    
                                }
                                
                                this.select_range(this.search_length, this.textbox.value.length);
                             }
      },
      last_word        : function(){
                            var vwords    = this.textbox.value.split(/\W+/);
                            return vwords.pop();
      }
    }
    sg.init();
    return sg;
}

/* ev handlers */

var keyup_handler = function(ev) {
                    var myev = ev || window.event;
                    var target = myev.target || myev.srcElement;

                    var key = ev.keyCode ? ev.keyCode : ev.charCode;

                    if (inputs[target.id]){

                      if (key <= 32 
                        || (key >= 33 && key <= 46) 
                        || (key >= 112 && key <= 123)) {

                            if ( inputs[target.id].AJAXres 
                                 && inputs[target.id].AJAXres.suggestions ){

                              if (key === 40  
                                  && inputs[target.id].AJAXres.index < (inputs[target.id].AJAXres.suggestions.length - 1)){
                               
                                  //arrdown show next in array
                                  inputs[target.id].AJAXres.index++;
                                  if ( inputs[target.id].AJAXres.suggestions[ inputs[target.id].AJAXres.index ] ) {
                                      inputs[target.id].refresh();
                                  }
                                  else {
                                      inputs[target.id].AJAXres.index--;
                                  }

                              }
                              else if (key === 38 && inputs[target.id].AJAXres.index > 0){
                                  //arrup show prev in array
                                  inputs[target.id].AJAXres.index--;
                                  if ( inputs[target.id].AJAXres.suggestions[ inputs[target.id].AJAXres.index ] ) {
                                      inputs[target.id].refresh();
                                  }
                                  else {
                                      inputs[target.id].AJAXres.index++;
                                  }

                              }
                            }
                      }
                      else {
                           // just search & show first
                             inputs[target.id].search();
                      }
                        
                    }
}


/* run */
var inputs = new Array();

window.onload=function(){

  var elements = document.getElementsByTagName('input');
  var all = elements.length;

  for (var i = 0; i < all; i++){
      if ( hasClass(elements[i], 'suggest_ahead') ){
          inputs[elements[i].id] 
            = suggest({    url:    'http://www.ferrarihaines.com/cgi-bin/suggest.pl',
                        input_id : elements[i].id
                      });
      }
  }

    /* attach ev handlers */
    addEventL(window.document, 'keyup', keyup_handler);
}

