// Cross-Browser Rich Text Editor
// http://www.kevinroth.com/rte/demo.htm
// Written by Kevin Roth (kevin@NOSPAMkevinroth.com - remove NOSPAM)
// Visit the support forums at http://www.kevinroth.com/forums/index.php?c=2

//init variables
var isRichText = false;
var rng;
var currentRTE;
var allRTEs='';

var isIE;
var isGecko;
var isSafari;
var isKonqueror;

var imagesPath;
var includesPath;
var cssFile;

var sourceRTES=new Array();
var hdnFld=new Array();
var jLib_controls=new Array();
var curSelectedObj=new Array(); 

function submitForm() {
	updateRTEs();
	return true;
}

function initRTE(imgPath, incPath, css, prop) {
		//Инициализация диалога таблиц
		document.tableDialogIns=new insertTableDLG('tableDialogIns');
		
		//иниц. диалога свойств
		if(prop){
			document.propDialog=new propertiesEditor('propDialog');
			this.props=true;
		}else this.props=false;
        //set browser vars
        var ua = navigator.userAgent.toLowerCase();
        isIE = ((ua.indexOf("msie") != -1) && (ua.indexOf("opera") == -1) && (ua.indexOf("webtv") == -1));
        isGecko = (ua.indexOf("gecko") != -1);
        isSafari = (ua.indexOf("safari") != -1);
        isKonqueror = (ua.indexOf("konqueror") != -1);
        //check to see if designMode mode is available
        if (document.getElementById && document.designMode && !isSafari && !isKonqueror) {
                isRichText = true;
        }

        if (isIE) {
                document.onmouseover = raiseButton;
                document.onmouseout  = normalButton;
                document.onmousedown = lowerButton;
                document.onmouseup   = raiseButton;
        }

        //set paths vars
        imagesPath = imgPath;
        includesPath = incPath;
        cssFile = css;

        if (isRichText) document.writeln('<style type="text/css">@import "/css/wysiwyg_editor.css";</style>');
		/*
        if (isRichText){
			var stl=document.createElement("style");
			stl.type='text/css';
			stl.text='@import "/css/wysiwyg_editor.css";';
			//stl.text='/css/wysiwyg_editor.css';
			document.body.appendChild(stl);
		}
		*/		
        //for testing standard textarea, uncomment the following line
        //isRichText = false;
}

function placeRichText(place,txt,rte,html,width,height,buttons) {
		var readOnly=false;
		var puts=new Array();
		puts['rte']=rte;
		puts['width']=width;
		puts['height']=height;
		puts['imagesPath']=imagesPath;
		puts['includesPath']=includesPath;
		
		if(txt) hdnFld[rte]=txt;
		var placeObj=document.getElementById(place);
		if(placeObj==undefined) return false;
        if (isRichText) {
                if (allRTEs.length > 0) allRTEs += ";";
                allRTEs += rte;
                if (readOnly) buttons = false;
				/*
                //adjust minimum table widths
                if (isIE) {
                        if (buttons && (width < 540)) width = 540;
                        var tablewidth = width;
                } else {
                        if (buttons && (width < 540)) width = 540;
                        var tablewidth = width + 4;
                }
				*/
				tablewidth = parseInt(width) + 4;
				puts['tablewidth']=tablewidth;	puts['width']=width;
				
				var resout='', buttons_tmp=new Array(), lines_tmp=new Array();
                if (buttons == true) {
					for(var i=0, cnt=bar.buttons.length; i<cnt; i++){
						for(var k=0, kcnt=bar.buttons[i].length; k<kcnt; k++){
							if( bar.dropdown[bar.buttons[i][k]]==undefined ){ 
								//BUTTONS
								var tmp= bar.buttons[i][k]!='separator' ? tpl.bar_button.tpl.replace(/{command_code}/g,	bar.commands[ bar.buttons[i][k] ] || bar.commands['def_command'] ) : tpl.bar_button_sep.tpl ;
								tmp=tmp.replace(/{command}/g, bar.buttons[i][k] );
								tmp=tmp.replace(/{commandMSG}/g,	bar.msg[ bar.buttons[i] ]||bar.buttons[i][k] );
								for(var j=0, jcnt=tpl.bar_button.place.length; j<jcnt; j++) tmp=tmp.replace('{'+tpl.bar_button.place[j]+'}',puts[tpl.bar_button.place[j]]);

								buttons_tmp.push(tmp);
							}else{
								//SELECTS
								var opt_tmp='';
								for(var j=0, jcnt= bar.dropdown[bar.buttons[i][k]].length; j<jcnt; j++ ) 
									opt_tmp+='<option value="'+bar.dropdown[bar.buttons[i][k]][j][0]+'">'+bar.dropdown[bar.buttons[i][k]][j][1] +'</option>';
								var tmp='<td><select id="'+bar.buttons[i][k]+'_'+rte+'" onchange="selectFont(\''+rte+'\', this.id);">'+opt_tmp+'</select></td>';
								buttons_tmp.push(tmp);
							}
						}
						lines_tmp.push( tpl.bar_line.tpl.replace('{line}',buttons_tmp.join(tpl.bar_buttons_separator.tpl)) );
						buttons_tmp=new Array();
					}
					if(this.props){
						//buttons_tmp.push('<td><input type="text" id="prop_'+rte+'style" onBlur="document.propDialog.set_prop(\''+rte+'\',this);" value="Стиль" disabled></td>');
						var barProp=new Array(
							'<td><div id="'+rte+'classDIV" style="position:relative;"></div></td>'
						);
						lines_tmp.push ( tpl.bar_line.tpl.replace('{line}', barProp.join(tpl.bar_buttons_separator.tpl)) );
					}
					//Составляю ВСЕ блоки вместе
					var tmp=tpl.container.tpl.replace('{body}',  tpl.bar_body.tpl.replace('{body}', lines_tmp.join(tpl.bar_line_sep.tpl)) );
					tmp=tmp.replace('{toggler}',  tpl.toggler.tpl);
					tmp=tmp.replace('{tagParams}',  tpl.tagParams.tpl);
					for(var j=0, jcnt=tpl.bar_body.place.length; j<jcnt; j++) tmp=tmp.replace(new RegExp('{'+tpl.bar_body.place[j]+'}','g'),puts[tpl.bar_body.place[j]]);
					for(var j=0, jcnt=tpl.container.place.length; j<jcnt; j++) tmp=tmp.replace(new RegExp('{'+tpl.container.place[j]+'}','g'),puts[tpl.container.place[j]]);
					resout+=tmp;
//					alert(tmp);
					
                } else {
					if(navigator.appVersion.indexOf('MSIE')>1){
					  resout+='<table class="rteBack" cellpadding="0" cellspacing="0" id="Buttons_' + rte + '" width="' + tablewidth + '">';
					  resout+='        <tr>';
					  if(ShowCopyBut){
						resout+='                <td><img class="rteImage" src="' + imagesPath + 'copy.gif" width="25" height="24" alt="Paste" title="Copy to clipboard" onClick="CopyToClipboard(\'' + rte + '\');"></td>';
					  }
					  if(ShowPasteBut){
						resout+='                <td><img class="rteImage" src="' + imagesPath + 'paste.gif" width="25" height="24" alt="Paste" title="Paste from clipboard" onClick="PasteFromClipboard(\'' + rte + '\');"></td>';
					  }
					  resout+='                <td width="100%"></td>';
					  resout+='        </tr>';
					  resout+='</table>';
					}
               }
				
				if(!txt){
					//Если реального Тэга TEXTAREA в форме небыло - создать 
					resout+='<textarea id="hdn' + rte + '" name="' + rte + '" style="display:none; width:'+width+'px; height:'+height+'px;" value=""></textarea>';
					hdnFld[rte]='hdn'+rte;
				}else{	// Иначе использовать тот, что был
					document.getElementById(hdnFld[rte]).style.display='none';
					document.getElementById(hdnFld[rte]).style.width=width+'px';
					document.getElementById(hdnFld[rte]).style.height=(parseInt(height)+22)+'px';
				}
				
				placeObj.innerHTML=resout;
				if(txt){
					var tst=document.getElementById(hdnFld[rte]).value;
					if(tst!='') html=tst;
				}
				document.getElementById(hdnFld[rte]).value = html;
                enableDesignMode(rte, jLib_show_objs(rte,html), readOnly);
				jset_events(rte);
        } else {
				if(!txt) {
					resout='<textarea name="' + rte + '" id="' + rte + '" style="width: ' + width + 'px; height: ' + height + 'px;">' + html + '</textarea>';
					placeObj.innerHTML=resout;
				}
        }
}

var bar={
	buttons:[
		['formatblock','justifyleft','justifycenter','justifyright','justifyfull','separator','undo','redo','separator'],
		['bold','italic','strikethrough','removeformat','separator'],
		['increasefontsize','decreasefontsize','superscript','subscript','separator'],
		['hyperlink','unlink','separator'],
		['insertorderedlist','insertunorderedlist','outdent','indent','separator','inserthorizontalrule','inserttable','insertfile','cleancode']
	],
	ieonly:[
		['assa']
	],
	drops:	['css','font_size','font_face'],
	dropdown:{
		'formatblock':[
			['class','=Select='],
			['<p>','Paragraph'],
			['<h2>','Header2'],
			['<h3>','Header3']
		]
	},
	commands:{
		def_command	:	'rteCommand(\'{rte}\', \'{command}\'); return false;',
		forecolor	:	'dlgColorPalette(\'{rte}\',\'forecolor\',\'\'); return false;',
		hilitecolor	:	'dlgColorPalette(\'{rte}\',\'hilitecolor\',\'\'); return false;',
		hyperlink	:	'dlgInsertLink(\'{rte}\'); return false;',
		inserttable	:	'dlgInsertTable(\'{rte}\',\'inserttable\',true); return false;',
		insertfile	:	'dlgInsertFile(\'{rte}\',\'insertfile\',true); return false;',
		'cleancode':'CleanHTMLCode(\'{rte}\'); return false;'
	},
	msg:{
		'bold':'Жирно',
		'italic':'Криво',
		'underline':'Потдать'
	}
};

var tpl={
	container:{
		tpl:'<div id="{rte}Container" style="width:{width}px;" class="rteDiv"><table border=0 style="width:{width}px;" cellpadding=0 cellspacing=0><tr><td>{body}</td></tr><tr><td><iframe id="{rte}" name="{rte}" style="width:{width}px; height:{height}px;" src=""></iframe></td></tr></table></div> <div style="width:{tablewidth}px; border:1px solid #949494;">{toggler}{tagParams}</div> <div style="width:{width}px;" id="exProp{rte}"></div>',
		place:['rte','width','height','includesPath']
	},
	bar_body:{
		tpl:'<DIV id="Buttons_{rte}" style="width:{tablewidth}px; height:30px; background-color:#FFFFFF;">{body}</DIV>',
		place:['rte','tablewidth']
	},
	bar_line:{
		tpl:"<table style=\"float:left;\" cellpadding=0 cellspacing=1 border=0><tr>{line}</tr></table>"
	},
	bar_line_sep:{
		tpl:''
	},
	bar_button:{
		tpl:'<td> <button style="width:25px; height:25px; padding:0px; background-color:white; border:1px solid #e4e4e4;" id="{rte}_{command}ID" alt="{commandMSG}" title="{commandMSG}" onClick="{command_code}"><img src="{imagesPath}{command}.gif"> </button></td>',
		place:['rte','command','imagesPath','commandMSG']
	},
	bar_button_sep:{
		tpl:'<td><img class="rteVertSep" src="{imagesPath}blackdot.gif" width="1" height="20" border="0" alt=""></td>',
		place:['imagePath']
	},
	bar_buttons_separator:{
		tpl:''
	},
	toggler:{
		tpl:'<span style="padding-right:20px; "> <input id="chkSrc{rte}" onclick="toggleHTMLSrc(\'{rte}\',true,true);" type="checkbox">&nbsp;<label for="chkSrc{rte}">В формате HTML</label></span>',
		place:['rte']
	},
	tagParams:{
		tpl:'<span style="color:blue; font-weight:bold;" id="{rte}_params"></span>',
		place:['rte']
	},
	ex_props_body:{
		tpl:'<table>{body}</table>'
	},
	ex_props_line:{
		tpl:'<tr><td>{caption}</td><td>{field}</td></tr>'
	}
};

var usControls={
	panel:{
		control_name:'Панель',
		dscr:'Базовый контрол, умеет вывести свое тело или шаблон',
		params:{
			tpl	:'Шаблон контрола',
			pg	:'Тело контрола',
			test:{
				dscr:'Пробный параметр',
				defaults:'DefValue'
			}
		}
	}
}

function CopyToClipboard(rte){
	var oRTE=frames[rte].document;
	var s=oRTE.body.innerHTML;
	s=s.replace(/<([a-z][^>]*)*>/gi, TagOpenEncode64);
	s=s.replace(/<\/([a-z][^>]*)*>/gi, TagCloseEncode64);
	s=s.replace(/\/&/gi, '/ &');
	//s=s.replace(/\&nbsp;/gi, ' ');
	s=s.replace(/\&amp;/gi, ' and ');
	window.clipboardData.setData('text', s);
}

function PasteFromClipboard(rte){
	var oRTE=frames[rte].document;
	var s=window.clipboardData.getData('text');
	s=s.replace(/<_([a-z][^>]*)*>/gim, TagOpenDecode64);
	s=s.replace(/<_\/([a-z][^>]*)*>/gim, TagCloseDecode64);
	s=s.replace(/\/ &/gi, '/&');
	oRTE.body.innerHTML=s;
}

function enableDesignMode(rte, html, readOnly) {
        var frameHtml = "<html id=\"" + rte + "\">\n";
        frameHtml += "<head>\n";
        //to reference your stylesheet, set href property below to your stylesheet path and uncomment
        if (cssFile.length > 0) {
                frameHtml += "<link media=\"all\" type=\"text/css\" href=\"" + cssFile + "\" rel=\"stylesheet\">\n";
        } else {
                frameHtml += "<style>\n";
                frameHtml += "body {\n";
                frameHtml += "        background: #FFFFFF;\n";
                frameHtml += "        margin: 0px;\n";
                frameHtml += "        padding: 0px;\n";
                frameHtml += "}\n";
                frameHtml += "</style>\n";
        }
        frameHtml += "</head>\n";
        frameHtml += "<body>\n";
        frameHtml += html + "\n";
        frameHtml += "</body>\n";
        frameHtml += "</html>";

        if (document.all) {
                var oRTE = frames[rte].document;
				
                oRTE.open();
                oRTE.write(frameHtml);
                oRTE.close();
				
                if (!readOnly){
                   oRTE.designMode = "On";
                   frames[rte].document.attachEvent("onmouseover", function evt_ie_keypress(event) {ieKeyPress(event, rte);});
                   frames[rte].document.attachEvent("onkeydown", function evt_ie_keydown(event) {ieKeyDown(event, rte);});
//                   frames[rte].document.attachEvent("onkeypress", function evt_ie_keypress(event) {ieKeyPress(event, rte);});
                }
        } else {
                try {
                        try {
                                var oRTE = document.getElementById(rte).contentWindow.document;
                                oRTE.open();
                                oRTE.write(frameHtml);
                                oRTE.close();
								/*
                                if (isGecko && !readOnly) {
                                        //attach a keyboard handler for gecko browsers to make keyboard shortcuts work
                                        oRTE.addEventListener("keypress", kb_handler, true);
                                }
                                //SymbCount(rte, rte+'_symb', 'rte_moz');
								*/
						} catch (e) { alert("Error preloading content."); }
                        if (!readOnly) document.getElementById(rte).contentDocument.designMode = "on";						
                } catch (e) {
                        //gecko may take some time to enable design mode.
                        //Keep looping until able to set.
                        if (isGecko) {	
								return false;
                                setTimeout("enableDesignMode('" + rte + "', '" + html + "', " + readOnly + ");", 10);
                        } else {
                                return false;
                        }
                }
        }
}

function updateRTEs() {
        var vRTEs = allRTEs.split(";");		
        for (var i = 0; i < vRTEs.length; i++) {
			updateRTE(vRTEs[i]);
        }
}

function updateRTE(rte) {
        if (!isRichText) return;

        //set message value
        var oHdnMessage = document.getElementById(hdnFld[rte]);
        var oRTE = document.getElementById(rte);
        var readOnly = false;

        //check for readOnly mode
        if (document.all) {
                if (frames[rte].document.designMode != "On") readOnly = true;
        } else {
                if (document.getElementById(rte).contentDocument.designMode != "on") readOnly = true;
        }

        if (isRichText && !readOnly) {
                if (oHdnMessage.value == null) oHdnMessage.value = "";
                if (document.all) {
                        oHdnMessage.value = frames[rte].document.body.innerHTML;
                } else {
                        oHdnMessage.value = oRTE.contentWindow.document.body.innerHTML;
                }
                //if there is no content (other than formatting) set value to nothing
                if (stripHTML(oHdnMessage.value.replace("&nbsp;", " ")) == "" && oHdnMessage.value.toLowerCase().search("<hr") == -1 && oHdnMessage.value.toLowerCase().search("<img") == -1) oHdnMessage.value = "";
                //fix for gecko
                if (escape(oHdnMessage.value) == "%3Cbr%3E%0D%0A%0D%0A%0D%0A") oHdnMessage.value = "";
        }
}

function rteCommand(rte, command, option, uclass) {
        //function to perform command
				var oRTE;
				if (document.all) {	oRTE = frames[rte];
				} else {						oRTE = document.getElementById(rte).contentWindow; }
        
				try {
					oRTE.focus();
					oRTE.document.execCommand(command, false, option);
					if(uclass) { //Если указан класс Тэга
						var nodes = get_selected_tags(oRTE, option);
						alert(nodes);
						for(var i = 0; i < nodes.length; i++)	nodes[i].className = uclass;
					}
					oRTE.focus();
        } catch (e) {
//                alert(e);
//                setTimeout("rteCommand('" + rte + "', '" + command + "', '" + option + "');", 10);
        }
				jset_events(rte);
}

function toggleHTMLSrc(rte) {
        //contributed by Bob Hutzel (thanks Bob!)
        var oRTE;
        if (document.all) {
                oRTE = frames[rte].document;
        } else {
                oRTE = document.getElementById(rte).contentWindow.document;
        }
		if(sourceRTES[rte]==undefined) sourceRTES[rte]=false; //нету отметки - значит код не показывается.
		if( sourceRTES[rte]==false){//показать код, спятать HTML
			//showHideElement("Buttons_" + rte, "hide");
			//updateRTEs();
			document.getElementById(hdnFld[rte]).value=jLib_show_objs_code(rte, oRTE.body.innerHTML);
			document.getElementById(rte+'Container').style.display='none';
			document.getElementById(hdnFld[rte]).style.display='';
			sourceRTES[rte]=true;
		}else{//Спятать код , показать HTML
			oRTE.body.innerHTML=jLib_show_objs(rte,document.getElementById(hdnFld[rte]).value);
			document.getElementById(rte+'Container').style.display='';
			document.getElementById(hdnFld[rte]).style.display='none';
			sourceRTES[rte]=false;
			jset_events(rte);
		}
}

function dlgColorPalette(rte, command) {
        //function to display or hide color palettes
        if(!setRange(rte)){
			alert('Make Selection');
			return;
		}
        //get dialog position
        var oDialog = document.getElementById('colorpalette');
        var buttonElement = document.getElementById(rte+'_'+command + 'ID');
        var iLeftPos = getOffsetLeft(buttonElement);
        var iTopPos = getOffsetTop(buttonElement) + (buttonElement.offsetHeight);
		var rteEl=document.getElementById(rte+'Container');
        iLeftPos += getOffsetLeft(rteEl);
		iTopPos  += getOffsetTop(rteEl);
        oDialog.style.left = (iLeftPos) + "px";
        oDialog.style.top = (iTopPos) + "px";
        if ((command != parent.command) || (rte != currentRTE)) {
			oDialog.style.display='none';
		}
		
        //save current values
        parent.command = command;
        currentRTE = rte;
		//if current command dialog is currently open, close it
		if (oDialog.style.display=="none")	showHideElement(oDialog, 'show');
		else 								showHideElement(oDialog, 'hide');
}

function dlgInsertTable(rte, command,nw) {
        //function to open/close insert table dialog
        //save current values
		setRange(rte);
		parent.command = command;
		currentRTE = rte;
		if(!nw){
			var windowOptions = 'history=no,toolbar=0,location=0,directories=0,status=0,menubar=0,scrollbars=no,resizable=no,width=360,height=200';
			window.open(includesPath + 'insert_table.htm', 'InsertTable', windowOptions);
		}else {
			//alert(document.tableDialogIns);return;
			document.tableDialogIns.show(rte,command);
		}
}

function dlgInsertFile(rte, command,nw) {
        //function to open/close insert table dialog
        //save current values
		setRange(rte);
		parent.command = command;
		currentRTE = rte;
		var windowOptions = 'history=no,toolbar=0,location=0,directories=0,status=0,menubar=0,scrollbars=no,resizable=no';
		try{
			//var ret=window.showModalDialog('/admin/pop/filedialog', 'InsertFile', windowOptions);
			var ret=window.showModalDialog('/tpl/_sys/pop/insertfile/filedialog.php', 'InsertFile', windowOptions);
			insertHTML(ret);
		}catch(e){
			alert('Ошибка диалога файл-менеджера.');
		}
}


function dlgInsertLink(rte) {
    //function to insert link
    var szURL = prompt("Enter a URL:", "", "target", "");
    try {
			rteCommand(rte, "Unlink", null);
			rteCommand(rte, "CreateLink", szURL);
    } catch (e) {
			alert('LINK ERROR');
      //do nothing
    }
}

function setColor(color) {
        //function to set color
        var rte = currentRTE;
        var parentCommand = parent.command;

        if (document.all) {
                //retrieve selected range
                var sel = frames[rte].document.selection;
                if (parentCommand == "hilitecolor") parentCommand = "backcolor";
                if (sel != null) {
                        var newRng = sel.createRange();
                        newRng = rng;
                        newRng.select();
                }
        }

        rteCommand(rte, parentCommand, color);
        showHideElement('colorpalette', "hide");
		toggleHTMLSrc(rte);toggleHTMLSrc(rte);
}

function addImage(rte) {
        //function to add image
        imagePath = prompt('Enter Image URL:', 'http://');
        if ((imagePath != null) && (imagePath != "")) {
                rteCommand(rte, 'InsertImage', imagePath);
        }
}

// Ernst de Moor: Fix the amount of digging parents up, in case the RTE editor itself is displayed in a div.
// KJR 11/12/2004 Changed to position palette based on parent div, so palette will always appear in proper location regardless of nested divs
function getOffsetTop(elm) {
        var mOffsetTop = elm.offsetTop;
        var mOffsetParent = elm.offsetParent;
        var parents_up = 2; //the positioning div is 2 elements up the tree

        while(parents_up > 0) {
                mOffsetTop += mOffsetParent.offsetTop;
                mOffsetParent = mOffsetParent.offsetParent;
                parents_up--;
        }

        return mOffsetTop;
}

// Ernst de Moor: Fix the amount of digging parents up, in case the RTE editor itself is displayed in a div.
// KJR 11/12/2004 Changed to position palette based on parent div, so palette will always appear in proper location regardless of nested divs
function getOffsetLeft(elm) {
        var mOffsetLeft = elm.offsetLeft;
        var mOffsetParent = elm.offsetParent;
		if(!mOffsetParent) mOffsetParent=0;
        var parents_up = 2;

        while(parents_up > 0) {
                mOffsetLeft += mOffsetParent.offsetLeft;
                mOffsetParent = mOffsetParent.offsetParent;
                parents_up--;
        }

        return mOffsetLeft;
}

function selectFont(rte, selectname) {
        //function to handle font changes
        var idx = document.getElementById(selectname).selectedIndex;
        // First one is always a label
        if (idx != 0) {
                var selected = document.getElementById(selectname).options[idx].value;
                var cmd = selectname.replace('_' + rte, '');
				if(cmd=='formatblock'){
					var tmp_arr=selected.split('_');
					if(tmp_arr[1]){
							selected=tmp_arr[0];
							uclass=tmp_arr[1];
							//Очистка предыдущего.
								if (document.all) var tmpO = frames[rte];
								else var tmpO = document.getElementById(rte).contentWindow;
								var bounds=get_selection_bounds(tmpO);
								for(var i=0; i<bounds.length; i++) alert(bounds[i]);
					}else	uclass=false;
				}
                rteCommand(rte, cmd, selected, uclass);
                document.getElementById(selectname).selectedIndex = 0;
        }
}

//*****************
//IE-Only Functions
//*****************
function ieKeyPress(ev, rte) {
       SymbCount(rte, rte+'_symb', 'rte_ie');
}
// clean from word formatting
function ieKeyDown(ev, rte) {
/*
       if(ev.ctrlKey && ev.keyCode==86){
       	var oRTE=frames[rte].document;
       	oRTE.body.innerHTML='';

       	PasteFromClipboard(rte);

       	window.clipboardData.setData('text', '');
       }

       if(ev.ctrlKey && ev.keyCode==67){
       	var oRTE=frames[rte].document;
       	oRTE.body.innerHTML=oRTE.body.innerHTML;

       	CopyToClipboard(rte);
       }
*/
}

// clean clipboard from word formatting
function CleanClipboard(rte) {
       	var oRTE=frames[rte].document;
       	oRTE.body.innerHTML='';
       	rteCommand(rte, 'paste');
       	oRTE.body.innerHTML=CleanCode(oRTE.body.innerHTML);
}


// clean up code
function CleanHTMLCode(rte) {
       	var oRTE=frames[rte].document;
       	oRTE.body.innerHTML=CleanCode(oRTE.body.innerHTML);
}

//									John 
//	to delete container tags				<tag> someData </tag>
//	Для удаления контейнерных тэгов <tag> someData </tag>
function delInTags (txt, tag, tag2){
	var limit=100;
	if(tag2==undefined){ tag2='</'+tag+'>'; tag='<'+tag+'>'; }
	do{
		var pfrom=txt.search(tag);
		var pto=txt.search(tag2); pto+=tag2.length;
		if(pfrom>0 && pto>0){
			txt=txt.substring(0, pfrom)+txt.substring(pto);
		}else break;
		limit--;
	}while( limit>0 )
	return txt;
}

function CleanCode(D){
	D=delInTags (D, 'xml');
	D=delInTags (D, 'style');
	
	// make one line
/*	D = D.replace(/\r\n/g, ' ').
		replace(/\n/g, ' ').
		replace(/\r/g, ' ').
		replace(/\&nbsp\;/g,' ');
*/

	//clean up tags
	D = D.replace(/<b [^>]*>/gi,'<b>').
		replace(/<i [^>]*>/gi,'<i>').
		replace(/<div [^>]*>/gi,'<br>').
		replace(/<li [^>]*>/gi,'<li>').
		replace(/<ul [^>]*>/gi,'<ul>').
		replace(/<meta [^>]*>/gi,'').
		replace(/<link [^>]*>/gi,'')
		.replace(/<xml>.*<\/xml>/gim,'')
		;
		

	// keep tags, strip attributes
	D = D.replace(/ class=[^\s|>]*/gi,'').
		replace(/<p [^>]*TEXT-ALIGN: justify[^>]*>/gi,'<p align="justify">').
		replace(/ style=\"[^>]*\"/gi,'').
		replace(/ align=[^\s|>]*/gi,'');
	// replace outdated tags
	D = D.replace(/<b>/gi,'<strong>').
		replace(/<\/b>/gi,'</strong>');
	// mozilla doesn't like <em> tags
	D = D.replace(/<em>/gi,'<i>').
		replace(/<\/em>/gi,'</i>');
	// kill unwanted tags
	D = D.replace(/<\?xml:[^>]*>/g, '').       // Word xml
		replace(/<\/?st1:[^>]*>/g,'').     // Word SmartTags
		replace(/<\/?[a-z]\:[^>]*>/g,'').  // All other funny Word non-HTML stuff
		replace(/<\/?font[^>]*>/gi,'').    // Disable if you want to keep font formatting
		replace(/<\/?span[^>]*>/gi,' ').
		replace(/<\/?div[^>]*>/gi,' ').
		replace(/<\/?pre[^>]*>/gi,' ').
		replace(/<\/?a[^>]*>/gi,' ').
		replace(/<\/?h[1-6][^>]*>/gi,' ');
	//remove empty tags
	D = D.replace(/<strong><\/strong>/gi,'').
	replace(/<i><\/i>/gi,'').
	replace(/<P[^>]*><\/P>/gi,'');
	// nuke double tags
	oldlen = D.length + 1;
	while(oldlen > D.length) {
		oldlen = D.length;
		// free the tags
		D = D.replace(/<([a-z][a-z]*)> *<\/\1>/gi,' ').
			replace(/<([a-z][a-z]*)> *<([a-z][^>]*)> *<\/\1>/gi,'<$2>');
	}
	D = D.replace(/<([a-z][a-z]*)><\1>/gi,'<$1>').
		replace(/<\/([a-z][a-z]*)><\/\1>/gi,'<\/$1>');
	// nuke double spaces
	D = D.replace(/  */gi,' ');

	if(D.substring(0, 4)=='<br>') D=D.substring(4);
	D=trim(D)
	if(D.substring(0, 4)=='<br>') D=D.substring(4);
	D=trim(D)
	if(D.substring(0, 4)=='<br>') D=D.substring(4);

	return trim(D);
}

function kb_handler(evt) {
        var rte = evt.target.id;

        //contributed by Anti Veeranna (thanks Anti!)
        if (evt.ctrlKey) {
                var key = String.fromCharCode(evt.charCode).toLowerCase();
                var cmd = '';
                switch (key) {
                        case 'b': cmd = "bold"; break;
                        case 'i': cmd = "italic"; break;
                        case 'u': cmd = "underline"; break;
                };

                if (cmd) {
                        rteCommand(rte, cmd, null);
                        // stop the event bubble
                        evt.preventDefault();
                        evt.stopPropagation();
                }
         }
}

function insertHTML(html) {
        //function to add HTML -- thanks dannyuk1982
        var rte = currentRTE;
        var oRTE;
        if (document.all) {
			oRTE = typeof(rte)=='string'?frames[rte]:rte;
        } else {
			oRTE = typeof(rte)=='string'?document.getElementById(rte).contentWindow:rte;
        }

        oRTE.focus();
        if (document.all) {
			oRTE.document.selection.createRange().pasteHTML(html);
        } else {
			oRTE.document.execCommand('insertHTML', false, html);
        }
}

function showHideElement(element, showHide) {
        //function to show or hide elements
        //element variable can be string or object
        if (document.getElementById(element)) element = document.getElementById(element);
		else if(typeof(element)!='object'){alert('"'+element+'" not found element is '+typeof(element)); return true;}
        if (showHide == "show") {
                element.style.display = "";
        } else if (showHide == "hide") {
                element.style.display = "none";
        }
}

function setRange(rte) {
        //function to store range of current selection
        var oRTE;
        if (document.all) {
                oRTE = typeof(rte)=='string'?frames[rte]:rte;
                var selection = oRTE.document.selection;
                if (selection != null) rng = selection.createRange();
				else return false;
        } else {
                oRTE = typeof(rte)=='string'?document.getElementById(rte).contentWindow:rte;
                var selection = oRTE.getSelection();
				if(selection!='') rng = selection.getRangeAt(selection.rangeCount - 1).cloneRange();
				else return false;
        }
		return true;
}

function stripHTML(oldString) {
        //function to strip all html
        var newString = oldString.replace(/(<([^>]+)>)/ig,"");

        //replace carriage returns and line feeds
   newString = newString.replace(/\r\n/g," ");
   newString = newString.replace(/\n/g," ");
   newString = newString.replace(/\r/g," ");

        //trim string
        newString = trim(newString);

        return newString;
}

function trim(inputString) {
   // Removes leading and trailing spaces from the passed string. Also removes
   // consecutive spaces and replaces it with one space. If something besides
   // a string is passed in (null, custom object, etc.) then return the input.
   if (typeof inputString != "string") return inputString;
   var retValue = inputString;
   var ch = retValue.substring(0, 1);

   while (ch == " ") { // Check for spaces at the beginning of the string
      retValue = retValue.substring(1, retValue.length);
      ch = retValue.substring(0, 1);
   }
   ch = retValue.substring(retValue.length - 1, retValue.length);

   while (ch == " ") { // Check for spaces at the end of the string
      retValue = retValue.substring(0, retValue.length - 1);
      ch = retValue.substring(retValue.length - 1, retValue.length);
   }

        // Note that there are two spaces in the string - look for multiple spaces within the string
   while (retValue.indexOf("  ") != -1) {
                // Again, there are two spaces in each of the strings
      retValue = retValue.substring(0, retValue.indexOf("  ")) + retValue.substring(retValue.indexOf("  ") + 1, retValue.length);
   }
   return retValue; // Return the trimmed string back to the user
}

function raiseButton(e) {
        //IE-Only Function
        var el = window.event.srcElement;

        className = el.className;
        if (className == 'rteImage' || className == 'rteImageLowered') {
                el.className = 'rteImageRaised';
        }
}

function normalButton(e) {
        //IE-Only Function
        var el = window.event.srcElement;

        className = el.className;
        if (className == 'rteImageRaised' || className == 'rteImageLowered') {
                el.className = 'rteImage';
        }
}

function lowerButton(e) {
        //IE-Only Function
        var el = window.event.srcElement;

        className = el.className;
        if (className == 'rteImage' || className == 'rteImageRaised') {
                el.className = 'rteImageLowered';
        }
}




// Base64 encode/decode
var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";

function encode64(input) {
   var output = "";
   var chr1, chr2, chr3;
   var enc1, enc2, enc3, enc4;
   var i = 0;

   do {
      chr1 = input.charCodeAt(i++);
      chr2 = input.charCodeAt(i++);
      chr3 = input.charCodeAt(i++);

      enc1 = chr1 >> 2;
      enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
      enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
      enc4 = chr3 & 63;

      if (isNaN(chr2)) {
         enc3 = enc4 = 64;
      } else if (isNaN(chr3)) {
         enc4 = 64;
      }

      output = output + keyStr.charAt(enc1) + keyStr.charAt(enc2) +
         keyStr.charAt(enc3) + keyStr.charAt(enc4);
   } while (i < input.length);

   return output;
}

function decode64(input) {
   var output = "";
   var chr1, chr2, chr3;
   var enc1, enc2, enc3, enc4;
   var i = 0;

   // remove all characters that are not A-Z, a-z, 0-9, +, /, or =
   input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");

   do {
      enc1 = keyStr.indexOf(input.charAt(i++));
      enc2 = keyStr.indexOf(input.charAt(i++));
      enc3 = keyStr.indexOf(input.charAt(i++));
      enc4 = keyStr.indexOf(input.charAt(i++));

      chr1 = (enc1 << 2) | (enc2 >> 4);
      chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
      chr3 = ((enc3 & 3) << 6) | enc4;

      output = output + String.fromCharCode(chr1);

      if (enc3 != 64) {
         output = output + String.fromCharCode(chr2);
      }
      if (enc4 != 64) {
         output = output + String.fromCharCode(chr3);
      }
   } while (i < input.length);

   return output;
}

function TagOpenEncode64(){
  return '<_'+encode64(arguments[1])+'>';
}
function TagCloseEncode64(){
  return '<_/'+encode64(arguments[1])+'>';
}

function TagOpenDecode64(){
  return '<'+decode64(arguments[1])+'>';
}
function TagCloseDecode64(){
  return '</'+decode64(arguments[1])+'>';
}

// Подсчет символов в поле
//   fieldNameID - id поля с текстом
//   fieldCountID - id поля с цифрой

function SymbCount(fieldID, fieldCountID, type){
  return true;
  if(type=='input') field=document.getElementById(fieldID).value;
  else if(type=='rte_moz') field=document.getElementById(fieldID).contentDocument.body.innerHTML;
  else if(type=='rte_ie') field=frames[fieldID].document.body.innerHTML;
  else field='';

  if(field){
    document.getElementById(fieldCountID).value=field.length;
  }
}

function jfunc(e,rte){
	if(e.target.getAttribute('class')=='jLib_control') {
			document.getElementById(rte+'_params').innerHTML='Jlib Control: '+e.target.getAttribute('id');
	}else	document.getElementById(rte+'_params').innerHTML=e.target.tagName;
	curSelectedObj[rte]=e.target;
	this.properties(rte);
}
function jfuncIE(e,rte){
	if(e.srcElement.attributes['class']!=undefined && e.srcElement.attributes['class'].value=='jLib_control') {
			document.getElementById(rte+'_params').innerHTML='Jlib Control: '+e.srcElement.getAttribute('id');
	}else	document.getElementById(rte+'_params').innerHTML=e.srcElement.tagName;
	curSelectedObj[rte]=e.srcElement;
	this.properties(rte);
}

function jset_events(rte){
	if(!rte) return false;
	if(isIE){
		frames[rte].document.attachEvent('onmouseup', function(e){jfuncIE(e,rte);});
		document.getElementById(hdnFld[rte]).form.attachEvent('onsubmit', function(e){submitForm();});
	}else{
		var tst=document.getElementById(rte).contentWindow.document.getElementsByTagName('*');
		document.getElementById(hdnFld[rte]).form.addEventListener('submit',submitForm,true);
		var bodyf=false;
	}
		
	if(!isIE){
		var j=0, objs='';
		for(var i in tst){
			if(tst[i] && tst[i].tagName!=undefined) {
				objs+=' '+tst[i].tagName;
				if(tst[i].tagName=='BODY') bodyf=true;
				if( !bodyf ) continue;
				tst[i].addEventListener('click',function(e){jfunc(e,rte);},true);
				j++; 
			}
		}
	}
	document.getElementById(rte+'_params').innerHTML='';
	if(this.props) document.propDialog.clear(rte);
}

this.properties=function(rte){
	if(!this.props) return true;
	document.propDialog.show_prop(rte);
}

//Замена Jlib контролов на картинки в HTML коде и запоминание их.
function jLib_show_objs(rte,text){
	var controlsCNT=0;
	jLib_controls[rte]=new Array();
	if(jLib_controls[rte]==undefined) jLib_controls[rte]=new Array();
	var pattern=/{(\w+):(\w*)[^}]*}/ig;
	var prmPattern=/(\w+)=("?)([a-zA-Z0-9\/\."]+)\2/ig;
	//ищу регой контролы
	var res=false; while(res=pattern.exec(text)){
		if(res[2]=='' || jLib_controls[rte][res[2]]!=undefined){ objID='control_'+controlsCNT; } else objID=res[2];
		var prm=false,prm_str=''; var tmp_params=new Object(); while(prm=prmPattern.exec(res[0])) {
			tmp_params[ prm['1'] ]=prm['3'];
			prm_str+=' '+ prm['1'] +'="'+prm['3']+'"';
		}
		jLib_controls[rte][objID]={
			params:tmp_params,
			show	:'<img id="'+objID+'" class="jLib_control" src="'+imagesPath+'control_'+jLib_get_image(res[1])+'.gif" border=0>',
			code	:'{'+ res[1] +':'+ objID +' '+prm_str+'}'
		};
		text=text.replace(res[0], jLib_controls[rte][objID].show);
		controlsCNT++;
	};
	return text;
}
//функция подставляет код контролов вместо картинок в исходный код HTMLы
//Вызывается при режиме просмотра исходного кода и перед отправкой формы
//Приходится заменять по реге! потому что эксплорер все переставляет по своему, 
//так же есть ряд различий с кавычками у значений аттрибутов в МФФ и ИЕ
function jLib_show_objs_code(rte, text){
	for(var i in jLib_controls[rte]){
		var ptn=new RegExp('<img.*id="?'+i+'"?[^>]*>','ig');
		text=text.replace(ptn, jLib_controls[rte][i].code);
	}
	return text;
}

function print_r(aObj,offset) {
	if (typeof(aObj)!='object') return aObj;
	if (!offset) offset='';
	var out='';
	for (var i in aObj) {
		if (typeof(aObj[i])=='object') out+=offset+i+'\r\n'+print_r(aObj[i],offset+'  ');
		else if (typeof(aObj[i])=='function') out+=offset+i+' - function\r\n';
		else out+=offset+i+' - '+aObj[i]+'\r\n';
	}
	if (offset=='') return alert(out); else return out;
}

//***************************************************		uStudio EXPANSIONS

function jLib_get_image(tst){
	return 'panel';
}

//***************************************************************************
//ПРИМЕЧАНИЕ: код взят из внешнего источника и доработан по необходимости.
//Источник:	http://xpoint.ru/
//
//***************************************************************************

// Взятие крайних узлов выделения (корня — root и самых крайних "слева" и "справа" — start и end)
// на вход даем окно (т.е. iframe.contentWindow)
function get_selection_bounds(editor_window){
   var range, root, start, end

   if(editor_window.getSelection){ // Gecko, Opera
      var selection = editor_window.getSelection()
      // Выделение, вообще говоря, может состоять из нескольких областей.
      // Но при написании редактора нас это не должно заботить, берем 0-ую:
      range = selection.getRangeAt(0)
      
      start = range.startContainer
      end = range.endContainer
      root = range.commonAncestorContainer

      if(start.nodeName.toLowerCase() == "body") return null
      // если узлы текстовые, берем их родителей
      if(start.nodeName == "#text") start = start.parentNode
      if(end.nodeName == "#text") end = end.parentNode

      if(start == end) root = start
      
      return {
         root: root,
         start: start,
         end: end
      }

   }else if(editor_window.document && editor_window.document.selection){ // MSIE
      range = editor_window.document.selection.createRange()
      if(!range.duplicate) return null
      
      var r1 = range.duplicate()
      var r2 = range.duplicate()
      r1.collapse(true)
      r2.moveToElementText(r1.parentElement())
      r2.setEndPoint("EndToStart", r1)
      start = r1.parentElement()
      
      r1 = range.duplicate()
      r2 = range.duplicate()
      r2.collapse(false)
      r1.moveToElementText(r2.parentElement())
      r1.setEndPoint("StartToEnd", r2)
      end = r2.parentElement()
      
      root = range.parentElement()
      if(start == end) root = start
      
      return {
         root: root,
         start: start,
         end: end
      }
   }
   return null // браузер, не поддерживающий работу с выделением
}

//функция, скорее всего, нуждается в оптимизации, а то она через глобальную переменную написана...
var global_stage // некрасивая глобальная переменная
// bounds — массив [root, start, end]
// tag_name — имя тега
// остальные аргументы не указываем, используются для рекурсии
function find_tags_in_subtree(bounds, tag_name, stage, second){
   var root = bounds['root']
   var start = bounds['start']
   var end = bounds['end']

   if(start == end) return [start]

   if(!second) global_stage=stage

   if(global_stage == 2) return []
   if(!global_stage) global_stage = 0

   tag_name = tag_name.toLowerCase()

   var nodes=[]
   for(var node = root.firstChild; node; node = node.nextSibling){
      if(node==start && global_stage==0){
         global_stage = 1
      }
      if(node.nodeName.toLowerCase() == tag_name && node.nodeName != '#text' || tag_name == ''){
         if(global_stage == 1){
            nodes.push(node)
         }
      }
      if(node==end && global_stage==1){
         global_stage = 2
      }
      nodes=nodes.concat(find_tags_in_subtree({root:node, start:start, end:end}, tag_name, global_stage, true))
   }
   return nodes
}

// Ближайший родитель с нужным тегом
function closest_parent_by_tag_name(node, tag_name){
   tag_name = tag_name.toLowerCase()
   var p = node
   do{
      if(tag_name == '' || p.nodeName.toLowerCase() == tag_name) return p
   }while(p = p.parentNode)

   return node
}

//Массив всех узлов с нужным тегом, попавших в выделение
function get_selected_tags(editor_window, tag_name){
   if(tag_name){
      tag_name = tag_name.toLowerCase()
   }else{
      tag_name = ''
   }
   var bounds = get_selection_bounds(editor_window)
   if(!bounds) return null

   bounds['start'] = closest_parent_by_tag_name(bounds['start'], tag_name)
   bounds['end'] = closest_parent_by_tag_name(bounds['end'], tag_name)
   return find_tags_in_subtree(bounds, tag_name)
}

function setProperty(rte){
	if(!curSelectedObj[rte] || curSelectedObj[rte]==undefined) return;
	curSelectedObj[rte].style.color="#e4e4e4";
}

function editor_generate(name){
	initRTE("/img/cms/jw/", "/tpl/_sys/pop/", "/css/rte.css",true);
	placeRichText('place_'+name,name,'txt_'+name, '', '800', '300', true);
}