/* $Id$ */
(function( $ )
{
	//var tbd = '';
    $.fn.editor = function( options )
    {
		if(arguments && arguments.length > 0 && typeof arguments[0] == "string")
		{
			var mode = arguments[0].toLowerCase();
			if(mode == 'close' || mode == 'cancel')
			{
				return this.each(function()
				{
					//user requested that the editor be closed.
					var mainEditor = $(this).data('editor');
					if(!mainEditor) return; //no editor was created
					mainEditor.destroy(mode);
				});
			}//if(arguments && arguments.length > 0 && arguments[0].toLowerCase() == 'close')
		}//if(arguments && arguments.length > 0 && typeof arguments[0] == "string")
		var opts = $.extend({}, $.fn.editor.defaults, options);
		//create a toolBarTemplate from the toolBar definition
		//tbd = createToolBar(eval(opts.toolBarDef));

		return this.each(function()
		{
			return (this instanceof Editor || $(this).data('editor')) ? $(this).init(opts): new Editor($(this), opts);
		});
    };//$.fn.editor(options)

	// define default behaviour - main item being the location of toolBarDefinition.
	$.fn.editor.defaults =
	{
		toolBarDef:
		[{
			mainMenu:
				[
                    {startBlock: 'yes'},
					{command:'bold', className: 'imgBold', text: ei18n['zohodiscussions.editor.bold']},//No I18N
                    {seperator: 'yes'},
					{command:'italic', className: 'imgItalic', text: ei18n['zohodiscussions.editor.italic']},//No I18N
                    {seperator: 'yes'},
					{command:'underline', className: 'imgUnderline', text: ei18n['zohodiscussions.editor.underline']},//No I18N
					{menuOptions: 'textformatOptions', defIndex: 2, className: 'imgTextFormat', text: ei18n['zohodiscussions.editor.textformat']},//No I18N
                    {endBlock: 'yes'},
					
                    {startBlock: 'yes'},
					{menuOptions: 'highlightOptions', defIndex: 6, menuCommand: 'hilitecolor', className: 'imgTexbg', text: ei18n['zohodiscussions.editor.highlight']},//No I18N
                    {endBlock: 'yes'},

                    {startBlock: 'yes'},
					{command:'insertUnOrderedlist', className: 'imgBullets', text: ei18n['zohodiscussions.editor.insert.unorderedlist']},//No I18N
                    {seperator: 'yes'},
					{command:'insertOrderedList', className: 'imgNumbering', text: ei18n['zohodiscussions.editor.insert.orderedlist']},//No I18N
                    {endBlock: 'yes'},

                    {startBlock: 'yes'},
					{command:'outdent', className: 'imgDecreaseIndent', text: ei18n['zohodiscussions.editor.outdent']},//No I18N
                    {seperator: 'yes'},
					{command:'indent', className: 'imgIncreaseIndent', text: ei18n['zohodiscussions.editor.indent']},//No I18N
                    {endBlock: 'yes'},
					
                    {startBlock: 'yes'},
					{menuOptions: 'justifyOptions', defIndex: 5, className: 'imgJustifyOption', text: ei18n['zohodiscussions.editor.justify']},//No I18N
                    {endBlock: 'yes'},
					
                    {startBlock: 'yes'},
					{callBack:'getEditor(\'$id$\').showLinkDialog()', className: 'imgLink', text: ei18n['zohodiscussions.editor.makelink']},//No I18N
                    {seperator: 'yes'},
					{command:'unlink', className: 'imgUnLink', text: ei18n['zohodiscussions.editor.unlink']},//No I18N
                    {endBlock: 'yes'},

                    {startBlock: 'yes'},
					{callBack:'getEditor(\'$id$\').showImageDialog()', className: 'imgInsertImage', text: ei18n['zohodiscussions.editor.insert.image']},//No I18N
                    {seperator: 'yes'},
					{callBack:'getEditor(\'$id$\').quote()', className: 'imgInsertQuote', text: ei18n['zohodiscussions.editor.quote']},//No I18N
                    {seperator: 'yes'},
                                        {callBack:'getEditor(\'$id$\').code()', className: 'imgInsertCode', text: ei18n['zohodiscussions.editor.code']},//No I18N
                    {seperator: 'yes'},
					{menuOptions: 'insertOptions', defIndex: 3, className: 'imgInsert', text: ei18n['zohodiscussions.editor.insert']},//No I18N
                    {endBlock: 'yes'},
                                        
                    {startBlock: 'yes'},
					{menuOptions: 'simleyOptions', defIndex: 4, menuCommand: 'insertImage', className: 'imgSmiley', text: ei18n['zohodiscussions.editor.insert.smiley']},//No I18N
                    //{endBlock: 'yes'},
					
                    //{startBlock: 'yes'},
                    //{callBack:'getEditor(\'$id$\').showHTMLMode()', className: 'imgHtml', text: 'HTML Mode'},
                    {endBlock: 'yes'},

//                                        {startBlock: 'yes'},
//					{callBack:'getEditor(\'$id$\').maximize()', className: 'imgView', text: 'maximize'},
//                                        {endBlock: 'yes'}
				]
                },
                {
                        headingOptions:
                                [
                                        {callBack:'getEditor(\'$id$\').insertHeading(\'h1\')', className: 'menuOptiontext', image: '<img width="18" height="18" border="0" src="/images/spacer.gif" class="imgHeading1"/>', text: ei18n['zohodiscussions.editor.heading1']},//No I18N
                                        {callBack:'getEditor(\'$id$\').insertHeading(\'h2\')', className: 'menuOptiontext', image: '<img width="18" height="18" border="0" src="/images/spacer.gif" class="imgHeading2"/>', text: ei18n['zohodiscussions.editor.heading2']},//No I18N
                                        {callBack:'getEditor(\'$id$\').insertHeading(\'h3\')', className: 'menuOptiontext', image: '<img width="18" height="18" border="0" src="/images/spacer.gif" class="imgHeading3"/>', text: ei18n['zohodiscussions.editor.heading3']},//No I18N
                                ]
                },
                {
                      textformatOptions:
                                [
                                        {command: "superscript", image: '<img width="18" height="18" border="0" src="/images/spacer.gif" class="imgSuperscript"/>', text: ei18n['zohodiscussions.editor.superscript'], className: 'menuOptiontext'},//No I18N
                                        {command: "subscript", image: '<img width="18" height="18" border="0" src="/images/spacer.gif" class="imgSubscript"/>', text: ei18n['zohodiscussions.editor.subscript'], className: 'menuOptiontext'},//No I18N
                                        {command: "strikethrough", image: '<img width="18" height="18" border="0" src="/images/spacer.gif" class="imgStrikethrough"/>', text: ei18n['zohodiscussions.editor.strikethrough'], className: 'menuOptiontext'},//No I18N
                                ]
                },
                {
                        insertOptions:
                            [
                                        {callBack:'getEditor(\'$id$\').showObjectDialog()', className: 'menuOptiontext',  image: '<img width="18" height="18" border="0" src="/images/spacer.gif" class="imgInsertObject"/>', text: ei18n['zohodiscussions.editor.insert.object']},//No I18N
                                        {callBack:'getEditor(\'$id$\').inserthorizontalrule()', className: 'menuOptiontext',  image: '<img width="18" height="18" border="0" src="/images/spacer.gif" class="imgInsertHR"/>', text: ei18n['zohodiscussions.editor.insert.horizontalrule']},//No I18N
                                        {callBack:'getEditor(\'$id$\').insertDate()', className: 'menuOptiontext',  image: '<img width="18" height="18" border="0" src="/images/spacer.gif" class="imgInsertDate"/>', text: ei18n['zohodiscussions.editor.insert.date']},//No I18N
                                        {callBack:'getEditor(\'$id$\').insertTime()', className: 'menuOptiontext',  image: '<img width="18" height="18" border="0" src="/images/spacer.gif" class="imgInsertTime"/>', text: ei18n['zohodiscussions.editor.insert.time']}//No I18N
                            ]
                },
                {
                    simleyOptions:
				[
					
					{option: "/images/smiley/smiley-smile.gif", text: '<img width="18" height="18" border="0" title="'+ei18n['zohodiscussions.editor.smiley.smile']+'" alt="'+ei18n['zohodiscussions.editor.smiley.smile']+'" src="/images/spacer.gif" class="imgInsertSmile"/>', className: 'flLeft clearSmileyBG'},//No I18N
					{option: "/images/smiley/smiley-tongue-out.gif", text: '<img width="18" height="18" border="0" title="'+ei18n['zohodiscussions.editor.smiley.tongue']+'" alt="'+ei18n['zohodiscussions.editor.smiley.tongue']+'" src="/images/spacer.gif" class="imgInsertTongueOut"/>', className: 'flLeft clearSmileyBG'},//No I18N
					{option: "/images/smiley/smiley-cool.gif", text: '<img width="18" height="18" border="0" title="'+ei18n['zohodiscussions.editor.smiley.cool']+'" alt="'+ei18n['zohodiscussions.editor.smiley.cool']+'" src="/images/spacer.gif" class="imgInsertCool"/>', className: 'flLeft clearSmileyBG'},//No I18N
					{option: "/images/smiley/smiley-foot-in-mouth.gif", text: '<img width="18" height="18" border="0" title="'+ei18n['zohodiscussions.editor.smiley.foot']+'" alt="'+ei18n['zohodiscussions.editor.smiley.foot']+'" src="/images/spacer.gif" class="imgInsertFootInMouth"/>', className: 'clearSmileyBG'},//No I18N
					{option: "/images/smiley/smiley-frown.gif", text: '<img width="18" height="18" border="0" title="'+ei18n['zohodiscussions.editor.smiley.frown']+'" alt="'+ei18n['zohodiscussions.editor.smiley.frown']+'" src="/images/spacer.gif" class="imgInsertFrown"/>', className: 'flLeft clearSmileyBG', parentClass: 'clear_both'},//No I18N
					{option: "/images/smiley/smiley-innocent.gif", text: '<img width="18" height="18" border="0" title="'+ei18n['zohodiscussions.editor.smiley.innocent']+'" alt="'+ei18n['zohodiscussions.editor.smiley.innocent']+'" src="/images/spacer.gif" class="imgInsertInnoncent"/>', className: 'flLeft clearSmileyBG'},//No I18N
					{option: "/images/smiley/smiley-kiss.gif", text: '<img width="18" height="18" border="0" title="'+ei18n['zohodiscussions.editor.smiley.kiss']+'" alt="'+ei18n['zohodiscussions.editor.smiley.kiss']+'" src="/images/spacer.gif" class="imgInsertKiss"/>', className: 'flLeft clearSmileyBG'},//No I18N
					{option: "/images/smiley/smiley-laughing.gif", text: '<img width="18" height="18" border="0" title="'+ei18n['zohodiscussions.editor.smiley.laughing']+'" alt="'+ei18n['zohodiscussions.editor.smiley.laughing']+'" src="/images/spacer.gif" class="imgInsertLaughing"/>', className: 'clearSmileyBG'},//No I18N
					{option: "/images/smiley/smiley-money-mouth.gif", text: '<img width="18" height="18" border="0" title="'+ei18n['zohodiscussions.editor.smiley.money']+'" alt="'+ei18n['zohodiscussions.editor.smiley.money']+'" src="/images/spacer.gif" class="imgInsertMoneyMouth"/>', className: 'clear_both flLeft clearSmileyBG', parentClass: 'clear_both'},//No I18N
					{option: "/images/smiley/smiley-sealed.gif", text: '<img width="18" height="18" border="0" title="'+ei18n['zohodiscussions.editor.smiley.sealed']+'" alt="'+ei18n['zohodiscussions.editor.smiley.sealed']+'" src="/images/spacer.gif" class="imgInsertSealed"/>', className: 'flLeft clearSmileyBG'},//No I18N
                    {option: "/images/smiley/smiley-cry.gif", text: '<img width="18" height="18" border="0" title="'+ei18n['zohodiscussions.editor.smiley.cry']+'" alt="'+ei18n['zohodiscussions.editor.smiley.cry']+'" src="/images/spacer.gif" class="imgInsertCry"/>', className: 'flLeft clearSmileyBG'},//No I18N
					{option: "/images/smiley/smiley-surprised.gif", text: '<img width="18" height="18" border="0" title="'+ei18n['zohodiscussions.editor.smiley.surprised']+'" alt="'+ei18n['zohodiscussions.editor.smiley.surprised']+'" src="/images/spacer.gif" class="imgInsertSurprised"/>', className: 'clearSmileyBG'},//No I18N
                    {option: "/images/smiley/smiley-embarassed.gif", text: '<img width="18" height="18" border="0" title="'+ei18n['zohodiscussions.editor.smiley.embarassed']+'" alt="'+ei18n['zohodiscussions.editor.smiley.embarassed']+'" src="/images/spacer.gif" class="imgInsertEmbarassed"/>', className: 'clear_both flLeft clearSmileyBG', parentClass: 'clear_both'},//No I18N
					{option: "/images/smiley/smiley-undecided.gif", text: '<img width="18" height="18" border="0" title="'+ei18n['zohodiscussions.editor.smiley.undecided']+'" alt="'+ei18n['zohodiscussions.editor.smiley.undecided']+'" src="/images/spacer.gif" class="imgInsertUndecided"/>', className: 'flLeft clearSmileyBG'},//No I18N
					{option: "/images/smiley/smiley-wink.gif", text: '<img width="18" height="18" border="0" title="'+ei18n['zohodiscussions.editor.smiley.wink']+'" alt="'+ei18n['zohodiscussions.editor.smiley.wink']+'" src="/images/spacer.gif" class="imgInsertWink"/>', className: 'flLeft clearSmileyBG'},//No I18N
					{option: "/images/smiley/smiley-yell.gif", text: '<img width="18" height="18" border="0" title="'+ei18n['zohodiscussions.editor.smiley.yell']+'" alt="'+ei18n['zohodiscussions.editor.smiley.yell']+'" src="/images/spacer.gif" class="imgInsertSmileyYell"/>', className: 'flLeft clearSmileyBG'}//No I18N

				]//simleyOptions
                },
                {
                            justifyOptions:
                            [
                                        {command: "justifyleft", image: '<img width="18" height="18" border="0" src="/images/spacer.gif" class="imgLeft"/>', text: ei18n['zohodiscussions.editor.justify.left'], className: 'menuOptiontext'},//No I18N
                                        {command: "justifycenter", image: '<img width="18" height="18" border="0" src="/images/spacer.gif" class="imgCenter"/>', text: ei18n['zohodiscussions.editor.justify.center'], className: 'menuOptiontext'},//No I18N
                                        {command: "justifyright", image: '<img width="18" height="18" border="0" src="/images/spacer.gif" class="imgRight"/>', text: ei18n['zohodiscussions.editor.justify.right'], className: 'menuOptiontext'},//No I18N
                                        {command: "justifyfull", image: '<img width="18" height="18" border="0" src="/images/spacer.gif" class="imgJustify"/>', text: ei18n['zohodiscussions.editor.justify'], className: 'menuOptiontext'}//No I18N
                            ]
                },
                {
                            highlightOptions:
				[

					{option: "#FFFFFF", text: '<div class = "highlightOption" style = "background-color:#FFFFFF"></div>', className: 'flLeftNone'},
					{option: "#FFF5EE", text: '<div class = "highlightOption" style = "background-color:#FFF5EE"></div>', className: 'flLeftNone'},
					{option: "#FFF8DC", text: '<div class = "highlightOption" style = "background-color:#FFF8DC"></div>', className: 'flLeftNone'},
					{option: "#FFFACD", text: '<div class = "highlightOption" style = "background-color:#FFFACD"></div>', className: 'flLeftNone'},
					{option: "#FFFFE0", text: '<div class = "highlightOption" style = "background-color:#FFFFE0"></div>', className: 'flLeftNone'},
					{option: "#98FB98", text: '<div class = "highlightOption" style = "background-color:#98FB98"></div>', className: 'flLeftNone'},

                    {option: "#AFEEEE", text: '<div class = "highlightOption" style = "background-color:#AFEEEE"></div>', className: '  clear_both'},
					{option: "#E6E6FA", text: '<div class = "highlightOption" style = "background-color:#E6E6FA"></div>', className: 'flLeftNone'},
					{option: "#DDA0DD", text: '<div class = "highlightOption" style = "background-color:#DDA0DD"></div>', className: 'flLeftNone'},
					{option: "#D3D3D3", text: '<div class = "highlightOption" style = "background-color:#D3D3D3"></div>', className: 'flLeftNone'},
					{option: "#FFC0CB", text: '<div class = "highlightOption" style = "background-color:#FFC0CB"></div>', className: 'flLeftNone'},
					{option: "#FFC0CB", text: '<div class = "highlightOption" style = "background-color:#FFC0CB"></div>', className: 'flLeftNone'},

                    {option: "#FFE4B5", text: '<div class = "highlightOption" style = "background-color:#FFE4B5"></div>', className: ' clear_both'},
					{option: "#F0E68C", text: '<div class = "highlightOption" style = "background-color:#F0E68C"></div>', className: 'flLeftNone'},
					{option: "#90EE90", text: '<div class = "highlightOption" style = "background-color:#90EE90"></div>', className: 'flLeftNone'},
					{option: "#20B2AA", text: '<div class = "highlightOption" style = "background-color:#20B2AA"></div>', className: 'flLeftNone'},
					{option: "#87CEFA", text: '<div class = "highlightOption" style = "background-color:#87CEFA"></div>', className: 'flLeftNone'},
					{option: "#6495ED", text: '<div class = "highlightOption" style = "background-color:#6495ED"></div>', className: 'flLeftNone'},

                    {option: "#EE82EE", text: '<div class = "highlightOption" style = "background-color:#EE82EE"></div>', className: ' clear_both'},
					{option: "#C0C0C0", text: '<div class = "highlightOption" style = "background-color:#C0C0C0"></div>', className: 'flLeftNone'},
					{option: "#F08080", text: '<div class = "highlightOption" style = "background-color:#F08080"></div>', className: 'flLeftNone'},
					{option: "#F4A460", text: '<div class = "highlightOption" style = "background-color:#F4A460"></div>', className: 'flLeftNone'},
					{option: "#FFA500", text: '<div class = "highlightOption" style = "background-color:#FFA500"></div>', className: 'flLeftNone'},
					{option: "#EEE8AA", text: '<div class = "highlightOption" style = "background-color:#EEE8AA"></div>', className: 'flLeftNone'},

                    {option: "#7FFF00", text: '<div class = "highlightOption" style = "background-color:#7FFF00"></div>', className: ' clear_both'},
					{option: "#48D1CC", text: '<div class = "highlightOption" style = "background-color:#48D1CC"></div>', className: 'flLeftNone'},
					{option: "#87CEEB", text: '<div class = "highlightOption" style = "background-color:#87CEEB"></div>', className: 'flLeftNone'},
					{option: "#7B68EE", text: '<div class = "highlightOption" style = "background-color:#7B68EE"></div>', className: 'flLeftNone'},
					{option: "#DA70D6", text: '<div class = "highlightOption" style = "background-color:#DA70D6"></div>', className: 'flLeftNone'},
					{option: "#808080", text: '<div class = "highlightOption" style = "background-color:#808080"></div>', className: 'flLeftNone'},

                    {option: "#FF0000", text: '<div class = "highlightOption" style = "background-color:#FF0000"></div>', className: ' clear_both'},
					{option: "#FF4500", text: '<div class = "highlightOption" style = "background-color:#FF4500"></div>', className: ''},
					{option: "#FF8C00", text: '<div class = "highlightOption" style = "background-color:#FF8C00"></div>', className: ''},
					{option: "#32CD32", text: '<div class = "highlightOption" style = "background-color:#32CD32"></div>', className: ''},
					{option: "#8FBC8F", text: '<div class = "highlightOption" style = "background-color:#8FBC8F"></div>', className: ''},
					{option: "#4169E1", text: '<div class = "highlightOption" style = "background-color:#4169E1"></div>', className: ''},

				]//simleyOptions
		},
        ],
		linkPrompter: _simplePrompt,
		imagePrompter: _simplePrompt,
		objectPrompter: _simplePrompt,
                minWidth: 500,
                minHeight: 250
	};//$.fn.editor.defaults

	function getEditor(editorId)
	{
                return $('#editor_'+editorId).data('editor');
	}


    /*
    * Editor class that holds a single editor instance
    */
	function Editor($el, options)
	{
            $.fn.editor.defaults.countEditors = $.fn.editor.defaults.countEditors ? $.fn.editor.defaults.countEditors + 1 : 1;
            //construct a new editor
            var assocId = $.fn.editor.defaults.countEditors;
            this.$boundTo = $el.show();
            var editorCss = this.$boundTo.position();
            editorCss.height = this.$boundTo.outerHeight()-2;
            editorCss.width = this.$boundTo.outerWidth()-2;

            this.$boundTo.hide();

            var thisObj = this;

            this.$boundTo.getEditor = function(){return thisObj};
            $el.data('editor', this);

            this.options = options;

			tbd = createToolBar(eval(options.toolBarDef));
            this.$editor = $(tbd.replace(/\$id\$/ig, assocId));

            //things dont work if I compute width etc after inserting to the textarea.
            //so gathering the required co-ords
            this.$editor
                    .css(editorCss)
                    .insertAfter(this.$boundTo);

            this.$editor.data('editor', this);

            this.boundId = assocId;
            this.options = options;
	}//function Editor(el, options)

	Editor.prototype.init = function()
	{
		//will be called when the editor is ready
		var assocId = this.boundId;
		this.$frame = $(eval('window.te_' + assocId));
		this.frame = eval('window.te_' + assocId);

		this.document = this.document || eval('window.te_' + assocId + '.document');

		//position the editor over the bound to element
		this.$editor.show();

		$('#te_' + assocId)
			.height(this.$editor.innerHeight()-15)
			.width(this.$editor.innerWidth()-4);


		if(this.$boundTo.is(':input'))
		{
			this.val(wrapInP(this.$boundTo.hide().val()));
		}
		else
		{
			this.val(wrapInP(this.$boundTo.hide().html()));
		}

	//var range = this.document.createRange();
	//range.selectNode(this.document.getElementsByTagName("p").item(0).firstChild);
	//range.deleteContents();

	function wrapInP(content) {
	    //return content;
	    if (content == "" || content == "<br>" || content == "<BR>") {
		return "<div><br/></div>"; //No I18N
	    } else {
		return content;
	    }
        }
        
		this.setDesignMode('On');

		eval('window.te_' + assocId + '.focus()');
		this.bindToolBarEvents();

        this.bindContextMenuEvents();
	};//function initEditor

    /**
     * Bind Context Menu Events
     */
    Editor.prototype.bindContextMenuEvents = function () {

		var assocId = this.boundId;
        var frameDoc = this.document;
        var frameObj = this;

        var frameOffset = $("#te_" + assocId).offset();

        var images = frameDoc.getElementsByTagName("img");
        for (j = 0; j< images.length; j++) {

            $(images[j]).click(function (e) {

                var rightclick;
                if (!e) var e = window.event;
                if (e.which)
                    rightclick = (e.which == 3);
                else if (e.button)
                    rightclick = (e.button == 2);

                if (!rightclick) {
                    // If it is a left click

                    var offset = $(this).offset();

                    var posx = 0;
                    var posy = 0;
                    if (offset.top < frameDoc.body.scrollTop) {
                        posx  = offset.left + frameOffset.left - frameDoc.body.scrollLeft;
                        posy = offset.top + frameOffset.top - frameDoc.body.scrollTop + (frameDoc.body.scrollTop - offset.Top);
                    } else {
                        posx  = offset.left + frameOffset.left - frameDoc.body.scrollLeft;
                        posy = offset.top + frameOffset.top - frameDoc.body.scrollTop;
                    }
                    var imgObj = $(this);

                    $("#imageContextMenu").hide().show()
                        .css("left", posx)
                        .css("top", posy)
                        .find(".cmImageEdit").unbind().click(function () {
                            frameObj.showImageDialog();
                            $("#imageContextMenu").hide();
                        })
                        .end()
                        .find(".cmImageDelete").unbind().click(function () {
                            var firstParent  = imgObj.parent();
                            if (firstParent.get(0).tagName.toLowerCase() == "span") {
                                firstParent.remove();
                            } else if (firstParent.get(0).tagName.toLowerCase() == "a") {
                                var secondParent = firstParent.parent();
                                if (secondParent.get(0).tagName.toLowerCase() == "span") {
                                    secondParent.remove();
                                }
                                firstParent.remove();
                            }
                            imgObj.remove();
                            $("#imageContextMenu").hide();
                        });
                }

                // To close the already opened menu if it was not used
                setTimeout('$("#imageContextMenu").hide();',5000);
            });
        }
    };

    /**
     * Link Contect Menu
     */
            Editor.prototype.showLinkContextMenu = function ()
	{
        
        var currentNode = this.getSelectedNode();
        if (currentNode && currentNode.tagName && (currentNode.tagName.toLowerCase() == "a"))
        {
            var assocId = this.boundId;
            var frameDoc = this.document;
            var frameOffset = $("#te_" + assocId).offset();
            var thisEditor = this;
            var $currentNode = $(currentNode);
            var offset = $currentNode.offset();
            var scrollTop = $(window).scrollTop();
            var posx = 0;
            var posy = 0;

            if (offset.top < frameDoc.body.scrollTop) {
                posx  = offset.left + frameOffset.left - frameDoc.body.scrollLeft;
                posy = offset.top + frameOffset.top - frameDoc.body.scrollTop + (frameDoc.body.scrollTop - offset.Top);
            } else {
                posx  = offset.left + frameOffset.left - frameDoc.body.scrollLeft;
                if ($.browser.msie)
                {
                    scrollTop = 0;
                }
               posy = frameOffset.top+(offset.top-scrollTop);
            }
            var linkLocation = $currentNode.attr("href");
            var linkText = $currentNode.attr("href");
            if(linkLocation.length > 50)
            {
                var lastThreeDig = linkLocation.length - 4;
                //to trim the link text to the maximum of 50 characters
                linkText = linkLocation.substring(0,40) + "[...]"+linkLocation.substring(lastThreeDig,linkLocation.length);
            }
            
            posy = posy + 20;
            $('#linkContextMenu').hide().show()
            .css("left", posx)
            .css("top", posy)
            .find('#cmLink').attr("href",linkLocation).attr("title",linkLocation).html(linkText)
            .end()
            .find('.imgAshEditLink').unbind().click(function () {
                thisEditor.showLinkDialog(currentNode);
                $("#linkContextMenu").hide();
            })
            .end()
            .find('.imgAshDeleteLink').unbind().click(function () {
                $currentNode.before($currentNode.html());
                $currentNode.remove();
                $("#linkContextMenu").hide();
            });

            // if it is a mailto link then disable popout option.
            if ($currentNode.attr("href").substr(0, 7) == "mailto:") {
                    $("#cmLinkPopout").hide();
            } else {
                    $("#cmLinkPopout").show();
            }
        } else {
            $('#linkContextMenu').hide();
        }
    }

	Editor.prototype.resize = function (newDimensions)
	{
		if (!newDimensions){return;}
		if(newDimensions.width < $.fn.editor.defaults.minWidth)
		{
			newDimensions.width = $.fn.editor.defaults.minWidth;
		}
		if(newDimensions.height < $.fn.editor.defaults.minHeight)
		{
			newDimensions.height = $.fn.editor.defaults.minHeight;
		}
		this.$editor.css(newDimensions);
		$('#te_' + this.boundId)
				.height(this.$editor.innerHeight()-15)
				.width(this.$editor.innerWidth()-4);
	}//Editor.prototype.resize(newDimensions)

	Editor.prototype.setDesignMode = function(designMode, stopIteration)
	{
		if(!designMode || designMode != 'On') designMode = 'Off'
		try
		{
			if($.browser.msie)
			{
				this.document.body.contentEditable = (designMode == 'On') ? true :  false;
			}
			else
			{
				this.document.designMode = designMode;
			}
			return;
		}
		catch(ex){}
		var thisObj = this;
		if(!stopIteration){setTimeout(function(){thisObj.setDesignMode(designMode, true);}, 100);}
	}

	Editor.prototype.destroy = function(mode)
	{
		this.$boundTo.data('editor', undefined);
		this.$editor.data('editor', undefined);
		if (mode != 'cancel')
		{
			if(this.$boundTo.is(':input'))
			{
				this.$boundTo.val(this.val());
			}
			else
			{
				this.$boundTo.html(this.val());
			}

			this.$boundTo.html(this.val());
		}
		this.setDesignMode ('Off');
		this.$editor.hide().html('').remove();
		//this is to remove attachments container from editor
                $('#editorHolder').parent().siblings('div[purpose="editorActionUtilCont"],div[purpose="editorAuthorProfileCont"]').remove().end().remove();
                this.$boundTo.parent().remove();
	};//destroy()

	Editor.prototype.val = function (newContent)
	{
		if (newContent)
		{
			//if ie browser, then wrap the content with a div - so that line spacing is taken care.
			if (newContent.replace(/^\s+/,'').indexOf('<div>') < 0)
			{
				newContent = "<div>" + newContent + "</div>";
			}
			$(this.document).find('body').html(newContent);
		}
		else
		{
			try
			{
				this.document.getElementById('ted').removeAttribute('id');
			}
			catch(ex){}
			if(this.$boundTo.is(':visible'))
			{
				return this.$boundTo.val();
			}
			var $body = $(this.document).find('body');
			removeNestedCodeBlocks ($body);
			return $(this.document).find('body').html();
		}
	};//function val (newContent)

	function removeNestedCodeBlocks($body)
	{
		//make sure we remove all multiple lines in code block and replace with single ol li
                var $codeBlocks = $body.find('ol.code');
		$codeBlocks.each(function (index, eachCodeBlock)
		{
			var codeBlockHTML = $(eachCodeBlock).html();
			$(eachCodeBlock).get(0).innerHTML = codeBlockHTML.replace(/<\/?ol(\s[^>]*)?>/ig, '');
		});//$codeBlocks.each(function (eachCodeBlock)
		$codeBlocks.find ('> span, > div, > p').wrap('li');
	}//function removeNestedCodeBlocks($body)

	function removeNestedCodeBlocks_dombased ($body)
	{
		//make sure we remove all multiple lines in code block and replace with single ol li
                var $codeBlocks = $body.find('ol.code');
                //make sure there are no nested code blocks
                var $nestedCode = $codeBlocks.find('ol.code');
                while($nestedCode && $nestedCode.length > 0)
                {
                    //nested ol.code blocks exist. Remove them
                    $nestedCode.each(function(index, eachNestedCode){
                        var $eachNestedCode = $(eachNestedCode);
                        $($eachNestedCode.html()).insertBefore($eachNestedCode);
                    });
                    $nestedCode.remove();
                    $nestedCode = $codeBlocks.find('ol.code');
                }//while($nestedCode && $nestedCode.length > 0)
	}//function removeNestedCodeBlocks ($body)
	/*
	*  assigns basic toolbar events.
	*/

	Editor.prototype.bindToolBarEvents = function()
	{
		var $toolBarContainer = this.$editor.find('div.toolBar');
		var thisEditor = this;
		var menuSlideHandles = new Array();
		//bind simple toolbar items that have a command to execute
		$( 'div.toolBarItem', $toolBarContainer)
			.hover(function(){$(this).addClass('toolBarItemHover')}, function(){$(this).removeClass('toolBarItemHover')})
			.click(function(event)
			{
				var $this = $(this);
				cmd = $this.attr('command');
                                assocMenu = $this.attr('assocMenu');
				callBack = $this.attr('callBack');
				$('div.menuOptions', $toolBarContainer).hide();
				if(cmd)
				{   
                                        thisEditor.execCommand(cmd);
					event.preventDefault();
					return false;
				}
				else if (assocMenu)
				{   
                                    thisEditor.prepareForPopup();
					$(assocMenu)
						.css({left: $this.position().left, top : ($this.position().top + $this.outerHeight())})
						.toggle();
				}
				else if(callBack)
				{
					eval(callBack);
				}
			});//$('div.toolBarItem').click(function(event)

		$('div.menuOptions', $toolBarContainer).hover(
			function()
			{
				id = '' + $(this).attr('id');
				if(menuSlideHandles[id])
				{
					clearTimeout(menuSlideHandles[id]);
					menuSlideHandles[id] = null;
				}
			},
			function()
			{
				var $this = $(this);
				menuSlideHandles[''+this.id] = setTimeout(function(){$this.hide();}, 500);
			}
		);//$('div.menuOptions').hover(

		$('div.menuOption', $toolBarContainer)
			.click(function(event){
				var $this = $(this);
				cmd = $this.parent().attr('command');
                                if(!cmd){
                                    cmd = $this.attr('command');
                                    if (cmd) {
                                        $this.parent().parent().hide();
                                    }
                                } else {
                                    $this.parent().hide();
                                }

                                if(!cmd) {
                                    callBack = $this.attr('callBack');
                                    if(callBack) {
                                        $this.parent().parent().hide();
                                        eval(callBack);
                                    } else {
                                        return;
                                    }
                                } else {
                                  thisEditor.execCommand(cmd, $this.attr('option'),"true");
                                  event.preventDefault();
                                  return false;
                                }
			})
			.hover(
				function(){$(this).addClass('menuHover');},
				function(){$(this).removeClass('menuHover');}
			);

		$(this.document)
			.keydown(function(event){thisEditor.routeEvents(event);})
			.keypress(function(event){thisEditor.routeEvents(event);})
			.mousedown(function(event){thisEditor.routeEvents(event);})
			.mouseup(function(event){thisEditor.routeEvents(event);});
	};//function bindToolBarEvents()

	Editor.prototype.routeEvents = function(event)
	{
		if(event.type == "keydown" || event.type == "keypress")
		{
			if(event.keyCode == 116 || event.keyCode == 9)
			{
				//user pressed Ctrl-F5 or tab, ignore the event
				if (event.keyCode == 9)
				{
					event.preventDefault();
					event.stopPropagation();
					//this.insertCustomHTML ('\t');
					if ($.browser.msie)
					{
						this.prepareForPopup();
						this.currRange.pasteHTML("&nbsp;&nbsp;&nbsp;&nbsp;"); //No I18N
					}
					else
					{this.document.execCommand('insertHTML', false, "&nbsp;&nbsp;&nbsp;&nbsp;")}; //No I18N
				}
				return true;
			}
			if(event.ctrlKey)
			{
				var input = String.fromCharCode(event.keyCode).toLowerCase();
				var cmd=null;
				switch(input)
				{
					case 'b': cmd="bold";break;
					case 'i': cmd="italic";break;
					case 'u': cmd="underline";break;
					case 'l': cmd="justifyleft";break;
					case 'e': cmd="justifycenter";break;
					case 'r': cmd="justifyright";break;
					case 'j': cmd="justifyfull";break;
					//case 't': cmd="indent";break;
					//case 'd': cmd="outdent";break;
				}//switch(input)
				if(cmd)
				{
					this.execCommand(cmd);
					this.updateToolBar();
					this.$frame.focus();
					event.preventDefault();
					return false;
				}//if(cmd)
			}//if(event.ctrlKey)
			else
			{
				/*var currKey = String.fromCharCode(event.keyCode).toLowerCase();
				if (event.keyCode == 13)
				{
					//user pressed enter
					var currentParent = this.getSelectedNode().parentNode;
					while (currentParent)
					{

						if (currentParent.tagName.toLowerCase() == 'pre' && currentParent.className == 'likeCode')
						{
							break;
						}
						currentParent = currentParent.parentNode;
					}
					
				}*/
			}
		}//if(event.type == "keydown" || event.type == "keypress")
        
        // This is for showing the context menu for links
        this.showLinkContextMenu();

		this.updateToolBar();
	};//routeEvents(event)

	Editor.prototype.execCommand = function(command, options,isMenu)
	{ 
            if(!options) options = null;
            this.frame.focus();
            if($.browser.msie && isMenu == "true")
            {   
                if(command == "hilitecolor")
                {
                    command = "backcolor";
                }
                this.currRange.select();
            }
            this.document.execCommand(command, false, options);
        };

	Editor.prototype.updateToolBar = function()
	{
		if(this.utimer)
			clearTimeout(this.utimer);
		var thisObj = this;
		this.utimer = setTimeout(function(){thisObj.doUpdate();},100);
	};

	Editor.prototype.doUpdate = function()
	{
		var commands = $('div.toolBarItem', this.$editor).get();

		for( var i = 0; i < commands.length; i ++)
		{
			var $menuOption = $(commands[i]);
			var commandToCheck = $menuOption.attr('command');
			try
			{
				if(this.document.queryCommandState(commandToCheck))
				{
					$menuOption.addClass('toolBarItemSelected');
				}
				else
				{
					$menuOption.removeClass('toolBarItemSelected');
				}
			}catch(ex){}
		}//for( var i = 0; i < commands.length; i ++)
	};//doUpdate = function()

	Editor.prototype.getSelection = function()
	{
		//return window.te.getSelection ? window.te.getSelection() : this.document.selection;
		return this.document.selection || this.$frame.get(0).getSelection();
	};//Editor.prototype.getSelection = function()

	Editor.prototype.getRange = function(selection)
	{
		seletion = selection || this.getSelection();
		if(selection.createRange)
		{
			return selection.createRange();
		}
		else
		{
			//if (typeof selection != "undefined")
			if(selection)
			{
				this.$frame.focus();
				try
				{
					return selection.getRangeAt(0);
				}
				catch(e){}
			}
			return this.document.createRange();
		}
		return null;
	};//Editor.prototype.getRange()

	Editor.prototype.getSelectedNode = function()
	{
		var selection = this.getSelection();
		var range = this.getRange(selection);
                if(selection && selection.type && !$.browser.safari)
		{
			//ie.
			switch (selection.type)
			{
				case "Text":
				case "None":
					return range.parentElement();
				case "Control":
					return range.item(0);
				default:
					return this.document.body;
			}
		}
		else
		{
			try
			{
				var p = range.commonAncestorContainer;
				if (
						!range.collapsed
					&&
						range.startContainer == range.endContainer
					&&
						range.startOffset - range.endOffset <= 1
					&&
						range.startContainer.hasChildNodes()
				)
				{
					p = range.startContainer.childNodes[range.startOffset];
				}
				while (p.nodeType == 3)
				{
					p = p.parentNode;
				}
				return p;
			}
			catch (e)
			{
				return null;
			}
		}
		return null;
	};//Editor.prototype.getSelectedNode ()

	Editor.prototype.getParentAnchor = function(node)
	{
		if(!node) node = this.getSelectedNode();
		if(!node) return null;
		while(node.tagName && (node.tagName.toLowerCase() != 'a') && node.parentNode)
		{
			node = node.parentNode;
		}
		if(node.tagName && node.tagName.toLowerCase() == 'a')
		{
			return node;
		}
		else
		{
			return null;
		}
	};//Editor.prototype.getParentAnchor()

    /**
     * Retrieve the currently selected image
     */
	Editor.prototype.getParentImage = function(node)
	{
		if(!node) node = this.getSelectedNode();
		if(!node) return null;
		while(node.tagName && (node.tagName.toLowerCase() != 'img') && node.parentNode)
		{
			node = node.parentNode;
		}
		if(node.tagName && node.tagName.toLowerCase() == 'img')
		{
            var firstParent = node.parentNode;
            if (firstParent.tagName.toLowerCase() == "a") {
                if (firstParent.parentNode.tagName.toLowerCase() == "span") {
                    node = firstParent.parentNode;
                } else {
                    node = firstParent;
                }
            } else if (firstParent.tagName.toLowerCase() == "span") {
                node = firstParent;
            }
			return node;
		}
		else
		{
			return null;
		}
	};//Editor.prototype.getParentImage()

	Editor.prototype.showImageDialog = function()
	{
        $('#screen').show();
		this.prepareForPopup();
		var thisObj = this;
        var parentImage = this.getParentImage();
		this.options.imagePrompter(parentImage, function(linkToAdd){thisObj.addImage(linkToAdd)});
	};//Editor.prototype.showImageDialog

	Editor.prototype.showObjectDialog = function()
	{
        $('#screen').show();
// ######remove following prepareForPopup
		//this.prepareForPopup();
		var thisObj = this;
		this.options.objectPrompter(function(linkToAdd){thisObj.insertObject(linkToAdd);});
	};

	Editor.prototype.showLinkDialog = function(parentAnchor)
	{
        $('#screen').show();
        this.prepareForPopup();

        if (!parentAnchor) {
            parentAnchor = this.getParentAnchor();
            if (!parentAnchor) {
                // If the current selection is not a node, try to see if it is just a text
                parentAnchor = this.currSelectedText;
            }
        }
        this.options.linkPrompter(parentAnchor);
	};//Editor.prototype.showLinkDialog

    Editor.prototype.showHTMLMode = function()
    {
            if(! this.$boundTo.is(':visible'))
            {
                this.$boundTo.val(this.val());
                this.$boundTo.show().focus();
                this.$editor.hide();
                var $backToEditor = $('<div style = "text-decoration:underline;cursor:pointer">Back to Editor</div>');
                var _self = this;
                $backToEditor.click (function()
                {
                    var htmlValue = _self.$boundTo.val();
                    htmlValue = (htmlValue) ? htmlValue : "<br/>";
                    _self.$editor.show();
                    _self.$boundTo.hide();
                    _self.val(htmlValue);
                    $backToEditor.hide().remove();
                    _self.bindContextMenuEvents();
                });//$backToEditor.click (function()
                this.$boundTo.parent().append($backToEditor);
            }//if(! this.$boundTo.is(':visible'))
    };

	function _simplePrompt(callBack)
	{
		var newUrl = prompt('Url to add');
		if(newUrl)
			callBack(newUrl);
	}

	Editor.prototype.addImage = function (imageUrl, props)
	{
            var $myImageDialog = $("#imageDialog");
            var toInsert = "";
            if (props && props.linkTo && $.trim(props.linkTo)!= "")
            {
                toInsert = toInsert + "<a href = '" + props.linkTo + "' target='_blank'>"
            }
            
            toInsert = toInsert + '<img border="0" src = "'+ imageUrl + '"';
            if (props && props.altText)
            {
              toInsert = toInsert + "alt='" + props.altText + "'";
            }
            if (props && props.title)
            {
              toInsert = toInsert + "title='" + props.title + "'";
            }
            if (props && props.htmlClass)
            {
              toInsert = toInsert + "class='" + props.htmlClass + "'";
            }
            if($('#urldiv').is(':visible')) {
                if (props && props.width)
                {
                  toInsert = toInsert + "width='" + props.width + "px'";
                }
                if (props && props.height)
                {
                    toInsert = toInsert + "height='" + props.height + "px'";
                }
            }
            toInsert = toInsert + "style='";

            if (props && props.border)
            {
                toInsert = toInsert + "border:" + props.border + props.border_px  + " solid #efefef;";
            }
            if (props && props.padding)
            {
                toInsert = toInsert + "padding:" + props.padding +  props.padding_px + "; margin:0px 2px;";
            }
            
            toInsert = toInsert + "' ";

            if (props && props.htmlClass)
            {
                toInsert = toInsert + "class='" + props.htmlClass + "'";
            }
            toInsert += ">";
            if (props && props.linkTo && $.trim(props.linkTo)!= "")
            {
                toInsert += "</a>";
            }

            var currentImageNode = this.getParentImage();
            if(currentImageNode) {
                $(currentImageNode).remove();
            }
            this.insertCustomHTML(toInsert);

            // Bind the context Menu Event for the images.
            //TODO Binding should be done only for new images.
            this.bindContextMenuEvents();
	};//addImage

	Editor.prototype.insertObject = function (objectHTML)
	{   
		objectHTML = '<span style = "border:1px solid grey;width:24px;height:24px;background-color:grey">' + objectHTML + '</span>';
		this.insertCustomHTML(objectHTML);
	};

    Editor.prototype.prepareForPopup = function ()
	{
            this.$frame.focus();
            if (window.getSelection)
            {
                    this.currSelection = this.frame.getSelection();
                    this.currSelectedText = this.currSelection;
            }
            else if ($.browser.msie) { // should come last; Opera!
                    this.currSelection = this.document.selection.createRange();
                    this.currSelectedText = this.currSelection.text;
            }
            this.currRange = this.getRangeObject(this.currSelection);
	};//prepareForPopup()

    Editor.prototype.maximize = function ()
    {
        //opens up the editor in full screen mode or restores back
        var newDimensions = {};
        if (this.$editor.attr('currentState') == 'maximized')
        {
          //page is already maximized
          //now restore the editor dimensions
          newDimensions.top = this.$editor.attr('originalTop');
          newDimensions.left = this.$editor.attr('originalLeft');
          newDimensions.height = this.$editor.attr('originalHeight');
          newDimensions.width = this.$editor.attr('originalWidth');
          newDimensions.position = this.$editor.attr('originalPosition');
          this.$editor.attr('currentState', 'restored');
          $('#te_' + this.boundId)
                  .height(newDimensions.height-15)
                  .width(newDimensions.width-4);
          this.$editor.css (newDimensions);
          //this.$editor.height(newDimensions.height);
          //this.$editor.width(newDimensions.width);
          this.$editor.get(0).style.width = newDimensions.width+"px";
          this.$editor.get(0).style.height = newDimensions.height+"px";
        }//if (this.$editor.attr('currentState') == 'maximized')
        else //currently not maximized. So maximize
        {
          //first save the current width and height of the editor
          this.$editor.attr('originalHeight', this.$editor.innerHeight());
          this.$editor.attr('originalWidth', this.$editor.innerWidth()); //use this later to reset size
          this.$editor.attr('originalLeft', this.$editor.css('left'));
          this.$editor.attr('originalTop', this.$editor.css('top')); //use this later to reset size
          this.$editor.attr('originalPosition', this.$editor.css('position'));

          //now maximize the editor dimensions
          newDimensions.top = 0;
          newDimensions.left = 0;
          newDimensions.height = ($(window).height()-10);
          newDimensions.width = $(window).width();
          newDimensions.position = 'absolute';

          this.$editor.attr('currentState', 'maximized');
          this.$editor.css (newDimensions);
          $('#te_' + this.boundId)
                  .height(this.$editor.innerHeight()-15)
                  .width(this.$editor.innerWidth()-4);
        }//else - end of maximization
    };//Editor.prototype.maximize()

	Editor.prototype.getRangeObject = function (selectionObject)
	{
		this.$frame.focus();
		if($.browser.msie)
			return selectionObject;
		else if($.browser.safari)
		{ // Safari!
			var range = this.frame.document.createRange();
			range.setStart(selectionObject.anchorNode,selectionObject.anchorOffset);
			range.setEnd(selectionObject.focusNode,selectionObject.focusOffset);
			if(range == "")
                        {
                            range.setStart(selectionObject.focusNode,selectionObject.focusOffset);
                            range.setEnd(selectionObject.anchorNode,selectionObject.anchorOffset);
                        }
			return range;

		}
		else if (selectionObject.getRangeAt) {
			return selectionObject.getRangeAt(0);
        }
	};//function getRangeObject(selectionObject

	Editor.prototype.addLink = function (urlToAdd, displayText, options)
	{
	    this.insertCustomHTML('<a href = "' + urlToAdd + '"' + options + '>'+displayText+'</a>'+' ');
	};//addLink (urlToAdd, title)

	Editor.prototype._createNewRange = function()
	{
		if($.browser.msie) {
			return this.document.body.createTextRange();
		} else {
			return this.document.createRange();
		}
	}
	Editor.prototype.moveCursor = function (div, start, offset) 
	{
		if(!div) {return;}

		var range = this._createNewRange();
	if ($.browser.msie) {
		if(div.nodeType == 3) {// Text Node
			range.moveToElementText(div.parentNode);
		}else {
			range.moveToElementText(div);
		}

		if(start) {
			offset = 0;	
		}else if(!offset) {
			offset = range.text.length;
		}

		range.move("character" , offset); //No I18N	
		range.select();
	}else {
		if($.browser.opera) {
			if(div.nodeType != 3) {
				var ln = div.childNodes.length - 1;
				while(ln > 0) {
					if(div.childNodes[ln].nodeType == 3) {
						div = div.childNodes[ln];
						break;
					}
					ln--;
				}
			}
			range.selectNodeContents(div);
			range.setStart(div, range.endOffset);
		}else {
			if(offset) {
				range.setEnd(div , offset);
			}else {
				if(div.nodeName.toLowerCase() == 'img') {
					range.selectNode(div);
				}else {
					range.selectNodeContents(div);
				}
			}
		}
		var sel = this.getSelection();
		sel.removeAllRanges();
		sel.addRange(range);
		if(start) {
			sel.collapseToStart();
		}else {
			sel.collapseToEnd();	
		}
	}		
}//Editor.prototype.moveCursor

	Editor.prototype.quote = function()
	{   
	    this.prepareForPopup();
	    var toInsert= null;
	    /*if($.browser.msie)
	    {
		    toInsert = this.currRange.htmlText;
	    }
	    else
	    {
		    var df = this.currRange.cloneContents();
		    var tdiv = this.document.createElement("div");
		    tdiv.appendChild(df);
		    toInsert = tdiv.innerHTML;
	    }*/
	    toInsert = this.getHTMLFromCurrentRange();
	    if(!toInsert || toInsert == ''){toInsert = '&nbsp;';}
	    var blockQuote = this.document.createElement('blockquote');
	    blockQuote.className = 'block_quote';
	    blockQuote.innerHTML = '<div id = "__zd_newele__">'+toInsert+'</div>';
	    this.insertCustomHTML (blockQuote);
	    blockQuote.parentNode.insertBefore(this.document.createElement('br'), blockQuote);
	    var newQuote = this.document.getElementById('__zd_newele__');
	    this.moveCursor(newQuote, true);
	    newQuote.id = '';
	    return;
	};//addQuote

	Editor.prototype.removeFormat = function()
	{
		this.prepareForPopup();
		this.execCommand('removeFormat');
		//loop through each child item
	}
        Editor.prototype.getHTMLFromCurrentRange = function()
	{
		var toInsert;
		if($.browser.msie)
	        {
                    toInsert = this.currRange.htmlText;
                    toInsert = toInsert.replace(/(\r|\n)/ig, "").replace(/(<p>&nbsp;<\/p>)/ig,"");
                }
                else
                {
		    var df = this.currRange.cloneContents();
                    var tdiv = this.document.createElement("div");
                    tdiv.appendChild(df);
                    toInsert = tdiv.innerHTML;
                }
		return toInsert;
	}
	Editor.prototype.code = function()
	{
            var toInsert= null;
	    this.prepareForPopup();
            var node = this.getSelectedNode();
	    toInsert = this.getHTMLFromCurrentRange();
            /*if($.browser.msie)
	    {
		    toInsert = this.currRange.htmlText;
                    toInsert = toInsert.replace(/(\r|\n)/ig, "").replace(/(<p>&nbsp;<\/p>)/ig,"");
            }
	    else
	    {       var df = this.currRange.cloneContents();
                    var tdiv = this.document.createElement("div");
                    tdiv.appendChild(df);
		    toInsert = tdiv.innerHTML;
            }*/
	    while (node && node.parentNode && node.parentNode.tagName)
	    {
		if(node.parentNode.tagName.toLowerCase() == 'ol' && node.parentNode.className == 'code')
            	{
			//there is already a ol tag for code. So, IF THE CONTENT IS EMPTY, then  insert this next to that ol tag
			if (toInsert)
			{
				//user trying to create a new code block for something that already exists inside a code block. Do not allow this
                		return;
			}
			else
			{
				//insert a new code block next to the current code block.
				//node = node.parentNode;
				var newCode = this.document.createElement('ol');
				newCode.className = 'code';
				newCode.innerHTML = '<li class="alt"><span id = "__zd_newele__">&nbsp;</span></li>';
				node = node.parentNode;
				if (node.nextSibling)
				{
					node.parentNode.insertBefore (this.document.createElement ('br'), node.nextSibling);
					node.parentNode.insertBefore (newCode, node.nextSibling);
				}
				else
				{
					node.parentNode.appendChild (this.document.createElement('br'));
					node.parentNode.appendChild(newCode);
					node.parentNode.appendChild (this.document.createElement('br'));
				}
				newCode = this.document.getElementById('__zd_newele__');
			        this.moveCursor(newCode, true);
			        newCode.id = '';
				return;
			}
            	}
	    	node = node.parentNode;
	    }//while (node && node.parentNode)
            toInsert = toInsert.replace(/\n/ig,'<li></li>');
            toInsert = toInsert.replace(/<\/p>|<br>|<\/div>/ig, '</li><li>').replace(/p(\s[^>]*)?>|<div(\s[^>]*)?>/ig, '');
            var newCode = this.document.createElement('ol');
            newCode.className = 'code';
	    if(!toInsert)
	    {
		 toInsert = '<li id = "__zd_newele__" class="alt"></li>';
	    }
	    else
	    {
            	toInsert = '<li id = "__zd_newele__" class="alt">' + toInsert + '</li>';
	    }

            toInsert = toInsert.replace(/(<li><\/li>|<li> <\/li>)/ig,'');
	    newCode.innerHTML = toInsert;
            this.insertCustomHTML(newCode);
	    if (!newCode.nextSibling)
	    {
		newCode.parentNode.appendChild(this.document.createElement ('br'));
	    }
	    newCode = this.document.getElementById('__zd_newele__');
	    this.moveCursor(newCode, true);
	    newCode.id = '';
        };//code

    /**
     * Insert a heading
     * headingType - h1, h2 or h3
     */
	Editor.prototype.insertHeading = function(headingType)
	{
	    this.prepareForPopup();
	    var toInsert = '<'+ headingType + '>' + this.currSelectedText + '</'+ headingType + '>';
            this.insertCustomHTML(toInsert);
        };//insertHeading

	Editor.prototype.insertCustomHTML = function (toInsert)
	{
            this.$frame.focus();
            var currSelection = this.getSelection();
            if($.browser.msie)
            {
                this.currRange.select();
            }
            else if($.browser.safari)
            {
                this.currSelection.setBaseAndExtent(this.currRange.startContainer,this.currRange.startOffset,this.currRange.endContainer,this.currRange.endOffset);
            }
	    else
	    {
		this.currRange = this.getRange (currSelection);
	    }

            if(this.currRange.clear)
            {
                this.currRange.clear();
            }
            else if(this.currRange.deleteContents)
            {
                this.currRange.deleteContents();
            }
            if(this.currRange.pasteHTML)
            {
		if (toInsert.innerHTML)
		{
                	this.currRange.pasteHTML (toInsert.outerHTML);
		}
		else
		{
			this.currRange.pasteHTML (toInsert);
		}
            }
            else
            {
		if (!toInsert.innerHTML)
		{
                	var insertObj = this.document.createElement('span');
                	insertObj.innerHTML = toInsert;
	                this.currRange.insertNode(insertObj);
		}
		else
		{
			this.currRange.insertNode(toInsert);
		}
            }
	};//insertCustomHTML (toInsert)

	Editor.prototype.removeLink = function ()
	{
		var a = this.getParentAnchor();
		if(a)
		{
			$(a).replaceWith($(a).text());
		}
	};//Editor.prototype.removeLink()
        
        Editor.prototype.inserthorizontalrule = function()
	{
	    //this.prepareForPopup();
            var toInsert = "<hr style='width: 100%; height: 2px;'>";
	    this.insertCustomHTML(toInsert);
	};//inserthorizontalrule
	
        Editor.prototype.insertDate = function()
	{
	    var currentDate = new Date();
	    var toInsert = currentDate.getFullYear() + '-' + currentDate.getMonth() + '-' + currentDate.getDate();
	    this.insertCustomHTML(toInsert);
	};//insertDate

	Editor.prototype.insertTime = function()
	{
	    var currentDate = new Date();
            var hour = currentDate.getHours();
            var minutes = currentDate.getMinutes();
            var seconds = currentDate.getSeconds();
            
            hour = (hour < 10) ? "0" + hour : hour;
            minutes = (minutes < 10) ? "0" + minutes : minutes;
            seconds = (seconds < 10) ? "0" + seconds : seconds;
            
	    var toInsert = hour + ':' + minutes + ':' + seconds;
	    this.insertCustomHTML(toInsert);
	};//insertTime
        
    /*
    * private function to construct the editor
    */
	function createToolBar (toolBarDef)
	{
		var toolBarHTML = '<div id = "editor_$id$" unselectable="on" style = "display:none">\n';
		toolBarHTML += '<div class = "toolBar" unselectable="on" >';
		var menuOptionHTML = '<div>\n';
		$.each(toolBarDef[0].mainMenu, function(index, item)
		{
            if(!item)
            {
                return;
            }
            if (item.startBlock) {
                   toolBarHTML += '<div class = "startBlock"></div>' ;
            }
            else if (item.seperator) {
                   toolBarHTML += '<div class = "seperator"></div>' ;
            }
            else if (item.endBlock) {
                   toolBarHTML += '<div class = "endBlock"></div>' ;
            }
			else if (item.command)
			{
				toolBarHTML += '<div class = "toolBarItem" command = "' + item.command + '" unselectable="on"><img src= "/images/spacer.gif" class="' + item.className + '" alt = "' + item.text + '" title = "' + item.text + '"></div>'; //alt = "' + item.text + '"
			}
			else if(item.callBack)
			{
				toolBarHTML += '<div class = "toolBarItem" callBack = "' + item.callBack + '" unselectable="on"><img  src= "/images/spacer.gif" class="' + item.className + '" alt = "' + item.text + '" title = "' + item.text + '"></div>'; //alt = "' + item.text + '"
			}
			else if (item.menuOptions)
			{
				toolBarHTML += '<div class = "toolBarItem" assocMenu = "#' + item.menuOptions + '_$id$" unselectable="on">\n';
				toolBarHTML += '<img src= "/images/spacer.gif" class="' + item.className + '" alt = "' + item.text + '" title = "' + item.text + '"></div>'; //alt = "' + item.text + '"
				menuOptionHTML += buildMenuOptions(item, eval('toolBarDef[' + item.defIndex + '].' + item.menuOptions));
			}
		});
		menuOptionHTML += '</div>';
		toolBarHTML += menuOptionHTML ;
		toolBarHTML += '<div id = "frameContainer_$id$" style = "float:left;min-height:0;margin-left:-8px;margin-right:-1px;"><iframe src = "/html/blank.html" style="margin-top:0px;border:1px solid #ccc;background-color:#fff;" id = "te_$id$" name = "te_$id$" frameborder="0" onload = "$(\'#editor_$id$\').data(\'editor\').init();"></iframe></div>';
		toolBarHTML += '</div></div>';
		return toolBarHTML;
	}//function createToolBar (toolBarDef)

	/*helper function to build menu dropdowns*/
	function buildMenuOptions(menuOptionDef, menuOptions)
	{
		var toLoop = menuOptions;
                if (!menuOptionDef.menuCommand) {
                    var menuOptionHTML = '<div id = "' + menuOptionDef.menuOptions + '_$id$" class = "menuOptions" >\n';
                    $.each(toLoop, function(menuOptionIndex, eachMenuOption){
                        if(!eachMenuOption)
                        {
                            return;
                        }
                        if (eachMenuOption.image) {
                            menuOptionHTML += '<div><div class = "menuOptionImg">' + eachMenuOption.image  + '</div>';
                        }
                        menuOptionHTML += '<div class = "menuOption ' + (eachMenuOption.className || ' ') + '" ';
                        if(eachMenuOption.callBack) {
                            menuOptionHTML += 'callBack = "' + eachMenuOption.callBack + '" ';
                        }
                        if(eachMenuOption.command) {
                            menuOptionHTML += 'command = "' + eachMenuOption.command + '" ';                                
                        }
                        menuOptionHTML += '>' + eachMenuOption.text + '</div>';
                        if (eachMenuOption.image) {
                            menuOptionHTML += '</div>\n';
                        }
                    });//$.each(menuOptionDef, function(menuOptionIndex, eachMenuOption){
                    menuOptionHTML += '\n</div>';                    
                } else {
                    var menuOptionHTML = '<div id = "' + menuOptionDef.menuOptions + '_$id$" class = "menuOptions" command = "' + menuOptionDef.menuCommand + '">\n';
                    $.each(toLoop, function(menuOptionIndex, eachMenuOption){
                        if(!eachMenuOption)
                        {
                            return;
                        }
                        if (eachMenuOption.image)
                        {
                            menuOptionHTML += '<div><div class = "menuOptionImg">' + eachMenuOption.image  + '</div>';
                        }
                        menuOptionHTML += '<div class = "menuOption ' + (eachMenuOption.className || ' ') + '" option = "' + eachMenuOption.option + '">' + eachMenuOption.text + '</div>';
                        if (eachMenuOption.image) {
                            menuOptionHTML += '</div>\n';
                        }
                    });//$.each(menuOptionDef, function(menuOptionIndex, eachMenuOption){
                    menuOptionHTML += '\n</div>';                    
                }
		return menuOptionHTML;
	}//function buildMenuOptions(menuOptionDef, menuOptions, boundToId)
})(jQuery);