/*
Editable Dropdown SHAZAM!
Or something like that.

clayton@physics.umn.edu
*/

  var EditableDrop = new Class.create();
  
  EditableDrop.prototype = {
    initialize: function(textarea, Entries) {
      textarea = $(textarea);
      this.textarea = textarea;
      this.doblur = false;
      this.active = false;
      this.allowUnfocus = false;

      if (navigator.appVersion.indexOf("Win")!=-1) { imagename = 'winffdropdn.png'; left = '-1'; top = '6'; }
      else { imagename = 'newdrop.png'; left = '-5'; top = '8'; }

      textarea.insert({after: '<a href="#" id="' + textarea.identify() + '_magic_button" style="position: relative; left: '+left+'px; top: '+top+'px;"><image src="/images/'+imagename+'" border="0"></a><div class="editabledrop" id="' + textarea.identify() + '_magic_list" style="display:none; z-index: 100;"></div>'});

      this.dropbutton = $(textarea.identify() + '_magic_button');
      this.completionbox = $(textarea.identify() + '_magic_list');
  
     this.completer = new Autocompleter.Local(this.textarea, this.completionbox, Entries, {choices: 999,
     selector: function(instance) {
        var ret       = []; // Beginning matches
        var partial   = []; // Inside matches
        var entry     = (instance.doAsEmpty ? '' : instance.getToken());
        var count     = 0;

        for (var i = 0; i < instance.options.array.length &&  
          ret.length < instance.options.choices ; i++) { 

          var elem = instance.options.array[i];
          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><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>" + 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 (foundPos == 0)
              break;

          }
        }
        if (partial.length)
          ret = ret.concat(partial.slice(0, instance.options.choices - ret.length))
        return "<ul>" + ret.join('') + "</ul>";
      }
  });

      // This should fix the case of clicking from the textbox to the selections drop
      // (Otherwise the textbox blur sets a timer which hides the box after click) 
      this.completer.options.onHide = function(element, update){ if (!this.active || this.doblur) { new Effect.Fade(update,{duration:0.15}); } else { this.completer.show(); } }.bind(this);

      // Copied from AutoCompleter and changed so width is not forced to be the same
      // as the textbox
      this.completer.options.onShow = function(element, update){ 
	    if(!update.style.position ||
update.style.position=='absolute') {
	      update.style.position = 'absolute';
	      Position.clone(element, update, {
		setHeight: false,
                setWidth: false,
		offsetTop: element.offsetHeight
	      });
              update.style.width = 'auto';
              update.style.overflowX = 'hidden';
	    }
	    Effect.Appear(update,{duration:0.15});
	  };


      this.dropbutton.observe('click', this.onClick.bindAsEventListener(this));
      this.dropbutton.observe('blur', this.onBlur.bindAsEventListener(this));
    },

    onClick: function(evt) {
      if (this.active) {
        this.allowUnfocus = false;
        // onBlur gets called and handles the rest...
        this.textarea.focus();
      } else {
        this.doblur = false;
        this.active = true;
        this.completer.doAsEmpty = true;
        this.completer.getUpdatedChoices();
        this.completer.activate();
        setTimeout(this.unfocusWaitOver.bind(this), 250);
      }
      evt.preventDefault();
    },

    unfocusWaitOver: function() {
      if (this.active) {
        this.allowUnfocus = true;
      }
    },

    onBlur: function(evt) {
      this.doblur = true;
      this.active = false;
      this.allowUnfocus = false;
      setTimeout(this.doBlur.bind(this), 250);
    },

    doBlur: function() {
      if (this.doblur) {
        this.completer.doAsEmpty = false;
        this.completer.hide();
        this.doblur = false;
      }
    }
  };
