// AUTO COMPLETE v0.1c - Ronnie Kilsbo (c) 2006

// ============================================================================

function AutoComplete() {
  // Variable for element properties.
  this.lastchar = new Array();
  this.lastword = new Array();
  this.lastkey = new Array();
  this.currentword = new Array();
  this.suggestwords = new Array();
  this.suggestlist = new Array();
  this.lastsuggestedword = new Array();
  this.shownumrows = new Array();

  // Debug variables

  this.debugvars = new Array();

  // Global variables.
  this.debuglog = "";
  this.typeTimer = {
    last:0,
    //delay:9000
    delay:10
  };
}

// ============================================================================

AutoComplete.prototype.getRequestObject = function () {
  // Create XMLHttpRequest object if not defined (IE...).
  var request = null;

  if ( typeof(XMLHttpRequest) == 'undefined' ) {
    try {
      request = new ActiveXObject('Msxml2.XMLHTTP');
    } catch(e) {
      try {
        request = new ActiveXObject('Microsoft.XMLHTTP');
      } catch(ee) {
      }
    }
    return request;
  } else {
    var request = new XMLHttpRequest();

    if (request.overrideMimeType) {
      request.overrideMimeType('text/xml');
    }
    return request;
  }
}

// ============================================================================

AutoComplete.prototype.keyStroke = function (event, element, wordlist, num) {
  var code = event.which ? event.which : event.keyCode;



  this.shownumrows[element.id] = num;

  this.lastkey[element.id] = code;
  this.lastchar[element.id] = String.fromCharCode(code).toLowerCase();

//  this.lastchar[element.id] = document.getElementById(element.id).value.substring( document.getElementById(element.id).value.length - 1, document.getElementById(element.id).value.length);
  this.debugWrite(element);

  // Check if special key was used.
  switch (code) {
    case 37: // Left arrow.
    break;
    case 38: // Up arrow.
    break;
    case 39: // Right arrow.
      this.finishAC(element);
    break;
    case 40: // Down arrow.
    break;
    case 13: // Enter.
      this.finishAC(element);
    break;

    case 33: // Page up.
    break;
    case 34: // Page down.
    break;
    case 35: // End.
    break;
    case 36: // Home.
    break;
    case 45: // Help (mac).
    break;
/*
    case : //
    break;
*/
    case 9: // Tab.
    break;

    case 32: // Space
      this.lastword[element.id] = this.currentword[element.id];
      this.currentword[element.id] = '';
      this.suggestwords[element.id] = new Array();
      this.closeSuggestWindow(element.id);
      this.debugWrite(element);
    break;
    case 8: // Backspace
      this.closeSuggestWindow(element.id);
      this.currentword[element.id] = element.value.substring( element.value.lastIndexOf(" ") + 1, element.value.length );
      this.debugWrite(element);
    break;
    default: // Check for autocompletion.


      if ( !this.currentword[element.id] ) {
        this.currentword[element.id] = this.lastchar[element.id];
      } else {
        this.currentword[element.id] += this.lastchar[element.id];
      }

      this.lastsuggestedword[element.id] = "";

      this.debugWrite(element);

      //
      var now = new Date();

      //alert (this.typeTimer.last);
      //alert (this.typeTimer.delay);
      //alert(now - this.typeTimer.last);


      if ( (now - this.typeTimer.last) > this.typeTimer.delay) {
      //    alert(now - this.typeTimer.last + " > " + this.typeTimer.delay);
        //setTimeout( this.writeSuggestions(element, this.currentword[element.id], wordlist), 200);
        this.writeSuggestions(element, this.currentword[element.id], wordlist);
        this.typeTimer.last = new Date();
      }
    break;
  }
}

// ============================================================================

AutoComplete.prototype.writeSuggestions = function(element, phrase, wordlist) {
  this.suggestwords[element.id] = this.dbLookup(element, phrase, wordlist);
  this.debugWrite(element);

  if (this.suggestwords[element.id].length > 0) {
    this.debugWrite(element);

    // Add automaticaly to textpad.
    //JERNIS this.updateMarkedContent(element, 0);

  } else {
    this.closeSuggestWindow(element.id);
    return;
  }

  var output = '';
  this.suggestlist[element.id] = new Array();

  for (i = 0; i < this.suggestwords[element.id].length; i++) {
    output += '<div onmouseover="ac.highlightRow(this, \'' + element.id + '\', ' + i + ');" onmouseout="ac.highlightRow(this, \'' + element.id + '\', ' + i + ');" style="padding-left: 2px; width: 100%; cursor: pointer;"><span class="normal">' + this.suggestwords[element.id][i] + '</span></div>\n';
    this.suggestlist[element.id][i] = 0;
  }

//  this.currentword[element.id] = this.suggestwords[element.id][0];
  this.openSuggestWindow(element.id, output);
  this.debugWrite(element);
}

AutoComplete.prototype.updateMarkedContent = function (element, num) {

  var s_word = this.suggestwords[element.id][num];
  var s_word_length = this.suggestwords[element.id][num].length;
  var c_word = this.currentword[element.id];
  var c_word_length = this.currentword[element.id].length;

  var l_s_word = "";
  if ( this.lastsuggestedword[element.id] || this.lastsuggestedword[element.id] == "" ) {
    l_s_word = this.lastsuggestedword[element.id];
  }

/*
  this.debugvars[0] = "";
  this.debugvars[0] += "l_s_word: " + l_s_word + "\n";
  this.debugvars[0] += "l_s_word_length: " + l_s_word.length + "\n";
  this.debugvars[0] += "c_word: " + c_word + "\n";
  this.debugvars[0] += "c_word_length: " + c_word_length + "\n";;
  this.debugvars[0] += "s_word: " + s_word + "\n";
  this.debugvars[0] += "s_word_length: " + s_word_length + "\n";
  this.debugvars[0] += "s_word.substring( c_word_length, s_word_length): " + s_word.substring( c_word_length, s_word_length) + "\n";
  this.debugvars[0] += "kalle: " + element.value.substring( 0, element.value.length - 1 ) + c_word + s_word.substring( c_word_length, s_word_length ) + "\n";

  this.debugvars[0] += "element.value.substring( 0, element.value.length - 1 ): " + element.value.substring( 0, element.value.length - 1 ) + "\n";
  this.debugvars[0] += "element.value.length: " + element.value.length + "\n";
  this.debugvars[0] += "s_word.substring( c_word_length, s_word_length ): " + s_word.substring( c_word_length, s_word_length ) + "\n";
  this.debugvars[0] += "l_s_word.length: " + l_s_word.length + "\n";
*/
  this.debugWrite(element);


  if (l_s_word.length == 0) {
    element.value = element.value.substring( 0, element.value.length - c_word_length ) + c_word + s_word.substring( c_word_length, s_word_length );
  } else {
    element.value = element.value.substring( 0, element.value.length - l_s_word.length ) + c_word + s_word.substring( c_word_length, s_word_length );
  }

  if(element.createTextRange) { // For IE
    var range = element.createTextRange();
    range.moveStart("character", element.value.length - (s_word_length - c_word_length) );
    range.moveEnd("character", element.value.length);
    range.select();
  } else if(element.setSelectionRange) { // For Mozilla
    element.setSelectionRange(element.value.length - ( s_word.length - c_word_length ), element.value.length);
  }

  this.lastsuggestedword[element.id] = s_word;

  this.debugWrite(element);
}

// ============================================================================

AutoComplete.prototype.highlightRow = function(rowelement, elementid, num) {
  if ( this.suggestlist[elementid][num] == 1 ) {
    rowelement.style.backgroundColor = "";
    this.suggestlist[elementid][num] = 0;
  } else {
    rowelement.style.backgroundColor = "#aaa";
    this.suggestlist[elementid][num] = 1;
    this.debugWrite( document.getElementById(elementid) );
    this.updateMarkedContent( document.getElementById(elementid), num);
  }
}

AutoComplete.prototype.finishAC = function (element) {
  element.value += " ";
  this.lastsuggestedword[element.id] = "";
//  this.currentword[element.id] = this.suggestwords[element.id][i];
  this.currentword[element.id] = "";
  this.closeSuggestWindow(element.id);

  setTimeout( "ac.placeCursor('" + element.id + "')", 100);
  this.suggestlist[element.id] = new Array();
  this.suggestwords[element.id] = new Array();
  this.debugWrite(element);
}

AutoComplete.prototype.onBlur = function (element) {

  for (i = 0; i < this.suggestlist[element.id].length; i++) {
    if ( this.suggestlist[element.id][i] == 1 ) {

      this.finishAC(element);

      return;
    }
  }

  this.closeSuggestWindow(element.id);
}

AutoComplete.prototype.placeCursor = function (elementid) {
  document.getElementById(elementid).focus();

  if(document.getElementById(elementid).createTextRange) /* For IE */ {
    var range = document.getElementById(elementid).createTextRange();
    range.moveStart( "character", document.getElementById(elementid).value.length );
    range.moveEnd( "character", document.getElementById(elementid).value.length );
    range.select();
  } else if(document.getElementById(elementid).setSelectionRange) { // For Mozilla
    document.getElementById(elementid).setSelectionRange(document.getElementById(elementid).value.length, document.getElementById(elementid).value.length);
  }

}

AutoComplete.prototype.openSuggestWindow   = function ( elementid, data ) {
  var element = document.getElementById(elementid + "_suggest");

//  alert(navigator.appCodeName);

  if (element) {
    element.innerHTML = data;
    element.style.display = "";
  }
}

AutoComplete.prototype.closeSuggestWindow = function ( elementid ) {
  var element = document.getElementById(elementid + "_suggest");

  if (element) {
    element.innerHTML = "";
    element.style.display = "none";
  }
}


// ============================================================================

AutoComplete.prototype.dbLookup = function(element, phrase, wordlist) {
  this.debuglog += "phrase: " + phrase + " currentword: " + this.currentword + "\n";
  // Check if we got a phrase.
  if (phrase.length == 0) return new Array();

  // Make synchronious request.
  var request = this.getRequestObject();
  var url = 'xmlAutocomplete.jsp?phrase=' + escape(phrase) + '&wordlist=' + wordlist + "&maxnum=" + this.shownumrows[element.id];

  request.open('GET', url, false);
  request.send(null);


  if (request.status == 200) {
    var xmldoc = request.responseXML;
    var wordNodes = xmldoc.getElementsByTagName("word");

    if ( wordNodes.length > 0 ) {
      var tempwords = new Array();

      for (i = 0; i < wordNodes.length; i++) {
        tempwords[i] = wordNodes.item(i).firstChild.data;
      }

      return tempwords;
    } else {
      return new Array();
    }

  } else {
    alert("xmlAutocomplete.jsp error!");
  }

  return new Array();
}

// ============================================================================

AutoComplete.prototype.debugWrite = function(element) {
  return; // ON/OFF
  var output = '';
  output += '<pre>';
  output += this.debugvars[0] + '\n\n';
  output += 'this.lastsuggestedword[element.id] = ' + this.lastsuggestedword[element.id] + '\n';
  output += 'lastkey = ' + this.lastkey[element.id] + '\n';
  output += 'lastchar = \'' + this.lastchar[element.id] + '\'\n';
  output += 'currentword = \'' + this.currentword[element.id] + '\'\n';
  output += 'lastword = \'' + this.lastword[element.id] + '\'\n';
  output += 'currentElemId = \'' + element.id + '\'\n';

  if ( this.suggestwords[element.id] instanceof Object ) output += 'suggestedword = ' + this.suggestwords[element.id][0] + '\n';
//  output += 'suggestedword = ' + this.suggestwords[element.id].length + '\n';

  output += 'debuglog = \n--------\n' + this.debuglog;
  output += '</pre>';

  //alert(this.suggestwords[element.id]);
  if (document.getElementById("debug") != null) {
    document.getElementById("debug").innerHTML = output;
  }
}

// ============================================================================

var ac = new AutoComplete();












