(function( $ )
{
  var Wysiwyg = function( element, options )
  {
    this.init(element, options);
  };

  $['fn']['document'] = function()
  {
    var element = this.get(0);

    if ( element.nodeName.toLowerCase() == 'iframe' )
    {
      return element.contentWindow.document;
    }
    return this;
  };

  $['fn']['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();
    }
  };

  $['fn']['wysiwyg'] = function( options )
  {
    if ( arguments.length > 0 && arguments[0].constructor == String )
    {
      var action = arguments[0].toString();
      var params = [];

      for ( var i = 1; i < arguments.length; i++ )
      {
        params[i - 1] = arguments[i];
      }
      if (action in Wysiwyg)
      {
        return this.each(function()
        {
          $.data(this, 'wysiwyg').designMode();

          Wysiwyg[action].apply(this, params);
        });
      }
      else
      {
        return this;
      }
    }

    var controls = {};

    if (options && options['controls'])
    {
      controls = options['controls'];
      delete options['controls'];
    }

    options = $.extend({
      "html": '<'+'?xml version="1.0" encoding="UTF-8"?'+'><!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>',
      "css": {},

      "debug": false,

      "autoSave" : true,  // http://code.google.com/p/jwysiwyg/issues/detail?id=11
      "rmUnwantedBr" : true,  // http://code.google.com/p/jwysiwyg/issues/detail?id=15
      "brIE" : true,

      "EnablePaste" : true,

      "controls" : {},
      "messages" : {}
    }, options);

    options['messages'] = $.extend(true, options['messages'], Wysiwyg['MSGS_EN']);
    options['controls'] = $.extend(true, options['controls'], Wysiwyg['TOOLBAR']);

    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 Wysiwyg(this, options);
    });
  };




  $.extend(Wysiwyg, {
    "insertImage" : function( szURL, attributes )
    {
      var self = $.data(this, 'wysiwyg');

      if ( self.constructor == Wysiwyg && szURL && szURL.length > 0 )
      {
        if ($.browser.msie)
        {
          self.focus();
        }
        if ( attributes )
        {
          self.editorDoc.execCommand('insertImage', false, '#jwysiwyg#');
          var img = self.getElementByAttributeValue('img', 'src', '#jwysiwyg#');

          if ( img )
          {
            img.src = szURL;

            for ( var attribute in attributes )
            {
              img.setAttribute(attribute, attributes[attribute]);
            }
          }
        }
        else
        {
          self.editorDoc.execCommand('insertImage', false, szURL);
        }
      }
    },

    "createLink" : function( szURL )
    {
      var self = $.data(this, 'wysiwyg');

      if ( self.constructor == Wysiwyg && szURL && szURL.length > 0 )
      {
        var selection = $(self.editor).documentSelection();

        if ( selection.length > 0 )
        {
          if ($.browser.msie)
          {
            self.focus();
          }
          self.editorDoc.execCommand('unlink', false, []);
          self.editorDoc.execCommand('createLink', false, szURL);
        }
        else if ( self.options.messages.nonSelection )
        {
          alert(self.options.messages.nonSelection);
        }
      }
    },

    "insertHtml" : function( szHTML )
    {
      var self = $.data(this, 'wysiwyg');

      if ( self.constructor == Wysiwyg && szHTML && szHTML.length > 0 )
      {
        self.focus();
        if ($.browser.msie)
        {
          self.editorDoc.execCommand('insertImage', false, '#jwysiwyg#');
          var img = self.getElementByAttributeValue('img', 'src', '#jwysiwyg#');
          if (img)
          {
            $(img).after(szHTML);
            $(img).remove();
          }

          var editorDoc = $(self.editor).document();
          if ( editorDoc.selection && editorDoc.selection.createRange )
          {
      			var range = editorDoc.selection.createRange();
      			setTimeout( function(){ self.saveContent(); range.select(); }, 0 ); 
          }
        }
        else
        {
          self.editorDoc.execCommand('insertHTML', false, szHTML);
        	setTimeout( function(){ self.saveContent(); $(self.editor).get(0).contentWindow.focus();}, 0 );
        }


      }
    },

    "setContent" : function( newContent )
    {
      var self = $.data(this, 'wysiwyg');
        self.setContent( newContent );
        self.saveContent();
    },

    "clear" : function()
    {
      var self = $.data(this, 'wysiwyg');
        self.setContent('');
        self.saveContent();
    },

    "MSGS_EN" : {
      "nonSelection" : 'Выделите текст, который хотите сделать ссылкой'
    },

    "TOOLBAR" : {
      "bold"          : { "visible" : true, "tags" : ['b', 'strong'], "css" : { "fontWeight" : 'bold' }, "tooltip" : "Bold" },
      "italic"        : { "visible" : true, "tags" : ['i', 'em'], "css" : { "fontStyle": 'italic' }, "tooltip" : "Italic" },
      "strikeThrough" : { "visible" : true, "tags" : ['s', 'strike'], "css" : { "textDecoration" : 'line-through' }, "tooltip" : "Strike-through" },
      "underline"     : { "visible" : true, "tags" : ['u'], "css" : { "textDecoration" : 'underline' }, "tooltip" : "Underline" },

      separator00 : { "visible": true, "separator": true },

      "justifyLeft"   : { "visible": true, "css": { "textAlign": 'left' }, "tooltip": "Justify Left" },
      "justifyCenter" : { "visible": true, "tags": ['center'], "css": { "textAlign": 'center' }, "tooltip": "Justify Center" },
      "justifyRight"  : { "visible": true, "css": { "textAlign": 'right' }, "tooltip": "Justify Right" },
      "justifyFull"   : { "visible": true, "css": { "textAlign": 'justify' }, "tooltip": "Justify Full" },

      separator01 : { "visible": true, "separator": true },

      "insertOrderedList"    : { "visible": true, "tags": ['ol'], "tooltip": "Insert Ordered List 1" },
      "insertUnorderedList"  : { "visible": true, "tags": ['ul'], "tooltip": "Insert Unordered List" },
      "insertHorizontalRule" : { "visible": true, "tooltip": "Sport812 Cut", "exec" : function()
        {
          var body = $(this.editorDoc.body);
          var text = body.html();

          if(text.match(/pixel-cut/ig))
          {
            alert('уже установлена область "под кат", удалите ее сначало');
            this.focus();
            return;
          }

          var szURL = prompt('Текст ссылки для вырезки', 'Читать дальше...');

          if(!szURL)
          {
            alert('Так не пойдет, вводи текст ссылки на вырезку!');
            return;
          }
//          var x = this;
//          var y = element;
          $(this.original).wysiwyg('insertHtml', '<img alt="#@#' + szURL + '" class="pixel-cut" src="/images/pixel.gif"/>');
        }
      },

      separator05 : { "separator": true },

      "createLink" : {
        "visible": true,
        "exec"   : function()
        {
          var selection = $(this.editor).documentSelection();

          if ( 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, []);
                this.editorDoc.execCommand('createLink', false, szURL);
              }
            }
          }
          else if ( this.options.messages.nonSelection )
          {
            alert(this.options.messages.nonSelection);
          }
        },
        "tags": ['a'],
        "tooltip": "Create link"
      },

      "insertImage" : {
        "visible": true,
        "exec"   : function()
        {

          var __this = this;
  	      $('#insertImageFile').overlay({ 
            expose: { 
              color: '#e8e8e8', 
              loadSpeed: 200, 
              opacity: 0.8 
            }, 
            closeOnClick: true, 
            api: true 
	        }).load();

/*
          var page = '<label class="pastelabel">Загрузить изображение</label><div class="pastetext" id="pasteText">';
              page += '<div class="line"><p class="swfupload-control"><span id="spanButtonPlaceholder"></span></p></div>';
              page += '</div><a href="#" class="pastelink">Вставить</a>';
          
//          var _self = this;
          var __this = this;
		      var self = $.data(this, 'wysiwyg');


          var swfu;

          $.fancybox(page, 
          {
            'hideOnOverlayClick' : false, 
            'onComplete' : function()
            {
              $('#pasteText').focus();
              $('.pastelink').hide();

              $('.swfupload-control').swfupload({
                  upload_url : "/ajax/blogupload.html", 
                  file_post_name: 'imagefilename',
                  file_size_limit : "1024", // 100MB
                  file_types : "*.jpeg;*.png;*.jpg;*.gif",
                  file_types_description : "All Images",
                  file_upload_limit : "10",
                  file_queue_limit : "0",
                  button_placeholder_id : "spanButtonPlaceholder",
                  button_width: 150,
                  button_height: 29,
                  button_text: '<span class="theFont">загрузить</span>',
                  button_text_style: ".theFont { font-size: 16; text-align: center;color: #6699ff; }",
                  button_text_left_padding: 12,
                  button_text_top_padding: 3,
                  flash_url : "/scripts/swfupload/swfupload.swf"
              });

              $('.swfupload-control')
                  .bind('fileQueued', function(event, file){ $(this).swfupload('startUpload'); })
                  .bind('uploadSuccess', function(event, file, serverData)
                  {
                      $('#pasteText').html('<img id="insertImage" src="/images/temp/preview/' + serverData + '" alt="'+ serverData +'" />');
                      $('.pastelink').show();
                      $('.pastelink').click(function()
                      {
                        var response = $('#insertImage').attr('alt');
                        $(__this.original).wysiwyg('insertHtml', '<img src="/images/temp/preview/'+ response +'" alt=""/>');
                        $.fancybox.close();
                        return false;
                      });
                      $(this).swfupload('startUpload');
                  });
            }
          });
*/
        },
        "tags": ['img'],
        "tooltip": "Insert image"
      },

      "insertObject" : {
        "visible": true,
        "exec"   : function()
        {
  	      $('#insertObject').overlay({ 
            expose: { 
              color: '#e8e8e8', 
              loadSpeed: 200, 
              opacity: 0.8 
            }, 
            closeOnClick: true, 
            api: true 
	        }).load();


/*
          $.fancybox('<label class="pastelabel">Вставка видео</label><textarea name="PastText" rows="20" cols="20" class="pastetext" id="pasteText"></textarea><div style="clear: both;"><a href="#" id="insert" class="pastelink-right">Вставить</a><a href="#" id="preview" class="pastelink-right">Предпросмотр</a></div>', 
          {
            'hideOnOverlayClick' : false, 
            'autoDimensions' : true,
            'onComplete' : function()
            {
              $('#pasteText').focus();
              $('#preview').css('margin-right', '5px');

              $('#preview').click(function(){
                var paste          = $('#pasteText').val();
                var result = paste.match(/<\/?\s*(object|embed|param)(\s+[a-z_]+=($[^']+$|"[^"]+"))*\s*\/?>/ig);
                if (result) 
                {
                  paste = result.join('');
                  result = paste.match(/\b(https?|ftp|file):\/\/[\-A-Z0-9+&@#\/%?=~_|$!:,.;]*[A-Z0-9+&@#\/%=~_|$]/ig);

                  if(!result[0])
                  {
                    alert('Мы не нашли видео в этом...');
                    return false;
                  }

                  $('#pasteText').css('height','50px');
                  $('#pasteText').before('<div id="templary-preview">Hello world</div>');
                  swfobject.embedSWF(result[0], "templary-preview", "460", "285", "9");
                  alert('Готово');
                  $.fancybox.resize();
                  $('#pasteText').val(paste);
                } 
                else 
                {
                  alert('Неверный формат вводимых данных');
                }
                return false;
              });

              $('#insert').click(function()
              {
                var paste  = $('#pasteText').val();
                var result = paste.match(/<\/?\s*(object|embed|param)(\s+[a-z_]+=($[^']+$|"[^"]+"))*\s*\/?>/ig);
                if (result) 
                {
                  paste = result.join('');
                  result = paste.match(/\b(https?|ftp|file):\/\/[\-A-Z0-9+&@#\/%?=~_|$!:,.;]*[A-Z0-9+&@#\/%=~_|$]/ig);

                  if(!result[0])
                  {
                    alert('Мы не нашли видео в этом...');
                    return false;
                  }
                  $(__this.original).wysiwyg('insertHtml', '<img src="/images/pixel.gif" class="pixel" alt="' + result[0] + '" />');
                } 
                else 
                {
                  alert('Неверный формат вводимых данных');
                }

                $.fancybox.close();
                return false;
              });
            }
          });
*/
        },
        "tags": ['img'],
        "tooltip": "Вставить видео"
      },


      separator08 : { "separator": false && !( $.browser.msie ) },

      "increaseFontSize" : { "visible": false && !( $.browser.msie ), "tags": ['big'], "tooltip": "Increase font size" },
      "decreaseFontSize" : { "visible": false && !( $.browser.msie ), "tags": ['small'], "tooltip": "Decrease font size" },

      separator09 : { "separator": true },

      "html" : {
        "visible" : true,
        "exec"    : function()
        {
          if ( this.viewHTML )
          {
            this.setContent( $(this.original).val() );
            $(this.original).hide();
          }
          else
          {
            this.saveContent();
            $(this.original).show();
          }

          this.viewHTML = !( this.viewHTML );
        },
        "tooltip": "View source code"
      },

      "removeFormat" : {
        "visible": true,
        "exec"   : function()
        {
          if ($.browser.msie)
          {
            this.focus();
          }
          this.editorDoc.execCommand('removeFormat', false, []);
          this.editorDoc.execCommand('unlink', false, []);
        },
        "tooltip": "Remove formatting"
      }
    }
  });

  $.extend(Wysiwyg.prototype,
  {
    original : null,
    options  : {},

    element  : null,
    editor   : null,

    focus : function()
    {
      $(this.editorDoc.body).focus();
    },

    init : function( element, options )
    {
      var self = this;

      this.editor = element;
      this.options = options || {};

      $.data(element, 'wysiwyg', 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;
        }
        if ( newY == 0 && element.rows )
        {
          newY = ( element.rows * 16 ) + 16;
        }
        this.editor = $(location.protocol == 'https:' ? '<iframe src="javascript:false;"></iframe>' : '<iframe></iframe>').css({
          minHeight : ( newY - 6 ).toString() + 'px',
          width  : ( newX - 8 ).toString() + 'px'
        }).attr('id', $(element).attr('id') + 'IFrame')
          .attr('frameborder', '0')
          ;

        this.editor.attr('tabindex', $(element).attr('tabindex'));

        if ( $.browser.msie )
        {
          this.editor
            .css('height', ( newY ).toString() + 'px');
        }
      }

      var panel = this.panel = $('<ul role="menu" class="panel"></ul>');

      this.appendControls();
      this.element = $('<div></div>')
      /*
      .css({
        width : ( newX > 0 ) ? ( newX ).toString() + 'px' : '100%'
      })*/
	      .addClass('wysiwyg')
        .append(panel)
        .append( $('<div><!-- --></div>').css({ clear : 'both' }) )
        .append(this.editor)
        ;

      $(element)
        .hide()
        .before(this.element)
        ;

      this.viewHTML = false;
      this.initialHeight = newY - 8;

      /**
       * @link http://code.google.com/p/jwysiwyg/issues/detail?id=52
       */
      this.initialContent = $(element).val();
      this.initFrame();

      if ( this.initialContent.length === 0 )
      {
        this.setContent('');
      }

      /**
       * http://code.google.com/p/jwysiwyg/issues/detail?id=100
       */
      var form = $(element).closest('form');

      if ( this.options.autoSave )
      {
        form.submit(function() { self.saveContent(); });
      }

      this.panel.bind('mousedown', function()
      {
        if ( $.browser.msie )
        {
            var editorDoc = $(self.editor).document();
            if ( editorDoc.selection && editorDoc.selection.createRange )
            {
        			var range = editorDoc.selection.createRange();
        			setTimeout( function(){ range.select(); }, 0 ); 
            }
        }
        else 
        	setTimeout( function(){ $(self.editor).get(0).contentWindow.focus();}, 0 );
      });


      form.bind('reset', function()
      {
        self.setContent( self.initialContent );
        self.saveContent();
      });

      $(this.editorDoc.body).bind('paste', function(e) 
      {
	      var x = $('#insertText').overlay({ 
          expose: { 
            color: '#e8e8e8', 
            loadSpeed: 200, 
            opacity: 0.8 
          }, 
          closeOnClick: true, 
          effect: 'apple',
          api: true,
          obj : element 
        });
        
        x.load();
        return false;
      });
    },


/*
TextToPasteButton
        $.fancybox('<label class="pastelabel">Вставте текст</label><textarea name="PastText" rows="20" cols="20" class="pastetext" id="pasteText"></textarea><a href="#" class="pastelink">Вставить</a>', 
        {
          'hideOnOverlayClick' : false, 
          'onComplete' : function()
          {
            $('#pasteText').focus();
            $('.pastelink').click(function(){
              var paste          = $('#pasteText').val();
              paste = paste.replace(/<\/?[a-z][a-z0-9]*[^<>]*>|<!--[\s\S]*?-->/ig, "");
//              paste = paste.replace(/([^&gt;])\\n/g, '$1&lt;br /&gt;');
							paste = paste.replace(/([^>]?)\n/g, '$1\<br \/\>\n');
              $(y).wysiwyg('insertHtml', paste);
              $.fancybox.close();
              return false;
            });
          }
        });
*/


    initFrame : function()
    {
      var self = this;
      var style = '';

      /**
       * @link http://code.google.com/p/jwysiwyg/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 = $(this.editor).document();

      this.editorDoc_designMode = false;

      try
      {
        this.editorDoc.designMode = 'on';
        this.editorDoc_designMode = true;
      } catch ( e )
      {
        // Will fail on Gecko if the editor is placed in an hidden container element
        // The design mode will be set ones the editor is focused

        $(this.editorDoc).focus(function()
        {
          self.designMode();
        });
      }

      this.editorDoc.open();
      this.editorDoc.write(
        this.options.html
          /**
           * @link http://code.google.com/p/jwysiwyg/issues/detail?id=144
           */
          .replace(/INITIAL_CONTENT/, function() { return self.initialContent; })
          .replace(/STYLE_SHEET/, function() { return style; })
      );
      this.editorDoc.close();

      this.editorDoc.contentEditable = 'true';

      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/jwysiwyg/issues/detail?id=20
       */
      $(this.original).focus(function()
      {
        if (!$.browser.msie)
        {
          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/jwysiwyg/issues/detail?id=11
         */
        $(this.editorDoc).keydown(function() { self.saveContent(); })
          .keyup(function() { self.saveContent(); })
          .mousedown(function() { self.saveContent(); })
          ;
      }

      if ( this.options.css )
      {
        window.setTimeout(function()
        {
          if (self.options.css.constructor == String)
          {
          }
          else
          {
            $(self.editorDoc).find('body').css(self.options.css);
          }
        }, 0);
      }

    },

    designMode : function()
    {
      if (!(this.editorDoc_designMode))
      {
        try {
          this.editorDoc.designMode = 'on';
          this.editorDoc_designMode = true;
        } catch ( e ) {}
      }
    },

    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();
    },

    getContent : function()
    {
      var markup = $( $(this.editor).document() ).find('body').html();

      return markup.replace('<b>', '<span class="bold">')
      						 .replace('</b>','</span>')
      						 .replace('<strong>', '<span class="bold">')
      						 .replace('</strong>', '</span>')
      						 .replace('<i>', '<span class="italic">')
      						 .replace('</i>', '</span>')
      						 .replace('<u>', '<span class="underline">')
      						 .replace('</u>', '</span>')
      						 .replace('<em>', '<span class="italic">')
      						 .replace('</em>', '</span>')
      						 .replace('<strike>', '<span class="strike">')
      						 .replace('</strike>', '</span>')
      						 .replace(/<br>/g, '<br />')
      						 .replace(/align/, 'class')
      						 .replace(/<br>/g, '<br />')
      						 .replace(/<BR>/g, '<br />');

      //return $( $(this.editor).document() ).find('body').html();
    },

    setContent : function( newContent )
    {
/*
      newContent = newContent.replace('<span class="bold">', '<b>')
                						 .replace('</span>', '</b>')
                						 .replace('<span class="bold">', '<strong>')
                						 .replace('</span>', '</strong>')
                						 .replace('<i>', '<span class="italic">')
                						 .replace('</i>', '</span>')
                						 .replace('<u>', '<span class="underline">')
                						 .replace('</u>', '</span>')
                						 .replace('<em>', '<span class="italic">')
                						 .replace('</em>', '</span>')
                						 .replace('<strike>', '<span class="strike">')
                						 .replace('</strike>', '</span>')
                						 .replace(/<br>/g, '<br />')
                						 .replace(/align/, 'class')
                						 .replace(/<br>/g, '<br />')
                						 .replace(/<BR>/g, '<br />');
*/
      $( $(this.editor).document() ).find('body').html(newContent);
    },

    saveContent : function()
    {
      if ( this.original )
      {
        var content = this.getContent();

        if ( this.options.rmUnwantedBr )
        {
          content = ( content.substr(-4) == '<br />' ) ? content.substr(0, content.length - 4) : content;
        }

        $(this.original).val(content);
      }
    },

    withoutCss: function()
    {
      if ($.browser.mozilla)
      {
        try
        {
          this.editorDoc.execCommand('styleWithCSS', false, false);
        }
        catch (e)
        {
          try
          {
            this.editorDoc.execCommand('useCSS', false, true);
          }
          catch (e2)
          {
          }
        }
      }
    },

    appendMenu : function( cmd, args, className, fn, tooltip )
    {
      var self = this;
      args = args || [];

      $('<li></li>').append(
        $('<a role="menuitem" tabindex="-1" href="javascript:;">' + (className || cmd) + '</a>')
          .addClass(className || cmd)
          .attr('title', tooltip)
      ).click(function() {
        if ( fn )
        {
          fn.apply(self);
        }
        else
        {
//          self.withoutCss();
//          alert(cmd + ' ' + args);
          self.editorDoc.execCommand(cmd, false, args);
        }
        if ( self.options.autoSave )
        {
          self.saveContent();
        }
        this.blur();
      }).appendTo( this.panel );
    },

    appendMenuSeparator : function()
    {
      $('<li role="separator" class="separator"></li>').appendTo( this.panel );
    },

    appendControls : function()
    {
      for ( var name in this.options.controls )
      {
        var control = this.options.controls[name];

        if ( control.separator )
        {
          if ( control.visible !== false )
          {
            this.appendMenuSeparator();
          }
        }
        else if ( control.visible )
        {
          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);

