// Copyright (c) 2006 - 2008 Gabriel Lanzani (http://www.glanzani.com.ar)
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
// SEE CHANGELOG FOR A COMPLETE CHANGES OVERVIEW
// VERSION 0.4
var ARRRA = [];
for (var x=9; x<=40; x++){
    ARRRA.push(x);
}
Autocompleter.AutoCombo = Class.create();
Autocompleter.AutoCombo.prototype = Object.extend(new Autocompleter.Base(), {
  initialize: function(select, options) {
	this.element = "<input type=\"text\" id=\"" + $(select).id + "_combo\" />"
	new Insertion.Before(select, this.element)
	var inputClasses = Element.classNames(select);

	this.update = "<div id=\"" + $(select).id + "_options\" class=\"" + inputClasses + "\"></div>"
	new Insertion.Before(select, this.update)

    this.baseInitialize($(select).id + "_combo", $(select).id + "_options", options);
    this.select = select;
	this.selectOptions = [];

    this.modelName = "Vika";

	if(!this.options.debug)Element.hide(select);
	Element.addClassName(this.element.id, this.options.css) ;

	var optionList = $(this.select).getElementsByTagName('option');
	var nodes = $A(optionList);
    this.options.array = $A(nodes);
    this.options.array_id = $A(nodes);
    this.options.array_styles = $A(nodes);
    this.wForReset=false;

	for(i=0; i<nodes.length;i++){
        this.options.array_styles[i] = this.options.array_styles[i].className;
        this.options.array_id[i] = this.options.array_id[i].value;
        this.options.array[i] = this.options.array[i].innerHTML;
		this.selectOptions.push("<li id=\"" + nodes[i].value + "\">" + nodes[i].innerHTML + '</li>');
		if (nodes[i].getAttribute("selected")) this.element.value = nodes[i].innerHTML;
		if(this.options.debug) debugText += 'option ' + nodes[i].innerHTML + ' added to '+ this.update.id + "\r\n";
	}

	Event.observe(this.element, "click", this.resetActivate.bindAsEventListener(this));
	Event.observe(this.element, "keyup", this.keyActivate.bindAsEventListener(this));

	if ($(select).selectedIndex >= 0)this.element.value = $(select).options[$(select).selectedIndex].innerHTML;

	var self = this;
	this.options.afterUpdateElement = function(text, li) {
        this.wForReset=false;
		var optionList = $(select).getElementsByTagName('option');
		var nodes = $A(optionList);

		var opt = nodes.find( function(node){
			return (node.value == li.childNodes[0].value);
		});

		$(select).selectedIndex=opt.index;

		if(self.options.redirect) document.location.href = opt.value;
		if(self.options.submit != '') $(self.options.submit).submit();
	}

	if(this.options.debug) alert(debugText);
  },
  resetActivate: function(e){
      this.wForReset=false;
      this.activate(this);
  },
  keyActivate: function(e){
      if(ARRRA.inArray(e.keyCode)){
      }else{
        this.wForReset=true;
        this.activate(this);
      }
  },
  getUpdatedChoices: function() {
  		this.updateChoices(this.setValues());
        this.updateChoices(this.options.selector(this));
  },

  setValues : function(){
		return ("<ul>" + this.selectOptions.join('') + "</ul>");
  },
  disable: function(){
      this.disabled = true;
  },
  enable:function(){
      this.disabled = false;
  },
  updateElement: function(selectedElement) {
        if (this.options.updateElement) {
          this.options.updateElement(selectedElement);
          return;
        }
        var value = '';
        if (this.options.select) {
          var nodes = $(selectedElement).select('.' + this.options.select) || [];
          if(nodes.length>0) value = Element.collectTextNodes(nodes[0], this.options.select);
        } else
          value = Element.collectTextNodesIgnoreClass(selectedElement, 'informal');

        var bounds = this.getTokenBounds();
        if (bounds[0] != -1) {
          var newValue = this.element.value.substr(0, bounds[0]);
          var whitespace = this.element.value.substr(bounds[0]).match(/^\s+/);
          if (whitespace)
            newValue += whitespace[0];
          this.element.value = newValue + value + this.element.value.substr(bounds[1]);
        } else {
          this.element.value = value;
        }

        //verych hack
        this.element.value = value;

        this.oldElementValue = this.element.value;
        this.element.focus();

        if (this.options.afterUpdateElement)
          this.options.afterUpdateElement(this.element, selectedElement);

        if($(this.select).onchange)
            $(this.select).onchange();
        $(this.select).fire('dd:change');
        $(this.select).fire('dd:changeAutocomplete');
    },

    setOptions: function(options) {
        this.options = Object.extend({
          submit: false, //form Id to submit after change
		  redirect: false, // redirects to option value
		  debug: false, //show alerts with information
		  css: 'combo',	 //css class for new element
          choices: 10,
          partialSearch: true,
          partialChars: 2,
          ignoreCase: true,
          fullSearch: true,
          selector: function(instance) {
            var ret       = []; // Beginning matches
            var partial   = []; // Inside matches
            var entry     = instance.getToken();
            var count     = 0;
            var fullContent="";
            if(instance.wForReset==false){entry=''}
            for (var i = 0; i < instance.options.array.length &&
              ret.length < instance.options.choices ; i++) {
                var elem = instance.options.array[i];
                if (instance.options.array_id){
                    var elem_id = instance.options.array_id[i];
                }

                if (instance.options.array_styles){
                    var elem_ico = instance.options.array_styles[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 id='" + elem_id + "' class='" + elem_ico + "'><input type='hidden' value='" + elem_id + "'><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='" + elem_id + "' class='" + elem_ico + "'><input type='hidden' value='" + elem_id + "'>" + elem.substr(0, foundPos) + "<strong>" +
                      elem.substr(foundPos, entry.length) + "</strong>" + elem.substr(
                      foundPos + entry.length) + "</li>");
                    break;
                  }
                }
                fullContent+="<li id='" + elem_id + "' class='" + elem_ico + "'><input type='hidden' value='" + elem_id + "'>"+ elem + "</li>";

                foundPos = instance.options.ignoreCase ?
                  elem.toLowerCase().indexOf(entry.toLowerCase(), foundPos + 1) :
                  elem.indexOf(entry, foundPos + 1);

              }
            }
            if (partial.length)
                ret = ret.concat(partial.slice(0, instance.options.choices - ret.length))

            if (ret.length){
                return "<ul>" + ret.join('') + "</ul>";
            }else{
                return "<ul>" + fullContent + "</ul>"
            }

          }
        }, options || { });
  }
});
