/*
  Proto!MultiSelect 0.2
  - Prototype version required: 6.0


/* Copyright: InteRiders <http://interiders.com/> - Distributed under MIT - Keep this message! */

var SearchList = Class.create(TextboxList, {

  hf:null,
  input:null,
  link:null,
  type:null,
  searchURL:null,
  version:null,

  loptions: $H({
    autocomplete: {
      'opacity': 1,
      'maxresults': 10,
      'minchars': 1
    },
    
    target:'',
    
    trans:function(id){return id;}
  }),


  initialize: function($super, element, autoholder, link, type, searchURL, options, func) {
    $super(element, options);
    this.loptions = this.loptions.merge(options);
    this.data = [];
    this.autoholder = $(autoholder).setOpacity(this.loptions.get('autocomplete').opacity);

    this.autoholder.observe('mouseover',function() {this.curOn = true;}.bind(this)).observe('mouseout',function() {this.curOn = false;}.bind(this));
    this.autoresults = this.autoholder.select('ul').first();
    var children = this.autoresults.select('li');
    children.each(function(el) { this.add({value:el.readAttribute('value'),caption:el.innerHTML}); }, this);

    this.type = type;
    this.hf = $(element).form;
    this.version = this.hf.version.value;

    this.searchURL = searchURL;
    
    this.link = $(link);
    this.link.onclick = this.search;
    this.link.controller = this;

    document.observe("holder:loaded",function(event) {
    	this.input.value = event.memo.get(this.type);
    }.bind(this));
  },

  search:function() {
	var controller = this.version ? this : this.controller;
    Holder.store(controller.input, controller.type);
    new Ajax.Request(controller.searchURL, {
        parameters: {query: controller.input.value, version: controller.version, type: controller.type},
        onSuccess: function(transport) {
        	controller.autoAdd(transport.responseText.evalJSON(true).id, transport.responseText.evalJSON(true).query);
        }.bind(controller)
    });

    return false;
  },

  autoShow: function(search) {
    this.input.removeClassName('alert');
    this.autocurrent = false;
    this.autoholder.setStyle({'display': 'block'});
    this.autoholder.descendants().each(function(e) { e.hide() });
    if(! search || ! search.strip() || (! search.length || search.length < this.loptions.get('autocomplete').minchars))
    {
      //this.autoholder.select('.default').first().setStyle({'display': 'block'});
      this.resultsshown = false;
    } else {
      this.resultsshown = true;
      this.autoresults.setStyle({'display': 'block'}).update('');
      if (this.options.get('wordMatch'))
        var regexp = new RegExp("(^|\\s)"+search,'i')
      else
        var regexp = new RegExp(search,'i')
      var count = 0;
      this.data.filter(function(str) { return true; }).each(function(result, ti) {
        var content = result.evalJSON(true).title;
        var subtitle = result.evalJSON(true).subtitle;
        if(subtitle) {
            content = '(' + subtitle + ') ' + content;
        }

        count++;
        if(ti >= this.loptions.get('autocomplete').maxresults) return;
        var that = this;
        var el = new Element('li');
        el.controller = this;
        el.number = (count - 1);
        el.observe('click',function(e) {
            e.stop();

            var n = this.number;
            var id = (this.controller.data[n]).evalJSON(true).id;
            var title = (this.controller.data[n]).evalJSON(true).title;
            that.autoAdd(id,title);

        }).observe('mouseover',function() {
            that.autoFocus(this);
        }).update(this.autoHighlight(content, search));
        this.autoresults.insert(el);
        el.cacheData('result', result.evalJSON(true));
        if(ti == 0) this.autoFocus(el);
      }, this);
    }
    if (count > this.options.get('results'))
        this.autoresults.setStyle({'height': (this.options.get('results')*24)+'px'});
    else
        this.autoresults.setStyle({'height': (count?(count*24):0)+'px'});
    return this;
  },

  autoHighlight: function(html, highlight) {
    return html.gsub(new RegExp(highlight,'i'), function(match) {
      return '<em>' + match[0] + '</em>';
    });
  },

  autoHide: function() {
    this.resultsshown = false;
    this.autoholder.hide();
    this.autocurrent = false;

    return this;
  },

  autoFocus: function(el) {
    if(! el) return;
    if(this.autocurrent) this.autocurrent.removeClassName('auto-focus');
    this.autocurrent = el.addClassName('auto-focus');
    return this;
  },

  autoMove: function(direction) {
    if(!this.resultsshown) return;
    this.autoFocus(this.autocurrent[(direction == 'up' ? 'previous' : 'next')]());
    this.autoresults.scrollTop = this.autocurrent.positionedOffset()[1]-this.autocurrent.getHeight();
    return this;
  },

  autoFeed: function(text) {
    if (this.data.indexOf(Object.toJSON(text)) == -1)
        this.data.push(Object.toJSON(text));
    return this;
  },

  autoAdd: function(fileId, title) {
    if(title) {
        this.input.value = title;
        Holder.store(this.input, this.type, title);
    }

    this.autoHide();

    if(fileId) {
        this.hf.action = this.loptions.get('trans')(fileId);
        this.hf.target = this.loptions.get('target');
        this.hf.q.value = title;
        this.hf.submit();
    } else {
        this.input.addClassName('alert');
    }
  },

  createInput: function($super,options) {
    var li = $super(options);
    var input = li.retrieveData('input');
    input.writeAttribute('autocomplete', 'off');

    input.observe('keydown', function(e) {
        this.dosearch = false;
        switch(e.keyCode) {
          case Event.KEY_UP: e.stop(); return this.autoMove('up');
          case Event.KEY_DOWN: e.stop(); return this.autoMove('down');
          case Event.KEY_RETURN:
            e.stop();
            if(! this.autocurrent) {
                this.search();
                break;
            }

            var n = this.autocurrent.number;
            var id = (this.data[n]).evalJSON(true).id;
            var title = (this.data[n]).evalJSON(true).title;
            this.autoAdd(id,title);

            this.autocurrent = false;
            break;
        
          case Event.KEY_ESC:
            this.autoHide();
            break;

          default: this.dosearch = true;
        }
        
        return true;
        
    }.bind(this));
    
    input.observe('keyup',function(e) {
          switch(e.keyCode) {
          case Event.KEY_UP:
          case Event.KEY_DOWN:
          case Event.KEY_RETURN:
          case Event.KEY_ESC:
            break;
          default:
        	  new Ajax.Request(this.options.get('fetchFile'), {
        		  parameters: {query: input.value, version: this.version, type: this.type},
                  onSuccess: function(transport) {
        			  this.data=[];
                      transport.responseText.evalJSON(true).each(function(t){this.autoFeed(t)}.bind(this));
                      this.autoShow(input.value);
                  }.bind(this)
           });
        }
        return true; 
    }.bind(this));

    this.input = input;

    return li;
  }

});

QueryHolder = Class.create(
{
    options : null,
    nameTemplate : new Template('VER#{0}-#{1}'),
    data : null,
    
    initialize : function(options) {
        this.options = options;
   
        new Ajax.Request(this.options.loadURL, {
            parameters: {version: this.options.vers},
            onSuccess: function(transport) {
            	this.data = $H(transport.responseText.evalJSON(true));
            	document.fire("holder:loaded",this.data);
            }.bind(this)
        });
    },

    store : function(inpt, type, value) {
        if(!value) {
            value = inpt.value;
        }
        
        this.data.set(type, value);
        
        new Ajax.Request(this.options.storeURL, {
            parameters: {version: this.options.vers, type: type, query: value}

        });
    }});