/*
	SV2Software.AdvancedWebLibrary.JS.ContentEditor
	build 20070816
	Tested IE 5.5+ / FF 2.0, 1.5, 1.0 / Opera 9 [sic]
*/

var ua=navigator.userAgent.toLowerCase();
var isOpera=ua.indexOf('opera/9')!=-1,isIE=(ua.indexOf('msie')!=-1)&&(!isOpera),isGecko=ua.indexOf('gecko')!=-1;

/*
var isIE=!!window.ActiveXObject;
var isOpera=!!window.opera;
var isGecko=;???
*/

var encoding='utf-8';
var allRTEs=[];
var isRichText=document.getElementById&&(isOpera||isIE||isGecko);

function loadCSS(path,name){
	if(window[name+'_loaded']==true){
		return;
	}
	var s=document.documentElement.firstChild.appendChild(ce('link'));
	s.type='text/css';
	s.setAttribute('rel','stylesheet');
	s.setAttribute('href',path+name+'?'+Math.random());
	window[name+'_loaded']=true;
}

function _AWLrte(rte,html,path,width,height,restricted,pluginConfig){

	/* self config */
	var t=this;
	t.css=path+'editor.css?'+Math.random();
	t.cssHints=path+'hints.css?'+Math.random();

	t.getMaxWidth=true;
	t.restricted=restricted=':'+restricted.join(':')+':';

	/* content config */
	t.prevHTML='';
	t.bookmark=null;
	t.init=true;

	t.icon={x:23,y:23};
	t.cache=[];
	t.cacheDrops=[];

	t.undo=[];
	t.redo=[];

	function isAllowed(name){
		return (name=='')||restricted.indexOf(':'+name+':')==-1;
	}

	t.plugins={};

	['table:TTable','link:Link','image:TImage','HTMLObject:THTMLObject','color:TColor','specialchar:TSpecialChar','htmledit:THTMLEdit','listtypeswitch:TListTypeSwitcher'].each(
		function(el){
			el=el.split(':');
			t.plugins[el[0]]=new (window[el[1]])(isAllowed(el[0]),t);
		}
	);

	t.isFontTagValid=(isAllowed('color')||isAllowed('fontname')||isAllowed('fontsize'));

	for(var name in pluginConfig){
		if(!t.plugins[name]){
			alert('Plugin '+name+' not found');
			continue;
		}
		pluginConfig[name]['data']&&t.plugins[name].loadData(pluginConfig[name]['data']);
		pluginConfig[name]['config']&&t.plugins[name].loadConfig(pluginConfig[name]['config']);
	}

	t.isUndo=false;
	t.frameFocus=false;

	$E.Add(window,'load',function(){loadCSS(path,'rte.css')});

	var ss=document.getElementsByTagName('script');
	var root=ss[ss.length-1].parentNode.appendChild(cn('div')).cls('rteRoot');
//	root.ss({display:'none'})

	if(!isRichText){
		var b=ce2('div').cls('rteTArea').sp(root);
		b.add('h2','Rich edit capabilities not supported');
		b.ac2('textarea').att('name',rte).ac(ct(html));
		return;
	}

/*
	if(isGecko){
		html=html.replace(/<strong(\s+|>)/g,"<b$1");
		html=html.replace(/<\/strong(\s+|>)/g,"</b$1");
		html=html.replace(/<em(\s+|>)/g,"<i$1");
		html=html.replace(/<\/em(\s+|>)/g,"</ei$1");
	}
*/

	if(t.getMaxWidth){
		$E.Add(window,'load',function(){
			root.s().width='100%';
			(root.offsetWidth>4)&&(t.iframe.s().width=(root.offsetWidth-4)+'px');
		});
		$E.Add(window,'resize',function(){
			(root.offsetWidth>4)&&(t.iframe.s().width=(root.offsetWidth-4)+'px');
		});
	}
	root.s().width=width+'px';

	t.root=root;
	t.name=rte;

	t.restricted=restricted;
	// inner vars
	t.noHideSlave=false;
	t.allowTagsCache=':#text:a:em:h1:h2:h3:h4:h5:h6:img:li:ol:p:strong:ul:sup:sub:u:strike:address:table:tbody:tr:td:div:br:hr:q:blockquote:ins:';

	if(t.isFontTagValid){
		t.allowTagsCache+='font:';
	}

	html=html.validTags(this);

	for(var name in t.plugins){
		html=t.plugins[name].preDataConverter(html);
	}

	if(html==''){
		html = '<p>&nbsp;</p>';
	}

	t.names={td:'cell',tr:'row',table:'table',tbody:'table body',a:'link',ul:'unordered list',ol:'ordered list',li:'list item',p:'para',h1:'heading 1',h2:'heading 2',h3:'heading 3',h4:'heading 4',h5:'heading 5',h6:'heading 6',i:'italic',em:'italic',b:'bold',strong:'bold',u:'underline',s:'strikethrough',strike:'strikethrough'};
	//	allRTEs.push(this); //(?)

var buttonData=[
'b:0:print:Print (Ctrl+P):print',
's',
'b:1:selectall:Select All (Ctrl+A):selectAll',
'b:2:removeformat:Clear text decoration',
's',
'bIE:3:cut:Cut (Ctrl+X)',
'bIE:4:copy:Copy (Ctrl+C)',
'bIE:5:paste:Paste (Ctrl+V)',
's',
'b:6:undo:Undo (Ctrl+Z):doUndo',
'b:7:redo:Redo:doRedo',
's',
'd:-1:format:formatblock',
'd:-2:fontname:fontname',
'd:-3:fontsize:fontsize',
'b:8:bold:Bold (Ctrl+B)',
'b:9:italic:Italic (Ctrl+I)',
'b:10:underline:Underline (Ctrl+U)',
'b:11:strikethrough:Strikethrough (Ctrl+S)',
's',
'b:24:justifyleft:Align left',
'b:25:justifycenter:Align Center',
'b:26:justifyright:Align right',
'b:27:justifyfull:Justify Full',
's',
'b:12:insertorderedlist:Ordered list',
'b:13:insertunorderedlist:Unordered list',
'b:14:outdent:Outdent',
'b:15:indent:Indent',
'b:28::Toggle highlight:toggleHighlight',
's',
'b:22:subscript:Subscript',
'b:23:superscript:Superscript',
's',
'b:16:inserthorizontalrule:Insert Horizontal Rule'
].each(function(el){return el.split(':')});


	var gf=0; //groupflag
	var node=cn('div').cls('rteButtons');
	var dropDData=[];
	dropDData[1]=[[''],['<h1>','Heading 1'],['<h2>','Heading 2'],['<h3>','Heading 3'],['<h4>','Heading 4'],['<h5>','Heading 5'],['<h6>','Heading 6'],['<p>','Para'],['<address>','Address'],['<pre>','Preformatted']];
	dropDData[2]=[[''],['Arial'],['Tahoma'],['Trebuchet MS'],['Times'],['Courier'],['Verdana'],['Comic Sans MS']];
	dropDData[3]=[[''],['-3'],['-2'],['-1'],['0',''],['+1'],['+2'],['+3']];

	for(var i=0,count=buttonData.length;i<count;i++){
		var item=buttonData[i];

		if(!isAllowed(item[2])){
			continue;
		}

		switch(item[0]){
			case 'b':
				t.cache[item[1]]=t.button(node,item);gf++;
			break;
			case 'bIE':
				if(isIE){
					t.cache[item[1]]=t.button(node,item);gf++;
				}
			break;

			case 'd':
				var data=dropDData[item[1]*-1];
				t.cacheDrops[item[1]*-1]=function(cmd){
					var s=node.ac2('select');
					s.Eadd('change',function(e){t.actionHandler(e,'stylize',cmd);});
					for(var j=0;j<data.length;j++){
						var oData=data[j];
						s.add('option',oData[1]||oData[0]).value=oData[0];
					}
					return s;
				}(item[3]);gf++;
			break;

			case 's':
				if(gf>0){
					node.ac2('em').cls('rteSeparator');gf=0;
				}
			break;
		}
	}

	for(var name in t.plugins){
		var pl=t.plugins[name];
		pl.panelIconEnabled()&&pl.addPanelIcons(node);
	}

	node.ac2('div').ss({clear:'both'});
	node.sp(root);
	t.buttons=node;

	// path
	t.route=cn('div').cls('route').sp(root);

	// edit area
	var fr=cn('iframe').sp(root);
	fr.att('frameBorder',0);
	fr.att('border',0);
	fr.src=path+'blank.htm';
	fr.s().width=width+'px';
	fr.s().height=height+'px';
	fr.Eadd('focus',function(){t.hideSlave();});
	t.iframe=fr;

	// show html
	var ft=cn('div').cls('rteFooter').sp(root);
	ft.add('a','view current html').att('href','javascript:void(0)').Eadd('click',function(){alert(t);});

// RESIZE

	function mover(e){
		var dY=e.clientY-t.zeroY;
		var hy=t.height+dY;
		if(hy>=150){
			t.r.s().height=hy+'px';
			t.dY=dY;
		}
	}

	var resize=ft.ac2('em').cls('resize').att('title','Resize height').att('resizer',1);

	root.Eadd('mousedown',function(e){
		var el=e.srcElement||e.target;
		if(tag(el)=='em'&&el.getAttribute('resizer')){

			var r=t.root.parentNode.insertBefore(cn('div'),t.root);
			t.r=r;
			t.height=t.root.offsetHeight;
			t.iheight=t.iframe.offsetHeight;
			t.root.s().display='none';
			r.s().height=(t.height)+'px';
			t.zeroY=e.clientY;
			t.dY=0;
			r.cls('rteResize');

			EvMan.Add(window.document,'mousemove',mover);
			EvMan.Add(window.document,'mouseup',function(e){
				t.root.s().display='';
				t.iframe.s().height=(t.iheight+t.dY)+'px';
				t.r.s().display='none';
				EvMan.Rem(window.document,'mousemove',mover);
				t.initExec();
			});
		}
	});

// EO RESIZE

	t.hdn=t.root.ac(input('hidden',rte));
	t.hdn.value=t.html;

	t.enableDesignMode(html);
	if(t.hdn.form){
		EvMan.Add(t.hdn.form,'submit',function(){t.update();});
	}
}

var _b=_AWLrte.prototype;

_b.button=function(node,data){
	var self=this;
	var a=node.ac2('a').cls('rteAction').att('href','Action: '+data[3]).att('title',data[3]);
	a.s().backgroundPosition=(-data[1]*(this.icon.x+1))+'px 50%';
	a.Eadd('click',function(e){stopEvent(e);self.actionHandler(e,data[4],data[2]);});
	return a;
};

_b.actionHandler=function(e,method,param){

	var t=this;
	t.hideSlave();
	t.ffocus();
	t.saveRange();

	if(method==null){
		t.exec(param);
	}else{
		if(typeof(t[method])=='function'){
			t[method](e,param);
		}else{
			alert('AWLrte object: method "'+method+'" not found');
		}
	}
	t.checkState(true);
};

_b.enableDesignMode=function(html){

	var t=this;
	var data='<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html><head>';
	data+="<meta http-equiv='Content-Type' content='text/html; charset="+encoding+"' />";
	if(t.css){
		data+='<link rel="stylesheet" type="text/css" href="'+t.css+'"></link><link rel="alternate stylesheet" id="hints" type="text/css" href="'+t.cssHints+'"></link>';
	}
	data+='</head><body class="rteContent">'+html+'</body></html>';
	var fd=t.getFrameDoc();

	fd.open();
	fd.write(data);
	fd.close();

	if(isIE){
		fd.designMode='On';
	}

	function clickMenu(e){

		t.saveRange();
		t.hideSlave();
		t.saveBookmark();

		if(e.event.button>1){
			e.stop();
			t.contextMenu(e);
		}
	};

	EvMan.Add(window,'load',function(){
		t.paragraphise();
		setTimeout(function(){
			var fd=t.getFrameDoc();
			fd.designMode='on';
			t.initExec();
			t.checkState(true);
			t.init=false;
			//REinitialize drag&drop to recalculate iframe position after loading control icons
			t.root.ss({display:''});
			DragDrop.init();
			t.saveRange();

			$E.Add(t.getFrame(),'blur',function(){t.frameFocus=false;});

			$E.Add(fd,'dblclick',function(e){e.stop();t.preventHide();t.contextMenu(e);});
			$E.Add(fd,'click',clickMenu);
			$E.Add(fd,'keyup',function(){t.saveRange();t.checkState();});
			$E.Add(fd,'mouseup',function(){t.clrRange();t.saveBookmark();t.checkState();});
			$E.Add(fd,'keydown',function(e){t.keydown(e);t.saveBookmark();});
			$E.Add(fd,'contextmenu',function(e){t.saveRange();e.stop();t.contextMenu(e);});

		},300);
	});
};

_b.initExec=function(){
	var init={LiveResize:0,useCSS:1,styleWithCSS:0,insertBrOnReturn:0,enableObjectResizing:0,enableInlineTableEditing:0},exec=this.getFrameDoc().execCommand;
	for(var cmd in init)try{exec(cmd,false,!!init[cmd])}catch(er){};
};

_b.ffocus=function(){

	if(this.frameFocus==true&&isIE){
		return;
	}

	this.frameFocus=true;
	this.getFrame().focus();

	var r=this.rng;
	if(r&&isIE){
		r.select();
	}
};

_b.exec=function(cmd,opt){
	opt=(typeof(opt)=='undefined'?'':opt);
	try{
		this.ffocus();
		this.getFrameDoc().execCommand(cmd,false,opt);
		this.ffocus();
	}catch(e){
//		alert('AWLrte object: errorous command '+cmd);
	}
};

_b.stylize=function(e,cmd){
	var el=e.srcElement||e.target;
	if(tag(el)=='select'){
		var val=el.options[el.selectedIndex].value;
		switch(cmd){
			case'fontname':
			case'fontsize':
			case'formatblock':
				this.exec(cmd,val);
			break;
		}
		el.selectedIndex=0;
	}
};

_b.getSlave=function(){
	if(!this.slave){
		this.slave=cn('div').cls('rteSlave').sp(this.root.ownerDocument.body);
	}
	return this.slave;
};

_b.hideSlave=function(){
	if(this.slave && !this.noHideSlave){
		this.slave.ss({visibility:'hidden',top:'-1000px',left:'-1000px'});
		EvMan.CleanTmp('dlg');
		this.ffocus();
	}
};

_b.getFrame=function(){
	return this.iframe.contentWindow;
};

_b.getFrameDoc=function(){
	return this.getFrame().document;
};

_b.saveRange=function(){
	if(this.frameFocus==true){
		this.rng=this.getRange().range;
	}
};

_b.clrRange=function(){
	this.rng=null;
};

_b.selectNode=function(el,avoid){
	var r;
	var d=el.ownerDocument;

	if(isIE){
		r=d.body.createTextRange();
		r.moveToElementText(el);
		r.select();
	}else{
		if(avoid==true && tag(el)=='td'){
			el=el.firstChild;
		}
		r=d.createRange();
		var sel=this.getFrame().getSelection();
		r.selectNode(el);
		sel.removeAllRanges();
		sel.addRange(r);
	}
};

_b.contextMenu=function(e){

	this.checkState();
	this.hideSlave();

	var el=$(e.el);
	var t=this,tg=tag(el),config={},create=[],noSel=true;

	for(var name in this.plugins){
		var pl=this.plugins[name];
		if(pl.contextDependable(el,[])){ // [] = should be named path
			config[name]=pl.list();
			noSel=false;
		}
		if(pl.haveAddAction()){
			create=create.concat(pl.getAddAction());
		}
	}

	config[1]=create;
	config[0]=[['hideSlave','\u2205 Close']];

	if(!noSel){
		t.selectNode(el,true);
	}

	var c=t.getSlave().cls('rteSlave cMenu');
	clearNode(c);
	var sepClass='';

	for(var name in config){
		config[name].each(function(cmd){
			t.menuItem(c,cmd,el,name).cls(sepClass);
			sepClass='';
		});
		delete config[name];
		sepClass='cMenuSeparated';
	}

	var pos=getXY(t.iframe);
	c.ss({left:(e.x+pos.x)+'px',top:(e.event.clientY+10+pos.y)+'px'});
	t.draw(c.s());
};

_b.menuItem=function(c,cmd,el,scope){

	var self=this;
	var host=this.plugins[scope];
	var a=c.add('a',cmd[1]).att('href','action: '+cmd[1]);

	if(host){
		EvMan.AddTmp('dlg',a,'click',function(e){host.action(el,cmd[0]);self.hideSlave();stopEvent(e)});
	}else{
		if(scope==0){
			EvMan.AddTmp('dlg',a,'click',function(e){self[cmd[0]](el);self.hideSlave();stopEvent(e)});
		}else if(scope==1){
			EvMan.AddTmp('dlg',a,'click',function(e){cmd[0].xy=null;cmd[0].add(cmd);self.hideSlave();stopEvent(e)});
		}
	}
	return a;
};

_b.draw=function(s){
	var self=this;
	this.oStyle=s;
	s.visibility='visible';
/*
	this.setOpacity(0.2);
	window.clearInterval(this.oThread);
	this.oThread=window.setInterval(function(){self.opacityRoll();},40);
*/
};

_b.opacityRoll=function(){
	var o=this.getOpacity();
	if(o>1){
		clearInterval(this.oThread);
	}
	this.setOpacity(o+0.3);
}

if(isIE){
	_b.getOpacity=function(){
		return parseFloat(this.oStyle.filter.replace(/[^0-9]/g,''))/100;
	}
	_b.setOpacity=function(v){
		this.oStyle.filter='alpha(opacity='+v*100+')';
	}
}else{
	_b.getOpacity=function(){
		return parseFloat(this.oStyle.opacity);
	}
	_b.setOpacity=function(v){
		this.oStyle.opacity=v;
	}
}

_b.hotkey=function(cmd,e){
	this.exec(cmd);
	e.stop();
	this.checkState();
};

_b.keydown=function(e){
	var ev=e.event;
	if(e.event.ctrlKey){
		var t=this;
		var oldBookmark=t.bookmark;
		switch(ev.keyCode){
			case 86:
				setTimeout(function(){t.cleanPaste();t.restoreBookmark(oldBookmark);t.checkState(true);},100);
			break;
			case 66:this.hotkey('bold',e);break;
			case 73:this.hotkey('italic',e);break;
			case 85:this.hotkey('underline',e);break;
			case 83:this.hotkey('strikethrough',e);break;
			case 76:/*addLink?*/break;
			case 80:/*Print?*/break;
			case 90:this.doUndo();e.stop();break;
		}
	}else if(ev.keyCode=='13'){
		// workaround to gecko - insert br instead p on return
		if(isGecko&&tag(this.getRange().n)!='li'){
			e.stop();
			this.insertHTML('<p>&nbsp;</p>');
		}
	}
};

_b.saveBookmark=function(){

	var b=null;
	var doc=this.getFrameDoc();
	var sp,le,s,e,nl,i,si,ei;
	var trng,sx,sy,xx=-999999999;
	sx=doc.body.scrollLeft+doc.documentElement.scrollLeft;
	sy=doc.body.scrollTop+doc.documentElement.scrollTop;
	var r=this.getRange().range;
	if(isIE){
		if(r.item){
			e=r.item(0);
			nl=doc.getElementsByTagName(e.nodeName);
			for(i=0;i<nl.length&&e!=nl[i];i++);
			b={tag:tag(e),index:i,x:sx,y:sy};
		}else{
			trng=r.duplicate();
			trng.collapse(true);
			sp=Math.abs(trng.move('character',xx));
			trng=r.duplicate();
			trng.collapse(false);
			le=Math.abs(trng.move('character',xx))-sp;
			b={start:sp,length:le,x:sx,y:sy};
		}
	}else{
		var st=extractRangeNodeInfo(r.startContainer,doc);
		var en=extractRangeNodeInfo(r.endContainer,doc);
		b={startTag:st.tag,start:st.pos,startIndex:st.index,
		endTag:en.tag,end:en.pos,endIndex:en.index,
		startOffset:r.startOffset,endOffset:r.endOffset,x:sx,y:sy};
	}
	this.bookmark=b;
};

function extractRangeNodeInfo(s,doc){

	var pn=s;
	while((s=s.parentNode)!=null&&s.nodeType!=1);
	for(var si=0;si<s.childNodes.length&&s.childNodes[si]!=pn;si++);
	var nl=doc.getElementsByTagName(s.nodeName);
	for(var i=0;i<nl.length&&s!=nl[i];i++);
	return{tag:tag(s),pos:i,index:si};
}

_b.restoreBookmark=function(b){

	var r,d=this.getFrameDoc(),self=this;
if(isIE){
	if(b.tag){
		r=d.body.createControlRange();
		nl=d.getElementsByTagName(b.tag);

		if(nl.length>b.index){
			try{
				r.addElement(nl[b.index]);
			}catch(er){
				// Might be thrown if the node no longer exists
			}
		}
	}else{
		r=d.selection.createRange();
		r.moveToElementText(d.body);
		r.collapse(true);
		r.moveStart('character',b.start);
		r.moveEnd('character',b.length);
	}
	r.select();
	this.getFrame().scrollTo(b.scrollX,b.scrollY);
}else{
	setTimeout(function(){
		var r=d.createRange();
		var sel=self.getFrame().getSelection();

		var nl=d.getElementsByTagName(b.startTag);
		if(nl.length>b.start){
			var n=nl[b.start].childNodes[b.startIndex];
			r.setStart(n,n.nodeValue.length<b.startOffset?n.nodeValue.length:b.startOffset);
			r.setEnd(n,n.nodeValue.length<b.startOffset?n.nodeValue.length:b.startOffset);
//			r.setEnd(n,n.nodeValue.length<b.endOffset?n.nodeValue.length:b.endOffset);
		}
/*
		nl=d.getElementsByTagName(b.endTag);
		if(nl.length>b.end){
			var n=nl[b.end].childNodes[b.endIndex];
			r.setEnd(n,n.nodeValue.length<b.endOffset?n.nodeValue.length:b.endOffset);
		}
*/
		sel.removeAllRanges();
		sel.addRange(r);
	},1);
}
};

function changeNodeType(old,type){

	var p=$(old.parentNode),n=p.ce(type);
	if(p!==null){

		for(var i=0,count=old.childNodes.length;i<count;i++){
			n.ac(old.childNodes[i].cloneNode(true));
		}

		p.replaceChild(n,old);
	}
	return true;
};

function replaceNodeWithChildren(n){

	var p=n.parentNode;
	if(p!==null){
		for(var i=0,count=n.childNodes.length;i<count;i++){
			p.insertBefore(n.childNodes[i].cloneNode(true),n);
		}
		p.removeChild(n);
		return p;
	}
	return true;
}

_b.cleanPaste=function(){

	var html=this.getHTML();
	html=html.replace(/&nbsp;/gi,' ').replace(/\r/g,' ').replace(/\n/g,' ');
	html=html.validTags(this);

	html=html.replace(/%7b/gi,'{').replace(/%7d/gi,'}');

	for(var name in this.plugins){
		html=this.plugins[name].preDataConverter(html);
	}

	this.getFrameDoc().body.innerHTML=html;
	this.paragraphise();
};

_b.saveChanges=function(prev,r){

	var t=this;
	if(t.init){
		return;
	}

	if(t.isUndo){
		t.isUndo=false;
	}else{
		if(!t.undo[t.undo.length-1]||t.undo[t.undo.length-1].data!=prev){
			t.undo.push({data:prev,point:t.bookmark});
			t.redo=[];
		}
	}
};

_b.doRedo=function(){

	var step,t=this;
	if(!(step=t.redo.pop())){
		return;
	}

	t.undo.push({data:t.getHTML(),point:t.bookmark});
	t.isUndo=true;
	t.getFrameDoc().body.innerHTML=step.data;
	t.restoreBookmark(step.point);
};

_b.doUndo=function(){

	var len,b,t=this;
	if(!(step=t.undo.pop())){
		return;
	}
	t.redo.push({data:t.getHTML(),point:t.bookmark});

	t.isUndo=true;
	t.getFrameDoc().body.innerHTML=step.data;
	t.restoreBookmark(step.point);
};

_b.checkState=function(bForce){

	var html=this.getHTML();
	if(this.prevHTML!=html){
		this.saveChanges(this.prevHTML,this.prevRange);
		this.prevHTML=html;
	}

	var n=this.getRange().n;
	if(n==this.oldNode&&!bForce){
		return;
	}
	this.oldNode=n;

	var cache=this.cache;
	var cacheDrops=this.cacheDrops;

	cache.each(function(el,i){el&&el.cls('')});
	cacheDrops.each(function(el){el&&(el.selectedIndex=0)})

	var elPath=[];
	var no=[];

	while(tag(n)!='body'){

		var tg=tag(n);
		elPath.push(n);
		
		switch(tg){
			case'a':no.push(18);no.push(19);break;
			case'u':no.push(10);break;
			case's':case'strike':no.push(11);break;
			case'i':case'em':no.push(9);break;
			case'b':case'strong':no.push(8);break;
			case'ol':no.push(12);break;
			case'ul':no.push(13);break;
			case'sup':no.push(23);break;
			case'sub':no.push(22);break;
			case'h1':case'h2':case'h3':case'h4':case'h5':case'h6':case'p':case'pre':case'address':cacheDrops[1].value='<'+tg+'>';break;
			case'img':no.push(20);break;
			case'blockquote':no.push(14);no.push(15);break;
			case'font':

				if(n.getAttribute('face')&&cacheDrops[2]&&cacheDrops[2].selectedIndex==0){
					cacheDrops[2].value=n.getAttribute('face');
				}

				if(n.getAttribute('size')&&cacheDrops[3]&&cacheDrops[3].selectedIndex==0){
					var sz=n.getAttribute('size');
					if(!/[-+]\d/.test(sz)){ // IE recalculates +3 into 6
						sz=(sz-3);
						sz=sz>0?'+'+sz:'-'+sz;
					}
					cacheDrops[3].value=sz;
				}

				if(n.getAttribute('color')){
					no.push(29);
				}

			break;
		}
		n=n.parentNode;
	}

	no.each(function(no){cache[no]&&cache[no].cls('active')});

	var names=this.names;
	var r=this.route;
	clearNode(r);

	elPath=elPath.reverse();
	r.add('strong','Path: ');
	var text='',tg='';
	EvMan.CleanTmp('path');

	for(var i=0;i<elPath.length;i++){
		text=names[tag(elPath[i])]||tag(elPath[i]);
		this.pathItem(r,text,elPath[i]);
		if(i<(elPath.length-1)){
			r.add('span','\u2192');
		}
	}
};

_b.pathItem=function(n,txt,el){

	var t=this;

	$E.AddTmp('path',n.add('a',txt).att('href','action: Select element').att('title','Click to select element contents'),'click',function(e){

		t.cleanRouteHL();
		e.el.s().background='#f90';

		t.selectNode(el);
		t.ffocus();

		$E.AddTmp('path',t.route.add('a','remove tag').cls('removeTag').att('href','action: remove current tag'),'click',function(e){
			if(tag(el).isInlineName()){
				replaceNodeWithChildren(el);
			}else if(':table:tbody:tr:td:ul:ol:'.indexOf(':'+tag(el)+':')!=-1){
				clearNode(el);
				el.parentNode.removeChild(el);
			}else{
				changeNodeType(el,'p');
			}
			t.checkState();
			t.ffocus();
			e.stop();
		});
		e.stop();
	});
};

_b.cleanRouteHL=function(){
	for(var i=0,list=this.route.childNodes;i<list.length;i++){
		list[i].s().background='';
	}
};

_b.update=function(){

	this.hideSlave();
	this.hdn.value=this;
};

_b.toString=function(){

	this.paragraphise();

	var s=this.getHTML();
	s=s.replace(/\r/g,' ').replace(/\n/g,' ').replace(/\t/g,' ').replace(/\s/g,' ');
	s=s.validTags(this);

	s=s.replace(/^\s+/,'');
	s=s.replace(/\s+$/,'');
	s=s.replace(/<(br|hr)>/g,"<$1 />");
	s=s.replace(/<br \/>\s*<\/(h1|h2|h3|h4|h5|h6|li|p)/g,"</$1");
	s=s.replace(/(<img [^>]+[^\/])>/g,"$1 />");

//	s=s.replace(/(<[^\/]>|<[^\/][^>]*[^\/]>)\s*<\/[^>]*>/g,'');

	s=s.replace(/(\s*)(<\/[^>]>)/g,'$2$1');
	s=s.replace(/\s*<(h1|h2|h3|h4|h5|h6|li|p|table|tbody|tr|td|hr)/g,"<$1");

	s=s.replace(/\s+/,' ');
	return replaceSpecialChars(s);
}

_b.getHTML=function(){
	return this.getFrameDoc().body.innerHTML;
};

_b.paragraphise=function(){

	var fd=this.getFrameDoc();
	var bd=fd.body;

	for(var i=0;i<bd.childNodes.length;i++){
		if(tag(bd.childNodes[i])=="#text" && bd.childNodes[i].data.search(/^\s*$/)!=-1){
			bd.removeChild(bd.childNodes[i]);
			i--;
		}
	}

	var els=[];

	for(i=0;i<bd.childNodes.length;i++){

		if(bd.childNodes[i].nodeName.isInlineName()){

			els.push(bd.childNodes[i].cloneNode(true));
			bd.removeChild(bd.childNodes[i]);
			i--;

		}else if(tag(bd.childNodes[i])=='br'){

			if((i+1)<bd.childNodes.length){

				if(tag(bd.childNodes[i+1])=='br'){
					while(i<bd.childNodes.length && tag(bd.childNodes[i])=='br'){
						bd.removeChild(bd.childNodes[i]);
					}
					if(els.length>0){
						this.insertNewParagraph(els,bd.childNodes[i]);
						els=[];
					}

				}else if(!bd.childNodes[i+1].nodeName.isInlineName()){
					bd.removeChild(bd.childNodes[i]);
				}else if(els.length>0){
					els.push(bd.childNodes[i].cloneNode(true));
					bd.removeChild(bd.childNodes[i]);
				}else{
					bd.removeChild(bd.childNodes[i]);
				}
				i--;

			}else{
				bd.removeChild(bd.childNodes[i]);
			}

		}else if(els.length>0){
			this.insertNewParagraph(els,bd.childNodes[i]);
			els=[];
		}
	}

	if(els.length>0){
		this.insertNewParagraph(els);
	}
};

_b.insertNewParagraph=function(els,next){

	var d=this.getFrameDoc(),body=d.body;
	var p=d.createElement('p');
	els.each(function(el){p.appendChild(el)});
	(next!==undefined)? body.insertBefore(p,next): body.appendChild(p);
	return true;
};

_b.initSlave=function(name,cls,title){
	return this.initSlaveXY(getXY(this.cache[name]),cls,title);
};

_b.initSlaveXY=function(xy,cls,title){

	var el=this.cache[name];
	var c=this.getSlave().cls('rteSlave '+cls);
	clearNode(c);

	this.controlSlave(c.add('h2',title));
	xy&&xy.x&&xy.y&&xy.h&&c.ss({top:(xy.y+xy.h+5)+'px',left:(xy.x+5)+'px'});

	this.draw(c.s());
	return c;
};

_b.controlSlave=function(hd){

	DragDrop.Bind(hd,hd.parentNode);
	var em=hd.add('em','x').att('title','Close dialog');

	$E.AddTmp('dlg',em,'click',this.hideSlave.bind(this));
	$E.AddTmp('dlg',em,'mouseover',function(){em.cls('active')});
	$E.AddTmp('dlg',em,'mouseout',function(){em.cls('')});
	hd.att('title','Click to move dialog');
};

function input(type,name){
	var e;
	try{
		e=cn('<input type="'+type+'" name="'+name+'">');
	}catch(er){
		e=cn('input');
		e.type=type;
		e.name=name;
	}
	$E.AddTmp('dlg',e,'keypress',function(ev){(ev.keyCode==13)&&ev.stop()});
	setHover(e);
	return e;
}

function setHover(el){
	$E.AddTmp('dlg',el,'mouseover',function(){el.cls('hover',true)});
	$E.AddTmp('dlg',el,'mouseout',function(){el.cls('hover',false)});
	$E.AddTmp('dlg',el,'focus',function(){el.cls('focus')});
	$E.AddTmp('dlg',el,'blur',function(){el.cls('focus',false)});
}

_b.getRange=function(){

	var d=this.getFrameDoc();
	var sel,text='',rng,n;
	if(isIE){
		rng=d.selection.createRange();
		sel=rng.text;
		try{
			n=rng.parentElement();
		}catch(e){
			// control
			n=rng.item(0);
		}
	}else{
		sel=this.getFrame().getSelection();
		rng=sel.getRangeAt(0);
		if(rng.startContainer==rng.endContainer&&rng.startOffset-rng.endOffset<2&&rng.startContainer.hasChildNodes()){
			n=rng.startContainer.childNodes[rng.startOffset];
		}
		if(!n){
			n=rng.commonAncestorContainer;
		}
	}

	while(n.nodeType==3){
		n=n.parentNode;
	}
	return{'range':rng,'sel':sel,'n':n};
};

_b.onBuiltMenu=function(){
	this.preventHide();
	var c=this.getSlave();
	if((c.offsetWidth+c.offsetLeft)>c.parentNode.offsetWidth){
		c.s().left=(c.parentNode.offsetWidth-c.offsetWidth-20)+'px';
	}
};

_b.preventHide=function(){
	var self=this;
	this.noHideSlave=true;
	setTimeout(function(){self.noHideSlave=false;},10);
};

_b.insertHTML=function(html){

	var f=this.getFrame();
	f.focus();
	this.hideSlave();
	if(isIE){
		var r=this.rng;
		if(r){
			r.pasteHTML(html);
			r.collapse(false);
			r.select();
		}
		this.clrRange();
	}else{
		this.exec('insertHTML',html);
	}
};

_b.toggleHighlight=function(){
	var ss=this.getFrameDoc().getElementById('hints');
	if(ss.getAttribute('rel')=='alternate stylesheet'){
		ss.disabled=false;
		ss.setAttribute('rel','stylesheet');
		ss.rel='stylesheet';
	}else{
		ss.disabled=true;
		ss.setAttribute('rel','alternate stylesheet');
		ss.rel='alternate stylesheet';
	}
};

_b.selectAll=function(){
	this.ffocus();
	this.getFrameDoc().execCommand('SelectAll',false,false);
};

_b.print=function(){
	this.getFrame().print();
};

function replaceSpecialChars(html){

	var s=getSpecials();
	var u=getUnicodes();

	for(var i=0;i<s.length;i++){
		var re=new RegExp(u[i],'gi');
		html=html.replace(re,s[i]);
	}

	return html;
};

function getSpecials(){
	return '&cent;:&euro;:&pound;:&curren;:&yen;:&copy;:&reg;:&trade;:&divide;:&times;:&plusmn;:&frac14;:&frac12;:&frac34;:&deg;:&sup1;:&sup2;:&sup3;:&micro;:&laquo;:&raquo;:&lsquo;:&rsquo;:&lsaquo;:&rsaquo;:&sbquo;:&bdquo;:&ldquo;:&rdquo;:&iexcl;:&brvbar;:&sect;:&not;:&macr;:&para;:&middot;:&cedil;:&iquest;:&fnof;:&mdash;:&ndash;:&bull;:&hellip;:&permil;:&ordf;:&ordm;:&szlig;:&dagger;:&Dagger;:&eth;:&ETH;:&oslash;:&Oslash;:&thorn;:&THORN;:&oelig;:&OElig;:&scaron;:&Scaron;:&acute;:&circ;:&tilde;:&uml;:&agrave;:&aacute;:&acirc;:&atilde;:&auml;:&aring;:&aelig;:&Agrave;:&Aacute;:&Acirc;:&Atilde;:&Auml;:&Aring;:&AElig;:&ccedil;:&Ccedil;:&egrave;:&eacute;:&ecirc;:&euml;:&Egrave;:&Eacute;:&Ecirc;:&Euml;:&igrave;:&iacute;:&icirc;:&iuml;:&Igrave;:&Iacute;:&Icirc;:&Iuml;:&ntilde;:&Ntilde;:&ograve;:&oacute;:&ocirc;:&otilde;:&ouml;:&Ograve;:&Oacute;:&Ocirc;:&Otilde;:&Ouml;:&ugrave;:&uacute;:&ucirc;:&uuml;:&Ugrave;:&Uacute;:&Ucirc;:&Uuml;:&yacute;:&yuml;:&Yacute;:&Yuml;'.split(':');
}

function getUnicodes(){
	return '\u00a2:\u20ac:\u00a3:\u00a4:\u00a5:\u00a9:\u00ae:\u2122:\u00f7:\u00d7:\u00b1:\u00bc:\u00bd:\u00be:\u00b0:\u00b9:\u00b2:\u00b3:\u00b5:\u00ab:\u00bb:\u2018:\u2019:\u2039:\u203a:\u201a:\u201e:\u201c:\u201d:\u00a1:\u00a6:\u00a7:\u00ac:\u00af:\u00b6:\u00b7:\u00b8:\u00bf:\u0192:\u2014:\u2013:\u2022:\u2026:\u2030:\u00aa:\u00ba:\u00df:\u2020:\u2021:\u00f0:\u00d0:\u00f8:\u00d8:\u00fe:\u00de:\u0153:\u0152:\u0161:\u0160:\u00b4:\u02c6:\u02dc:\u00a8:\u00e0:\u00e1:\u00e2:\u00e3:\u00e4:\u00e5:\u00e6:\u00c0:\u00c1:\u00c2:\u00c3:\u00c4:\u00c5:\u00c6:\u00e7:\u00c7:\u00e8:\u00e9:\u00ea:\u00eb:\u00c8:\u00c9:\u00ca:\u00cb:\u00ec:\u00ed:\u00ee:\u00ef:\u00cc:\u00cd:\u00ce:\u00cf:\u00f1:\u00d1:\u00f2:\u00f3:\u00f4:\u00f5:\u00f6:\u00d2:\u00d3:\u00d4:\u00d5:\u00d6:\u00f9:\u00fa:\u00fb:\u00fc:\u00d9:\u00da:\u00db:\u00dc:\u00fd:\u00ff:\u00dd:\u0178'.split(':');
}

String.extend({

isInlineName:function(){
	return ':#text:a:em:i:font:span:b:strong:u:strike:s:sup:sub:q:cite:'.indexOf(':'+this.toLowerCase()+':')!=-1;
},

validTags:function(orte){

	var s=this;
	s=s.replace(/%7b/gi,'{').replace(/%7d/gi,'}');
	s=s.replace(/<[^>\s]*/g,function(match){return match.toLowerCase();});
	s=s.replace(/<[^>]*>/g,function(match){
		match=match.replace(/\s[^=]+=/g,function(match2){return match2.toLowerCase();});
		return match;
	});
	s=s.replace(/<[^>]*>/g,function(match){
			match=match.replace(/( [^=]+=)([^"][^\s>]*)/g,"$1\"$2\"");
			return match;
	});
	s=s.replace(/<!\-\-.{0,}\-\->/g,'');
	s=s.replace(/<b(\s+|>)/g,"<strong$1");
	s=s.replace(/<\/b(\s+|>)/g,"</strong$1");
	s=s.replace(/<i(\s+|>)/g,"<em$1");
	s=s.replace(/<\/i(\s+|>)/g,"</em$1");

	var skip=['','object','param','embed','ol','ul',''].join(':');

	s=s.replace(/<[^>]*>/g,function(match){
			var tag=match.split(' ')[0].replace(/[<>\/]/g,'').toLowerCase();
			if(skip.indexOf(':'+tag+':')!=-1){
				return match;
			}else if(orte.allowTagsCache.indexOf(':'+tag+':')==-1){
				return '';
			}else{
				match=match.replace(/\s([^=]+)="([^"]*)"/g,function(match2,att,value){
					switch(att){
						case'alt':case'title':case'href':case'align':case'target':break;
						case'style':if(tag!='img'){match2='';}break;
						case'face':case'size':case'color':if(tag!='font'||!orte.isFontTagValid){match2='';}break;
						case'src':break;
						default:match2='';break;
					}
					return match2;
				});
				return match;
			}
		}
	);

	for(var name in orte.plugins){
		s=orte.plugins[name].postDataConverter(s);
	}
	return s;
}

});

function TTable(isEnabled,rte){
	this.cfg.enabled=isEnabled;
	this.rte=rte;
	this.title='table';
	this.panelIconConfig=[[21,'add','Insert Table']];
};

TTable.prototype=new TPlugin();

TTable.prototype.action=function(td,opc){

switch(opc){
	case 'addCol':
		var t=td.parentNode.parentNode,tr=null;
		for(var i=0;tr=t.rows[i];i++){
			$(tr).add('td','\u00a0');
		}
	break;
	case 'addRow':
		var t=$(td.parentNode.parentNode),row=t.lastChild,tr=t.ac2('tr');
		for(var i=0;i<row.cells.length;i++){
			tr.add('td','\u00a0');
		}
	break;
	case 'delRow':
		td.parentNode.parentNode.removeChild(td.parentNode);
	break;
	case 'delCol':
		var ci=td.cellIndex;
		var t=td.parentNode.parentNode;
		for(var i=0;i<t.rows.length;i++){
			t.rows[i].removeChild(t.rows[i].cells[ci]);
		}
	break;
	case 'delCell':
		var tr=td.parentNode;
		tr.removeChild(td);
		if(tr.cells.length==0){
			tr.parentNode.removeChild(tr);
		}
	break;
	case 'colSpan+':
		td.att('colSpan',(td.att('colSpan')||1)+1);
	break;
	case 'colSpan-':
		td.att('colSpan',((td.att('colSpan')||1)>1?td.att('colSpan')-1:1));
	break;
	case 'rowSpan+':
		td.att('rowSpan',(td.att('rowSpan')||1)+1);
	break;
	case 'rowSpan-':
		td.att('rowSpan',((td.att('rowSpan')||1)>1?td.att('rowSpan')-1:1));
	break;
	case 'cellBefore':
		td.before().add('td','\u00a0');
	break;
	case 'cellAfter':
		td.after().add('td','\u00a0');
	break;
}
};

TTable.prototype.list=function(n,path){
	return [
		['addRow','Add Row'],
		['addCol','Add Column'],
		['cellBefore','Add Cell Before'],
		['cellAfter','Add Cell After'],
		['colSpan+','Cell ColSpan+'],
		['colSpan-','Cell ColSpan-'],
		['rowSpan+','Cell RowSpan+'],
		['rowSpan-','Cell RowSpan-'],
		['delCell','Remove this Cell'],
		['delCol','Remove this Column'],
		['delRow','Remove this Row']
	];
};

TTable.prototype.contextDependable=function(n,path){
	return tag(n)=='td';
};

TTable.prototype.add=function(){

	var rte=this.rte;
	rte.saveRange();
	var c=rte.initSlaveXY(this.xy,'addTable','Insert Table');
	var rows=c.add('label','Number of rows: ').ac(input('text','rows'));
	rows.setAttribute('maxLength','2');

	var cols=c.add('label','Number of cols: ').ac(input('text','cols'));
	cols.setAttribute('maxLength','2');

	var b=c.add('button','do it');

	if(!isIE){
		b.att('type','button');
	}

	$E.AddTmp('dlg',b,'click',addTable);

	function addTable(){

		if(!(/^\d+$/.test(rows.value))){alert('Enter number of rows!');rows.focus();return;}
		if(!(/^\d+$/.test(cols.value))){alert('Enter number of columns!');cols.focus();return;}

		var html='',row='',col='';

		for(var i=0;i<cols.value;i++){
			col+='<td>&nbsp;</td>';
		}

		for(var i=0;i<rows.value;i++){
			row+='<tr>'+col+'</tr>';
		}

		rte.insertHTML('<table>'+row+'</table>');
	}
	rte.onBuiltMenu();
};




function Link(isEnabled,rte){
	this.cfg.enabled=isEnabled;
	this.rte=rte;
	this.title='link';
	this.panelIconConfig=[
		[18,'add','Insert Link'],
		[19,'remove','Remove link']
	];
}

Link.prototype=new TPlugin();

Link.prototype.add=function(){

	var targets=[
		['New window','_blank'],
		['Current window','']
	];

	var rte=this.rte;
	var rng=rte.getRange(),n=rng.n,sel=rng.sel,parentLink=n;

	while(tag(parentLink)!='a' && parentLink.parentNode){
		parentLink=parentLink.parentNode;
	}

	var text;
	var lu=input('text','lu');
	var lh=input('text','lh');
	var tg=cn('select');

	targets.each(function(el){tg.add('option',el[0]).att('value',el[1]);});

	if(tag(parentLink)=='a'){

		rte.selectNode(parentLink);
		lh.value=parentLink.title;
		lu.value=parentLink.href;
		text=parentLink.innerHTML;
		tg.value=parentLink.target||'';

	}else if(sel.toString()!==''||rng.range.htmlText!==''){

		lu.value='http://';
		var temp=ce('div');
		try{
			temp.appendChild(rng.range.cloneContents());
			text=temp.innerHTML;
		}catch(er){

			text=rng.range.htmlText;
		}
	}else{
		lu.value='http://';
	}

	rte.saveRange();
	var c=rte.initSlaveXY(this.xy,'addLink','add/edit link');

	c.add('label','link URL');
	c.ac(lu);
	c.add('label','link hover message');
	c.ac(lh);
	c.add('label','open in');
	c.ac(tg);
	c.add('label','link text (html)');
	var lt=c.add('textarea',text||'');
	setHover(lt);

	var b=c.add('button','do it');

	if(!isIE){
		b.att('type','button');
	}

	EvMan.AddTmp('dlg',b,'click',function(e){

		if(lu.value===''){
			lu.focus();
			alert('Please enter link URL');
			return;
		}

		if(lt.value===''){
			lt.focus();
			alert('Please enter link text');
			return;
		}

		var target='';
		if(tg.value!==''){
			target=' target="'+tg.value+'"';
		}
		var link='<a href="'+lu.value+'" title="'+lh.value+'"'+target+'>'+lt.value+'</a>';
		rte.insertHTML(link);
	});

	rte.onBuiltMenu();
};

Link.prototype.remove=function(){this.rte.exec('unlink','');}
Link.prototype.action=function(n,opc){
	switch(opc){
		case 'add':this.add();break;
		case 'remove':this.remove();break;
		case 'open':var w=window.open(n.href); window.setTimeout(function(){w.focus()},10);break;
	}
};

Link.prototype.list=function(n,path){
	return [
		['add','Edit Link'],
		['remove','Remove Link'],
		['open','Open link(new window)']
	];
};

Link.prototype.contextDependable=function(n,path){
	return tag(n)=='a';
};



function TSpecialChar(isEnabled,rte){
	this.cfg.enabled=isEnabled;
	this.rte=rte;
	this.title='Special Char';
	this.panelIconConfig=[[17,'add','Insert '+this.title]];
}

TSpecialChar.prototype=new TPlugin();
TSpecialChar.prototype.add=function(){

	var rte=this.rte;
	rte.saveRange();
	var c=cn('div');

	$E.AddTmp('dlg',c,'click',click);
	$E.AddTmp('dlg',c,'mouseover',over);
	$E.AddTmp('dlg',c,'mouseout',out);

	getUnicodes().each(function(t){c.add('span',t)});

	function over(e){e.el.cls('rteChar');}
	function out(e){e.el.cls('');}
	function click(e){rte.insertHTML(e.el.firstChild.nodeValue);}

	rte.initSlave(17,'addChar','Insert '+this.title).ac(c);
	rte.onBuiltMenu();
};


function TColor(isEnabled,rte){
	this.cfg.enabled=isEnabled;
	this.rte=rte;
	this.title='Text Color';
	this.panelIconConfig=[[29,'add','Set '+this.title]];
}

TColor.prototype=new TPlugin();
TColor.prototype.add=function(){

	var rte=this.rte;
	var c=cn('table').ac2('tbody');

	function h(e){e.el.cls('hover')}
	function o(e){e.el.cls('')}
	function _c(e){
		var v=e.el.style.backgroundColor;
		if(/^rgb/.test(v)){
			v='#'+v.replace(/[^0-9,]/g,'').replace(/\d+/g,function(m){return parseInt(m).toString(16).replace(/^(\d)$/,'0$1')}).replace(/,/g,'');
		}
		rte.exec('forecolor',v);
		rte.hideSlave();
	}

	$E.AddTmp('dlg',c,'mouseover',h);
	$E.AddTmp('dlg',c,'mouseout',o);
	$E.AddTmp('dlg',c,'click',_c);

	['fff:fcc:fc9:ff9:ffc:9f9:9ff:cff:ccf:fcf','ccc:f66:f96:ff6:ff3:6f9:3ff:6ff:99f:f9f','C0C0C0:f00:f90:fc6:ff0:3f3:6cc:3cf:66c:c6c','999:c00:f60:fc3:fc0:3c0:0cc:36f:63f:c3c','666:900:c60:c93:990:090:399:33f:60c:939','333:600:930:963:660:060:366:009:339:636','000:300:630:633:330:030:033:006:309:303'].each(
		function(str){
			var tr=c.ac2('tr');
			str.split(':').each(function(str){
				tr.add('td','\u00a0').style.backgroundColor='#'+str.replace(/^(\S{3})$/g,'$1$1')
			});
		}
	);

	rte.initSlaveXY(this.xy,'addColor','Set '+this.title).ac(c.parentNode);
	rte.onBuiltMenu();
};







function TImage(isEnabled,rte){
	this.cfg.enabled=isEnabled;
	this.rte=rte;
	this.title='image';
	this.panelIconConfig=[[20,'add','Insert Image']];
}

TImage.prototype=new TPlugin();
TImage.extend({

action:function(n,opc){
	switch(opc){
		case'left':this.align(n,'left');break;
		case'right':this.align(n,'right');break;
		case'none':n.style.position='relative';this.align(n,'');break;
		case'replace':this.add();break;
	}
},

align:function(el,al){
	el.align='';
	el.setAttribute('align','');
	el.removeAttribute('align');
	el.removeAttribute('style');
	if(al){
		el.style['float']=al;
		el.setAttribute('align',al);
	}
},

list:function(n,path){
	return [
		['replace','Replace image'],
		['left','Align: left'],
		['right','Align: right'],
		['none','Align: none']
	];
},

contextDependable:function(n,path){
	return tag(n)=='img';
},

preDataConverter:function(html){
	return html.replace(/\{TPL_REL_IMG_URL\}/gi,this.config.TPL_REL_IMG_URL+'//');
},

postDataConverter:function(html){
	return html.replace(/<img[^>]*>/g,function(match){return match.replace(/src=".+\/\/\//,'src="{TPL_REL_IMG_URL}')});
},

add:function(){

	var rte=this.rte;
	rte.saveRange();

	var c=rte.initSlaveXY(this.xy,'addImage','Insert Image');

	var ims=this.data;
	if(ims.length==0){
		c.add('h3','No images');
		EvMan.AddTmp('dlg',c.add('button','close'),'click',function(e){rte.hideSlave();stopEvent(e);});
	}

	var c2=c.ac2('div');
	var c3=c.ac2('p');

	for(var i=0;i<ims.length;i++){
		this.item(c2,c3,ims[i]);
	}

	rte.onBuiltMenu();
},

item:function(n,p,im){

	var o=n.add('a',im[0]).att('href','action: Click to preview').att('title','Click to preview'),self=this.rte;
	path = this.config.TPL_REL_IMG_URL+'//';

	$E.AddTmp('dlg',o,'click',function(e){

		clearNode(p);
		p.add('h2','Preview: '+im[0]);
		var maxX=200,maxY=150;
		var src=path+im[1];
		var img=ce('img');
		img.src=src;
		p.ac(img);
		img.width=maxX;
		img.height=maxY;

		var b=p.add('button','insert');
		if(!isIE){
			b.att('type','button');
		}
		$E.AddTmp('dlg',b,'click',function(){
			self.insertHTML('<img src="'+src+'" alt="'+im[0]+'" />');
		});

		e.stop();
	});
}

});





THTMLObject=function(isEnabled,rte){
	this.rte=rte;
	this.title='HTML Object';
	this.cfg.icon=false;
	this.cfg.enabled=isEnabled;
};

THTMLObject.prototype=new TPlugin();
THTMLObject.extend({

listItem:function(c2,li){
	var rte=this.rte;
	$E.AddTmp('dlg',c2.add('a',li[0]).att('href','action: '+li[0]),'click',function(e){
		e.stop();
		rte.insertHTML(li[1]);
	});
},

action:function(n,opc){
	switch(opc){
		case 'add': this.add();break;
	}
},

getAddAction:function(){
	var titles=[],self=this;
	this.data.each(function(de){(de.length>0)&&titles.push([self,de[1],de[0]])});
	return titles;
}
});

THTMLObject.prototype.add=function(cmd){

	var id=cmd[2],list=[],title='';
	for(var i=0;i<this.data.length;i++){
		if(this.data[i][0]==id && this.data[i][2].length>0){
			title=this.data[i][1];
			list=this.data[i][2];
		}
	}

	if(list.length==0){
		return false;
	}

	var rte=this.rte;
	var rng=rte.getRange();

	if(tag(rng.n)=='img'){
		rte.selectNode(rng.n.parentNode);
	}

	var c=rte.initSlaveXY(null,'addObject','Insert '+title+' Object');
	var c2=c.ac2('div');

	for(var i=0;i<list.length;i++){
		this.listItem(c2,list[i]);
	}

	rte.onBuiltMenu();
};




function THTMLEdit(isEnabled,rte){
	this.rte=rte;
	this.title='HTMLEditor';
	this.panelIconConfig=[[30,'action','Edit HTML']];
	this.cfg.enabled=isEnabled;
	this.cfg.context.add=false;
}

THTMLEdit.prototype=new TPlugin();

THTMLEdit.prototype.action=function(){

	var rte=this.rte;

	var root=rte.root.before().add('div','').cls('HTMLEdit');
	var oldToString = this.rte.toString;

	root.add('a','\u2190 back to editor').att('href','#').Eadd('click',function(e){
		stopEvent(e);
		rte.getFrameDoc().body.innerHTML=ta.value.validTags(rte);
		root.parentNode.removeChild(root);
		rte.toString=oldToString;
		rte.root.style.display='block';
		rte.paragraphise();
	});

	var ta=root.add('textarea',rte.toString().replace(/<\/p>/g,'</p>\n'));
	var xy=getXY(this.rte.root);
	var fxy=getXY(this.rte.iframe);
	var rs=root.style;

	rs.height=xy.h+'px';
	ta.focus();

	ta.style.width=(fxy.w-2)+'px';
	ta.style.height=fxy.h+'px';
	rte.toString=function(){return ta.value;};

	rte.root.style.display='none';
};

function TListTypeSwitcher(isEnabled,rte){
	this.rte=rte;
	this.title='List Type Switcher';
	this.panelIconConfig=null;
	this.cfg.enabled=isEnabled;
	this.cfg.context.add=true;

	this.listTypes1='decimal,lower-roman,upper-roman,lower-alpha,upper-alpha';
	this.listTypes2='disc,circle,square';
}

TListTypeSwitcher.prototype=new TPlugin();
TListTypeSwitcher.extend({

contextDependable:function(n){
if(tag(n)!='li'){
	return;
}
var lh=n.parentNode;
switch(tag(lh)){
	case'ol':
		this.listType=(lh.style.listStyleType||'decimal').toLowerCase();
		this.listTypes=this.listTypes1;
		return true;
	break;
	case'ul':
		this.listType=(lh.style.listStyleType||'disc').toLowerCase();
		this.listTypes=this.listTypes2;
		return true;
	break;
}},

action:function(li,cmd){li.parentNode.style.listStyleType=cmd},

list:function(){
	var ret=[];
	this.listTypes.split(',').each(function(tp){(tp!=this.listType)&&ret.push([tp,'List: '+tp])}.bind(this));
	return ret;
}});


function TPlugin(){
	this.xy=null;
	this.data=[];
	this.config={};
	// inner plugin config
	this.cfg={
		context:{ // context menu options
			add:true // add "Add foo" option in context menu
		},
		icon:true, // have panel icon or not
		enabled:true //pugin enabled
	};
};

TPlugin.extend({

isEnabled:function(){return this.cfg.enabled},
panelIconEnabled:function(){return this.cfg.enabled&&this.cfg.icon},
contextDependable:function(n,path){return false},
haveAddAction:function(){return this.cfg.enabled&&this.cfg.context.add},
action:function(n,opc){},

getTitle:function(){return this.title;},

getAddAction:function(){return [[this,'Add '+this.getTitle()]]},

addPanelIcons:function(node){
	var t=this;
	t.panelIconConfig&&t.panelIconConfig.each(function(item_){item_&&node.appendChild(t.iconItem(item_))});
},

iconItem:function(data){
	var t=this,a=cn('a').cls('rteAction').att('href','Action: '+data[2]).att('title',data[2]),rte=t.rte;
	a.s().backgroundPosition=(-data[0]*(rte.icon.x+1))+'px 50%';
	$E.Add(a,'click',function(e){rte.hideSlave();e.stop();t.xy=getXY(a);t[data[1]]();});
	rte.cache[data[0]]=a;
	return a;
},

loadData:function(data){this.data=data;},
loadConfig:function(config){this.config=config;},
preDataConverter:function(html){return html;},
postDataConverter:function(html){return html;}
});