// yo
Ext.namespace('Ext.ux.plugins');

Ext.ux.Box = Ext.extend(Ext.Component, {
  initComponent : function(){
    Ext.ux.Box.superclass.initComponent.call(this);
  },

  onRender: function(ct, position){
    Ext.ux.Box.superclass.onRender.call(this, ct, this.maininput);

    this.addEvents('remove');

    this.addClass('bit-box');

    this.el = ct.createChild({ tag: "li" }, this.maininput);
    this.el.addClassOnOver('bit-hover');

    Ext.apply(this.el, {

      'focus': function(){
        this.down('a').focus();
      },

      'dispose': function(){
        this.dispose()
      }.createDelegate(this)

    });

    this.el.on('click', function(e){
      this.focus()
    }, this, {stopEvent:true});

    this.el.update(this.caption);

    this.lnk = this.el.createChild({
      'tag': 'a',
      'class': 'closebutton',
      'href':'#'
    });

    this.lnk.on({
      'click': function(e){
        e.stopEvent();
        this.fireEvent('remove', this);
        this.dispose();
      },
      'focus': function(){
        this.el.addClass("bit-box-focus");
      },
      'blur': function(){
        this.el.removeClass("bit-box-focus");
      },
      scope: this
    });

    new Ext.KeyMap(this.lnk, [
      {
        key: [Ext.EventObject.BACKSPACE, Ext.EventObject.DELETE],
        fn: function(){
          this.fireEvent('remove', this);
          this.dispose();
        }.createDelegate(this)
      },
      {
        key: Ext.EventObject.RIGHT,
        fn: function(){
          this.move('right');
        }.createDelegate(this)
      },
      {
        key: Ext.EventObject.LEFT,
        fn: function(){
          this.move('left');
        }.createDelegate(this)
      },
      {
        key: Ext.EventObject.TAB,
        fn: function(){
        }.createDelegate(this)
      }
    ]).stopEvent = true;

  },

  move: function(direction) {
    if(direction == 'left')
      el = this.el.prev();
    else
      el = this.el.next();
    if(el)
      el.focus();
  },

  dispose: function() {
    //if(el.prev() && this.retrieveData(el.prev(), 'small') ) el.prev().remove();
    //if(this.current == el) this.focus(el.next());
    //if(el.data['type'] == 'box') el.onBoxDispose(this);
    this.el.hide({
      duration: .5,
      callback: function(){
        this.move('right');
        this.destroy()
      }.createDelegate(this)
    });
    return this;
  }
});

Ext.ux.BoxSelect = Ext.extend(Ext.form.ComboBox, {

	boxes : [],
	
	/**
	* @cfg {bool} allowDuplicate
	* indicates if you can select the same item multiple times or not.
	*/
	allowDuplicate: true,

  initComponent:function() {

    this.addEvents({
        /**
         * @event remove
         * @param {Object} this
         */
        'remove' : true
    });
    Ext.apply(this, {
      selectedValues: {},
      boxElements: {},
      current: false,
      options: {
        className: 'bit',
        separator: ','
      },
      grow: false
    });

    Ext.ux.BoxSelect.superclass.initComponent.call(this);
  },

  onRender:function(ct, position) {
    Ext.ux.BoxSelect.superclass.onRender.call(this, ct, position);

    //this.el.removeClass('x-form-text');
    //this.el.className = 'maininput';
    //this.el.setWidth(20);

    this.holder = ct.createChild({
        tag: 'ul',
        "class" : 'holder x-form-text'
    });

    this.holder.on('click', function(e){
      e.stopEvent();
      if(this.maininput != this.current) this.focus(this.maininput);
    }, this);

    /*
    this.maininput = ct.wrap({
      'tag': 'li', 'class':'bit-input'
    });
    */

    Ext.apply(this.maininput, {
      'focus': function(){
        this.focus();
      }.createDelegate(this)
    });


  },

  onResize: function( w, h, rw, rh ){
    this._width = w;
    Ext.ux.BoxSelect.superclass.onResize.call(this, w, h, rw, rh);
    this.autoSize();
  },

  reset : function() {
      Ext.ux.BoxSelect.superclass.reset.call(this);
      // remove ux.Box and hiddens
      this.container.select('input[type=hidden]').each(function(el) {
          el.remove();
      });

      for (var n=0,len=this.boxes.length;n<len;n++) {
          this.boxes[n].destroy();
      }
      this.selectedValues = {};


  },

  onKeyUp : function(e) {

    if(this.editable !== false && !e.isSpecialKey()){
      this.lastKey = e.getKey();
      if(e.getKey() == e.BACKSPACE && this.el.dom.value.length == 0){
        e.stopEvent();
        this.collapse();
        if (typeof(this.maininput) == 'object') {
            var el = this.maininput.prev();
            if (el) {
                el.focus();
            }
        }
        return;
      }
      this.dqTask.delay(this.queryDelay);
    }

    this.autoSize();

    Ext.ux.BoxSelect.superclass.onKeyUp.call(this, e);
  },

  onSelect: function(record, index) {
    var val = record.data[this.valueField];
	if (this.allowDuplicate == false) {
		if (this.selectedValues[val] != null) {
			this.collapse();
	    this.setRawValue('');
	    this.lastSelectionText = '';
	    this.applyEmptyText();

	    this.autoSize();
			return;
		}		
	}
    this.selectedValues[val] = val;

    if(!this.boxElements[val]){
      var caption;
      if(this.displayFieldTpl)
        caption = this.displayFieldTpl.apply(record.data)
      else if(this.displayField)
         caption = record.data[this.displayField];

      var hidden = this.el.insertSibling({
        'tag':'input',
        'type':'hidden',
        'value': val,
        'name': (this.hiddenName || this.name)
      },'before', true);

      var el = new Ext.ux.Box({
        maininput: this.maininput,
        renderTo: this.holder,
        className: this.options['className'],
        caption: caption,
        'value': record.data[this.valueField],
        listeners: {
          'remove': function(box){
            this.selectedValues[box.value] = null;
            Ext.fly(hidden).remove();
            this.fireEvent('remove', this);
          },
          scope: this
        }
      });
      el.render();
      this.boxes.push(el);
      this.fireEvent('select', this, record, index);


    }
    this.collapse();
    this.setRawValue('');
    this.lastSelectionText = '';
    this.applyEmptyText();

    this.autoSize();
  },

  autoSizeeeee : function(){

    if(!this.rendered){
        return;
    }
    if(!this.metrics){
        this.metrics = Ext.util.TextMetrics.createInstance(this.el);
    }
    var el = this.el;
    var v = el.dom.value;
    var d = document.createElement('div');
    d.appendChild(document.createTextNode(v));
    v = d.innerHTML;
    d = null;
    v += "&#160;";
    var w = Math.min(this._width, Math.max(this.metrics.getWidth(v) +  10, 10));
    this.el.setWidth(w);

  },

  setValue : function(v) {
      for (var n=0,len=v.length;n<len;n++) {
          var idx = this.store.find('id', v[n]);
          if (idx > -1) {
              var rec = this.store.getAt(idx);
              this.onSelect(rec, idx);
          }
      }

  },

  getValue: function(){
    var ret = [];
    for(var k in this.selectedValues){
      if(this.selectedValues[k])
        ret.push(this.selectedValues[k]);
    }
    return ret.join(this.options['separator']);
  }
});

Ext.reg('boxselect', Ext.ux.BoxSelect);
