var TmeTextboxList = new Class({
    Extends: TextboxList,

    editBitsEnabled: true,
    suggestAddBitPending:false,

    removeAll: function() {
        this.list.empty();
        this.index = [];
        if (this.options.endEditableBit) this.create('editable', null, { tabIndex: this.original.tabIndex, infotext: this.options.infotext, referenceControlId: this.options.referenceControlId, remoteCheckUrl: this.options.remoteCheckUrl, relatedControlId: this.options.relatedControlId }).inject(this.list);
    },

    onRemove: function(bit) {
        var totcount = this.list.getChildren('.' + this.options.prefix + '-bit-box').length;
        this.fireEvent('actionDone', totcount - 1);
        if ($chk(this.options.max) && totcount == this.options.max) {
            this.fireEvent('linkEnable', totcount);
        }

        if (this.options.unique && bit.is('box')) {
            this.index.erase(this.uniqueValue(bit.value));
        };
        var prior = this.getBit($(bit).getPrevious());
        if (prior && prior.is('editable')) prior.remove();
        if (!this.focused) return;
        this.focusRelative('next', bit);
    },

    focusLast: function() {
        if (!this.editBitsEnabled) return this;
        var lastElement = this.list.getLast();
        if (lastElement) this.getBit(lastElement).focus();
        return this;
    },

    initialize: function(element, options) {
        this.setOptions(options);

        var lW = $(element).getSize().x - 4;
        if (lW < 0) lW = 0;
        if (lW == 0) {
            lW = document.getElementById(element).style.width;
            if (lW.length = 0) lW = $(element).getStyle("width");
        }
        else {
            lW = lW + "px";
        }

        // IE6 fix
        if (lW.indexOf("-") >= 0) lW = "0px";



        this.original = $(element).setStyle('display', 'none').set('autocomplete', 'off').addEvent('focus', this.focusLast.bind(this));
        this.container = new Element('div', { 'class': this.options.prefix, 'styles': { 'width': lW} }).inject(element, 'after');
        this.container.addEvent('click', function(e) {
            if ((e.target == this.list || e.target == this.container) && (!this.focused || $(this.current) != this.list.getLast())) this.focusLast();
        } .bind(this));
        this.list = new Element('ul', { 'class': this.options.prefix + '-bits' }).inject(this.container);
        for (var name in this.options.plugins) this.enablePlugin(name, this.options.plugins[name]);
        ['check', 'encode', 'decode'].each(function(i) { this.options[i] = this.options[i].bind(this); }, this);
        this.afterInit();
    },

    update: function(o) {
        var lValues = this.getValues();

        this.original.set('value', this.options.encode(lValues));
        if (this.options.max) {
            if (lValues.length >= this.options.max) {
                this.list.getChildren().map(function(el) {
                    var bit = this.getBit(el);
                    if (bit.is('editable')) {
                        bit.hide();
                        this.blur();
                    };
                }, this);
                this.editBitsEnabled = false;
            } else {
                if (!this.editBitsEnabled) {
                    this.editBitsEnabled = true;
                    this.list.getChildren().map(function(el) {
                        var bit = this.getBit(el);
                        if (bit.is('editable')) {
                            bit.show();
                        };
                    }, this);
                }
            };

        }
    },

    isInfoVisible: false,

    showInfoText: function() {
        if (this.suggestAddBitPending) return;
        if (this.options.infotext && !this.isInfoVisible) {
            if (this.getValues().length == 0) {

                this.list.getChildren().map(function(el) {
                    el.destroy();
                }, this);
                this.list.empty();
                this.index = [];
                var lInfoBit = this.create('editable', null, null).inject(this.list);

                lInfoBit.element.value = this.options.infotext;
                this.container.removeClass(this.options.prefix + '-focus');
                this.resize(this.options.infotext, lInfoBit.element);
                this.isInfoVisible = true;

            }
        }
    },

    resize: function(text, obj) {
        if (navigator.appName.toLowerCase() == "opera" /* || navigator.userAgent.toLowerCase().indexOf("chrome") != -1*/) {
            var w = this.list.offsetWidth;
            if (text.length == 0) w = 17;
            obj.setStyle('width', w + 'px');
        }
        else {
            var w = 0;
            if (text.length == 0) w = 17;
            else {
                var el = document.createElement("span");
                el.innerHTML = text;
                document.body.appendChild(el);
                w = el.offsetWidth;
                document.body.removeChild(el);
            }
            obj.setStyle('width', w + 'px');
        }
    },

    showInfoTextDummy: function() {
    
    },

    hideInfoText: function() {
        if (this.options.infotext) {
            this.list.getChildren().map(function(el) {
                var bit = this.getBit(el);
                if (bit.is('editable')) {
                    bit.element.value = "";

                    this.isInfoVisible = false;
                };
            }, this);
        }

    },


    setValues: function(values) {
        if (!values) return;
        values.each(function(v) {
            if (v) this.add.apply(this, $type(v) == 'array' ? [htmlDecode(v[1]), htmlDecode(v[0]), htmlDecode(v[2])] : [htmlDecode(v)]);
        }, this);
    },

    hideSelect: function() {
        if (Browser.Engine.name == 'trident' && Browser.Engine.version == 4) {
            var s = $(document).getElements('select').each(function(item) {
                item.setStyle('visibility', 'hidden');
            });
        }
    },

    showSelect: function() {
        if (Browser.Engine.name == 'trident' && Browser.Engine.version == 4) {
            var s = $(document).getElements('select').each(function(item) {
                item.setStyle('visibility', '');
            });
        }
    },

    afterInit: function() {
        if (this.options.unique) this.index = [];
        if (this.options.endEditableBit) this.create('editable', null, { tabIndex: this.original.tabIndex, infotext: this.options.infotext, referenceControlId: this.options.referenceControlId, remoteCheckUrl: this.options.remoteCheckUrl, relatedControlId: this.options.relatedControlId }).inject(this.list);
        var update = this.update.bind(this);

        this.addEvent('onFocus', this.hideInfoText, true);
        this.addEvent('onBlur', this.showInfoText, true);
        if (Browser.Engine.name == 'trident' && Browser.Engine.version == 4) {
            this.addEvent('onBitEditableFocus', this.hideInfoText, true);
            this.addEvent('onBitEditableBlur', this.showInfoTextDummy, true);
        } else {
            this.addEvent('onBitEditableFocus', this.hideInfoText, true);
            this.addEvent('onBitEditableBlur', this.showInfoText, true);
        }
        this.addEvent('onBitAdd', this.hideInfoText, true);
        this.addEvent('onBitRemove', this.showInfoText, true);

        this.addEvent('bitAdd', update, true).addEvent('bitRemove', update, true);
        document.addEvents({
            click: function(e) {
                if (!this.focused) return;
                if (e.target.className.contains(this.options.prefix)) {
                    if (e.target == this.container) return;
                    var parent = e.target.getParent('.' + this.options.prefix);
                    if (parent == this.container) return;
                }
                this.blur();
            } .bind(this),
            keydown: function(ev) {
                if (!this.focused || !this.current) return;
                var caret = this.current.is('editable') ? this.current.getCaret() : null;
                var value = this.current.getValue()[1];
                var special = ['shift', 'alt', 'meta', 'ctrl'].some(function(e) { return ev[e]; });
                var custom = special || (this.current.is('editable') && this.current.isSelected());
                switch (ev.code) {
                    case Event.Keys.backspace:
                        if (this.current.is('box')) {
                            ev.stop();
                            return this.current.remove();
                        }
                    case this.options.keys.previous:
                        if (this.current.is('box') || ((caret == 0 || !value.length) && !custom)) {
                            ev.stop();
                            this.focusRelative('previous');
                        }
                        break;
                    case Event.Keys['delete']:
                        if (this.current.is('box')) {
                            ev.stop();
                            return this.current.remove();
                        }
                    case this.options.keys.next:
                        if (this.current.is('box') || (caret == value.length && !custom)) {
                            ev.stop();
                            this.focusRelative('next');
                        }
                }
            } .bind(this)
        });
        this.showInfoText();
        this.container.style.color = "black";
    }
});



var entities = [
			['&amp;', '&'],
			['&nbsp;', ' '],
			['&lt;', '<'],
			['&gt;', '>']
		];

function htmlDecode(t) {
    var clean = (t + "").replace(/<[^>]*>/g, "");
    for (var i = 0, limit = entities.length; i < limit; ++i) {
        clean = clean.replace(new RegExp(entities[i][0], "ig"), entities[i][1]);
    }
    return clean;

}