Xsn.HtmlEditor = function(el, config){
	this.el = el;
	Ext.apply(this, config);
    Xsn.HtmlEditor.superclass.constructor.call(this, config);
    this.init();
};

Ext.extend(Xsn.HtmlEditor, Ext.util.Observable,  {

    setValue:function(val) { 
		this.value = val;
		if (this.rendered){
			this.init();		 
		}
		this.setHtml(val);
	},

    getRawValue : function(){
		return this.getHtml();	
	},
	
    init: function(){
       	//this.createToolBar();
        this.iframe = this.el.createChild({tag: 'iframe', frameborder:'0'});
        this.initDesignMode.defer(500,this);

    },
     /**
     * @method initDesignMode
     * @private - Makes the iframe editable 
     * called with a defer from init
     */
    initDesignMode:function(){
        this.iframe.dom.contentWindow.document.designMode="on";
    },
      /**
     * @method createToolBar
     * @private - Creates the toolbar for the editor
     * the toolbar buttons are similar to gmail
     */
    createToolBar:function(){
        var fontFaceMenu = new Ext.menu.Menu({
		 	items: [
				{text:'<span style="font-family:arial">Arial</span>', handler:this.executeCommand.createDelegate(this,['fontname','Arial'])}
			]
        });
        var fontSizeMenu =new Ext.menu.Menu({
		    items: [
				{text:'<font size="1">Small</font>',handler:this.executeCommand.createDelegate(this,['fontsize','1'])},
                {text:'<font size="2">Normal</font>',handler:this.executeCommand.createDelegate(this,['fontsize','3'])},
                {text:'<font size="3">Large</font>',handler:this.executeCommand.createDelegate(this,['fontsize','5'])},
                {text:'<font size="4">Huge</font>',handler:this.executeCommand.createDelegate(this,['fontsize','7'])}
            ]
		});  
		      
        this.toolbar = new Ext.Toolbar(this.el.createChild({tag:'div'}));
        this.toolbar.add('-',
            {
                cls: 'x-btn-icon icon-bold',
                tooltip:'Bold',
                handler:this.executeCommand.createDelegate(this,['bold'])
           
            },
            {
                cls: 'x-btn-icon icon-italic',
                tooltip:'Italic',
                handler:this.executeCommand.createDelegate(this,['italic'])
           
            },
            {
                cls: 'x-btn-icon icon-underline',
                tooltip:'Underline',
                handler:this.executeCommand.createDelegate(this,['underline'])
           
            },
            {
                cls: 'x-btn-icon icon-fontFace',
                tooltip:'Font Face',
			    menu:fontFaceMenu
           
            },
            {
                cls: 'x-btn-icon icon-fontSize',
                tooltip:'Font Size',				
                menu:fontSizeMenu
            },
            {
                cls: 'x-btn-icon icon-link',
                tooltip:'Link',
                handler:this.showPrompt.createDelegate(this)
            },
            {
                cls: 'x-btn-icon icon-mailtolink',
                tooltip:'Mailto Link',
                handler:this.showPrompt.createDelegate(this)
            },
            {
                cls: 'x-btn-icon icon-orderedList',
                tooltip:'Numbered List',
                handler:this.executeCommand.createDelegate(this,['insertorderedlist'])
           
            },
            {
                cls: 'x-btn-icon icon-unOrderedList',
                tooltip:'Bullet List',
                handler:this.executeCommand.createDelegate(this,['insertunorderedlist'])
           
            },
            {
                cls: 'x-btn-icon icon-alignLeft',
                tooltip:'Align left',
                handler:this.executeCommand.createDelegate(this,['justifyleft'])
           
            },
            {
                cls: 'x-btn-icon icon-alignCenter',
                tooltip:'Align center',
                handler:this.executeCommand.createDelegate(this,['justifycenter'])
           
            },
            {
                cls: 'x-btn-icon icon-alignRight',
                tooltip:'Align rigth',
                handler:this.executeCommand.createDelegate(this,['justifyright'])
           
            }
         );
    }, 
  /**
 * @method showPrompt
 * @private shows the prompt to the user to enter the url
 */
    showPrompt:function(){
        Ext.MessageBox.prompt('Link', 'Enter a URL:', this.getResult,this);
    },    
     /**
     * @method getResult
     * @private gets the result of the prompt and call executeCommand 
     * if any text is entered and ok is clicked
     * @TODO should make sure text entered is a valid url
     */
    getResult:function(btn,text){
       
        if(btn=="ok" && text!=""){
            this.executeCommand("CreateLink",text);
        }
    },
     /**
     * @method getHtml
     * Gets the html that is inside the editor at the moment
     */
    getHtml:function(){
       return this.getDocument().body.innerHTML;
    },
     /**
     * @method setHtml
     * Sets the html that is inside the editor at the moment
     */
    setHtml:function(html, css){
     	if (!html) return;
        var doc=this.getDocument();
        if(doc){
			doc.open();
	        doc.write(html);
	        doc.close();  

			this.createStyleSheet(doc, css);
			/*
			var style = (!doc.head.style ? Ext.get(doc.head).append({tag:'style', type:'text/css'}, true) : Ext.get(doc.head.style));  	        
			style.dom.innerHTML = 'hello';
			console.log(style);
			*/
			/*       
            doc.body.innerHTML = html;
         	console.log(doc.body.innerHTML);            
         	*/
            this.focus();
        } else {
            //horrible workaround for ie wait for iframe to be loaded   
        	this.setHtml.defer(100,this, [html]);
        }
    },
    
	createStyleSheet : function(doc, cssText){
	   var ss;
	   if(Ext.isIE){
	       ss = doc.createStyleSheet();
	       ss.cssText = cssText;
	   }else{
	       var head = doc.getElementsByTagName("head")[0];
	       var rules = doc.createElement("style");
	       rules.setAttribute("type", "text/css");
	       try{
	            rules.appendChild(doc.createTextNode(cssText));
	       }catch(e){
	           rules.cssText = cssText; 
	       }
	       head.appendChild(rules);
	       ss = rules.styleSheet ? rules.styleSheet : (rules.sheet || doc.styleSheets[doc.styleSheets.length-1]);
	   }
	   return ss;
	},		
		
	/**
     * @method getDocument
     * @private get the element that will execute the command
     */
    getDocument:function(){
   
        if(Ext.isIE||Ext.isIE7|| Ext.isSafari){
		    var doc=document.frames(this.iframe.id).document;
		    return doc;
		    /*
		    var range=doc.selection.createRange();
		    if(range.htmlText!=""){
			    return range;
		    } else{
		        return doc;
		    }*/
		} else{
            return this.iframe.dom.contentDocument;
        }
    },
      /**
     * @method executeCommand
     * @private Executes the command
     */
    executeCommand:function(cmd,param){
        //execute commands
        if(param) this.getDocument().execCommand(cmd, false, param);
        else this.getDocument().execCommand(cmd, false, null);
        
    },

    //set the focus inside the editor
    focus:function(){
        this.iframe.dom.contentWindow.focus();
    },
    
    getEl : function(){
		return this.el;
	},

	getToolbar : function(){
		return this.toolbar;	
	},
	
	getIFrame: function(){
		return this.iframe;
	},
	
	getFocusElement : function(){
		var doc, rng, sel, elm;

		doc = this.getDocument();

		if (Ext.ieIE) {
			rng = doc.selection.createRange();
			elm = rng.item ? rng.item(0) : rng.parentElement();
		} else {
			sel = this.getSel();
			rng = this.getRng();

			if (!sel || !rng)
				return null;

			elm = rng.commonAncestorContainer;
			//elm = (sel && sel.anchorNode) ? sel.anchorNode : null;

			// Handle selection a image or other control like element such as anchors
			if (!rng.collapsed) {
				// Is selection small
				if (rng.startContainer == rng.endContainer) {
					if (rng.startOffset - rng.endOffset < 2) {
						if (rng.startContainer.hasChildNodes())
							elm = rng.startContainer.childNodes[rng.startOffset];
					}
				}
			}

			// Get the element parent of the node
			elm = tinyMCE.getParentElement(elm);

			//if (tinyMCE.selectedElement != null && tinyMCE.selectedElement.nodeName.toLowerCase() == "img")
			//	elm = tinyMCE.selectedElement;
		}
		
		console.log(elm);
		return elm;
		
	},
	
	triggerNodeChange : function(focus, setup_content) {
		var elm, inst, editorId, undoIndex = -1, undoLevels = -1, doc, anySelection = false, st;

		if (tinyMCE.selectedInstance) {
			inst = tinyMCE.selectedInstance;
			elm = (typeof(setup_content) != "undefined" && setup_content) ? tinyMCE.selectedElement : inst.getFocusElement();

/*			if (elm == inst.lastTriggerEl)
				return;

			inst.lastTriggerEl = elm;*/

			editorId = inst.editorId;
			st = inst.selection.getSelectedText();

			if (tinyMCE.settings.auto_resize)
				inst.resizeToContent();

			if (setup_content && tinyMCE.isGecko && inst.isHidden())
				elm = inst.getBody();

			inst.switchSettings();

			if (tinyMCE.selectedElement)
				anySelection = (tinyMCE.selectedElement.nodeName.toLowerCase() == "img") || (st && st.length > 0);

			if (tinyMCE.settings['custom_undo_redo']) {
				undoIndex = inst.undoRedo.undoIndex;
				undoLevels = inst.undoRedo.undoLevels.length;
			}

			tinyMCE.dispatchCallback(inst, 'handle_node_change_callback', 'handleNodeChange', editorId, elm, undoIndex, undoLevels, inst.visualAid, anySelection, setup_content);
		}

		if (this.selectedInstance && (typeof(focus) == "undefined" || focus))
			this.selectedInstance.contentWindow.focus();
	}	

});
