// The local array autocompleter. Used when you'd prefer to
// inject an array of autocompletion options into the page, rather
// than sending out Ajax queries, which can be quite slow sometimes.
//
// The constructor takes four parameters. The first two are, as usual,
// the id of the monitored textbox, and id of the autocompletion menu.
// The third is the array you want to autocomplete from, and the fourth
// is the options block.
//
// Extra local autocompletion options:
// - choices - How many autocompletion choices to offer
//
// - partialSearch - If false, the autocompleter will match entered
//       text only at the beginning of strings in the 
//       autocomplete array. Defaults to true, which will
//       match text at the beginning of any *word* in the
//       strings in the autocomplete array. If you want to
//       search anywhere in the string, additionally set
//       the option fullSearch to true (default: off).
//
// - fullSsearch - Search anywhere in autocomplete array strings.
//
// - partialChars - How many characters to enter before triggering
//       a partial match (unlike minChars, which defines
//       how many characters are required to do any match
//       at all). Defaults to 2.
//
// - ignoreCase - Whether to ignore case when autocompleting.
//       Defaults to true.
//
// It's possible to pass in a custom function as the 'selector' 
// option, if you prefer to write your own autocompletion logic.
// In that case, the other options above will not apply unless
// you support them.

Autocompleter.LocalHash = Class.create();
Autocompleter.LocalHash.prototype = Object.extend(new Autocompleter.Base(), {
    initialize: function(element, update, array, options) {
      this.baseInitialize(element, update, options);
      this.options.array = array;
   },

   getUpdatedChoices: function() {
      this.updateChoices(this.options.selector(this));
   },

   setOptions: function(options) {
      this.options = Object.extend({
         choices: 10,
         partialSearch: true,
         partialChars: 2,
         ignoreCase: true,
         fullSearch: false,
         selector: function(instance) {
            var ret = []; // Beginning matches
            var partial = []; // Inside matches
            var entry  = instance.getToken();
            var count = 0;

            instance.options.array.each(function(pair) {
                             
               /* this is the key */
               var key = pair.key
               /* this is the ement */
               var elem = pair.value
               var foundPos = instance.options.ignoreCase ? 
                  elem.toLowerCase().indexOf(entry.toLowerCase()) : 
                  elem.indexOf(entry);

               while (foundPos != -1) {
                  if (foundPos == 0 && elem.length != entry.length) { 
                     ret.push("<li id=\'" + key + "\'><strong>" + elem.substr(0, entry.length) + "</strong>" + 
                        elem.substr(entry.length) + "</li>");
                     break;
                  } else if (entry.length >= instance.options.partialChars && 
                     instance.options.partialSearch && foundPos != -1) {
                     if (instance.options.fullSearch || /\s/.test(elem.substr(foundPos-1,1))) {
                        partial.push("<li id=\'" + key + "\'>" + elem.substr(0, foundPos) + "<strong>" +
                           elem.substr(foundPos, entry.length) + "</strong>" + elem.substr(
                           foundPos + entry.length) + "</li>");
                        break;
                     }
                  }

                  foundPos = instance.options.ignoreCase ? 
                     elem.toLowerCase().indexOf(entry.toLowerCase(), foundPos + 1) : 
                     elem.indexOf(entry, foundPos + 1);
               }
               
               if (ret.length == instance.options.choices) throw $break;
               
            });
            if (partial.length)
               ret = ret.concat(partial.slice(0, instance.options.choices - ret.length))
            return "<ul>" + ret.join('') + "</ul>";
         }
      }, options || {});
   }
});



