window.QCWPopup = Class.create({
    initialize: function ($el, data, options) {
        this.$element = $el;
        this.data = data;
        this.deleted = [];
        this.options = {
            ajaxUrl:                  '',
            createItemHeader:         '',
            editItemHeader:           '',
            deleteItemConfirmMessage: '',
            listHeight:               498,
            context:                  null,
            afterRender:              Prototype.emptyFunction,
            afterSetObserver:         Prototype.emptyFunction,
            onPopupAccept:            Prototype.emptyFunction,
            onPopupClose:             Prototype.emptyFunction,
            onNewCreate:              Prototype.emptyFunction,
            onNewCancel:              Prototype.emptyFunction,
            onEdit:                   Prototype.emptyFunction,
            onEditSave:               Prototype.emptyFunction,
            onEditCancel:             Prototype.emptyFunction,
            onToggleVisibility:       Prototype.emptyFunction,
            onDelete:                 Prototype.emptyFunction,
            additionalData:           []
        };

        Object.extend(this.options, options || {});

        this.createGUI()
            .setObserver();

        this.$search.focus();
    },

    formatConstant: function (str) {
        return str.toUpperCase().replace(/[\s]/g, '_').replace(/[^a-z0-9]/gi, '');
    },

    getData: function (constant) {
        var i;

        if (Object.isUndefined(constant))
        {
            return this.data;
        }

        for (i in this.data)
        {
            if (!this.data.hasOwnProperty(i))
            {
                continue;
            }

            if (this.data[i].const === constant)
            {
                return this.data[i];
            }
        }

        return null;
    },

    deleteData: function (constant) {
        var i;

        for (i in this.data)
        {
            if (!this.data.hasOwnProperty(i))
            {
                continue;
            }

            if (this.data[i].const === constant)
            {
                this.deleted.push(this.data[i]);
                delete this.data[i];
            }
        }
    },

    sortData: function () {
        this.data.sort(function (a, b) {
            return a.title.toLowerCase().localeCompare(b.title.toLowerCase());
        });
    },

    createGUI: function () {
        var $content = this.$element.down('.popup-content').update();

        this.$search = new Element('input', {type: 'search', className: 'input input-block', placeholder: idoit.Translate.get('LC__UNIVERSAL__SEARCH')});
        this.$list = new Element('ul', {style:'height:' + this.options.listHeight + 'px'});
        this.$form = new Element('div', {className: 'editor'});
        this.$formHider = new Element('div', {className: 'editor-overlay'})
            .update(new Element('button', {type:'button', className:'btn btn-large'})
                .update(new Element('img', {src:window.dir_images + 'icons/silk/add.png', className:'mr5'}))
                .insert(new Element('span').update(idoit.Translate.get('LC__MODULE__QCW__POPUP__NEW_ITEM'))));

        this.buildList()
            .buildForm()
            .appendFormButtons();

        // Append the elements, after they have been built. This is faster.
        $content
            .insert(new Element('div', {className: 'list'})
                .update(new Element('div', {className: 'p5'}).update(this.$search))
                .insert(this.$list))
            .insert(this.$form);

        this.$form.insert(this.$formHider);

        this.options.afterRender.call(this);

        return this;
    },

    buildListItem: function () {
        throw "Please extend this method.";
    },

    buildForm: function () {
        throw "Please extend this method.";
    },

    buildList: function () {
        var i;

        this.$list.update();

        this.sortData();

        if (this.data.length)
        {
            for (i in this.data)
            {
                if (!this.data.hasOwnProperty(i))
                {
                    continue;
                }

                this.$list.insert(this.buildListItem(this.data[i]));
            }
        }
        else
        {
            this.$list.insert(new Element('li', {className:'text-blue'})
                .update(new Element('img', {className:'mr5 vam', src:window.dir_images+'icons/silk/information.png'}))
                .insert(new Element('span', {className:'title vam'}).update(' ### No Data')))
        }

        return this;
    },

    appendFormButtons: function () {
        this.$form
            .insert(new Element('button', {type:'button', className:'btn mt10 mr5', 'data-action':'new-create'})
                .update(new Element('img', {src:window.dir_images + 'icons/silk/add.png', className:'mr5'}))
                .insert(new Element('span').update(idoit.Translate.get('LC__MODULE__QCW__POPUP__CREATE'))))
            .insert(new Element('button', {type:'button', className:'btn mt10', 'data-action':'new-cancel'})
                .update(new Element('img', {src:window.dir_images + 'icons/silk/cross.png', className:'mr5'}))
                .insert(new Element('span').update(idoit.Translate.get('LC_UNIVERSAL__ABORT'))))

            .insert(new Element('button', {type:'button', className:'btn mt10 mr5 hide', 'data-action':'edit-save'})
                .update(new Element('img', {src:window.dir_images + 'icons/silk/disk.png', className:'mr5'}))
                .insert(new Element('span').update(idoit.Translate.get('LC__MODULE__QCW__BUTTON_APPLY'))))
            .insert(new Element('button', {type:'button', className:'btn mt10 hide', 'data-action':'edit-cancel'})
                .update(new Element('img', {src:window.dir_images + 'icons/silk/cross.png', className:'mr5'}))
                .insert(new Element('span').update(idoit.Translate.get('LC_UNIVERSAL__ABORT'))));
    },

    setObserver: function () {
        // Add some button observer.
        this.$list.on('click', 'button[data-action="toggle-visibility"]', this.toggleVisibility.bindAsEventListener(this));
        this.$formHider.on('click', 'button', this.createItem.bindAsEventListener(this));
        this.$list.on('click', 'button[data-action="edit"]', this.editItem.bindAsEventListener(this));
        this.$list.on('click', 'button[data-action="delete"]', this.deleteItem.bindAsEventListener(this));
        // Create buttons.
        this.$form.on('click', 'button[data-action="new-create"]', this.newCreate.bindAsEventListener(this));
        this.$form.on('click', 'button[data-action="new-cancel"]', this.newCancel.bindAsEventListener(this));
        // Edit buttons.
        this.$form.on('click', 'button[data-action="edit-save"]', this.editSave.bindAsEventListener(this));
        this.$form.on('click', 'button[data-action="edit-cancel"]', this.editCancel.bindAsEventListener(this));

        // Add observer to the search.
        this.$search.on('keyup', this.filterItems.bindAsEventListener(this));

        // Create handler for closing the popup.
        this.$element.on('click', '.popup-closer', this.popupClose.bindAsEventListener(this));

        // Create handler for "accept" button, this will write the changes to the DB and close the popup.
        this.$element.down('.popup-footer button[data-action="accept"]').on('click', this.popupAccept.bindAsEventListener(this));

        this.options.afterSetObserver.call(this);

        return this;
    },

    filterItems: function (ev) {
        delay(function () {
            var search = this.$search.getValue().trim().toLowerCase();
        
            if (search.blank())
            {
                this.$list.select('li').invoke('removeClassName', 'hide');
                return;
            }
        
            this.$list.select('li')
                .invoke('removeClassName', 'hide')
                .filter(function ($li) {
                    var $title = $li.down('.title');
                
                    return ($title.textContent || $title.innerHTML).toLowerCase().indexOf(search) === -1;
                })
                .invoke('addClassName', 'hide');
        
        }.bind(this), 350, 'popup.filter');
    },

    newCreate: function (ev) {
        throw "Please extend this method.";
    },

    newCancel: function (ev) {
        this.options.onNewCancel.call(this, ev);

        this.$form.select('input,select,textarea').invoke('enable').invoke('setValue', '');
        this.$form.select('[data-message]').invoke('addClassName', 'hide');

        // Display the overlay.
        this.$formHider.removeClassName('hide');
    },

    editSave: function (ev) {
        throw "Please extend this method.";
    },

    editCancel: function (ev) {
        this.options.onEditCancel.call(this, ev);

        var $selected = this.$list.down('li.selected');

        if ($selected) {
            $selected.removeClassName('selected');
        }

        this.$form.down('h4').update(this.options.createItemHeader);
        this.$form.select('button').invoke('removeClassName', 'hide');
        this.$form.select('button[data-action^="edit-"]').invoke('addClassName', 'hide');
        this.$form.select('input,select,textarea').invoke('enable').invoke('setValue', '');
        this.$form.select('[data-message]').invoke('addClassName', 'hide');

        // Display the overlay.
        this.$formHider.removeClassName('hide');
    },

    toggleVisibility: function (ev) {
        var $button = ev.findElement('button'),
            $li     = $button.up('li'),
            data    = this.getData($li.readAttribute('data-const'));

        // Yay for reference!
        data.visible = !data.visible;
        data.changed = true;

        this.options.onToggleVisibility.call(this, ev, data);

        if (data.visible)
        {
            $li.removeClassName('not-assigned');
        }
        else
        {
            $li.addClassName('not-assigned');
        }

        $button
            .writeAttribute('data-visible', (data.visible ? 1 : 0))
            .writeAttribute('title', idoit.Translate.get((!data.visible ? 'LC__MODULE__QCW__SHOWN' : 'LC__MODULE__QCW__HIDDEN')))
            .down('img').writeAttribute('src', window.dir_images + (data.visible ? 'icons/silk/cross.png' : 'icons/silk/tick.png'));
    },

    createItem: function (ev) {
        this.$formHider.addClassName('hide');

        this.$form.down('input,select,textarea').focus();
    },

    editItem: function (ev) {
        var $button = ev.findElement('button'),
            $li     = $button.up('li'),
            data    = this.getData($li.readAttribute('data-const')),
            i, $tmp, $tmpInfo;

        this.options.onEdit.call(this, ev, data);
        this.$formHider.addClassName('hide');

        this.$list.select('li.selected').invoke('removeClassName', 'selected');
        $li.addClassName('selected');

        this.$form.down('h4').update(this.options.editItemHeader);
        this.$form.select('button').invoke('removeClassName', 'hide');
        this.$form.select('button[data-action^="new-"]').invoke('addClassName', 'hide');

        for (i in data)
        {
            if (!data.hasOwnProperty(i))
            {
                continue;
            }

            $tmp = this.$form.down('[data-mapping="' + i + '"]');

            if ($tmp) {
                $tmp.setValue(data[i])
                    .enable()
                    .removeClassName('mouse-help')
                    .writeAttribute('title', null)
                    .simulate('change')
                    .fire('chosen:updated');

                $tmpInfo = $tmp.next('[data-message]');

                if ($tmpInfo) {
                    if (data.hasOwnProperty(i + 'Orig') && data[i + 'Orig'].substr(0, 3) === 'LC_') {
                        $tmp.disable();
                        $tmpInfo.removeClassName('hide')
                            .update(new Element('img', {src: window.dir_images + 'icons/silk/information.png', className: 'vam mr5'}))
                            .insert($tmpInfo.readAttribute('data-message').replace('%s', data[i + 'Orig']));
                    } else {
                        $tmpInfo.addClassName('hide');
                    }
                }
            }
        }

        // Focus the first form element.
        this.$form.down('input,select,textarea').focus();
    },

    deleteItem: function (ev) {
        var $button = ev.findElement('button'),
            $li     = $button.up('li'),
            data    = this.getData($li.readAttribute('data-const'));

        // Delete only items if they are not disabled!!
        if(!$button.disabled)
        {
            this.options.onDelete.call(this, ev, data);

            if (confirm(this.options.deleteItemConfirmMessage.replace('%s', data.title)))
            {
                this.deleteData($li.readAttribute('data-const'));

                $li.remove();
            }

            this.newCancel(ev);
        }
    },

    popupAccept: function (ev) {
        var $button = ev.findElement('button'),
            data;

        $button
            .down('img').writeAttribute('src', window.dir_images + 'ajax-loading.gif')
            .next('span').update(idoit.Translate.get('LC__UNIVERSAL__LOADING'));

        // Only update changed data.
        data = this.getData().filter(function (d) {
            return d.changed;
        });

        new Ajax.Request(this.options.ajaxUrl, {
            parameters: {
                action:   'save',
                data:     Object.toJSON(data),
                deleted:  Object.toJSON(this.deleted),
                context:  this.options.context
            },
            onSuccess:  function (xhr) {
                var json = xhr.responseJSON;

                if (json.success) {
                    // Success message.
                    popup_close();

                    // Fire the callback.
                    this.options.onPopupAccept.call(this, ev, data);
                } else {
                    idoit.Notify.error('An error occured: ' + json.message, {sticky:true});
                }
            }.bind(this),
            onFailure:  function (xhr) {
                idoit.Notify.error('An error occured: ' + xhr.responseText, {sticky:true});
            },
            onComplete: function () {
                $button
                    .down('img').writeAttribute('src', window.dir_images + 'icons/silk/tick.png')
                    .next('span').update(idoit.Translate.get('LC_UNIVERSAL__ACCEPT'));
            }
        });
    },

    popupClose: function () {
        this.options.onPopupClose.call(this);

        popup_close();
    }
});

window.QCWObjectTypeGroupPopup = Class.create(QCWPopup, {
    buildListItem: function (data) {
        var $editButton = new Element('button', {className:'btn btn-small fr', type:'button', 'data-action':'edit', title:idoit.Translate.get('LC__UNIVERSAL__EDIT')})
                .update(new Element('img', {src:window.dir_images + 'icons/silk/pencil.png'})),
            $deleteButton = new Element('button', {className:'btn btn-small fr', type:'button', 'data-action':'delete', title:idoit.Translate.get('LC__MODULE__QCW__POPUP__DELETE')})
                .update(new Element('img', {src:window.dir_images + 'icons/silk/bin_closed.png'}));

        if (data.disableEdit) {
            $editButton.disable().addClassName('mouse-help').writeAttribute('title', idoit.Translate.get('LC__MODULE__QCW__POPUP__EDIT_DISABLED'));
        }

        if (data.disableDelete) {
            $deleteButton.disable().addClassName('mouse-help').writeAttribute('title', idoit.Translate.get('LC__MODULE__QCW__POPUP__DELETE_DISABLED'));
        }

        return new Element('li', {'data-const':data.const, className:(data.selfdefined ? 'selfdefined ' : '') + (data.visible ? '' : 'not-assigned')})
            .update(new Element('span', {className:'title'}).update(data.title))
            .insert($deleteButton)
            .insert($editButton)
            .insert(new Element('button', {className:'btn btn-small fr', type:'button', 'data-action':'toggle-visibility', 'data-visible':(data.visible ? 1 : 0), title:idoit.Translate.get((!data.visible ? 'LC__MODULE__QCW__SHOWN' : 'LC__MODULE__QCW__HIDDEN'))})
                .update(new Element('img', {src:window.dir_images + 'icons/silk/' + (data.visible ? 'cross' : 'tick') + '.png'})));
    },

    buildForm: function () {
        this.$form.update(new Element('h4', {className: 'p5 border mb10 gradient text-shadow'}).update(this.options.createItemHeader))
            .insert(new Element('label', {className: 'mb5 display-block'})
                .update(new Element('span').update(idoit.Translate.get('LC__UNIVERSAL__TITLE')))
                .insert(new Element('input', {
                    type:           'text',
                    className:      'input input-block',
                    'data-mapping': 'title',
                    id:             'qcw-adjuster-form-title',
                    placeholder:    idoit.Translate.get('LC__UNIVERSAL__TITLE')
                }))
                .insert(new Element('p', {className:'hide box-blue p5 mt5', style:'line-height:16px;', 'data-message':idoit.Translate.get('LC__MODULE__QCW__POPUP__LC_TITLE')})))
            .insert(new Element('label', {className: 'mb5 display-block hide'})
                .update(new Element('span').update(idoit.Translate.get('LC__CMDB__OBJTYPE__CONST')))
                .insert(new Element('input', {
                    type:           'text',
                    className:      'input input-block',
                    'data-mapping': 'const',
                    id:             'qcw-adjuster-form-const',
                    placeholder:    idoit.Translate.get('LC__CMDB__OBJTYPE__CONST')
                })));

        return this;
    },

    newCreate: function (ev) {
        var $title    = this.$form.down('input[data-mapping="title"]').removeClassName('box-red'),
            title     = $title.getValue(),
            data;

        if (title.blank()) {
            $title.highlight({startcolor:'#ffdddd', endcolor:'#ffffff', restorecolor:'#ffffff'});
            return;
        }

        data = {id:  0,
            title:   title,
            'const': 'C__OBJTYPE_GROUP__SD_' + this.formatConstant(title),
            selfdefined: true,
            visible: true,
            changed: true
        };

        this.options.onNewCreate.call(this, ev, data);

        this.data.push(data);
        this.buildList();

        // Call the cancel action, to reset the form etc.
        this.newCancel(ev);
    },

    editSave: function (ev) {
        var $title = this.$form.down('input[data-mapping="title"]'),
            title = $title.getValue(),
            $constant = this.$form.down('input[data-mapping="const"]'),
            data = this.getData($constant.getValue());

        if (title.blank())
        {
            $title.highlight({startcolor:'#ffdddd', endcolor:'#ffffff', restorecolor:'#ffffff'});
            return;
        }

        data.title = title;
        data.changed = true;

        this.options.onEditSave.call(this, ev, data);

        this.buildList();

        // Call the cancel action, to reset the form etc.
        this.editCancel(ev);
    }
});

window.QCWObjectTypePopup = Class.create(QCWPopup, {
    buildListItem: function (data) {
        var $li, $editButton = new Element('button', {className:'btn btn-small fr', type:'button', 'data-action':'edit', title:idoit.Translate.get('LC__UNIVERSAL__EDIT')})
            .update(new Element('img', {src:window.dir_images + 'icons/silk/pencil.png'})),
            $deleteButton = new Element('button', {className:'btn btn-small fr', type:'button', 'data-action':'delete', title:idoit.Translate.get('LC__MODULE__QCW__POPUP__DELETE')})
                .update(new Element('img', {src:window.dir_images + 'icons/silk/bin_closed.png'}));

        if (data.disableEdit) {
            $editButton.disable().addClassName('mouse-help').writeAttribute('title', idoit.Translate.get('LC__MODULE__QCW__POPUP__EDIT_DISABLED'));
        }

        if (data.disableDelete) {
            $deleteButton.disable().addClassName('mouse-help').writeAttribute('title', idoit.Translate.get('LC__MODULE__QCW__POPUP__DELETE_DISABLED'));
        }

        $li = new Element('li', {'data-const':data.const, className:(data.selfdefined ? 'selfdefined ' : '') + (data.visible ? '' : 'not-assigned')})
            .update(new Element('div', {className:'cmdb-marker', style:'background:#' + data.color + ';'}))
            .insert(new Element('span', {className:'title'}).update(data.title).insert(new Element('span').update((data.objectTypeGroupTitle ? '(' + data.objectTypeGroupTitle + ')' : ''))))
            .insert($deleteButton)
            .insert($editButton)
        if (!data.disableMove)
            $li.insert(new Element('button', {className:'btn btn-small fr', type:'button', 'data-action':'toggle-visibility', 'data-visible':(data.visible ? 1 : 0), title:idoit.Translate.get((!data.visible ? 'LC__MODULE__QCW__SHOWN' : 'LC__MODULE__QCW__HIDDEN'))})
                .update(new Element('img', {src:window.dir_images + 'icons/silk/' + (data.visible ? 'cross' : 'tick') + '.png'})));
        return $li;
    },

    buildForm: function () {
        var $selectCats, $selectTemplates, i;

        this.$form.update(new Element('h4', {className: 'p5 border mb10 gradient text-shadow'}).update(this.options.createItemHeader))
            .insert(new Element('label', {className: 'mb5 display-block'})
                .update(new Element('span').update(idoit.Translate.get('LC__UNIVERSAL__TITLE')))
                .insert(new Element('input', {
                    type:           'text',
                    className:      'input input-block',
                    'data-mapping': 'title',
                    id:             'qcw-adjuster-form-title',
                    placeholder:    idoit.Translate.get('LC__UNIVERSAL__TITLE')
                }))
                .insert(new Element('p', {className:'hide box-blue p5 mt5', style:'line-height:16px;', 'data-message':idoit.Translate.get('LC__MODULE__QCW__POPUP__LC_TITLE')})))
            .insert(new Element('label', {className: 'mb5 display-block hide'})
                .update(new Element('span').update(idoit.Translate.get('LC__CMDB__OBJTYPE__CONST')))
                .insert(new Element('input', {
                    type:           'text',
                    className:      'input input-block',
                    'data-mapping': 'const',
                    id:             'qcw-adjuster-form-const',
                    placeholder:    idoit.Translate.get('LC__CMDB__OBJTYPE__CONST')
                })))
            .insert(new Element('label', {className: 'mb5 display-block'})
                .update(new Element('span').update(idoit.Translate.get('LC__CMDB__OBJTYPE__CATS')))
                .insert(new Element('select', {
                    className:      'input input-block chosen-select',
                    'data-mapping': 'cats',
                    id:             'qcw-adjuster-form-cats',
                    disabled:       true
                })))
            .insert(new Element('label', {className: 'mb5 display-block'})
                .update(new Element('span').update(idoit.Translate.get('LC__MODULE__QCW__POPUP__DEFAULT_TEMPLATE')))
                .insert(new Element('select', {
                    className:      'input input-block chosen-select',
                    'data-mapping': 'template',
                    id:             'qcw-adjuster-form-template',
                    disabled:       true
                })))
            .insert(new Element('label', {className: 'mb5 display-block'})
                .update(new Element('span').update(idoit.Translate.get('LC__UNIVERSAL__COLOR')))
                .insert(new Element('input', {
                    type:           'text',
                    className:      'input input-block js-color',
                    'data-mapping': 'color',
                    id:             'qcw-adjuster-form-color',
                    placeholder:    'FFFFFF',
                    value:          'FFFFFF'
                })))
            .insert(new Element('label', {className: 'mb5 display-block'})
                .update(new Element('span').update(idoit.Translate.get('LC__MODULE__QCW__LOCATION_OBJECT')))
                .insert(new Element('select', {
                    className:      'input input-block',
                    'data-mapping': 'container',
                    id:             'qcw-adjuster-form-container'
                })
                .update(new Element('option', {value:0}).update(idoit.Translate.get('LC__UNIVERSAL__NO')))
                .insert(new Element('option', {value:1}).update(idoit.Translate.get('LC__UNIVERSAL__YES')))))
            .insert(new Element('label', {className: 'mb5 display-block'})
                .update(new Element('span').update(idoit.Translate.get('LC__CMDB__OBJTYPE__INSERTION_OBJECT')))
                .insert(new Element('select', {
                    className:      'input input-block',
                    'data-mapping': 'insertion',
                    id:             'qcw-adjuster-form-insertion'
                })
                .update(new Element('option', {value:0}).update(idoit.Translate.get('LC__UNIVERSAL__NO')))
                .insert(new Element('option', {value:1}).update(idoit.Translate.get('LC__UNIVERSAL__YES')))));

        $selectCats = this.$form.down('[data-mapping="cats"]').update(new Element('option', {value: -1}).update('-'));

        for (i in this.options.additionalData.specificCategories)
        {
            if (!this.options.additionalData.specificCategories.hasOwnProperty(i))
            {
                continue;
            }

            $selectCats.insert(new Element('option', {value: i.substr(4)}).update(this.options.additionalData.specificCategories[i]));
        }

        $selectTemplates = this.$form.down('[data-mapping="template"]').update(new Element('option', {value: -1}).update('-'));

        for (i in this.options.additionalData.defaultTemplates)
        {
            if (!this.options.additionalData.defaultTemplates.hasOwnProperty(i))
            {
                continue;
            }

            $selectTemplates.insert(new Element('option', {value: i}).update(this.options.additionalData.defaultTemplates[i]));
        }

        return this;
    },

    newCreate: function (ev) {
        var $title = this.$form.down('[data-mapping="title"]').removeClassName('box-red'),
            title = $title.getValue(),
            data;

        if (title.blank()) {
            $title.highlight({startcolor:'#ffdddd', endcolor:'#ffffff', restorecolor:'#ffffff'});
            return;
        }

        data = {
            id:        0,
            title:     title,
            cats:      this.$form.down('[data-mapping="cats"]').getValue(),
            template:  this.$form.down('[data-mapping="template"]').getValue(),
            container: this.$form.down('[data-mapping="container"]').getValue(),
            color:     this.$form.down('[data-mapping="color"]').getValue(),
            'const':   'C__OBJTYPE__SD_' + this.formatConstant(title),
            selfdefined:   true,
            visible:   true,
            changed:   true
        };

        this.options.onNewCreate.call(this, ev, data);

        this.data.push(data);
        this.buildList();

        // Call the cancel action, to reset the form etc.
        this.newCancel(ev);
    },

    editSave: function (ev) {
        var $title     = this.$form.down('[data-mapping="title"]'),
            title      = $title.getValue(),
            $constant  = this.$form.down('[data-mapping="const"]'),
            $cats      = this.$form.down('[data-mapping="cats"]'),
            $template  = this.$form.down('[data-mapping="template"]'),
            $color     = this.$form.down('[data-mapping="color"]'),
            $container = this.$form.down('[data-mapping="container"]'),
            $insertion = this.$form.down('[data-mapping="insertion"]'),
            data       = this.getData($constant.getValue());

        if (title.blank())
        {
            $title.highlight({startcolor:'#ffdddd', endcolor:'#ffffff', restorecolor:'#ffffff'});
            return;
        }

        data.title = title;
        data.color = $color.getValue();
        data.cats = $cats.getValue();
        data.template = $template.getValue();
        data.container = $container.getValue();
        data.insertion = $insertion.getValue();
        data.changed = true;

        this.options.onEditSave.call(this, ev, data);

        this.buildList();

        // Call the cancel action, to reset the form etc.
        this.editCancel(ev);
    }
});

window.QCWCategoryPopup = Class.create(QCWPopup, {
    buildListItem: function (data) {
        return new Element('li', {'data-const':data.const, className:(data.selfdefined ? 'selfdefined ' : '') + (data.visible ? '' : 'not-assigned')})
            .update(new Element('span', {className:'title'}).update(data.title))
            .insert(new Element('button', {className:'btn btn-small fr', type:'button', 'data-action':'toggle-visibility', 'data-visible':(data.visible ? 1 : 0), title:idoit.Translate.get((!data.visible ? 'LC__MODULE__QCW__SHOWN' : 'LC__MODULE__QCW__HIDDEN'))})
                .update(new Element('img', {src:window.dir_images + 'icons/silk/' + (data.visible ? 'cross' : 'tick') + '.png'})));
    },

    buildForm: function () {
        this.$form.update(new Element('h4', {className: 'p5 border mb10 gradient text-shadow'}).update(this.options.createItemHeader))
            .insert(new Element('p')
                .update(idoit.Translate.get('LC__MODULE__QCW__POPUP__CREATE_CATEGORY_DESCRIPTION')))
            .insert(new Element('a', {href: '', target: '_blank', className: 'mt10 btn btn-block'})
                .update(new Element('img', {src: window.dir_images + 'icons/silk/link.png', className: 'mr5'}))
                .insert(new Element('span').update(idoit.Translate.get('LC__CMDB__CUSTOM_CATEGORIES'))));

        return this;
    }
});