﻿///<reference path="Extjs_Intellisense.js" />
Ext.namespace('LUL');

LUL.extractData = function(element) {
    var data = element.getAttributeNS('lul', 'data');
    if (data != undefined)
        return Ext.util.JSON.decode('{' + data + '}');
    else
        return null;
}

LUL.TextField = Ext.extend(Ext.form.TextField, {
    listeners: {
        focus: function(c) {
            if (c.statusBar && c.tooltip) {
                c.statusBar.setStatus(c.tooltip);
            }
        },
        blur: function(c) {
            if (c.statusBar && c.tooltip) {
                c.statusBar.clearStatus();
            }
        },
        render: function(c) {
            if (c.tooltip) {
                Ext.QuickTips.register({
                    target: c.getEl(),
                    text: c.tooltip
                });
            }
        }
    }
});

LUL.Checkbox = Ext.extend(Ext.form.Checkbox, {
    listeners: {
        focus: function(c) {
            var a = 1;
            if (c.statusBar && c.tooltip) {
                c.statusBar.setStatus(c.tooltip);
            }
        },
        blur: function(c) {
        var a = 1;
        if (c.statusBar && c.tooltip) {
                c.statusBar.clearStatus();
            }
        },
        render: function(c) {
        var a = 1;
        if (c.tooltip) {
                Ext.QuickTips.register({
                    target: c.getEl(),
                    text: c.tooltip
                });
            }
        }
    }
});

LUL.HtmlEditor = Ext.extend(Ext.form.Field, {

    enableFormat: true,
    enableFontSize: true,
    enableColors: true,
    enableAlignments: true,
    enableLists: true,
    enableSourceEdit: true,
    enableLinks: true,
    enableFont: true,
    enableParagraphFormat: true,

    createLinkText: 'Ange URL för länken:',
    defaultLinkValue: 'http:/' + '/',

    paragraphFormats: [
        { title: 'Normal', tag: '<p>' },
        { title: 'Rubrik 1', tag: '<h1>' },
        { title: 'Rubrik 2', tag: '<h2>' },
        { title: 'Rubrik 3', tag: '<h3>' }
    ],
    defaultParagraphFormat: 'Normal',

    fontFamilies: [
        'Arial',
        'Courier New',
        'Tahoma',
        'Times New Roman',
        'Verdana'
    ],
    defaultFont: 'tahoma',

    validationEvent: false,
    deferHeight: true,
    initialized: false,
    activated: false,
    sourceEditMode: false,
    onFocus: Ext.emptyFn,
    iframePad: 3,
    hideMode: 'offsets',
    defaultAutoCreate: {
        tag: "textarea",
        style: "width:500px;height:300px;",
        autocomplete: "off"
    },

    initComponent: function() {
        this.addEvents(
            'initialize',
            'activate',
            'beforesync',
            'beforepush',
            'sync',
            'push',
            'editmodechange'
        )
    },

    createFontOptions: function() {
        var buf = [], fs = this.fontFamilies, ff, lc;
        for (var i = 0, len = fs.length; i < len; i++) {
            ff = fs[i];
            lc = ff.toLowerCase();
            buf.push(
                '<option value="', lc, '" style="font-family:', ff, ';"',
                    (this.defaultFont == lc ? ' selected="true">' : '>'),
                    ff,
                '</option>'
            );
        }
        return buf.join('');
    },

    createParagraphFormatOptions: function() {
        var buf = [], fs = this.paragraphFormats, ff, lc;
        for (var i = 0, len = fs.length; i < len; i++) {
            ff = fs[i];
            buf.push(
                '<option value="', ff.tag, '"',
                    (this.defaultParagraphFormat == ff.title ? ' selected="true">' : '>'),
                    ff.title,
                '</option>'
            );
        }
        return buf.join('');
    },

    createToolbar: function(editor) {

        var tipsEnabled = Ext.QuickTips && Ext.QuickTips.isEnabled();

        function btn(id, toggle, handler) {
            return {
                itemId: id,
                cls: 'x-btn-icon x-edit-' + id,
                enableToggle: toggle !== false,
                scope: editor,
                handler: handler || editor.relayBtnCmd,
                clickEvent: 'mousedown',
                tooltip: tipsEnabled ? editor.buttonTips[id] || undefined : undefined,
                tabIndex: -1
            };
        }

        var tb = new Ext.Toolbar({
            renderTo: this.wrap.dom.firstChild
        });

        tb.el.on('click', function(e) {
            e.preventDefault();
        });

        if (this.enableFont && !Ext.isSafari2) {
            this.fontSelect = tb.el.createChild({
                tag: 'select',
                cls: 'x-font-select',
                html: this.createFontOptions()
            });
            this.fontSelect.on('change', function() {
                var font = this.fontSelect.dom.value;
                this.relayCmd('fontname', font);
                this.deferFocus();
            }, this);
            tb.add(
                this.fontSelect.dom,
                '-'
            );
        };

        if (this.enableFormat) {
            tb.add(
                btn('bold'),
                btn('italic'),
                btn('underline')
            );
        };

        if (this.enableFontSize) {
            tb.add(
                '-',
                btn('increasefontsize', false, this.adjustFont),
                btn('decreasefontsize', false, this.adjustFont)
            );
        };

        if (this.enableColors) {
            tb.add(
                '-', {
                    itemId: 'forecolor',
                    cls: 'x-btn-icon x-edit-forecolor',
                    clickEvent: 'mousedown',
                    tooltip: tipsEnabled ? editor.buttonTips['forecolor'] || undefined : undefined,
                    tabIndex: -1,
                    menu: new Ext.menu.ColorMenu({
                        allowReselect: true,
                        focus: Ext.emptyFn,
                        value: '000000',
                        plain: true,
                        selectHandler: function(cp, color) {
                            this.execCmd('forecolor', Ext.isSafari || Ext.isIE ? '#' + color : color);
                            this.deferFocus();
                        },
                        scope: this,
                        clickEvent: 'mousedown'
                    })
                }, {
                    itemId: 'backcolor',
                    cls: 'x-btn-icon x-edit-backcolor',
                    clickEvent: 'mousedown',
                    tooltip: tipsEnabled ? editor.buttonTips['backcolor'] || undefined : undefined,
                    tabIndex: -1,
                    menu: new Ext.menu.ColorMenu({
                        focus: Ext.emptyFn,
                        value: 'FFFFFF',
                        plain: true,
                        allowReselect: true,
                        selectHandler: function(cp, color) {
                            if (Ext.isGecko) {
                                this.execCmd('useCSS', false);
                                this.execCmd('hilitecolor', color);
                                this.execCmd('useCSS', true);
                                this.deferFocus();
                            } else {
                                this.execCmd(Ext.isOpera ? 'hilitecolor' : 'backcolor', Ext.isSafari || Ext.isIE ? '#' + color : color);
                                this.deferFocus();
                            }
                        },
                        scope: this,
                        clickEvent: 'mousedown'
                    })
                }
            );
        };

        if (this.enableAlignments) {
            tb.add(
                '-',
                btn('justifyleft'),
                btn('justifycenter'),
                btn('justifyright')
            );
        };

        if (!Ext.isSafari2) {
            if (this.enableLinks) {
                tb.add(
                    '-',
                    btn('createlink', false, this.createLink)
                );
            };

            if (this.enableLists) {
                tb.add(
                    '-',
                    btn('insertorderedlist'),
                    btn('insertunorderedlist')
                );
            }
            if (this.enableSourceEdit) {
                tb.add(
                    '-',
                    btn('sourceedit', true, function(btn) {
                        this.toggleSourceEdit(btn.pressed);
                    })
                );
            }
        }

        this.tb = tb;

        // extra verktygsrad
        if (this.enableParagraphFormat) {
            var tb2container = Ext.DomHelper.insertAfter(tb.el, { tag: 'div', id: Ext.id() }, true);
            var tb2 = new Ext.Toolbar(tb2container);
            // utökning för styckeformat
            if (this.enableParagraphFormat) {
                this.paragraphFormatSelect = tb.el.createChild({
                    tag: 'select',
                    cls: 'x-font-select',
                    html: this.createParagraphFormatOptions()
                });
                this.paragraphFormatSelect.on('change', function() {
                    var tag = this.paragraphFormatSelect.dom.value;
                    this.relayCmd('formatblock', tag);
                    this.deferFocus();
                }, this);
                tb2.add(
                this.paragraphFormatSelect.dom,
                '-'
            );
            }

            this.tb2 = tb2;
        }
    },


    getDocMarkup: function() {
        return '<html><head><link href="Templates/HtmlEditor.css" rel="stylesheet" type="text/css" /></head><body></body></html>';
    },


    getEditorBody: function() {
        return this.doc.body || this.doc.documentElement;
    },


    getDoc: function() {
        return Ext.isIE ? this.getWin().document : (this.iframe.contentDocument || this.getWin().document);
    },


    getWin: function() {
        return Ext.isIE ? this.iframe.contentWindow : window.frames[this.iframe.name];
    },


    onRender: function(ct, position) {
        Ext.form.HtmlEditor.superclass.onRender.call(this, ct, position);
        this.el.dom.style.border = '0 none';
        this.el.dom.setAttribute('tabIndex', -1);
        this.el.addClass('x-hidden');
        if (Ext.isIE) {
            this.el.applyStyles('margin-top:-1px;margin-bottom:-1px;')
        }
        this.wrap = this.el.wrap({
            cls: 'x-html-editor-wrap', cn: { cls: 'x-html-editor-tb' }
        });

        this.createToolbar(this);

        this.tb.items.each(function(item) {
            if (item.itemId != 'sourceedit') {
                item.disable();
            }
        });

        var iframe = document.createElement('iframe');
        iframe.name = Ext.id();
        iframe.frameBorder = '0';

        iframe.src = Ext.isIE ? Ext.SSL_SECURE_URL : "javascript:;";

        this.wrap.dom.appendChild(iframe);

        this.iframe = iframe;

        this.initFrame();

        if (this.autoMonitorDesignMode !== false) {
            this.monitorTask = Ext.TaskMgr.start({
                run: this.checkDesignMode,
                scope: this,
                interval: 100
            });
        }

        if (!this.width) {
            var sz = this.el.getSize();
            this.setSize(sz.width, this.height || sz.height);
        }
    },

    initFrame: function() {
        this.doc = this.getDoc();
        this.win = this.getWin();

        this.doc.open();
        this.doc.write(this.getDocMarkup());
        this.doc.close();

        var task = {
            run: function() {
                if (this.doc.body || this.doc.readyState == 'complete') {
                    Ext.TaskMgr.stop(task);
                    this.doc.designMode = "on";
                    this.initEditor.defer(10, this);
                }
            },
            interval: 10,
            duration: 10000,
            scope: this
        };
        Ext.TaskMgr.start(task);
    },


    checkDesignMode: function() {
        if (this.wrap && this.wrap.dom.offsetWidth) {
            var doc = this.getDoc();
            if (!doc) {
                return;
            }
            if (!doc.editorInitialized || String(doc.designMode).toLowerCase() != 'on') {
                this.initFrame();
            }
        }
    },


    onResize: function(w, h) {
        Ext.form.HtmlEditor.superclass.onResize.apply(this, arguments);
        if (this.el && this.iframe) {
            if (typeof w == 'number') {
                var aw = w - this.wrap.getFrameWidth('lr');
                this.el.setWidth(this.adjustWidth('textarea', aw));
                this.iframe.style.width = aw + 'px';
            }
            if (typeof h == 'number') {
                var ah = h - this.wrap.getFrameWidth('tb') - this.tb.el.getHeight() - (this.tb2 ? this.tb2.el.getHeight() : 0);
                this.el.setHeight(this.adjustWidth('textarea', ah));
                this.iframe.style.height = ah + 'px';
                if (this.doc) {
                    this.getEditorBody().style.height = (ah - (this.iframePad * 2)) + 'px';
                }
            }
        }
    },


    toggleSourceEdit: function(sourceEditMode) {
        if (sourceEditMode === undefined) {
            sourceEditMode = !this.sourceEditMode;
        }
        this.sourceEditMode = sourceEditMode === true;
        var btn = this.tb.items.get('sourceedit');
        if (btn.pressed !== this.sourceEditMode) {
            btn.toggle(this.sourceEditMode);
            return;
        }
        if (this.sourceEditMode) {
            this.tb.items.each(function(item) {
                if (item.itemId != 'sourceedit') {
                    item.disable();
                }
            });
            if (this.tb2) {
                this.tb2.items.each(function(item) {
                    item.disable();
                });
            }
            this.syncValue();
            this.iframe.className = 'x-hidden';
            this.el.removeClass('x-hidden');
            this.el.dom.removeAttribute('tabIndex');
            this.el.focus();
        } else {
            if (this.initialized) {
                this.tb.items.each(function(item) {
                    item.enable();
                });
                if (this.tb2) {
                    this.tb2.items.each(function(item) {
                        item.enable();
                    });
                }
            }
            this.pushValue();
            this.iframe.className = '';
            this.el.addClass('x-hidden');
            this.el.dom.setAttribute('tabIndex', -1);
            this.deferFocus();
        }
        var lastSize = this.lastSize;
        if (lastSize) {
            delete this.lastSize;
            this.setSize(lastSize);
        }
        this.fireEvent('editmodechange', this, this.sourceEditMode);
    },


    createLink: function() {

        function ok() {
            if (url.getValue() != 'http:/' + '/') {
                var a = 1;

                var linkHtml = '<a href="' + url.getValue() + '" target="' + target.getValue() + '">' + title.getValue() + '</a>'

                if (Ext.isIE) {
                    this.win.focus();
                    if (range) {
                        range.collapse(true);
                        range.pasteHTML(linkHtml);
                        this.syncValue();
                        this.deferFocus();
                    }
                } else this.insertAtCursor(linkHtml);
                win.close();
            }
        }

        function testLink() {
            if (url.getValue() != '' && url.getValue() != 'http://')
                window.open(url.getValue())
        }

        var range = this.doc.selection.createRange();

        var url = new Ext.form.TextField({ fieldLabel: 'Url', name: 'href', anchor: '100%', value: 'http:/' + '/' });
        var target = new Ext.form.TextField({ fieldLabel: 'Mål', name: 'target', anchor: '100%', value: 'blank' });
        var title = new Ext.form.TextField({ fieldLabel: 'Titel', name: 'name', anchor: '100%', value: range.text });
        var form = new Ext.form.FormPanel({
            labelAlign: 'top',
            items: [title, url, target]
        });

        var mgr = new Ext.WindowGroup();
        mgr.zseed = 10000;

        var win = new Ext.Window({
            title: 'Skapa länk',
            width: 290,
            height: 250,
            layout: 'fit',
            hideBorders: true,
            bodyStyle: 'padding: 10px; background: white',
            manager: mgr,
            modal: true,
            items: [
                form
            ],
            tbar: [
                { text: 'Testa länk', iconCls: 'icon-folder-link', qtip: 'Öppnar angiven länk i nytt fönster', handler: testLink }
            ],
            bbar: new Ext.StatusBar({
                text: '',
                items: [
                    { text: 'OK', iconCls: 'icon-ok', handler: ok, scope: this },
                    { text: 'Avbryt', iconCls: 'icon-cancel', handler: function() { win.close(); } }
                ]
            })
        });

        win.show();


        //if (init) init.call(this, form.form);        
    },


    adjustSize: Ext.BoxComponent.prototype.adjustSize,


    getResizeEl: function() {
        return this.wrap;
    },


    getPositionEl: function() {
        return this.wrap;
    },


    initEvents: function() {
        this.originalValue = this.getValue();
    },


    markInvalid: Ext.emptyFn,


    clearInvalid: Ext.emptyFn,


    setValue: function(v) {
        Ext.form.HtmlEditor.superclass.setValue.call(this, v);
        this.pushValue();
    },


    cleanHtml: function(html) {
        html = String(html);
        if (html.length > 5) {
            if (Ext.isSafari) {
                html = html.replace(/\sclass="(?:Apple-style-span|khtml-block-placeholder)"/gi, '');
            }
        }
        if (html == '&nbsp;') {
            html = '';
        }
        return html;
    },


    syncValue: function() {
        if (this.initialized) {
            var bd = this.getEditorBody();
            var html = bd.innerHTML;
            if (Ext.isSafari) {
                var bs = bd.getAttribute('style');
                var m = bs.match(/text-align:(.*?);/i);
                if (m && m[1]) {
                    html = '<div style="' + m[0] + '">' + html + '</div>';
                }
            }
            html = this.cleanHtml(html);
            if (this.fireEvent('beforesync', this, html) !== false) {
                this.el.dom.value = html;
                this.fireEvent('sync', this, html);
            }
        }
    },


    pushValue: function() {
        if (this.initialized) {
            var v = this.el.dom.value;
            if (!this.activated && v.length < 1) {
                v = '&nbsp;';
            }
            if (this.fireEvent('beforepush', this, v) !== false) {
                this.getEditorBody().innerHTML = v;
                this.fireEvent('push', this, v);
            }
        }
    },


    deferFocus: function() {
        this.focus.defer(10, this);
    },


    focus: function() {
        if (this.win && !this.sourceEditMode) {
            this.win.focus();
        } else {
            this.el.focus();
        }
    },


    initEditor: function() {
        var dbody = this.getEditorBody();
        var ss = this.el.getStyles('font-size', 'font-family', 'background-image', 'background-repeat');
        ss['background-attachment'] = 'fixed';
        dbody.bgProperties = 'fixed';

        Ext.DomHelper.applyStyles(dbody, ss);

        if (this.doc) {
            try {
                Ext.EventManager.removeAll(this.doc);
            } catch (e) { }
        }

        this.doc = this.getDoc();

        Ext.EventManager.on(this.doc, {
            'mousedown': this.onEditorEvent,
            'dblclick': this.onEditorEvent,
            'click': this.onEditorEvent,
            'keyup': this.onEditorEvent,
            buffer: 100,
            scope: this
        });

        if (Ext.isGecko) {
            Ext.EventManager.on(this.doc, 'keypress', this.applyCommand, this);
        }
        if (Ext.isIE || Ext.isSafari || Ext.isOpera) {
            Ext.EventManager.on(this.doc, 'keydown', this.fixKeys, this);
        }
        this.initialized = true;

        this.fireEvent('initialize', this);

        this.doc.editorInitialized = true;

        this.pushValue();
    },


    onDestroy: function() {
        if (this.monitorTask) {
            Ext.TaskMgr.stop(this.monitorTask);
        }
        if (this.rendered) {
            this.tb.items.each(function(item) {
                if (item.menu) {
                    item.menu.removeAll();
                    if (item.menu.el) {
                        item.menu.el.destroy();
                    }
                }
                item.destroy();
            });
            this.wrap.dom.innerHTML = '';
            this.wrap.remove();
        }
    },


    onFirstFocus: function() {
        this.activated = true;
        this.tb.items.each(function(item) {
            item.enable();
        });
        if (Ext.isGecko) {
            this.win.focus();
            var s = this.win.getSelection();
            if (!s.focusNode || s.focusNode.nodeType != 3) {
                var r = s.getRangeAt(0);
                r.selectNodeContents(this.getEditorBody());
                r.collapse(true);
                this.deferFocus();
            }
            try {
                this.execCmd('useCSS', true);
                this.execCmd('styleWithCSS', false);
            } catch (e) { }
        }
        this.fireEvent('activate', this);
    },


    adjustFont: function(btn) {
        var adjust = btn.itemId == 'increasefontsize' ? 1 : -1;

        var v = parseInt(this.doc.queryCommandValue('FontSize') || 2, 10);
        if (Ext.isSafari3 || Ext.isAir) {


            if (v <= 10) {
                v = 1 + adjust;
            } else if (v <= 13) {
                v = 2 + adjust;
            } else if (v <= 16) {
                v = 3 + adjust;
            } else if (v <= 18) {
                v = 4 + adjust;
            } else if (v <= 24) {
                v = 5 + adjust;
            } else {
                v = 6 + adjust;
            }
            v = v.constrain(1, 6);
        } else {
            if (Ext.isSafari) {
                adjust *= 2;
            }
            v = Math.max(1, v + adjust) + (Ext.isSafari ? 'px' : 0);
        }
        this.execCmd('FontSize', v);
    },


    onEditorEvent: function(e) {
        this.updateToolbar();
    },



    updateToolbar: function() {

        if (!this.activated) {
            this.onFirstFocus();
            return;
        }

        var btns = this.tb.items.map, doc = this.doc;

        if (this.enableFont && !Ext.isSafari2) {
            var name = (this.doc.queryCommandValue('FontName') || this.defaultFont).toLowerCase();
            if (name != this.fontSelect.dom.value) {
                this.fontSelect.dom.value = name;
            }
        }
        if (this.enableParagraphFormat) {

            var tag = this.doc.queryCommandValue('formatblock').toLowerCase();
            if (Ext.isIE) {
                var mapping = [];
                mapping['rubrik 1'] = '<h1>';
                mapping['rubrik 2'] = '<h2>';
                mapping['rubrik 3'] = '<h3>';
                mapping['normal'] = '<p>';
                tag = mapping[tag];
            }
            if (tag != this.paragraphFormatSelect.dom.value) {
                this.paragraphFormatSelect.dom.value = tag;
            }
            //alert(doc.queryCommandValue('formatblock') + ' - ' + doc.queryCommandState('formatblock'));
        }
        if (this.enableFormat) {
            btns.bold.toggle(doc.queryCommandState('bold'));
            btns.italic.toggle(doc.queryCommandState('italic'));
            btns.underline.toggle(doc.queryCommandState('underline'));
        }
        if (this.enableAlignments) {
            btns.justifyleft.toggle(doc.queryCommandState('justifyleft'));
            btns.justifycenter.toggle(doc.queryCommandState('justifycenter'));
            btns.justifyright.toggle(doc.queryCommandState('justifyright'));
        }
        if (!Ext.isSafari2 && this.enableLists) {
            btns.insertorderedlist.toggle(doc.queryCommandState('insertorderedlist'));
            btns.insertunorderedlist.toggle(doc.queryCommandState('insertunorderedlist'));
        }

        Ext.menu.MenuMgr.hideAll();

        this.syncValue();
    },


    relayBtnCmd: function(btn) {
        this.relayCmd(btn.itemId);
    },


    relayCmd: function(cmd, value) {
        (function() {
            this.focus();
            this.execCmd(cmd, value);
            this.updateToolbar();
        }).defer(10, this);
    },


    execCmd: function(cmd, value) {
        this.doc.execCommand(cmd, false, value === undefined ? null : value);
        this.syncValue();
    },


    applyCommand: function(e) {
        if (e.ctrlKey) {
            var c = e.getCharCode(), cmd;
            if (c > 0) {
                c = String.fromCharCode(c);
                switch (c) {
                    case 'b':
                        cmd = 'bold';
                        break;
                    case 'i':
                        cmd = 'italic';
                        break;
                    case 'u':
                        cmd = 'underline';
                        break;
                }
                if (cmd) {
                    this.win.focus();
                    this.execCmd(cmd);
                    this.deferFocus();
                    e.preventDefault();
                }
            }
        }
    },


    insertAtCursor: function(text) {
        if (!this.activated) {
            return;
        }
        if (Ext.isIE) {
            this.win.focus();
            var r = this.doc.selection.createRange();
            if (r) {
                r.collapse(true);
                r.pasteHTML(text);
                this.syncValue();
                this.deferFocus();
            }
        } else if (Ext.isGecko || Ext.isOpera) {
            this.win.focus();
            this.execCmd('InsertHTML', text);
            this.deferFocus();
        } else if (Ext.isSafari) {
            this.execCmd('InsertText', text);
            this.deferFocus();
        }
    },


    fixKeys: function() {
        if (Ext.isIE) {
            return function(e) {
                var k = e.getKey(), r;
                if (k == e.TAB) {
                    e.stopEvent();
                    r = this.doc.selection.createRange();
                    if (r) {
                        r.collapse(true);
                        r.pasteHTML('&nbsp;&nbsp;&nbsp;&nbsp;');
                        this.deferFocus();
                    }
                } /*else if (k == e.ENTER) {
                    r = this.doc.selection.createRange();
                    if (r) {
                        var target = r.parentElement();
                        if (!target || target.tagName.toLowerCase() != 'li') {
                            e.stopEvent();
                            r.pasteHTML('<br />');
                            r.collapse(false);
                            r.select();
                        }
                    }
                }*/
            };
        } else if (Ext.isOpera) {
            return function(e) {
                var k = e.getKey();
                if (k == e.TAB) {
                    e.stopEvent();
                    this.win.focus();
                    this.execCmd('InsertHTML', '&nbsp;&nbsp;&nbsp;&nbsp;');
                    this.deferFocus();
                }
            };
        } else if (Ext.isSafari) {
            return function(e) {
                var k = e.getKey();
                if (k == e.TAB) {
                    e.stopEvent();
                    this.execCmd('InsertText', '\t');
                    this.deferFocus();
                }
            };
        }
    } (),


    getToolbar: function() {
        return this.tb;
    },


    buttonTips: {
        bold: {
            title: 'Fetstil (Ctrl+B)',
            text: 'Gör markerad text fet.',
            cls: 'x-html-editor-tip'
        },
        italic: {
            title: 'Kursiv (Ctrl+I)',
            text: 'Gör markerad text kursiv.',
            cls: 'x-html-editor-tip'
        },
        underline: {
            title: 'Understruken (Ctrl+U)',
            text: 'Stryker under markerad text.',
            cls: 'x-html-editor-tip'
        },
        increasefontsize: {
            title: 'Förstora teckensnitt',
            text: 'Ökar textstorleken.',
            cls: 'x-html-editor-tip'
        },
        decreasefontsize: {
            title: 'Förminska teckensnitt',
            text: 'Minskar textstorleken.',
            cls: 'x-html-editor-tip'
        },
        backcolor: {
            title: 'Markeringsfärg för text',
            text: 'Ändrar bakgrundsfärgen för markerad text.',
            cls: 'x-html-editor-tip'
        },
        forecolor: {
            title: 'Teckenfärg',
            text: 'Ändrar textfärgen för markerad text.',
            cls: 'x-html-editor-tip'
        },
        justifyleft: {
            title: 'Vänsterjustera text',
            text: 'Vänsterjusterar markerad text.',
            cls: 'x-html-editor-tip'
        },
        justifycenter: {
            title: 'Centrera text',
            text: 'Centrerar markerad text.',
            cls: 'x-html-editor-tip'
        },
        justifyright: {
            title: 'Högerjustera text',
            text: 'Högerjusterar markerad text.',
            cls: 'x-html-editor-tip'
        },
        insertunorderedlist: {
            title: 'Punktlista',
            text: 'Skapa en punktlista.',
            cls: 'x-html-editor-tip'
        },
        insertorderedlist: {
            title: 'Numrerad lista',
            text: 'Skapa en numrerad lista.',
            cls: 'x-html-editor-tip'
        },
        createlink: {
            title: 'Hyperlänk',
            text: 'Gör markerad text till en hyperlänk.',
            cls: 'x-html-editor-tip'
        },
        sourceedit: {
            title: 'Redigera HTML',
            text: 'Växlar till redigering av bakomliggande HTML-kod.',
            cls: 'x-html-editor-tip'
        }
    }
});
Ext.reg('htmleditor', LUL.HtmlEditor);

Ext.override(Ext.form.Field, {
    markInvalid: function(msg) {
        if (!this.rendered || this.preventMark) {
            return;
        }
        var markEl = this.markEl || this.el;
        markEl.addClass(this.invalidClass);
        msg = msg || this.invalidText;
        switch (this.msgTarget) {
            case 'qtip':
                markEl.dom.qtip = msg;
                markEl.dom.qclass = 'x-form-invalid-tip';
                if (Ext.QuickTips) {
                    Ext.QuickTips.enable();
                }
                break;
            case 'title':
                markEl.dom.title = msg;
                break;
            case 'under':
                if (!this.errorEl) {
                    var elp = this.getErrorCt();
                    if (!elp) {
                        markEl.dom.title = msg;
                        break;
                    }
                    this.errorEl = elp.createChild({ cls: 'x-form-invalid-msg' });
                    this.errorEl.setWidth(elp.getWidth(true) - 20);
                }
                this.errorEl.update(msg);
                Ext.form.Field.msgFx[this.msgFx].show(this.errorEl, this);
                break;
            case 'side':
                if (!this.errorIcon) {
                    var elp = this.getErrorCt();
                    if (!elp) {
                        markEl.dom.title = msg;
                        break;
                    }
                    this.errorIcon = elp.createChild({ cls: 'x-form-invalid-icon' });
                }
                this.alignErrorIcon();
                this.errorIcon.dom.qtip = msg;
                this.errorIcon.dom.qclass = 'x-form-invalid-tip';
                this.errorIcon.show();
                this.on('resize', this.alignErrorIcon, this);
                break;
            default:
                var t = Ext.getDom(this.msgTarget);
                t.innerHTML = msg;
                t.style.display = this.msgDisplay;
                break;
        }
        this.fireEvent('invalid', this, msg);
    },
    clearInvalid: function() {
        if (!this.rendered || this.preventMark) {
            return;
        }
        var markEl = this.markEl || this.el;
        markEl.removeClass(this.invalidClass);
        switch (this.msgTarget) {
            case 'qtip':
                markEl.dom.qtip = '';
                break;
            case 'title':
                markEl.dom.title = '';
                break;
            case 'under':
                if (this.errorEl) {
                    Ext.form.Field.msgFx[this.msgFx].hide(this.errorEl, this);
                } else {
                    markEl.dom.title = '';
                }
                break;
            case 'side':
                if (this.errorIcon) {
                    this.errorIcon.dom.qtip = '';
                    this.errorIcon.hide();
                    this.un('resize', this.alignErrorIcon, this);
                } else {
                    markEl.dom.title = '';
                }
                break;
            default:
                var t = Ext.getDom(this.msgTarget);
                t.innerHTML = '';
                t.style.display = 'none';
                break;
        }
        this.fireEvent('valid', this);
    },
    alignErrorIcon: function() {
        this.errorIcon.alignTo(this.markEl || this.el, 'tl-tr', [2, 0]);
    }
});

Ext.override(Ext.form.Checkbox, {
    onRender: function(ct, position) {
        Ext.form.Checkbox.superclass.onRender.call(this, ct, position);
        if (this.inputValue !== undefined) {
            this.el.dom.value = this.inputValue;
        }
        this.el.removeClass(this.baseCls);
        //this.el.addClass('x-hidden');
        this.innerWrap = this.el.wrap({
            //tabIndex: this.tabIndex,
            cls: this.baseCls + '-wrap-inner'
        });
        this.wrap = this.innerWrap.wrap({ cls: this.baseCls + '-wrap' });
        this.imageEl = this.innerWrap.createChild({
            tag: 'img',
            src: Ext.BLANK_IMAGE_URL,
            cls: this.baseCls
        });
        if (this.boxLabel) {
            this.labelEl = this.innerWrap.createChild({
                tag: 'label',
                htmlFor: this.el.id,
                cls: 'x-form-cb-label',
                html: this.boxLabel
            });
        }
        //this.imageEl = this.innerWrap.createChild({
        //tag: 'img',
        //src: Ext.BLANK_IMAGE_URL,
        //cls: this.baseCls
        //}, this.el);
        if (this.checked) {
            this.setValue(true);
        } else {
            this.checked = this.el.dom.checked;
        }
        this.originalValue = this.checked;
        this.markEl = this.innerWrap;
    },
    afterRender: function() {
        Ext.form.Checkbox.superclass.afterRender.call(this);
        //this.wrap[this.checked ? 'addClass' : 'removeClass'](this.checkedCls);
        this.imageEl[this.checked ? 'addClass' : 'removeClass'](this.checkedCls);
    },
    initCheckEvents: function() {
        //this.innerWrap.removeAllListeners();
        this.innerWrap.addClassOnOver(this.overCls);
        this.innerWrap.addClassOnClick(this.mouseDownCls);
        this.innerWrap.on('click', this.onClick, this);
        //this.innerWrap.on('keyup', this.onKeyUp, this);
        if (this.validationEvent !== false) {
            this.el.on(this.validationEvent, this.validate, this, { buffer: this.validationDelay });
        }
    },
    onFocus: function(e) {
        Ext.form.Checkbox.superclass.onFocus.call(this, e);
        //this.el.addClass(this.focusCls);
        this.innerWrap.addClass(this.focusCls);
    },
    onBlur: function(e) {
        Ext.form.Checkbox.superclass.onBlur.call(this, e);
        //this.el.removeClass(this.focusCls);
        this.innerWrap.removeClass(this.focusCls);
    },
    onClick: function(e) {
        if (e.getTarget().htmlFor != this.el.dom.id) {
            if (e.getTarget() != this.el.dom) {
                this.el.focus();
            }
            if (!this.disabled && !this.readOnly) {
                this.toggleValue();
            }
        }
        //e.stopEvent();
    },
    onEnable: Ext.form.Checkbox.superclass.onEnable,
    onDisable: Ext.form.Checkbox.superclass.onDisable,
    onKeyUp: undefined,
    setValue: function(v) {
        var checked = this.checked;
        this.checked = (v === true || v === 'true' || v == '1' || String(v).toLowerCase() == 'on');
        if (this.rendered) {
            this.el.dom.checked = this.checked;
            this.el.dom.defaultChecked = this.checked;
            //this.wrap[this.checked ? 'addClass' : 'removeClass'](this.checkedCls);
            this.imageEl[this.checked ? 'addClass' : 'removeClass'](this.checkedCls);
        }
        if (checked != this.checked) {
            this.fireEvent("check", this, this.checked);
            if (this.handler) {
                this.handler.call(this.scope || this, this, this.checked);
            }
        }
    },
    getResizeEl: function() {
        //if(!this.resizeEl){
        //this.resizeEl = Ext.isSafari ? this.wrap : (this.wrap.up('.x-form-element', 5) || this.wrap);
        //}
        //return this.resizeEl;
        return this.wrap;
    },
    markInvalid: Ext.form.Checkbox.superclass.markInvalid,
    clearInvalid: Ext.form.Checkbox.superclass.clearInvalid,
    validationEvent: 'click',
    validateOnBlur: false,
    validateValue: function(value) {
        if (this.vtype) {
            var vt = Ext.form.VTypes;
            if (!vt[this.vtype](value, this)) {
                this.markInvalid(this.vtypeText || vt[this.vtype + 'Text']);
                return false;
            }
        }
        if (typeof this.validator == "function") {
            var msg = this.validator(value);
            if (msg !== true) {
                this.markInvalid(msg);
                return false;
            }
        }
        return true;
    }
});
Ext.override(Ext.form.Radio, {
    checkedCls: 'x-form-radio-checked',
    markInvalid: Ext.form.Radio.superclass.markInvalid,
    clearInvalid: Ext.form.Radio.superclass.clearInvalid
});
