﻿

/* JEditor*/

if (jQuery) (function ($) {
    /**
    * @constructor
    * @private
    */
    var editor = function (element, options) {
        this.init(element, options);
    };

    var innerDocument = function (elts) {
        var element = $(elts).get(0);

        if (element.nodeName.toLowerCase() == 'iframe') {
            return element.contentWindow.document;
            /*
            return ( $.browser.msie )
            ? document.frames[element.id].document
            : element.contentWindow.document // contentDocument;
            */
        }
        return element;
    };

    var documentSelection = function () {
        var element = this.get(0);

        if (element.contentWindow.document.selection) {
            return element.contentWindow.document.selection.createRange().text;
        }
        else {
            return element.contentWindow.getSelection().toString();
        }
    };
    function htmlEncode(value) {
        return $('<div/>').text(value).html();
    }

    function htmlDecode(value) {
        return $('<div/>').html(value).text();
    }

    $.fn.jEditor = function (options) {
        if (arguments.length > 0 && arguments[0].constructor == String) {
            var action = arguments[0].toString();
            var params = [];

            if (action == 'enabled') {
                return this.data('jEditor') !== null;
            }
            for (var i = 1; i < arguments.length; i++) {
                params[i - 1] = arguments[i];
            }
            var retValue = null;
            this.each(function () {
                $.data(this, 'jEditor').designMode();
                retValue = editor[action].apply(this, params);
            });
            return retValue;
        }

        if (this.data('jEditor')) {
            return this;
        }

        var controls = {};

        /**
        * If the user set custom controls, we catch it, and merge with the
        * defaults controls later.
        */

        if (options && options.controls) {
            controls = options.controls;
            delete options.controls;
        }

        options = $.extend({}, $.fn.jEditor.defaults, options);
        options.controls = $.extend(true, options.controls, $.fn.jEditor.controls);
        for (var control in controls) {
            if (control in options.controls) {
                $.extend(options.controls[control], controls[control]);
            }
            else {
                options.controls[control] = controls[control];
            }
        }

        // not break the chain
        return this.each(function () {
            new editor(this, options);
        });
    };

    $.fn.jEditor.defaults = {
        html: '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">STYLE_SHEET</head><body style="margin: 0px;">INITIAL_CONTENT</body></html>',
        formTableHtml: '<form class="jEditor"><fieldset><legend>Insert table</legend><label>Count of columns: <input type="text" name="colCount" value="3" /></label><label><br />Count of rows: <input type="text" name="rowCount" value="3" /></label><input type="submit" class="button" value="Insert table" /> <input type="reset" value="Cancel" /></fieldset></form>',
        formImageHtml: '<form class="jEditor"><fieldset><legend>Insert Image</legend><label>Image URL: <input type="text" name="url" value="http://" /></label><label>Image Title: <input type="text" name="imagetitle" value="" /></label><label>Image Description: <input type="text" name="description" value="" /></label><input type="submit" class="button" value="Insert Image" /> <input type="reset" value="Cancel" /></fieldset></form>',
        formWidth: 440,
        formHeight: 270,
        tableFiller: 'Tablo',
        fileUrl: 'undefined',
        css: {},
        debug: false,
        autoSave: true,
        rmUnwantedBr: true,
        brIE: true,
        iFrameClass: null,
        messages:
                {
                    nonSelection: 'Bağlantı oluşturacağınız yazıyı seçiniz!'
                },
        events: {},
        controls: {},
        resizeOptions: false
    };
    $.fn.jEditor.controls = {
        bold: {
            visible: true,
            tags: ['b', 'strong'],
            css: {
                fontWeight: 'bold'
            },
            tooltip: 'Kalın'
        },
        italic: {
            visible: true,
            tags: ['i', 'em'],
            css: {
                fontStyle: 'italic'
            },
            tooltip: 'İtalik'
        },
        strikeThrough: {
            visible: true,
            tags: ['s', 'strike'],
            css: {
                textDecoration: 'line-through'
            },
            tooltip: 'Üzeri Çizili'
        },
        underline: {
            visible: true,
            tags: ['u'],
            css: {
                textDecoration: 'underline'
            },
            tooltip: 'ALtı Çizili'
        },
        justifyLeft: {
            visible: true,
            groupIndex: 1,
            css: {
                textAlign: 'left'
            },
            tooltip: 'Sola Hizala'
        },
        justifyCenter: {
            visible: true,
            tags: ['center'],
            css: {
                textAlign: 'center'
            },
            tooltip: 'Ortaya Hizala'
        },
        justifyRight: {
            visible: true,
            css: {
                textAlign: 'right'
            },
            tooltip: 'Sağa Hizala'
        },
        justifyFull: {
            visible: true,
            css: {
                textAlign: 'justify'
            },
            tooltip: 'Tam Hizala'
        },
        indent: {
            groupIndex: 2,
            visible: true,
            tooltip: 'Sağa Boşluk Ekle'
        },
        outdent: {
            visible: true,
            tooltip: 'Sağdan Boşluk Sil'
        },
        subscript: {
            groupIndex: 3,
            visible: true,
            tags: ['sub'],
            tooltip: 'Altyazı'
        },
        superscript: {
            visible: true,
            tags: ['sup'],
            tooltip: 'Üstyazı'
        },
        undo: {
            groupIndex: 4,
            visible: true,
            tooltip: 'Geri Al'
        },
        redo: {
            visible: true,
            tooltip: 'İleri Al'
        },
        insertOrderedList: {
            groupIndex: 5,
            visible: true,
            tags: ['ol'],
            tooltip: 'Sıralı Liste Ekle'
        },
        insertUnorderedList: {
            visible: true,
            tags: ['ul'],
            tooltip: 'Sırasız Liste Ekle'
        },
        insertHorizontalRule: {
            visible: true,
            tags: ['hr'],
            tooltip: 'Yatay Çizgi Ekle'
        },
        createLink: {
            groupIndex: 6,
            visible: true,
            exec: function () {
                var selection = documentSelection.call($(this.editor));

                if (selection && selection.length > 0) {
                    if ($.browser.msie) {
                        this.focus();
                        this.editorDoc.execCommand('createLink', true, null);
                    }
                    else {
                        var szURL = prompt('URL', 'http://');
                        if (szURL && szURL.length > 0) {
                            this.editorDoc.execCommand('unlink', false, null);
                            this.editorDoc.execCommand('createLink', false, szURL);
                        }
                    }
                }
                else if (this.options.messages.nonSelection) {
                    alert(this.options.messages.nonSelection);
                }
            },
            tags: ['a'],
            tooltip: 'Bağlantı Oluştur'
        },
        insertImage: {
            visible: true,
            exec: function () {
                var self = this;
                if ($.fancybox) {

                    $.fancybox({ height: '75%', width: '75%', autoScale: false, href: this.options.fileUrl, type: 'iframe', onCleanup:
                    function () {
                        item = $('#fancybox-frame').contents().find('.selectedFile');

                        if (item.size() > 0) {
                            var szURL = item.attr("href");
                            var title = "";
                            var description = "";
                            var img = "<img src='" + szURL + "' title='" + title + "' alt='" + description + "' />";
                            self.insertHtml(img);
                        }
                    }
                    });


                }
                else {
                    if ($.browser.msie) {
                        this.focus();
                        this.editorDoc.execCommand('insertImage', true, null);
                    }
                    else {
                        var szURL = prompt('URL', 'http://');
                        if (szURL && szURL.length > 0) {
                            this.editorDoc.execCommand('insertImage', false, szURL);
                        }
                    }
                }



            },
            tags: ['img'],
            tooltip: 'Resim Ekle'
        },
        insertTable: {
            visible: true,
            exec: function () {
                var self = this;
                if ($.fn.modal) {
                    $.modal($.fn.jEditor.defaults.formTableHtml, {
                        onShow: function (dialog) {
                            $('input:submit', dialog.data).click(function (e) {
                                e.preventDefault();
                                var rowCount = $('input[name="rowCount"]', dialog.data).val();
                                var colCount = $('input[name="colCount"]', dialog.data).val();
                                self.insertTable(colCount, rowCount, $.fn.jEditor.defaults.tableFiller);
                                $.modal.close();
                            });
                            $('input:reset', dialog.data).click(function (e) {
                                e.preventDefault();
                                $.modal.close();
                            });
                        },
                        maxWidth: $.fn.jEditor.defaults.formWidth,
                        maxHeight: $.fn.jEditor.defaults.formHeight,
                        overlayClose: true
                    });
                }
                else {
                    if ($.fn.dialog) {
                        var dialog = $($.fn.jEditor.defaults.formTableHtml).appendTo('body');
                        dialog.dialog({
                            modal: true,
                            width: $.fn.jEditor.defaults.formWidth,
                            height: $.fn.jEditor.defaults.formHeight,
                            open: function (event, ui) {
                                $('input:submit', $(this)).click(function (e) {
                                    e.preventDefault();
                                    var rowCount = $('input[name="rowCount"]', dialog).val();
                                    var colCount = $('input[name="colCount"]', dialog).val();
                                    self.insertTable(colCount, rowCount, $.fn.jEditor.defaults.tableFiller);
                                    $(dialog).dialog("close");
                                });
                                $('input:reset', $(this)).click(function (e) {
                                    e.preventDefault();
                                    $(dialog).dialog("close");
                                });
                            },
                            close: function (event, ui) {
                                $(this).dialog("destroy");

                            }
                        });
                    }
                    else {
                        var colCount = prompt('Kolon Sayısı', '3');
                        var rowCount = prompt('Satır Sayısı', '3');
                        this.insertTable(colCount, rowCount, $.fn.jEditor.defaults.tableFiller);
                    }
                }
            },
            tags: ['table'],
            tooltip: 'Tablo Ekle'
        },
        h1: {
            visible: true,
            groupIndex: 7,
            className: 'h1',
            command: ($.browser.msie || $.browser.safari) ? 'FormatBlock' : 'heading',
            'arguments': ($.browser.msie || $.browser.safari) ? '<h1>' : 'h1',
            tags: ['h1'],
            tooltip: 'Başlık 1'
        },
        h2: {
            visible: true,
            className: 'h2',
            command: ($.browser.msie || $.browser.safari) ? 'FormatBlock' : 'heading',
            'arguments': ($.browser.msie || $.browser.safari) ? '<h2>' : 'h2',
            tags: ['h2'],
            tooltip: 'Başlık 2'
        },
        h3: {
            visible: true,
            className: 'h3',
            command: ($.browser.msie || $.browser.safari) ? 'FormatBlock' : 'heading',
            'arguments': ($.browser.msie || $.browser.safari) ? '<h3>' : 'h3',
            tags: ['h3'],
            tooltip: 'Başlık 3'
        },
        cut: {
            groupIndex: 8,
            visible: false,
            tooltip: 'Kes'
        },
        copy: {
            visible: false,
            tooltip: 'Kopyala'
        },
        paste: {
            visible: false,
            tooltip: 'Yapıştır'
        },
        increaseFontSize: {
            groupIndex: 9,
            visible: false && !($.browser.msie),
            tags: ['big'],
            tooltip: 'Yazı Boyutunu Arttır'
        },
        decreaseFontSize: {
            visible: false && !($.browser.msie),
            tags: ['small'],
            tooltip: 'Yazı Boyutunu Azalt'
        },
        removeFormat: {
            visible: true,
            exec: function () {
                if ($.browser.msie) {
                    this.focus();
                }
                this.editorDoc.execCommand('formatBlock', false, '<P>'); // remove headings
                this.editorDoc.execCommand('removeFormat', false, null);
                this.editorDoc.execCommand('unlink', false, null);
            },
            tooltip: 'Biçimlendirmeyi Kaldır'
        },
        html: {
            groupIndex: 10,
            visible: true,
            exec: function () {
                if (this.viewHTML) {
                    this.setContent($(this.original).val());
                    $(this.original).hide();
                    $(this.editor).show();
                }
                else {
                    var $ed = $(this.editor);
                    this.saveContent();
                    $(this.original).show();
                    $ed.hide();
                }

                this.viewHTML = !(this.viewHTML);
            },
            tooltip: 'Kaynak Görüntüle'
        },
        rtl: {
            visible: false,
            exec: function () {
                var selection = $(this.editor).documentSelection();
                if ($("<div />").append(selection).children().length > 0) {
                    selection = $(selection).attr("dir", "rtl");
                }
                else {
                    selection = $("<div />").attr("dir", "rtl").append(selection);
                }
                this.editorDoc.execCommand('inserthtml', false, $("<div />").append(selection).html());
            },
            tooltip: "Sağdan Sola"
        },
        ltr: {
            visible: false,
            exec: function () {
                var selection = $(this.editor).documentSelection();
                if ($("<div />").append(selection).children().length > 0) {
                    selection = $(selection).attr("dir", "ltr");
                }
                else {
                    selection = $("<div />").attr("dir", "ltr").append(selection);
                }
                this.editorDoc.execCommand('inserthtml', false, $("<div />").append(selection).html());
            },
            tooltip: "Soldan Sağa"
        }
    };

    $.extend(editor, {
        insertImage: function (szURL, attributes) {
            var self = $.data(this, 'jEditor');
            if (self.constructor == editor && szURL && szURL.length > 0) {
                if ($.browser.msie) {
                    self.focus();
                }
                if (attributes) {
                    self.editorDoc.execCommand('insertImage', false, '#jjEditor#');
                    var img = self.getElementByAttributeValue('img', 'src', '#jjEditor#');

                    if (img) {
                        img.src = szURL;

                        for (var attribute in attributes) {
                            img.setAttribute(attribute, attributes[attribute]);
                        }
                    }
                }
                else {
                    self.editorDoc.execCommand('insertImage', false, szURL);
                }
            }
            return this;
        },

        createLink: function (szURL) {
            var self = $.data(this, 'jEditor');

            if (self.constructor == editor && szURL && szURL.length > 0) {
                var selection = documentSelection.call($(self.editor));

                if (selection && selection.length > 0) {
                    if ($.browser.msie) {
                        self.focus();
                    }
                    self.editorDoc.execCommand('unlink', false, null);
                    self.editorDoc.execCommand('createLink', false, szURL);
                }
                else if (self.options.messages.nonSelection) {
                    alert(self.options.messages.nonSelection);
                }
            }
            return this;
        },

        insertHtml: function (szHTML) {
            var self = $.data(this, 'jEditor');
            self.insertHtml(szHTML);
            return this;
        },

        insertTable: function (colCount, rowCount, filler) {
            $.data(this, 'jEditor').insertTable(colCount, rowCount, filler);
            return this;
        },

        getContent: function () {
            var self = $.data(this, 'jEditor');
            return self.getContent();
        },

        setContent: function (newContent) {
            var self = $.data(this, 'jEditor');
            self.setContent(newContent);
            self.saveContent();
            return this;
        },

        clear: function () {
            var self = $.data(this, 'jEditor');
            self.setContent('');
            self.saveContent();
            return this;
        },

        removeFormat: function () {
            var self = $.data(this, 'jEditor');
            self.removeFormat();
            return this;
        },

        save: function () {
            var self = $.data(this, 'jEditor');
            self.saveContent();
            return this;
        },

        "document": function () {
            var self = $.data(this, 'jEditor');
            return $(self.editorDoc);
        },

        destroy: function () {
            var self = $.data(this, 'jEditor');
            self.destroy();
            return this;
        }
    });

    var addHoverClass = function () {
        $(this).addClass('jEditor-button-hover');
    };
    var removeHoverClass = function () {
        $(this).removeClass('jEditor-button-hover');
    };

    $.extend(editor.prototype, {
        original: null,
        options: {
    },

    element: null,
    editor: null,

    removeFormat: function () {
        if ($.browser.msie) {
            this.focus();
        }
        this.editorDoc.execCommand('removeFormat', false, null);
        this.editorDoc.execCommand('unlink', false, null);
        return this;
    },
    destroy: function () {
        // Remove bindings
        var $form = $(this.element).closest('form');
        $form.unbind('submit', this.autoSaveFunction)
                             .unbind('reset', this.resetFunction);
        $(this.element).remove();
        $.removeData(this.original, 'jEditor');
        $(this.original).show();
        return this;
    },
    focus: function () {
        this.editor.get(0).contentWindow.focus();
        return this;
    },

    init: function (element, options) {
        var self = this;

        this.editor = element;
        this.options = options || {
    };

    $.data(element, 'jEditor', this);

    var newX = element.width || element.clientWidth || 0;
    var newY = element.height || element.clientHeight || 0;

    if (element.nodeName.toLowerCase() == 'textarea') {
        this.original = element;

        if (newX === 0 && element.cols) {
            newX = (element.cols * 8) + 21;
            element.cols = 0;
        }
        if (newY === 0 && element.rows) {
            newY = (element.rows * 16) + 16;
            element.rows = 0;
        }
        newX = $(element).width();
        newY = $(element).height();
        this.editor = $(location.protocol == 'https:' ? '<iframe src="javascript:false;"></iframe>' : '<iframe></iframe>').attr('frameborder', '0');
        if (options.iFrameClass) {
            this.editor.addClass(iFrameClass);
        }
        else {
            this.editor.css({
                minHeight: (newY - 6).toString() + 'px',
                width: (newX - 8).toString() + 'px'
            });
            if ($.browser.msie) {
                this.editor.css('height', newY.toString() + 'px');
            }
        }

        /**
        * http://code.google.com/p/jjEditor/issues/detail?id=96
        */
        this.editor.attr('tabindex', $(element).attr('tabindex'));
    }

    var panel = this.panel = $('<ul role="menu" class="panel"></ul>');

    this.appendControls();
    this.element = $('<div></div>').addClass('jEditor').append(panel).append($('<div><!-- --></div>').css({
        clear: 'both'
    })).append(this.editor);

    if (!options.iFrameClass) {
        this.element.css({
            width: (newX > 0) ? newX.toString() + 'px' : '100%'
        });
    }

    $(element).hide().before(this.element);

    this.viewHTML = false;
    this.initialHeight = newY - 8;

    /**
    * @link http://code.google.com/p/jjEditor/issues/detail?id=52
    */
    this.initialContent = $(element).val();
    this.initFrame();

    this.autoSaveFunction = function () {
        self.saveContent(true);
    };

    this.resetFunction = function () {
        self.setContent(self.initialContent);
        self.saveContent();
    }

    if (this.options.resizeOptions && $.fn.resizable) {
        this.element.resizable($.extend(true, {
            alsoResize: this.editor
        }, this.options.resizeOptions));
    }

    var $form = $(element).closest('form');

    if (this.options.autoSave) {
        $form.submit(self.autoSaveFunction);
    }

    $form.bind('reset', self.resetFunction);
},

initFrame: function () {
    var self = this;
    var style = '';

    /**
    * @link http://code.google.com/p/jjEditor/issues/detail?id=14
    */
    if (this.options.css && this.options.css.constructor == String) {
        style = '<link rel="stylesheet" type="text/css" media="screen" href="' + this.options.css + '" />';
    }

    this.editorDoc = innerDocument(this.editor);
    this.editorDoc_designMode = false;

    this.designMode();

    this.editorDoc.open();
    this.editorDoc.write(
                        this.options.html
    /**
    * @link http://code.google.com/p/jjEditor/issues/detail?id=144
    */
                        .replace(/INITIAL_CONTENT/, function () {
                            return self.initialContent;
                        }).replace(/STYLE_SHEET/, function () {
                            return style;
                        }));
    this.editorDoc.close();

    if ($.browser.msie) {
        /**
        * Remove the horrible border it has on IE.
        */
        window.setTimeout(function () {
            $(self.editorDoc.body).css('border', 'none');
        }, 0);
    }

    $(this.editorDoc).click(function (event) {
        self.checkTargets(event.target ? event.target : event.srcElement);
    });

    /**
    * @link http://code.google.com/p/jjEditor/issues/detail?id=20
    */
    $(this.original).focus(function () {
        if ($(this).filter(':visible')) {
            return;
        }
        self.focus();
    });

    if (!$.browser.msie) {
        $(this.editorDoc).keydown(function (event) {
            if (event.ctrlKey) {
                switch (event.keyCode) {
                    case 66:
                        // Ctrl + B
                        this.execCommand('Bold', false, false);
                        return false;
                    case 73:
                        // Ctrl + I
                        this.execCommand('Italic', false, false);
                        return false;
                    case 85:
                        // Ctrl + U
                        this.execCommand('Underline', false, false);
                        return false;
                }
            }
            return true;
        });
    }
    else if (this.options.brIE) {
        $(this.editorDoc).keydown(function (event) {
            if (event.keyCode == 13) {
                var rng = self.getRange();
                rng.pasteHTML('<br />');
                rng.collapse(false);
                rng.select();
                return false;
            }
            return true;
        });
    }

    if (this.options.autoSave) {
        /**
        * @link http://code.google.com/p/jjEditor/issues/detail?id=11
        */
        var handler = function () {
            self.saveContent();
        };
        $(this.editorDoc).keydown(handler).keyup(handler).mousedown(handler).bind($.support.noCloneEvent ? "input" : "paste", handler);

    }

    if (this.options.css) {
        window.setTimeout(function () {
            if (self.options.css.constructor == String) {
                /**
                * $(self.editorDoc)
                * .find('head')
                * .append(
                *	 $('<link rel="stylesheet" type="text/css" media="screen" />')
                *	 .attr('href', self.options.css)
                * );
                */
            }
            else {
                $(self.editorDoc).find('body').css(self.options.css);
            }
        }, 0);
    }

    if (this.initialContent.length === 0) {
        this.setContent('');
    }

    $.each(this.options.events, function (key, handler) {
        $(self.editorDoc).bind(key, handler);
    });
    $(this.editorDoc.body).addClass('jEditor');
    if (this.options.events && this.options.events.save) {
        var handler = this.options.events.save;
        $(self.editorDoc).bind('keyup', handler);
        $(self.editorDoc).bind('change', handler);
        if ($.support.noCloneEvent) {
            $(self.editorDoc).bind("input", handler);
        } else {
            $(self.editorDoc).bind("paste", handler);
            $(self.editorDoc).bind("cut", handler);
        }
    }
},

designMode: function () {
    var attempts = 3;
    var runner;
    var self = this;
    var doc = this.editorDoc;
    runner = function () {
        if (innerDocument(self.editor) !== doc) {
            self.initFrame();
            return;
        }
        try {
            doc.designMode = 'on';
        }
        catch (e) {
        }
        attempts--;
        if (attempts > 0 && $.browser.mozilla) {
            setTimeout(runner, 100);
        }
    };
    runner();
    this.editorDoc_designMode = true;
},

getSelection: function () {
    return (window.getSelection) ? window.getSelection() : document.selection;
},

getRange: function () {
    var selection = this.getSelection();

    if (!selection) {
        return null;
    }

    return (selection.rangeCount > 0) ? selection.getRangeAt(0) : (selection.createRange ? selection.createRange() : null);
},

getContent: function () {
    return $(innerDocument(this.editor)).find('body').html();
},

setContent: function (newContent) {
    $(innerDocument(this.editor)).find('body').html(newContent);
    return this;
},
insertHtml: function (szHTML) {
    if (szHTML && szHTML.length > 0) {
        if ($.browser.msie) {
            this.focus();
            this.editorDoc.execCommand('insertImage', false, '#jjEditor#');
            var img = this.getElementByAttributeValue('img', 'src', '#jjEditor#');
            if (img) {
                $(img).replaceWith(szHTML);
            }
        }
        else {
            this.editorDoc.execCommand('insertHTML', false, szHTML);
        }
    }
    return this;
},
insertTable: function (colCount, rowCount, filler) {
    if (isNaN(rowCount) || isNaN(colCount) || rowCount === null || colCount === null) {
        return;
    }
    colCount = parseInt(colCount, 10);
    rowCount = parseInt(rowCount, 10);
    if (filler === null) {
        filler = '&nbsp;';
    }
    filler = '<td>' + filler + '</td>';
    var html = ['<table border="1" style="width: 100%;"><tbody>'];
    for (var i = rowCount; i > 0; i--) {
        html.push('<tr>');
        for (var j = colCount; j > 0; j--) {
            html.push(filler);
        }
        html.push('</tr>');
    }
    html.push('</tbody></table>');
    return this.insertHtml(html.join(''));
},
saveContent: function (encode) {
    if (this.original) {
        var content = this.getContent();

        if (this.options.rmUnwantedBr) {
            content = (content.substr(-4) == '<br>') ? content.substr(0, content.length - 4) : content;
        }
        if (encode)
            content = htmlEncode(content);
        $(this.original).val(content);
        if (this.options.events && this.options.events.save) {
            this.options.events.save.call(this);
        }
    }
    return this;
},

withoutCss: function () {
    if ($.browser.mozilla) {
        try {
            this.editorDoc.execCommand('styleWithCSS', false, false);
        }
        catch (e) {
            try {
                this.editorDoc.execCommand('useCSS', false, true);
            }
            catch (e2) {
            }
        }
    }
    return this;
},

appendMenu: function (cmd, args, className, fn, tooltip) {
    var self = this;
    args = args || [];

    return $('<li role="menuitem" UNSELECTABLE="on">' + (className || cmd) + '</li>').addClass(className || cmd).attr('title', tooltip).hover(addHoverClass, removeHoverClass).click(function () {
        if (fn) {
            fn.apply(self);
        }
        else {
            self.focus();
            self.withoutCss();
            self.editorDoc.execCommand(cmd, false, args);
        }
        if (self.options.autoSave) {
            self.saveContent();
        }
        this.blur();
    }).appendTo(this.panel);
},

appendMenuSeparator: function () {
    return $('<li role="separator" class="separator"></li>').appendTo(this.panel);
},
parseControls: function () {
    if (this.options.parseControls) {
        return this.options.parseControls.call(this);
    }
    return this.options.controls;
},
appendControls: function () {
    var controls = this.parseControls();
    var currentGroupIndex = 0;
    var hasVisibleControls = true; // to prevent separator before first item
    for (var name in controls) {
        var control = controls[name];
        if (control.groupIndex && currentGroupIndex != control.groupIndex) {
            currentGroupIndex = control.groupIndex;
            hasVisibleControls = false;
        }
        if (!control.visible) {
            continue;
        }
        if (!hasVisibleControls) {
            this.appendMenuSeparator();
            hasVisibleControls = true;
        }
        this.appendMenu(
                                        control.command || name,
                                        control['arguments'] || '',
                                        control.className || control.command || name || 'empty',
                                        control.exec,
                                        control.tooltip || control.command || name || ''
                                );
    }
},

checkTargets: function (element) {
    for (var name in this.options.controls) {
        var control = this.options.controls[name];
        var className = control.className || control.command || name || 'empty';

        $('.' + className, this.panel).removeClass('active');

        if (control.tags) {
            var elm = element;
            do {
                if (elm.nodeType != 1) {
                    break;
                }

                if ($.inArray(elm.tagName.toLowerCase(), control.tags) != -1) {
                    $('.' + className, this.panel).addClass('active');
                }
            } while ((elm = elm.parentNode));
        }

        if (control.css) {
            var el = $(element);

            do {
                if (el[0].nodeType != 1) {
                    break;
                }

                for (var cssProperty in control.css) {
                    if (el.css(cssProperty).toString().toLowerCase() == control.css[cssProperty]) {
                        $('.' + className, this.panel).addClass('active');
                    }
                }
            } while ((el = el.parent()));
        }
    }
},

getElementByAttributeValue: function (tagName, attributeName, attributeValue) {
    var elements = this.editorDoc.getElementsByTagName(tagName);

    for (var i = 0; i < elements.length; i++) {
        var value = elements[i].getAttribute(attributeName);

        if ($.browser.msie) { /** IE add full path, so I check by the last chars. */
            value = value.substr(value.length - attributeValue.length);
        }

        if (value == attributeValue) {
            return elements[i];
        }
    }

    return false;
}
});
})(jQuery);

