/*!
 * 
 */
/**
 * @author Shea Frederick - http://www.vinylfox.com
 * @class Ext.ux.form.HtmlEditor.MidasCommand
 * @extends Ext.util.Observable
 * <p>A base plugin for extending to create standard Midas command buttons.</p>
 */
Ext.ns('Ext.ux.form.HtmlEditor');

Ext.ux.form.HtmlEditor.MidasCommand = Ext.extend(Ext.util.Observable, {
	// private
    init: function(cmp){
        this.cmp = cmp;
		this.btns = [];
        this.cmp.on('render', this.onRender, this);
		this.cmp.on('initialize', this.onInit, this, {delay:100, single: true});
    },
	// private
	onInit: function(){
        Ext.EventManager.on(this.cmp.getDoc(), {
            'mousedown': this.onEditorEvent,
            'dblclick': this.onEditorEvent,
            'click': this.onEditorEvent,
            'keyup': this.onEditorEvent,
            buffer:100,
            scope: this
        });
	},
	// private
    onRender: function() {
        var midasCmdButton, tb = this.cmp.getToolbar(), btn;
        Ext.each(this.midasBtns,function(b){
            if (Ext.isObject(b)) {
                midasCmdButton = {
                    iconCls: 'x-edit-' + b.cmd,
                    handler: function(){
                        this.cmp.relayCmd(b.cmd);
                    },
                    scope: this,
                    tooltip: b.title
                };
            }else{
                midasCmdButton = new Ext.Toolbar.Separator();
            }
			btn = tb.addButton(midasCmdButton);
			if (b.enableOnSelection){
				btn.disable();
			}
			this.btns.push(btn);
        }, this);
    },
	// private
	onEditorEvent: function(){
		var doc = this.cmp.getDoc();
		Ext.each(this.btns, function(b,i){
			if (this.midasBtns[i].enableOnSelection || this.midasBtns[i].disableOnSelection){
				if (doc.getSelection){
					if ((this.midasBtns[i].enableOnSelection && doc.getSelection() !== '') || (this.midasBtns[i].disableOnSelection && doc.getSelection() === '')){
						b.enable();
					}else{
						b.disable();
					}
				}else if(doc.selection){
					if ((this.midasBtns[i].enableOnSelection && doc.selection.createRange().text !== '') || (this.midasBtns[i].disableOnSelection && doc.selection.createRange().text === '')){
						b.enable();
					}else{
						b.disable();
					}
				}
			}
			if (this.midasBtns[i].monitorCmdState){
				b.toggle(doc.queryCommandState(this.midasBtns[i].cmd));
			}
		}, this);
	}
});/**
 * @author Shea Frederick - http://www.vinylfox.com
 * @class Ext.ux.form.HtmlEditor.Divider
 * @extends Ext.util.Observable
 * <p>A plugin that creates a divider on the HtmlEditor. Used for separating additional buttons.</p>
 */
Ext.ux.form.HtmlEditor.Divider = Ext.extend(Ext.util.Observable, {
	// private
    init: function(cmp){
        this.cmp = cmp;
        this.cmp.on('render', this.onRender, this);
    },
	// private
    onRender: function() {
        this.cmp.getToolbar().addButton([new Ext.Toolbar.Separator()]);
    }
});/**
 * @author Shea Frederick - http://www.vinylfox.com
 * @class Ext.ux.form.HtmlEditor.IndentOutdent
 * @extends Ext.ux.form.HtmlEditor.MidasCommand
 * <p>A plugin that creates two buttons on the HtmlEditor for indenting and outdenting of selected text.</p>
 */
Ext.ux.form.HtmlEditor.IndentOutdent = Ext.extend(Ext.ux.form.HtmlEditor.MidasCommand, {
	// private
    midasBtns: ['|',{
        cmd: 'indent',
        title: 'Indent Text'
    }, {
        cmd: 'outdent',
        title: 'Outdent Text'
    }]
});/**
 * @author Shea Frederick - http://www.vinylfox.com
 * @class Ext.ux.form.HtmlEditor.RemoveFormat
 * @extends Ext.ux.form.HtmlEditor.MidasCommand
 * <p>A plugin that creates a button on the HtmlEditor that will remove all formatting on selected text.</p>
 */
Ext.ux.form.HtmlEditor.RemoveFormat = Ext.extend(Ext.ux.form.HtmlEditor.MidasCommand, {
    midasBtns: ['|',{
		enableOnSelection: true,
        cmd: 'removeFormat',
        title: 'Remove Formatting'
    }]
});/**
 * @author Shea Frederick - http://www.vinylfox.com
 * @class Ext.ux.form.HtmlEditor.SubSuperScript
 * @extends Ext.ux.form.HtmlEditor.MidasCommand
 * <p>A plugin that creates two buttons on the HtmlEditor for superscript and subscripting of selected text.</p>
 */
Ext.ux.form.HtmlEditor.SubSuperScript = Ext.extend(Ext.ux.form.HtmlEditor.MidasCommand, {
	// private
    midasBtns: ['|',{
		enableOnSelection: true,
        cmd: 'subscript',
        title: 'Subscript'
    }, {
		enableOnSelection: true,
        cmd: 'superscript',
        title: 'Superscript'
    }]
});/**
 * @author Shea Frederick - http://www.vinylfox.com
 * @class Ext.ux.form.HtmlEditor.SpecialCharacters
 * @extends Ext.util.Observable
 * <p>A plugin that creates a button on the HtmlEditor for inserting special characters.</p>
 */
Ext.ux.form.HtmlEditor.SpecialCharacters = Ext.extend(Ext.util.Observable, {
    /**
     * @cfg {Array} specialChars
     * An array of additional characters to display for user selection.  Uses numeric portion of the ASCII HTML Character Code only. For example, to use the Copyright symbol, which is &#169; we would just specify <tt>169</tt> (ie: <tt>specialChars:[169]</tt>).
     */
	specialChars: [],
    /**
     * @cfg {Array} charRange
     * Two numbers specifying a range of ASCII HTML Characters to display for user selection. Defaults to <tt>[160, 256]</tt>.
     */
	charRange: [160, 256],
	// private
    init: function(cmp){
        this.cmp = cmp;
        this.cmp.on('render', this.onRender, this);
    },
	// private
    onRender: function() {
        var cmp = this.cmp;
        var btn = this.cmp.getToolbar().addButton({
          iconCls: 'x-edit-char',
          handler: function() {
		  	if (this.specialChars.length){
				Ext.each(this.specialChars, function(c,i){
					this.specialChars[i] = ['&#'+c+';'];
				}, this);
			}
		  	for (i=this.charRange[0];i<this.charRange[1];i++){
				this.specialChars.push(['&#'+i+';']);
			}
			var charStore = new Ext.data.ArrayStore({
				fields: ['char'],
				data: this.specialChars
			});
            this.charWindow = new Ext.Window({
                title: 'Insert Special Character',
				width: 436,
				autoHeight: true,
				layout: 'fit',
                items: [{
					xtype: 'dataview',
					store: charStore,
					ref: '../charView',
					autoHeight: true,
					multiSelect: true, 
					tpl: new Ext.XTemplate('<tpl for="."><div class="char-item">{char}</div></tpl><div class="x-clear"></div>'),
					overClass: 'char-over',
					itemSelector: 'div.char-item',
					listeners: {
						dblclick: function(t,i,n,e){
							this.insertChar(t.getStore().getAt(i).get('char'));
							this.charWindow.close();
						},
						scope: this
					}
                }],
                buttons: [{
                    text: 'Insert',
                    handler: function(){
						Ext.each(this.charWindow.charView.getSelectedRecords(), function(rec){
							var c = rec.get('char');
							this.insertChar(c);
						}, this);
						this.charWindow.close();
					},
                    scope: this
                }, {
                    text: 'Cancel',
                    handler: function() {
                      this.charWindow.close();
                    },
					scope: this
                }]
            });
			this.charWindow.show();
          },
          scope: this,
          tooltip: 'Insert Special Character'
        });
    },
    /**
     * Insert a single special character into the document.
     * @param c String The special character to insert (not just the numeric code, but the entire ASCII HTML entity).
     */
    insertChar: function(c) {
		if (c){
        	this.cmp.insertAtCursor(c);
        }
    }
});/**
 * @author Shea Frederick - http://www.vinylfox.com
 * @class Ext.ux.form.HtmlEditor.Table
 * @extends Ext.util.Observable
 * <p>A plugin that creates a button on the HtmlEditor for making simple tables.</p>
 */
Ext.ux.form.HtmlEditor.Table = Ext.extend(Ext.util.Observable, {
	// private
	cmd: 'table',
    /**
     * @cfg {Array} tableBorderOptions
     * A nested array of value/display options to present to the user for table border style. Defaults to a simple list of 5 varrying border types.
     */
	tableBorderOptions: [['none','None'],['1px solid #000','Sold Thin'],['2px solid #000','Solid Thick'],['1px dashed #000','Dashed'],['1px dotted #000','Dotted']],
	// private
    init: function(cmp){
        this.cmp = cmp;
        this.cmp.on('render', this.onRender, this);
    },
	// private
    onRender: function() {
        var cmp = this.cmp;
        var btn = this.cmp.getToolbar().addButton({
          iconCls: 'x-edit-table',
          handler: function() {
            var tableWindow = new Ext.Window({
                title: 'Insert Table',
                items: [{
                    itemId: 'insert-table',
                    xtype: 'form',
                    border: false,
                    plain: true,
                    bodyStyle: 'padding: 10px;',
                    labelWidth: 60,
                    labelAlign: 'right',
                    items: [{
                        xtype: 'numberfield',
                        allowBlank: false,
                        allowDecimals: false,
                        fieldLabel: 'Rows',
                        name: 'row',
                        width: 60
                    },{
                        xtype: 'numberfield',
                        allowBlank: false,
                        allowDecimals: false,
                        fieldLabel: 'Columns',
                        name: 'col',
                        width: 60
                    },{
                        xtype: 'combo',
                        fieldLabel: 'Border',
                        name: 'border',
                        forceSelection: true,
                        mode: 'local',
                        store: new Ext.data.ArrayStore({
                            autoDestroy: true,
                            fields: ['spec','val'],
                            data: this.tableBorderOptions
                        }),
                        triggerAction: 'all',
                        value: 'none',
                        displayField: 'val',
                        valueField: 'spec',
                        width: 90
                    }]
                }],
                buttons: [{
                    text: 'Insert',
                    handler: function() {
                        var frm = tableWindow.getComponent('insert-table').getForm();
                        var border = frm.findField('border').getValue();
                        if (frm.isValid()) {
                            var rowcol = [frm.findField('row').getValue(),frm.findField('col').getValue()];
                            if (rowcol.length == 2 && rowcol[0] > 0 && rowcol[0] < 10&& rowcol[1] > 0 && rowcol[1] < 10) {
                                var html = "<table style='border: "+border+";'>";
                                for (var row=0; row<rowcol[0]; row++) {
                                    html += "<tr>";
                                    for (var col=0; col<rowcol[1]; col++) {
                                        html += "<td width='20%'>"+row+"-"+col+"</td>";
                                    }
                                    html += "</tr>";
                                }
                                html += "</table>";
                                this.cmp.insertAtCursor(html);
                            }
                        }
                        tableWindow.close();
                    },
                    scope: this
                }, {
                    text: 'Cancel',
                    handler: function() {
                      tableWindow.close();
                    },
					scope: this
                }]
            }).show();
          },
          scope: this,
          tooltip: 'Insert Table'
        });
    }
});/**
 * @author Shea Frederick - http://www.vinylfox.com
 * @class Ext.ux.form.HtmlEditor.Word
 * @extends Ext.util.Observable
 * <p>A plugin that creates a button on the HtmlEditor for pasting text from Word without all the jibberish html.</p>
 */
Ext.ux.form.HtmlEditor.Word = Ext.extend(Ext.util.Observable, {
	// private
    init: function(cmp){
        
        this.cmp = cmp;
        this.cmp.on('render', this.onRender, this);
        
    },
    /**
     * Cleans up the jubberish html from Word pasted text.
     * @param wordPaste String The text that needs to be cleansed of Word jibberish html.
     * @return {String} The passed in text with all Word jibberish html removed.
     */
    fixWordPaste: function(wordPaste) {
        
        // remove microsoft jibberish using regex jibberish
        var removals = [/MsoNormal/g, /<\\?\?xml[^>]*>/g, /<\/?o:p[^>]*>/g, /<\/?v:[^>]*>/g, /<\/?o:[^>]*>/g, /<\/?st1:[^>]*>/g, /&nbsp;/g, 
            /<\/?SPAN[^>]*>/g, /<\/?FONT[^>]*>/g, /<\/?STRONG[^>]*>/g, /<\/?H1[^>]*>/g, /<\/?H2[^>]*>/g, /<\/?H3[^>]*>/g, /<\/?H4[^>]*>/g, 
            /<\/?H5[^>]*>/g, /<\/?H6[^>]*>/g, /<\/?P[^>]*><\/P>/g, /<!--(.*)-->/g, /<!--(.*)>/g, /<!(.*)-->/g, /<\\?\?xml[^>]*>/g, 
            /<\/?o:p[^>]*>/g, /<\/?v:[^>]*>/g, /<\/?o:[^>]*>/g, /<\/?st1:[^>]*>/g, /style=\"[^\"]*\"/g, /style=\'[^\"]*\'/g, /lang=\"[^\"]*\"/g, 
            /lang=\'[^\"]*\'/g, /class=\"[^\"]*\"/g, /class=\'[^\"]*\'/g, /type=\"[^\"]*\"/g, /type=\'[^\"]*\'/g, /href=\'#[^\"]*\'/g, 
            /href=\"#[^\"]*\"/g, /name=\"[^\"]*\"/g, /name=\'[^\"]*\'/g, / clear=\"all\"/g, /id=\"[^\"]*\"/g, /title=\"[^\"]*\"/g, 
            /&nbsp;/g, /\n/g, /\r/g, /<span[^>]*>/g, /<\/?span[^>]*>/g, /class=/g];
        
        Ext.each(removals, function(s){
            wordPaste = wordPaste.replace(s, "");
        });
        
        // keep the divs in paragraphs
        wordPaste = wordPaste.replace(/<div[^>]*>/g, "<p>");
        wordPaste = wordPaste.replace(/<\/?div[^>]*>/g, "</p>");
        return wordPaste;
        
    },
	// private
    onRender: function() {
        
        this.cmp.getToolbar().add({
          iconCls: 'x-edit-wordpaste',
          handler: function() {
            var wordPaste;
            var wordPasteEditor = new Ext.form.HtmlEditor({
              width: 520,
              height: 150
            });
            var wordPasteWindow = new Ext.Window({ 
              title: "Paste text here from Microsoft Word",  
              modal: true,
              width: 537,
              height: 220,
              shadow: true,
              resizable: false,
              plain: true,
              items: wordPasteEditor,
              buttons: [{
                text: 'Insert',
                handler: function() {
                  var wordPaste = wordPasteEditor.getValue();
                  this.cmp.insertAtCursor(this.fixWordPaste(wordPaste));
                  wordPasteWindow.close();
                },
                scope: this
              }, {
                text: 'Cancel',
                handler: function() {
                  wordPasteWindow.close();
                },
				scope: this
              }]
            });
            wordPasteWindow.show();
          },
          scope: this,
          tooltip: '<b>Paste Microsoft Word</b><br>Copy selected text from Microsoft Word and paste in this window'
        });
    }
});/**
 * @author Shea Frederick - http://www.vinylfox.com
 * @class Ext.ux.form.HtmlEditor.HR
 * @extends Ext.util.Observable
 * <p>A plugin that creates a button on the HtmlEditor for inserting a horizontal rule.</p>
 */
Ext.ux.form.HtmlEditor.HR = Ext.extend(Ext.util.Observable, {
	// private
	cmd: 'hr',
	// private
    init: function(cmp){
        this.cmp = cmp;
        this.cmp.on('render', this.onRender, this);
    },
	// private
    onRender: function() {
        var cmp = this.cmp;
        var btn = this.cmp.getToolbar().addButton({
          iconCls: 'x-edit-hr',
          handler: function() {
            this.hrWindow = new Ext.Window({
                title: 'Insert Rule',
                items: [{
                    itemId: 'insert-hr',
                    xtype: 'form',
                    border: false,
                    plain: true,
                    bodyStyle: 'padding: 10px;',
                    labelWidth: 60,
                    labelAlign: 'right',
                    items: [{
                        xtype: 'label',
                        html: 'Enter the width of the Rule in percentage<br/> followed by the % sign at the end, or to<br/> set a fixed width ommit the % symbol.<br/>&nbsp;'
                    },{
                        xtype: 'textfield',
                        maskRe: /[0-9]|%/,
                        regex: /^[1-9][0-9%]{1,3}/,
                        fieldLabel: 'Width',
                        name: 'hrwidth',
                        width: 60,
                        listeners: {
                            specialkey: function(f, e){
                                if (e.getKey() == e.ENTER || e.getKey() == e.RETURN){
                                    this.doInsertHR();
                                }
                            },
                            scope: this
                        }
                    }]
                }],
                buttons: [{
                    text: 'Insert',
                    handler: this.doInsertHR,
                    scope: this
                }, {
                    text: 'Cancel',
                    handler: function() {
                      this.hrWindow.close();
                    },
					scope: this
                }]
            }).show();
          },
          scope: this,
          tooltip: 'Insert Horizontal Rule'
        });
    },
	// private
    doInsertHR: function() {
        var frm = this.hrWindow.getComponent('insert-hr').getForm();
        if (frm.isValid()) {
            var hrwidth = frm.findField('hrwidth').getValue();
            if (hrwidth) {
                this.insertHR(hrwidth);
            }else{
                this.insertHR('100%');
            }
            this.hrWindow.close();
        }
    },
    /**
     * Insert a horizontal rule into the document.
     * @param w String The width of the horizontal rule as the <tt>width</tt> attribute of the HR tag expects. ie: '100%' or '400' (pixels).
     */
	insertHR: function(w){
		this.cmp.insertAtCursor('<hr width="'+w+'">');
	}
});
