Element.addMethods('iframe', {
	document: function(element) {
		element = $(element);
		if (element.contentWindow)
			return element.contentWindow.document;
		else if (element.contentDocument)
			return element.contentDocument;
		else
			return null;
	},
	$: function(element, frameElement) { 
		element = $(element);
		var frameDocument = element.document();
		if (arguments.length > 2) {
			for (var i = 1, frameElements = [], length = arguments.length; i < length; i++)
				frameElements.push(element.$(arguments[i]));
			return frameElements;
		}
		if (Object.isString(frameElement))
			frameElement = frameDocument.getElementById(frameElement);
		return frameElement || element;
	}
});

var Browser = {
	Engine: {name: 'unknown', version: 0},
	Platform: {name: (window.orientation != undefined) ? 'ipod' : (navigator.platform.match(/mac|win|linux/i) || ['other'])[0].toLowerCase()},
	Features: {xpath: !!(document.evaluate), air: !!(window.runtime), query: !!(document.querySelector)},
	Engines: {
		presto: function(){return (!window.opera) ? false : ((arguments.callee.caller) ? 960 : ((document.getElementsByClassName) ? 950 : 925));},
		trident: function(){return (!window.ActiveXObject) ? false : ((window.XMLHttpRequest) ? 5 : 4);},
		webkit: function(){return (navigator.taintEnabled) ? false : ((Browser.Features.xpath) ? ((Browser.Features.query) ? 525 : 420) : 419);},
		gecko: function(){return (document.getBoxObjectFor == undefined) ? false : ((document.getElementsByClassName) ? 19 : 18);}
	}
};
Browser.Platform[Browser.Platform.name] = true;
Browser.detect = function(){
	for (var engine in this.Engines){
		var version = this.Engines[engine]();
		if (version){
			this.Engine = {name: engine, version: version};
			this.Engine[engine] = this.Engine[engine + version] = true;
			break;
		}
	}
	return {name: engine, version: version};
};
Browser.detect();

editables = new Hash();

var editable=Class.create();
editable.prototype={
	initialize:function(text_id, options){
		this.id = text_id;
		this.textarea = $(text_id);
		this.height = this.textarea.getHeight();
		this.width = this.textarea.getWidth();
		this.content = (this.textarea.value!='')?this.textarea.value:'<p><br></p>';
		this.options = options || {};
		this.options.cleanup = this.options.cleanup || false;
		this.keys = ['b', 'i', 'u'];
		this.keyCodes = new Hash({'13':'enter','38':'up','40':'down','37':'left','39':'right','27':'esc','32':'space','9':'tab','46':'delete','8':'backspace', '66':'b', '73':'i', '85':'u'});
		var blockEls = /^(H1|H2|H3|H4|H5|H6|P|DIV|ADDRESS|PRE|FORM|TABLE|LI|OL|UL|TD|CAPTION|BLOCKQUOTE|CENTER|DL|DT|DD)$/;
		this.fonts = ['Arial','Arial Black','Arial Narrow','Courier New','Comic Sans MS','Tahoma','Georgia','Verdana','Palatino Linotype','Impact','Trebuchet MS','Franklin Gothic','Sylfaen','Lucida Grande','Times New Roman','Century Gothic','Bookman Old Style','Book Antiqua','Vrinda','Kartika','Monotype Corsiva','Garamond'];
		this.options.iconLoc = 'images/editableicons.gif';
		this.iconCount = 1;
		this.options.buttons = this.options.buttons || ['p','h1','h2','h3','b','i','u','left','center','right','justify','ol','ul','color','clear','indent','outdent','sup','sub','hr','link','unlink','image','ad','table','block','html'];
		this.actions = new Hash({
			html:{func:'html', num:'1', tags:[], css:{}, t:'edit html'}, 
			forecolor:{func:'forecolor', num:'2', tags:[], css:{}, t:'background color'}, 
			color:{func:'fontcolor', num:'3', tags:[], css:{}, t:'text color'}, 
			setcolor:{func:'setcolor', num:'3', tags:[], css:{}, t:'color'}, 
			b:{func:'bold', num:'4', tags:['b','strong','span'], css:{prop:'font-weight', val:'bold'}, t:'bold'}, 
			center:{func:'justifycenter', num:'5', tags:[], css:{prop:'text-align', val:'center'}, t:'align center'}, 
			hr:{func:'insertHorizontalRule', num:'6', tags:['hr'], css:{}, t:'horizontal rule'}, 
			indent:{func:'indent', num:'7', tags:['blockquote'], css:{}, t:'indent'}, 
			i:{func:'italic', num:'8', tags:['i', 'em'], css:{prop:'font-style', val:'italic'}, t:'italicize'}, 
			justify:{func:'justifyfull', num:'9', tags:[], css:{prop:'text-align', val:'justify'}, t:'justify'}, 
			left:{func:'justifyleft', num:'10', tags:[], css:{prop:'text-align', val:'left'}, t:'align left'}, 
			ol:{func:'insertorderedlist', num:'11', tags:['ol'], css:{}, t:'ordered list'}, 
			outdent:{func:'outdent', num:'12', tags:[], css:{}, t:'outdent'}, 
			right:{func:'justifyright', num:'13', tags:[], css:{prop:'text-align', val:'right'}, t:'align right'}, 
			save:{func:'save', num:'14', tags:[], css:{}, t:'save'}, 
			strikethrough:{func:'strikethrough', num:'15', tags:[], css:{}, t:'strike through'}, 
			sub:{func:'subscript', num:'16', tags:['sub'], css:{}, t:'subscript'}, 
			sup:{func:'superscript', num:'17', tags:['sup'], css:{}, t:'superscript'}, 
			ul:{func:'insertunorderedlist', num:'18', tags:['ul'], css:{}, t:'unordered list'}, 
			u:{func:'underline', num:'19', tags:['u'], css:{prop:'text-decoration',val:'underline'}, t:'underline'}, 
			image:{func:'image', num:'20', tags:['img'], css:{}, t:'add/edit image'}, 
			link:{func:'link', num:'21', tags:['a'], css:{}, t:'add/edit link'}, 
			unlink:{func:'unlink', num:'22', tags:[], css:{}, t:'remove link'}, 
			close:{func:'close', num:'23', tags:[], css:{}, t:'close'}, 
			darr:{func:'darr', num:'24', tags:[], css:{}, t:''}, 
			clear:{func:'removeformat', num:'25', tags:[], css:{}, t:'remove formatting'}, 
			ad:{func:'ad', num:'26', tags:['img'], css:{}, t:'ad'},
			h1:{func:'h1', num:'27', tags:['h1'], css:{}, t:'heading 1'}, 
			h2:{func:'h2', num:'28', tags:['h2'], css:{}, t:'heading 2'}, 
			h3:{func:'h3', num:'29', tags:['h3'], css:{}, t:'heading 3'}, 
			p:{func:'p', num:'30', tags:['p'], css:{}, t:'paragraph'},
			browse:{func:'browse', num:'31', tags:[], css:{}, t:'browse'},
			edit:{func:'edit', num:'32', tags:[], css:{}, t:'edit'},
			table:{func:'table', num:'33', tags:['td'], css:{}, t:'add/edit table'},
			block:{func:'block', num:'34', tags:[], css:{}, t:'style block'}
		});
		var container = Builder.node('div', {'id':'editable_'+this.id+'-contain', style:'position:relative;width:'+this.width+'px;margin:0px auto;font-family:Lucida Grande, Arial, sans-serif;font-size:11px;color:#333;'});
		
		var build_tools = Builder.node('div', {'id':'editable_'+this.id+'-tools', 'class':'toolbar'});
		build_tools.setStyle({width:(this.width-4)+'px', height:'20px', padding:'1px', background:'#EFEFEF', border:'1px solid #AAAAAA', borderBottom:'0px none'});

		var build_frame =  Builder.node('iframe', {'id': 'editable_'+this.id, src:'editable_blank.html', frameborder:'0', allowtransparency:'true', contentEditable:'true', style: this.textarea.readAttribute('style')});
		var build_panel_contain = Builder.node('div', {'id':'editable_'+this.id+'-panel'}).setStyle({background:'#F9F9F9', width:(this.width-2)+'px', borderLeft:'1px solid #AAA', borderRight:'1px solid #AAA', display:'none'});
		var build_panel_inner = Builder.node('div', {'id':'editable_'+this.id+'-panel-inner'}).setStyle({cssFloat:'left', width:(this.width-2-25)+'px'});
		close_opts = this.actions.get('close');
		var close = Builder.node('div', {'id':'ebtn-'+this.id+'-close','class':'ebtn','style':'float:right;margin:0px 4px 0px -3px; border:1px solid #F9F9F9;','func':'close'}, [
			Builder.node('img', {src:'images/spacer.gif', height:'18', width:'18', title:'close'}).setStyle({backgroundImage:"url('"+this.options.iconLoc+"')", backgroundPosition:((close_opts.num-1)*-18)+'px 0px', cursor:'pointer'})
		]);
		build_panel_contain.insert(close);
		build_panel_contain.insert(build_panel_inner);
		build_panel_contain.insert(Builder.node('div', {style:'clear:both;'}));
		
		container.insert({top:build_frame});
		container.insert({top:build_panel_contain});
		container.insert({top:build_tools});
		
		for(var i=0;i<this.options.buttons.length;i++){
			var btn_opts = this.actions.get(this.options.buttons[i]);
			var btn = Builder.node('div', {'id':'ebtn-'+this.id+'-'+this.options.buttons[i],'class':'ebtn-'+this.id,func:btn_opts.func,'title':btn_opts.t});
			btn.setStyle({backgroundImage:"url('"+this.options.iconLoc+"')", backgroundPosition:((btn_opts.num-1)*-18)+'px 0px', width:'18px', height:'18px', cursor:'pointer', border:'1px solid #efefef', float:'left'});
			build_tools.insert(btn);
		}
		
		if(this.options.debug){
			var build_info = Builder.node('div', {'id':'editable_'+this.id+'-info'});
			container.insert({bottom: build_info});
			this.info = $(build_info);
		}
		this.textarea.hide();
		this.textarea.insert({before: container});
		
		this.panel = $(build_panel_contain);
		this.panelFill = $(build_panel_inner);
		this.panelOverride = false;
		this.setCmd($(close));
		
		this.currentPanel = '';
		this.tools = $(build_tools);
		this.iframe=$(build_frame);

		this.buildStyle();

		this.win = this.iframe.contentWindow;

		if(this.iframe.contentDocument) this.doc = this.iframe.contentDocument;	// Firefox, Opera
		else if(this.iframe.contentWindow) this.doc = this.iframe.contentWindow.document;	// Internet Explorer
		else if(this.iframe.document) this.doc = this.iframe.document;	// Other
		
		window.initIframe = this.initIframe.bind(this);
		this.doc.open();
		this.doc.writeln('<html><head><script src="js/protoculous.js"></script><style>body{ margin: 0pt ! important; padding: 3px ! important; background: transparent ! important;}</style></head><body id="content" class="view"><script>parent.initIframe($(\'content\'));</script></body></html>');
		this.doc.close();
		
	},

	initIframe: function(){
	
		this.body = this.doc.body;
		
		var cssdoc = this.options.css?this.options.css:'css/editable_style.css';

		if(Browser.Engine.trident){
			iframe.document.createStyleSheet(cssdoc);	
		}else{
			var ss = Builder.node('link', {href:cssdoc, rel:'stylesheet', type:'text/css'});
			this.doc.getElementsByTagName("head")[0].appendChild(ss);
		}

		if (['trident', 'presto'].indexOf(Browser.Engine.name)!=-1){
			this.doc.observe('focus', function(){	// styleWithCSS, not supported in IE and Opera
				this.doc.execCommand('styleWithCSS', false, false);
				this.doc.stopObserving('focus');
			}.bind(this));
		}
		
		this.doc.observe('keyup', this.checkStates.bind(this));
		this.doc.observe('mouseup', this.checkStates.bind(this));
		//this.doc.observe('beforepaste', this.cleanPaste.bind(this));
		//this.doc.observe('paste', this.cleanPaste.bind(this));
		
		(Browser.Engine.trident) ? this.doc.body.contentEditable = true : this.doc.designMode = 'On';
		
		// make images selectable and draggable in Safari
		if(Browser.Engine.webkit) this.doc.observe('click', function(e){
			var el = e.target;
			if (el.nodeName == 'IMG') this.selectNode(el);
		});

		if (this.doc.addEventListener) // W3C DOM
			this.doc.addEventListener('keydown',this.keyListener.bind(this), true);
		else if (this.doc.attachEvent) { // IE DOM
			this.doc.attachEvent("onkeydown", this.keyListener.bind(this));
		}

		this.body.innerHTML = this.content;
		this.doc.execCommand("inserthtml", false, " ");
		this.doc.execCommand("undo", false, null); 

		editables.set(this.id, this);
		
		$$('div.ebtn-'+this.id).each(this.setCmd.bind(this));
		
	},

	setContent: function(c) {
		this.content = c;
		this.body.update(this.content);	
	},
	
	getContent: function(){
		this.content = this.doCleanup(this.body.innerHTML);
		return this.content;
	},
	
	saveContent: function(){
		this.getContent();
		this.textarea.value = this.content;
	},
	
	findEl : function(tag,attr,val) {
		var els = this.doc.getElementsByTagName(tag);
		for(var i=0;i<els.length;i++) {
			if(els[i].readAttribute(attr) == val) {
				return $(els[i]);
			}
		}
	},

	setCmd: function(btn){
		btn.observe('click', this.doCmd.bind(this, btn, true));
		btn.observe('mouseout', function(){
			if(!this.hasClassName('active')) this.setStyle({'border':'1px solid #EFEFEF'});
		});
		btn.observe('mouseover', function(){this.setStyle({'border':'1px solid #AAAAAA'});});
	},

	checkStates: function() {
		this.options.buttons.each(function(btn) {
			var btn_opts = this.actions.get(btn);
			var button = $('ebtn-'+this.id+'-'+btn);
			button.removeClassName('active');
			button.setStyle({border:'1px solid #EFEFEF'});
			
			if (btn_opts.tags) {
				var el = this.getNode();
				
				if (el) do {
					if (this.nodeType(el) != 'element') break;
					if (btn_opts.tags.indexOf(el.nodeName.toLowerCase()) != -1){
						var node_name = el.nodeName.toLowerCase();
						if(node_name == 'img' && el.readAttribute('imgtype') == 'ad'){
							btn_opts = this.actions.get('ad');
							button = $('ebtn-'+this.id+'-ad');
						}else if(node_name == 'img'){
							btn_opts = this.actions.get('image');
							button = $('ebtn-'+this.id+'-image');
						}
						button.setStyle({'border':'1px solid #333'});
						button.addClassName('active');
						if(btn_opts.func != this.currentPanel && !this.panelOverride) this.buildPanel(btn_opts.func);
					}
				}
				while (el = el.parentNode);
			}

			if(btn_opts.css.prop) {
				var el = this.getNode();
				if (el) do {
					
					if (this.nodeType(el) != 'element') break;
					if ($(el).getStyle(btn_opts.css.prop) == btn_opts.css.val){
						button.setStyle({'border':'1px solid #333'});
						button.addClassName('active');
					}
				}
				while (el = el.parentNode);
			}
			if(this.updatePanel) this.updatePanel();
			this.updateStyle();
			if(this.options.debug) this.info.innerHTML = 'name:'+this.getNode().nodeName+' - type:'+this.nodeType(this.getNode())+' - current:'+this.currentPanel;
		}.bind(this));
	},

	doCmd: function(btn, override) {
		
		var func = btn.readAttribute('func');
		btn.addClassName('active');
		switch(func){

			case 'browseimg':
			case 'editimg':
			case 'fontcolor':
			case 'browsead':
				this.buildPop(func);
			break;
			case 'link':
			case 'image':
			case 'ad':
			case 'table':
			case 'block':
			case 'html':
				if(override) this.panelOverride = true;
				this.buildPanel(func);
			break;
			case 'close':
				this.togglePanel(this.currentPanel);
				 this.panelOverride = false;
			break;
			case 'save':
				this.saveContent();
			break;
			case 'removeformat':
				this.doc.execCommand('removeFormat', false, false);
				var n = $(this.getNode());
				n.writeAttribute({style:''});
				n.descendants().each(function(child){
					child.writeAttribute({style:''});
				});
				var nHTML = n.innerHTML;
				nHTML.replace(/<font([^>]*)>(.*?)<\/font>/g, '$2');
				nHTML.replace(/<div([^>]*)>(.*?)<\/div>/g, '<p>$2</p>');
				n.innerHTML = nHTML;
			break;
			case 'p':
			case 'h1':
			case 'h2':
			case 'h3':
				this.doc.execCommand('formatBlock', false, func);
			break;
			default:
				this.doc.execCommand(func, false, false);
			break;
		}
		
		this.checkStates();
	},

	buildPop: function(func, extra){
		this.popfill.update('<div align="center"><img src="images/load/load_squares-24.gif"></div>');
		var pos = this.iframe.positionedOffset();
		this.pop.setStyle({top:pos.top+'px', left:pos.left+'px'});
		switch(func){
			case 'color':
			case 'fontcolor':
				this.popfill.innerHTML = '<div style="position:relative;"><div id="cp_'+this.id+'-container"><table><tr><td width="40">Swatches:<div id="cp_'+this.id+'_swatches"></div></td><td valign="top"> <div id="cp_'+this.id+'_ColorMap"></div></td><td valign="top"> <div id="cp_'+this.id+'_ColorBar"></div></td>  <td valign="top"><table>  <tr><td colspan="3" align="center"><div id="cp_'+this.id+'_Preview" style="background-color: #fff; width: 110px; height: 30px; padding: 0; margin: 0; border: solid 1px #000;">  <bR> </div></td>  </tr>  <tr><td> <input type="radio" id="cp_'+this.id+'_HueRadio" name="cp_'+this.id+'_Mode" value="0" /></td><td> <label for="cp_'+this.id+'_HueRadio">H:</label></td><td> <table cellspacing="0" cellpadding="0" width="100%"> <tr>  <td width="7"><img src="images/forms/text-field-left.gif"></td>  <td class="text-field-rpt"><input type="text" id="cp_'+this.id+'_Hue" value="0" style="width: 45px;" >&deg;</td>  <td width="7"><img src="images/forms/text-field-right.gif"></td> </tr> </table> </td>  </tr> <tr><td> <input type="radio" id="cp_'+this.id+'_SaturationRadio" name="cp_'+this.id+'_Mode" value="1" /></td><td> <label for="cp_'+this.id+'_SaturationRadio">S:</label></td><td> <table cellspacing="0" cellpadding="0" width="100%"> <tr>  <td width="7"><img src="images/forms/text-field-left.gif"></td>  <td class="text-field-rpt"><input type="text" id="cp_'+this.id+'_Saturation" value="0" style="width: 45px;" >%</td>  <td width="7"><img src="images/forms/text-field-right.gif"></td> </tr> </table></td>  </tr> <tr><td> <input type="radio" id="cp_'+this.id+'_BrightnessRadio" name="cp_'+this.id+'_Mode" value="2" /></td><td> <label for="cp_'+this.id+'_BrightnessRadio">B:</label></td><td> <table cellspacing="0" cellpadding="0" width="100%"> <tr>  <td width="7"><img src="images/forms/text-field-left.gif"></td>  <td class="text-field-rpt"><input type="text" id="cp_'+this.id+'_Brightness" value="0" style="width: 45px;" >%</td>  <td width="7"><img src="images/forms/text-field-right.gif"></td> </tr> </table></td>  </tr> <tr><td colspan="3" height="5">  </td>  </tr> <tr><td> <input type="radio" id="cp_'+this.id+'_RedRadio" name="cp_'+this.id+'_Mode" value="r" /></td><td> <label for="cp_'+this.id+'_RedRadio">R:</label></td><td> <table cellspacing="0" cellpadding="0" width="100%"> <tr>  <td width="7"><img src="images/forms/text-field-left.gif"></td>  <td class="text-field-rpt"><input type="text" id="cp_'+this.id+'_Red" value="0" style="width: 45px;" >&nbsp;</td>  <td width="7"><img src="images/forms/text-field-right.gif"></td> </tr> </table></td>  </tr> <tr><td> <input type="radio" id="cp_'+this.id+'_GreenRadio" name="cp_'+this.id+'_Mode" value="g" /></td><td> <label for="cp_'+this.id+'_GreenRadio">G:</label></td><td> <table cellspacing="0" cellpadding="0" width="100%"> <tr>  <td width="7"><img src="images/forms/text-field-left.gif"></td>  <td class="text-field-rpt"><input type="text" id="cp_'+this.id+'_Green" value="0" style="width: 45px;" >&nbsp;</td>  <td width="7"><img src="images/forms/text-field-right.gif"></td> </tr> </table></td>  </tr> <tr><td> <input type="radio" id="cp_'+this.id+'_BlueRadio" name="cp_'+this.id+'_Mode" value="b" /></td><td> <label for="cp_'+this.id+'_BlueRadio">B:</label></td><td> <table cellspacing="0" cellpadding="0" width="100%"> <tr>  <td width="7"><img src="images/forms/text-field-left.gif"></td>  <td class="text-field-rpt"><input type="text" id="cp_'+this.id+'_Blue" value="0" style="width: 45px;" >&nbsp;</td>  <td width="7"><img src="images/forms/text-field-right.gif"></td> </tr> </table></td>  </tr><tr><td colspan="3"> <table cellspacing="0" cellpadding="0" width="100%"> <tr>  <td align="right">Hex: &nbsp; </td>  <td width="7"><img src="images/forms/text-field-left.gif"></td>  <td class="text-field-rpt">#<input type="text" name="cp_'+this.id+'_Hex" id="cp_'+this.id+'_Hex" value="555555" style="width: 50px;" ></td>  <td width="7"><img src="images/forms/text-field-right.gif"></td> </tr> </table></td>  </tr></table>  </td></tr></table></div><div style="display:none;"><img src="images/colorpicker/rangearrows.gif" /><img src="images/colorpicker/mappoint.gif" /> <img src="images/colorpicker/bar-saturation.png" /><img src="images/colorpicker/bar-brightness.png" /> <img src="images/colorpicker/bar-blue-tl.png" /><img src="images/colorpicker/bar-blue-tr.png" /><img src="images/colorpicker/bar-blue-bl.png" /><img src="images/colorpicker/bar-blue-br.png" /><img src="images/colorpicker/bar-red-tl.png" /><img src="images/colorpicker/bar-red-tr.png" /><img src="images/colorpicker/bar-red-bl.png" /><img src="images/colorpicker/bar-red-br.png" /><img src="images/colorpicker/bar-green-tl.png" /><img src="images/colorpicker/bar-green-tr.png" /><img src="images/colorpicker/bar-green-bl.png" /><img src="images/colorpicker/bar-green-br.png" /> <img src="images/colorpicker/map-red-max.png" /><img src="images/colorpicker/map-red-min.png" /><img src="images/colorpicker/map-green-max.png" /><img src="images/colorpicker/map-green-min.png" /><img src="images/colorpicker/map-blue-max.png" /><img src="images/colorpicker/map-blue-min.png" /> <img src="images/colorpicker/map-saturation.png" /><img src="images/colorpicker/map-saturation-overlay.png" /><img src="images/colorpicker/map-brightness.png" /><img src="images/colorpicker/map-hue.png"/></div></div>';
				var btn = Builder.node('div', {style:'margin:1px 4px;'}, [Builder.node('input', {type:'button', name:'color-'+this.id+'-btn', id:'color-'+this.id+'-btn', style:'border:1px solid #AAA', value:'select color'})]);
				this.popfill.insert(btn);
				new Effect.Appear(this.pop, {duration:0.5,afterFinish:function(){
					startcolor = '000000';
					this.cp = new Refresh.Web.ColorPicker('cp_'+this.id,{startHex: startcolor, startMode:'h'});
				}.bind(this)});
				
				var site_id = (typeof(current) == 'object')?current.get('site_id'):0;
				var vars = 'act=color.functions&func=get-swatches&site_id='+site_id+'&nic=1&target='+this.id;
				getXHR('cp_'+this.id+'_swatches', 'index.php', vars, '0', 'get');
				
				$('color-'+this.id+'-btn').observe('click', function(){
					var color = $('cp_'+this.id+'_Hex').value;
					if(func == 'fontcolor') this.doc.execCommand('forecolor', false, color);
					else $(extra+'-'+this.id).value = color;
					new Effect.Fade(this.pop, {afterFinish:function(){this.popfill.innerHTML = '';}.bind(this)});
				}.bind(this));
			break;
			
			case 'browseimg':
				new Effect.Appear(this.pop);
				new Ajax.Updater(this.popfill, 'index.php?act=content.images&history=0&mode=select&target_container='+this.popfill.identify()+'&return_field=src-'+this.id+'&nic=1&editor='+this.id,{evalScripts: true});
				
			break;
			case 'editimg':
				var n = $(this.getNode());
				var img_id = n.readAttribute('id');
				new Effect.Appear(this.pop);
				new Ajax.Updater(this.popfill, 'index.php?act=content.edit-image&target_container='+this.popfill.identify()+'&return_field=src-'+this.id+'&nic=1&image_id='+img_id+'&editor='+this.id,{evalScripts: true});
				
			break;
			case 'browsead':
				new Effect.Appear(this.pop);
				new Ajax.Updater(this.popfill, 'index.php?act=manage.ads&history=0&mode=select&target_container='+this.popfill.identify()+'&return_field=ad_name-'+this.id+'&nic=1&editor='+this.id,{evalScripts: true});
				
			break;
			case 'editad':
				var n = $(this.getNode());
				var ad_id = n.readAttribute('id');
				new Effect.Appear(this.pop);
				new Ajax.Updater(this.popfill, 'index.php?act=manage.ad-functions&func=add-edit-ad&target='+this.popfill.identify()+'&return_field=ad_name-'+this.id+'&nic=1&config_id='+ad_id+'&editor='+this.id,{evalScripts: true});
			break;
			default:
			break;
		}
	},

	togglePanel: function(func){
		if(this.panel.visible() == true && func == 'html'){
			this.panel.hide();
			var new_height = this.height;
		}else if(func == 'html'||func == 'image'||func == 'link'||func == 'ad'||func == 'table'||func == 'block'){
			this.panel.show();
			var new_height = (this.height-2)-this.panel.getHeight();
		}
		this.iframe.setStyle({height:new_height+'px'});
		this.currentPanel = func;
	},

	buildPanel: function(func){

		switch(func){
			case 'html':
				this.updatePanel = null;
				var outer = Builder.node('div', {style:'padding:1px;'}),
					htmlcode = Builder.node('textarea', {'class':'codepress html',id:'htmlcode',style:'height:'+(this.height-30)+'px;width:'+(this.width-14)+'px;margin:1px 4px;'}),
					btn = Builder.node('div', {style:'margin:1px 4px;'}, [Builder.node('input', {type:'button', name:'btn', id:'btn-'+this.id, style:'border:1px solid #AAA', value:'update'}),Builder.node('input', {type:'button', name:'btn', id:'clean-word-btn-'+this.id, style:'border:1px solid #AAA;margin-left:20px;', value:'clean word'})]);
				
				htmlcode.update(this.getContent());
				outer.insert(btn);
				outer.insert(htmlcode);
				this.panelFill.update(outer);
		
				$(btn).observe('click', function(){
					var c = window.htmlcode.getCode();
					this.setContent(c);
					this.panelOverride = false;
					this.togglePanel('html');
				}.bind(this));
				
				$('clean-word-btn-'+this.id).observe('click', function(){
					var c = window.htmlcode.getCode();
					c = this.cleanWord(c);
					window.htmlcode.setCode(c);
				}.bind(this));
				
			break;
			case 'block':
				var outer = Builder.node('div', {style:'padding:1px;'}),
					clear = Builder.node('div', {style:'clear:both;'}),
					border = Builder.node('div', {style:'float:left;margin:1px 4px;'}, ['Border ', Builder.node('input', {name:'border', id:'border-'+this.id, style:'border:1px solid #AAA', size:'2', autocomplete:'off'})]),
					bcolor = Builder.node('div', {style:'float:left;margin:1px 4px;'}, ['Border Color ', Builder.node('input', {name:'bcolor', id:'bcolor-'+this.id, style:'border:1px solid #AAA', size:'6', autocomplete:'off'})]),
					bgcolor = Builder.node('div', {style:'float:left;margin:1px 4px;'}, ['BG Color ', Builder.node('input', {name:'bgcolor', id:'bgcolor-'+this.id, style:'border:1px solid #AAA', size:'6', autocomplete:'off'})]),
					width = Builder.node('div', {style:'float:left;margin:1px 4px;'}, ['Width ', Builder.node('input', {name:'width', id:'width-'+this.id, style:'border:1px solid #AAA', size:'3', autocomplete:'off'})]),
					pad = Builder.node('div', {style:'float:left;margin:1px 4px;'}, ['Pad ', Builder.node('input', {name:'pad', id:'pad-'+this.id, value:'5', style:'border:1px solid #AAA', size:'2', autocomplete:'off'})]),
					space = Builder.node('div', {style:'float:left;margin:1px 4px;'}, ['Space ', Builder.node('input', {name:'space', id:'space-'+this.id, value:'5', style:'border:1px solid #AAA', size:'2', autocomplete:'off'})]),
					fselect = Builder.node('div', {style:'float:left;margin:1px 4px;'}, ['float ',Builder.node('select', {name:'float', id:'float-'+this.id, style:'border:1px solid #AAA'}).insert('<option value="none">block</option>'+'<option value="left">left</option>'+'<option value="right">right</option>')]),
					btn = Builder.node('div', {style:'float:left;margin:1px 4px;'}, [Builder.node('input', {type:'button', name:'btn', id:'btn-'+this.id, style:'border:1px solid #AAA', value:'update'})]);
								
				outer.insert(btn);
				outer.insert(src);
				outer.insert(border);
				outer.insert(bcolor);
				outer.insert(bgcolor);
				outer.insert(width);
				outer.insert(pad);
				outer.insert(space);
				outer.insert(fselect);
				outer.insert(clear);
				this.panelFill.update(outer);

				$(bcolor).observe('click', function(){this.buildPop('color', 'bcolor');}.bind(this));
				$(bgcolor).observe('click', function(){this.buildPop('color', 'bgcolor');}.bind(this));
				
				this.updatePanel = function(){
					var n = $(this.getNode());
					fselect = $('float-'+this.id);
					if(n.getStyle('borderLeftWidthValue')) $('border-'+this.id).value = n.getStyle('borderLeftWidthValue').replace('px', '');
					if(n.getStyle('borderLeftColorValue')) $('bcolor-'+this.id).value = n.getStyle('borderLeftColorValue');
					if(n.getStyle('backgroundColorValue')) $('bcolor-'+this.id).value = n.getStyle('backgroundColorValue');
					if(n.getStyle('width')) $('width-'+this.id).value = (n.getStyle('width')!='734px')?n.getStyle('width').replace('px', ''):'';
					$('pad-'+this.id).value = n.getStyle('paddingLeft').replace('px', '');
					$('space-'+this.id).value = n.getStyle('marginLeft').replace('px', '');
					var cssfloat = n.getStyle('float');
					for(var i=0;i<fselect.options.length;i++) if(fselect.options[i].value==cssfloat) fselect.selectedIndex = i;

				}.bind(this);
				this.updatePanel();
				
				$(btn).observe('click', function(){
					var n = $(this.getNode());
					var border = $('border-'+this.id).value;
					var bcolor = $('bcolor-'+this.id).value;
					var bgcolor = $('bgcolor-'+this.id).value;
					var width = $('width-'+this.id).value;
					var pad = $('pad-'+this.id).value;
					var space = $('space-'+this.id).value;
					var cssfloat = $('float-'+this.id).value;
					if(border!='') n.setStyle({border:border+'px solid #'+(bcolor?bcolor:'000')});
					if(bgcolor!='') n.setStyle({background:'#'+bgcolor});
					if(width!='') n.setStyle({width:width+'px'});
					if(height!='') n.setStyle({height:height+'px'});
					if(pad!='') n.setStyle({padding:pad+'px'});
					if(space!='') n.setStyle({margin:space+'px'});
					n.setStyle({cssFloat:cssfloat});
					this.panelOverride = false;
				}.bind(this));
			break;
			case 'table':
				var outer = Builder.node('div', {style:'padding:1px;'}),
					clear = Builder.node('div', {style:'clear:both;'}),
					border = Builder.node('div', {style:'float:left;margin:1px 4px;'}, ['Border ', Builder.node('input', {name:'border', id:'border-'+this.id, style:'border:1px solid #AAA', size:'2', autocomplete:'off'})]),
					width = Builder.node('div', {style:'float:left;margin:1px 4px;'}, ['Width ', Builder.node('input', {name:'width', id:'width-'+this.id, style:'border:1px solid #AAA', size:'3', autocomplete:'off'})]),
					height = Builder.node('div', {style:'float:left;margin:1px 4px;'}, ['Height ', Builder.node('input', {name:'height', id:'height-'+this.id, style:'border:1px solid #AAA', size:'3', autocomplete:'off'})]),
					pad = Builder.node('div', {style:'float:left;margin:1px 4px;'}, ['Pad ', Builder.node('input', {name:'pad', id:'pad-'+this.id, style:'border:1px solid #AAA', size:'2', autocomplete:'off'})]),
					space = Builder.node('div', {style:'float:left;margin:1px 4px;'}, ['Space ', Builder.node('input', {name:'space', id:'space-'+this.id, style:'border:1px solid #AAA', size:'2', autocomplete:'off'})]),
					vselect = Builder.node('div', {style:'float:left;margin:1px 4px;'}, ['vAlign ',Builder.node('select', {name:'valign', id:'valign-'+this.id, style:'border:1px solid #AAA'}).insert('<option value="">middle</option>'+'<option value="top">top</option>'+'<option value="bottom">bottom</option>')]),
					btn = Builder.node('div', {style:'float:left;margin:1px 4px;'}, [Builder.node('input', {type:'button', name:'btn', id:'btn-'+this.id, style:'border:1px solid #AAA', value:'update'})]);
								
				outer.insert(btn);
				outer.insert(src);
				outer.insert(border);
				outer.insert(width);
				outer.insert(height);
				outer.insert(pad);
				outer.insert(space);
				outer.insert(vselect);
				outer.insert(clear);
				this.panelFill.update(outer);

				this.updatePanel = function(){
					var n = $(this.getNode());
					vselect = $('valign-'+this.id);
					if(n.nodeName == 'TD' || n.nodeName == 'TABLE'){
						$('border-'+this.id).value = n.up('table').readAttribute('border');
						$('width-'+this.id).value = n.readAttribute('width');
						$('height-'+this.id).value = n.readAttribute('height');
						$('pad-'+this.id).value = n.up('table').readAttribute('cellpadding');
						$('space-'+this.id).value = n.up('table').readAttribute('cellspacing');
						var valign = n.readAttribute('valign');
						for(var i=0;i<vselect.options.length;i++) if(vselect.options[i].value==valign) vselect.selectedIndex = i;
					}
				}.bind(this);
				this.updatePanel();
				
				$(btn).observe('click', function(){
					var n = $(this.getNode());
					if(n.nodeName != 'TABLE' && n.nodeName != 'TD'){
						var border = $('border-'+this.id).value;
						var width = $('width-'+this.id).value;
						var height = $('height-'+this.id).value;
						var table = '<table id="tmptable" border="'+border+'" style="'+(width!=''?'width:'+width+'px;':'100px;')+(height!=''?'height:'+height+'px;':'')+'"><tbody><tr><td></td></tr></tbody></table>';
						this.doc.execCommand("inserthtml", false, table);
						n = this.iframe.$('tmptable');
						n.writeAttribute('id', '');
						this.selectNode(n.down('td'));
					}
					var n = $(this.getNode());
					n.up('table').writeAttribute('border', $('border-'+this.id).value);
					n.writeAttribute('width', $('width-'+this.id).value);
					n.writeAttribute('height', $('height-'+this.id).value);
					n.writeAttribute('valign', $('valign-'+this.id).value);
					n.up('table').writeAttribute('cellpadding', $('pad-'+this.id).value);
					n.up('table').writeAttribute('cellspacing', $('space-'+this.id).value);
					this.panelOverride = false;
				}.bind(this));

			break;
			case 'image':
				var browse_opts = this.actions.get('browse');
				var edit_opts = this.actions.get('edit');
				var outer = Builder.node('div', {style:'padding:1px;'}),
					clear = Builder.node('div', {style:'clear:both;'}),
					src = Builder.node('div', {style:'float:left;margin:1px 4px;'}, [
						'Src ',Builder.node('input', {type:'text', name:'src', id:'src-'+this.id, style:'border:1px solid #AAA'})
					]),
					browseimg = Builder.node('div', {'id':'ebtn-'+this.id+'-browse','class':'ebtn',style:'float:left;margin:0px 4px 0px -3px; border:1px solid #F9F9F9;background:#EEE;',func:'browseimg'}, [
						Builder.node('img', {src:'images/spacer.gif', height:'18', width:'18', title:'browse'}).setStyle({backgroundImage:"url('"+this.options.iconLoc+"')", backgroundPosition:((browse_opts.num-1)*-18)+'px 0px', cursor:'pointer'})
					]),
					editimg = Builder.node('div', {'id':'ebtn-'+this.id+'-editimg','class':'ebtn',style:'float:left;margin:0px 4px 0px -3px; border:1px solid #F9F9F9;background:#EEE;display:none;',func:'editimg'}, [
						Builder.node('img', {src:'images/spacer.gif', height:'18', width:'18', title:'edit image'}).setStyle({backgroundImage:"url('"+this.options.iconLoc+"')", backgroundPosition:((edit_opts.num-1)*-18)+'px 0px', cursor:'pointer'})
					]),
					hspace = Builder.node('div', {style:'float:left;margin:1px 4px;'}, [
						'h ',Builder.node('input', {type:'text', name:'hspace', id:'hspace-'+this.id, style:'border:1px solid #AAA', size:'2'})
					]),
					vspace = Builder.node('div', {style:'float:left;margin:1px 4px;'}, [
						'v ',Builder.node('input', {type:'text', name:'vspace', id:'vspace-'+this.id, style:'border:1px solid #AAA', size:'2'})
					]),
					fselect = Builder.node('div', {style:'float:left;margin:1px 4px;'}, [
						'Align ',Builder.node('select', {name:'align', id:'align-'+this.id, style:'border:1px solid #AAA'}).insert('<option value="left">left</option>'+'<option value="none">block</option>'+'<option value="right">right</option>')
					]),
					border = Builder.node('div', {style:'float:left;margin:1px 4px;'}, ['Border ', Builder.node('input', {name:'border', id:'border-'+this.id, style:'border:1px solid #AAA', size:'2'})]),
					alt = Builder.node('div', {style:'float:left;margin:1px 4px;'}, ['Alt ', Builder.node('input', {name:'alt', id:'alt-'+this.id, style:'border:1px solid #AAA;width:100px;'})]),
					img_id = Builder.node('input', {type:'hidden', name:'img_id', id:'imgid-'+this.id}),
					btn = Builder.node('div', {style:'float:left;margin:1px 4px;'}, [Builder.node('input', {type:'button', name:'btn', id:'btn-'+this.id, style:'border:1px solid #AAA', value:'update'})]);
								
				outer.insert(btn);
				outer.insert(src);
				outer.insert(browseimg);
				outer.insert(editimg);
				outer.insert(fselect);
				outer.insert(hspace);
				outer.insert(vspace);
				outer.insert(border);
				outer.insert(alt);
				outer.insert(img_id);
				outer.insert(clear);
				this.panelFill.update(outer);
				
				this.setCmd($(browseimg));
				this.setCmd($(editimg));
				
				this.updatePanel = function(){
					var n = $(this.getNode());
					var fselect = $('align-'+this.id);
					if(n.nodeName == 'IMG'){
						var imgid = n.readAttribute('id');
						$('imgid-'+this.id).value = imgid;
						$('src-'+this.id).value = n.readAttribute('src');
						$('alt-'+this.id).value = n.readAttribute('alt');
						$('hspace-'+this.id).value = n.readAttribute('hspace');
						$('vspace-'+this.id).value = n.readAttribute('vspace');
						$('border-'+this.id).value = n.readAttribute('border');
						var i_align = n.readAttribute('align');
						for(var i=0;i<fselect.options.length;i++) if(fselect.options[i].value==i_align) fselect.selectedIndex = i;
						if(imgid) $('ebtn-'+this.id+'-editimg').show();
					}
				}.bind(this);
				this.updatePanel();
				
		
				$(btn).observe('click', function(){
					var n = $(this.getNode());
					if(n.nodeName != 'IMG'){
					this.doc.execCommand('insertImage',false,'javascript:tmp();');
						var n = this.findEl('img', 'src', 'javascript:tmp();');
						if(n){
							n.writeAttribute('imgtype', 'image');
							this.selectNode(n);
						}
					}
					n.writeAttribute('src', $('src-'+this.id).value);
					n.writeAttribute('id', $('imgid-'+this.id).value);
					n.writeAttribute('alt', $('alt-'+this.id).value);
					n.writeAttribute('align', $('align-'+this.id).value);
					n.writeAttribute('hspace', $('hspace-'+this.id).value);
					n.writeAttribute('vspace', $('vspace-'+this.id).value);
					n.writeAttribute('border', $('border-'+this.id).value);
					n.writeAttribute('imgtype', 'image');
					this.panelOverride = false;
				}.bind(this));

			break;
			case 'ad':
				var edit_opts = this.actions.get('edit');
				var browse_opts = this.actions.get('browse');
				var outer = Builder.node('div', {style:'padding:1px;'}),
					clear = Builder.node('div', {style:'clear:both;'}),
					ad = Builder.node('div', {style:'float:left;margin:1px 4px;'}, [
						'Ad ',
						Builder.node('input', {type:'text', name:'ad_name', id:'ad_name-'+this.id, style:'border:1px solid #AAA'})
					]),
					browse = Builder.node('div', {'id':'ebtn-'+this.id+'-browse','class':'ebtn',style:'float:left;margin:0px 4px 0px -3px; border:1px solid #F9F9F9;background:#EEE;',func:'browsead'}, [
						Builder.node('img', {src:'images/spacer.gif', height:'18', width:'18', title:'browse'}).setStyle({backgroundImage:"url('"+this.options.iconLoc+"')", backgroundPosition:((browse_opts.num-1)*-18)+'px 0px', cursor:'pointer'})
					]),
					editad = Builder.node('div', {'id':'ebtn-'+this.id+'-editad','class':'ebtn',style:'float:left;margin:0px 4px 0px -3px; border:1px solid #F9F9F9;background:#EEE;display:none;',func:'editad'}, [
						Builder.node('img', {src:'images/spacer.gif', height:'18', width:'18', title:'edit ad'}).setStyle({backgroundImage:"url('"+this.options.iconLoc+"')", backgroundPosition:((edit_opts.num-1)*-18)+'px 0px', cursor:'pointer'})
					]),
					margin = Builder.node('div', {style:'float:left;margin:1px 4px;'}, [
						'Margin ',
						Builder.node('input', {type:'text', name:'margin', id:'margin-'+this.id, style:'border:1px solid #AAA', size:'2'})
					]),
					keyword = Builder.node('div', {style:'float:left;margin:1px 4px;'}, [
						'Keyword ',
						Builder.node('input', {type:'text', name:'ad_kw', id:'ad_kw-'+this.id, style:'border:1px solid #AAA'})
					]),
					fselect = Builder.node('div', {style:'float:left;margin:1px 4px;'}, [
						'Align ',
						Builder.node('select', {name:'align', id:'align-'+this.id, style:'border:1px solid #AAA'}).insert('<option value="">- select -</option>'+'<option value="left">left</option>'+'<option value="none">block</option>'+'<option value="right">right</option>')
					]),
					btn = Builder.node('div', {style:'float:left;margin:1px 4px;'}, [Builder.node('input', {type:'button', name:'btn', id:'btn-'+this.id, style:'border:1px solid #AAA', value:'update'})]),
					ad_h = Builder.node('input', {type:'hidden', name:'ad_height', id:'ad_height-'+this.id, style:'border:1px solid #AAA'}),
					ad_w = Builder.node('input', {type:'hidden', name:'ad_width', id:'ad_width-'+this.id, style:'border:1px solid #AAA'}),
					ad_id = Builder.node('input', {type:'hidden', name:'ad_id', id:'ad_id-'+this.id, style:'border:1px solid #AAA'});
								
				outer.insert(btn);
				outer.insert(ad);
				outer.insert(browse);
				outer.insert(editad);
				outer.insert(keyword);
				outer.insert(fselect);
				outer.insert(margin);
				outer.insert(ad_h);
				outer.insert(ad_w);
				outer.insert(ad_id);
				outer.insert(clear);
				this.panelFill.update(outer);
				
				this.setCmd($(browse));
				this.setCmd($(editad));
				
				this.updatePanel = function(){
					var n = $(this.getNode());
					var fselect = $('align-'+this.id);
					if(n.nodeName == 'IMG'){
						$('ad_id-'+this.id).value = n.readAttribute('id');
						$('ad_name-'+this.id).value = n.readAttribute('title');
						var i_align = n.readAttribute('align');
						for(var i=0;i<fselect.options.length;i++) if(fselect.options[i].value==i_align) fselect.selectedIndex = i;
						$('ad_width-'+this.id).value = n.readAttribute('width');
						$('ad_height-'+this.id).value = n.readAttribute('height');
						$('margin-'+this.id).value=n.getStyle('marginLeft').replace(/px/,'');
						$('ad_kw-'+this.id).value=n.readAttribute('class');
//						if($('ad_id-'+this.id).value) $('ebtn-'+this.id+'-editad').show();
					}
				}.bind(this);
				this.updatePanel();
											
				$(btn).observe('click', function(){
					var n = $(this.getNode());
					if(n.nodeName != 'IMG'){
					this.doc.execCommand('insertImage',false,'javascript:tmp();');
						var n = this.findEl('img', 'src', 'javascript:tmp();');
						if(n){
							n.writeAttribute('imgtype', 'ad');
							n.writeAttribute('src', 'images/drop_holder.gif');
							this.selectNode(n);
						}
					}
					n.writeAttribute('title', $('ad_name-'+this.id).value);
					n.writeAttribute('id', $('ad_id-'+this.id).value);
					n.writeAttribute('align', $('align-'+this.id).value);
					n.writeAttribute('style', 'margin:'+$('margin-'+this.id).value+'px;');
					n.writeAttribute('class', $('ad_kw-'+this.id).value.replace('#',''));
					n.writeAttribute('width', $('ad_width-'+this.id).value);
					n.writeAttribute('height', $('ad_height-'+this.id).value);
					n.writeAttribute('alt',$('ad_width-'+this.id).value+'x'+$('ad_height-'+this.id).value+'x'+$('margin-'+this.id).value+'x'+$('align-'+this.id).value);
					n.writeAttribute('imgtype', 'ad');
					this.panelOverride = false;
				}.bind(this));
			
			break;
			case 'link':
				var outer = Builder.node('div', {style:'padding:1px;'}),
					clear = Builder.node('div', {style:'clear:both;'}),
					page = Builder.node('div', {style:'float:left;margin:1px 4px;'}, ['Page ']),
					page_select = Builder.node('select', {name:'page', id:'page-'+this.id, style:'border:1px solid #AAA;width:100px;'}),
					href = Builder.node('div', {style:'float:left;margin:1px 4px;'}, [
						'URL ',
						Builder.node('input', {type:'text', name:'href', id:'href-'+this.id, style:'border:1px solid #AAA;width:150px;'})
					]),
					title = Builder.node('div', {style:'float:left;margin:1px 4px;'}, [
						'Title ',
						Builder.node('input', {type:'text', name:'title', id:'title-'+this.id, style:'border:1px solid #AAA;width:100px;'})
					]),
					target = Builder.node('div', {style:'float:left;margin:1px 4px;'}, [
						'Open in ',
						Builder.node('select', {name:'target', id:'target-'+this.id, style:'border:1px solid #AAA'}).insert('<option value="">Same Window</option>'+'<option value="_blank">New Window</option>')
					]),
					btn = Builder.node('div', {style:'float:left;margin:1px 4px;'}, [Builder.node('input', {type:'button', name:'btn', id:'btn-'+this.id, style:'border:1px solid #AAA', value:'update'})]);
				
				
				
				if(this.options.pages){
					page_select.insert(this.options.pages);
				}else{
					page_select.insert('<option value="">N/A</option>');
					page_select.disabled = true;
				}
				page.insert(page_select);
				
				outer.insert(btn);
				outer.insert(page);
				outer.insert(href);
				outer.insert(title);
				outer.insert(target);
				outer.insert(clear);
				this.panelFill.update(outer);

				this.updatePanel = function(){
					var n = $(this.getNode());
					var pselect = $('page-'+this.id);
					var tselect = $('target-'+this.id);
					if(n.nodeName == 'IMG') n = n.parentNode;
					if(n.nodeName == 'A'){
						var l_href = n.readAttribute('href');
						var l_title = n.readAttribute('title');
						var l_target = n.readAttribute('target');
						for(var i=0;i<pselect.options.length;i++) if(pselect.options[i].value==l_href) pselect.selectedIndex = i;
						for(var i=0;i<tselect.options.length;i++) if(tselect.options[i].value==l_target) tselect.selectedIndex = i;
						$('href-'+this.id).value=l_href=='javascript:temp();'?'':l_href;
						$('title-'+this.id).value=l_title;
					}
				}.bind(this);
				this.updatePanel();
				
				$(page_select).observe('change', function(pselect){
					$('href-'+this.id).value = pselect.value;
				}.bind(this, page_select));

				$(btn).observe('click', function(){
					var n = $(this.getNode());
					if(n.nodeName != 'A'){
						this.doc.execCommand('createlink',false,'javascript:tmp();');
						n = this.findEl('a', 'href', 'javascript:tmp();');
						if(n) this.selectNode(n);
					}
					n.writeAttribute('href', $('page-'+this.id).value?$('page-'+this.id).value:$('href-'+this.id).value);
					n.writeAttribute('target', $('target-'+this.id).value);
					n.writeAttribute('title', $('title-'+this.id).value);
					this.panelOverride = false;
				}.bind(this));

			break;
			default:
				
			break;
		}
		this.togglePanel(func);
		if(func == 'html'){
			window.setTimeout("CodePress.run();",100);
		}
	},

	buildStyle: function(){
		var styles = Builder.node('div', {style:'float:left;font-size:10px;height:18px;padding:1px;'}),
			table = Builder.node('table', {cellpadding:'0', cellspacing:'0'}),
			tbody = Builder.node('tbody'),
			tr = Builder.node('tr'),
			td1 = Builder.node('td'),
			td2 = Builder.node('td'),
			fselect = Builder.node('select', {name:'font', style:'border:1px solid #AAA;height:18px;width:100px;'}).insert('<option value="">- font -</option>'),
			sselect = Builder.node('select', {name:'size', style:'border:1px solid #AAA;height:18px;'}).insert('<option value="">- size -</option>');
			
		this.fonts.each(function(f){
			var opt = Builder.node('option', {value:f}).update(f).setStyle({'fontFamily':f});
			fselect.insert(opt);
		}.bind(fselect));
		fselect.selectedIndex = 0;
		var sizes = $H({'1':'8pt','2':'10pt','3':'12pt','4':'14pt','5':'18pt','6':'24pt','7':'34pt'});
		sizes.each(function(pair){
			var opt = Builder.node('option', {value:pair.key, style:'size:'+pair.key}).update(pair.value);
			sselect.insert(opt);
		});
		sselect.selectedIndex = 0;
		
		this.updateStyle = function(sselect, fselect){
			var n = $(this.getNode());
			
			
			var s_size = '';
			var s_font = '';
			
			if (n && n.nodeName != 'BODY') do {
				if (this.nodeType(n) != 'element') break;
				if(s_size == '' && n.nodeName == 'FONT') s_size = n.readAttribute('size')?n.readAttribute('size'):'';
				if(s_font == '') s_font = n.style.fontFamily?n.getStyle('fontFamily'):'';
			}
			while (n = n.parentNode);					
		
			for(var i=0;i<sselect.options.length;i++) if(sselect.options[i].value==s_size) sselect.selectedIndex = i;
			for(var i=0;i<fselect.options.length;i++) if(fselect.options[i].value==s_font) fselect.selectedIndex = i;
		}.bind(this, sselect, fselect);
				
		td1.insert(fselect);
		td2.insert(sselect);
		tr.appendChild(td1);
		tr.appendChild(td2);
		tbody.appendChild(tr);
		table.appendChild(tbody);
		styles.insert(table);
		this.tools.insert(styles);
		
		$(fselect).observe('change', function(fselect){
			this.doc.execCommand('fontName', false, fselect.value);
		}.bind(this, fselect));
		
		$(sselect).observe('change', function(sselect, fselect){
			this.doc.execCommand('fontSize', false, sselect.value);
		}.bind(this, sselect, fselect));
		
		var popHTML = '\
		<div class="boxOuter" id="editable_'+this.id+'-pop-box" style="display:none;z-index:1501;"><div class="boxInner">\
		\
		<div class="move"><img src="images/buttons/boxMove.gif" class="sudoMove"></div>\
		<div class="close"><img id="editable_'+this.id+'-pop-box-close" src="images/buttons/boxClose-up.gif" class="sudoLink" onclick="new Effect.Fade(\'editable_'+this.id+'-pop-box\');" onmouseover="this.src=\'images/buttons/boxClose-over.gif\'" onmouseout="this.src=\'images/buttons/boxClose-up.gif\'"></div>\
		<table cellspacing="0" cellpadding="0" class="boxTable" width="500">\
			<tr>\
				<td width="13" height="13" class="boxCorner"><img src="images/boxes/popBoxTL.gif" border="0"></td>\
				<td class="popBoxTop boxTop">&nbsp;</td>\
				<td width="13" class="boxCorner"><img src="images/boxes/popBoxTR.gif" border="0"></td>\
			</tr>\
			<tr>\
				<td class="popBoxLeft boxLeft">&nbsp;</td>\
				<td class="popBoxContent"><div id="editable_'+this.id+'-pop-box-content"></div></td>\
				<td class="popBoxRight boxRight">&nbsp;</td>\
			</tr>\
			<tr>\
				<td width="13" height="13" class="boxCorner"><img src="images/boxes/popBoxBL.gif" border="0"></td>\
				<td class="popBoxBottom boxBottom">&nbsp;</td>\
				<td width="13" class="boxCorner"><img src="images/boxes/popBoxBR.gif" border="0"></td>\
			</tr>\
		</table>\
		\
		</div></div>\
		';
		this.tools.up('form').insert({before:popHTML});
		this.pop = $('editable_'+this.id+'-pop-box');
		this.popfill = $('editable_'+this.id+'-pop-box-content');
		new Draggable(this.pop,{snap:false,handle:'move',revert:false, 
			onStart:function(){
				if($('over-iframe')) $('over-iframe').show();
			},
			onEnd: function(){
				if($('over-iframe')) $('over-iframe').hide();
			}
		});
	},

	keyListener: function(e){
		var code = e.which || e.keyCode;
		var key = this.keyCodes.get(code);
		
		if(e.ctrlKey && this.keys.indexOf(key)!=-1) {
			var act = this.actions.get(key);
			this.doc.execCommand(act.func, false, false);
			e.returnValue = false;
			e.stop();
		}else if(key == 'enter'){
			
			if(!e.shiftKey){
				if (Browser.Engine.gecko || Browser.Engine.webkit) {
					var node = this.getNode();
					var nodeStr = new RegExp(node.nodeName);
					//this.info.innerHTML = nodeStr;
					if(!nodeStr.test(this.blockEls)) this.doc.execCommand('insertparagraph', false, false);
				}
			}else{
				if (Browser.Engine.trident) {
					var r = this.getRange();
					var node = this.getNode();
					if (node.nodeName != 'LI') {
						if (r) {
							this.insertContent('<br>');
							this.collapse(false);
						}
					}
					e.stop();
				}
			}
		}
	},

	// --------- BEGIN selection code
	
	getSelection: function() {
		return (this.win.getSelection) ? this.win.getSelection() : this.doc.selection;
	},

	getRange: function() {
		var s = this.getSelection();

		if (!s) return null;

		try {
			return s.rangeCount > 0 ? s.getRangeAt(0) : (s.createRange ? s.createRange() : null);
		} catch (e) {
			// IE bug when used in frameset
			return this.doc.body.createTextRange();
		}
	},

	setRange: function(range) {
		if (range.select) $try(function(){
				range.select();
			});
		else {
			var s = this.getSelection();
			if (s.addRange) {
				s.removeAllRanges();
				s.addRange(range);
			}
		}
	},

	selectNode: function(node, collapse) {
		var r = this.getRange();
		var s = this.getSelection();

		if (r.moveToElementText) $try(function(){
				r.moveToElementText(node);
				r.select();
			});
		else if (s.addRange) {
			collapse ? r.selectNodeContents(node) : r.selectNode(node);
			s.removeAllRanges();
			s.addRange(r);
		} else
			s.setBaseAndExtent(node, 0, node, 1);

		return node;
	},

	isCollapsed: function() {
		var r = this.getRange();
		if (r.item) return false;
		return r.boundingWidth == 0 || this.getSelection().isCollapsed;
	},

	collapse: function(toStart) {
		var r = this.getRange();
		var s = this.getSelection();

		if (r.select) {
			r.collapse(toStart);
			r.select();
		}
		else
			toStart ? s.collapseToStart() : s.collapseToEnd();
	},

	getSelContent: function() {
		var r = this.getRange();
		var body = new Element('body');

		if (this.isCollapsed()) return '';

		if (r.cloneContents) body.appendChild(r.cloneContents());
		else if ($defined(r.item) || $defined(r.htmlText)) body.set('html', r.item ? r.item(0).outerHTML : r.htmlText);
		else body.set('html', r.toString());

		var content = body.get('html');
		return content;
	},

	getText : function() {
		var r = this.getRange();
		var s = this.getSelection();

		return this.isCollapsed() ? '' : r.text || s.toString();
	},

	getNode: function() {
		var r = this.getRange();

		if (!Browser.Engine.trident) {
			var el = null;

			if (r) {
				el = r.commonAncestorContainer;

				// Handle selection a image or other control like element such as anchors
				if (!r.collapsed)
					if (r.startContainer == r.endContainer)
						if (r.startOffset - r.endOffset < 2)
							if (r.startContainer.hasChildNodes())
								el = r.startContainer.childNodes[r.startOffset];

				while (this.nodeType(el) != 'element') el = el.parentNode;
			}

			return this.iframe.$(el);
		}

		return $(r.item ? r.item(0) : r.parentElement());
	},
	
	nodeType: function(obj){
		if (obj.nodeName){
			switch (obj.nodeType){
				case 1: return 'element';
				case 3: return (/\S/).test(obj.nodeValue) ? 'textnode' : 'whitespace';
			}
		}else{
			return typeof(obj);
		}
	},

	insertContent: function(content) {
		var r = this.getRange();

		if (r.insertNode) {
			r.deleteContents();
			r.insertNode(r.createContextualFragment(content));
		}
		else {
			// Handle text and control range
			if (r.pasteHTML) r.pasteHTML(content);
			else r.item(0).outerHTML = content;
		}
	},

	contains: function(string, separator){
		return (separator) ? (separator + this + separator).indexOf(separator + string + separator) > -1 : this.indexOf(string) > -1;
	},

	trim: function(str){
		return str.replace(/^\s+|\s+$/g, '');
	},

	clean: function(str){
		return str.replace(/\s+/g, ' ').trim();
	},

	cleanup: function(source) {
		// remove orphaned images
		source = source.replace(/<img.*?src="spacer\.gif"[^>]*>/gi, '');
		// remove empty links
		source = source.replace(/<a[^>]*><br[^>]*><\/a>/ig, '');
		source = source.replace(/<a[^>]*><\/a>/ig, '');
		
		if(!this.options.cleanup) return this.trim(source);

		// Webkit cleanup
		source = source.replace(/<br class\="webkit-block-placeholder">/gi, "<br />");
		source = source.replace(/<span class="Apple-style-span">(.*)<\/span>/gi, '$1');
		source = source.replace(/ class="Apple-style-span"/gi, '');
		source = source.replace(/<span style="">/gi, '');
		

		// Replace improper BRs (only if XHTML : true)
		if (this.options.xhtml) {
			source = source.replace(/<br>/gi, "<br />");
		}

		//<p> tags around a list will get moved to after the list
		if (Browser.Engine.name == 'gecko' || Browser.Engine.name == 'presto' || Browser.Engine.name == 'webkit') {
			//not working properly in safari?
			source = source.replace(/<p>[\s\n]*(<(?:ul|ol)>.*?<\/(?:ul|ol)>)(.*?)<\/p>/ig, '$1<p>$2</p>');
			source = source.replace(/<\/(ol|ul)>\s*(?!<(?:p|ol|ul|img).*?>)((?:<[^>]*>)?\w.*)$/g, '</$1><p>$2</p>');
		}

		source = source.replace(/<br[^>]*><\/p>/g, '</p>');			//remove <br>'s that end a paragraph here.
		source = source.replace(/<p>\s*(<img[^>]+>)\s*<\/p>/ig, '$1\n'); 	//if a <p> only contains <img>, remove the <p> tags

		//format the source
		source = source.replace(/<p([^>]*)>(.*?)<\/p>(?!\n)/g, '<p$1>$2</p>\n');  	//break after paragraphs
		source = source.replace(/<\/(ul|ol|p)>(?!\n)/g, '</$1>\n'); 			//break after </p></ol></ul> tags
		source = source.replace(/><li>/g, '>\n\t<li>'); 				//break and indent <li>
		source = source.replace(/([^\n])<\/(ol|ul)>/g, '$1\n</$2>');  			//break before </ol></ul> tags
		source = source.replace(/([^\n])<img/ig, '$1\n<img'); 				//move images to their own line
		source = source.replace(/^\s*$/g, '');						//delete empty lines in the source code (not working in opera)


		// Semantic conversion
		source = source.replace(/<span style="font-weight: bold;">(.*)<\/span>/gi, '<strong>$1</strong>');
		source = source.replace(/<span style="font-style: italic;">(.*)<\/span>/gi, '<em>$1</em>');
		source = source.replace(/<b\b[^>]*>(.*?)<\/b[^>]*>/gi, '<strong>$1</strong>');
		source = source.replace(/<i\b[^>]*>(.*?)<\/i[^>]*>/gi, '<em>$1</em>');
		source = source.replace(/<u\b[^>]*>(.*?)<\/u[^>]*>/gi, '<span style="text-decoration: underline;">$1</span>');

		// Replace uppercase element names with lowercase
		source = source.replace(/<[^> ]*/g, function(match){return match.toLowerCase();});

		// Replace uppercase attribute names with lowercase
		source = source.replace(/<[^>]*>/g, function(match){
			   match = match.replace(/ [^=]+=/g, function(match2){return match2.toLowerCase();});
			   return match;
		});

		// Put quotes around unquoted attributes
		source = source.replace(/<[^>]*>/g, function(match){
			   match = match.replace(/( [^=]+=)([^"][^ >]*)/g, "$1\"$2\"");
			   return match;
		});

		// Final trim
		source = this.trim(source);

		return source;
	},

	doCleanup : function(source) {
		do {
			var oSource = source;
			source = this.cleanup(source);
		} while (source != oSource);
		return source;
	},
	
	cleanPaste: function(e){
		console.log('paste triggered...');
		window.setTimeout(this.cleanWord.bind(this), 50);

	},
	
	cleanWord: function(d){

		console.log('cleaning...');

		//replacement characters
		var rchars = [["Ã±","Ã³", "Ã«", "Ã­", "Ã¬", "Ã®", 'â€ '], ["-", "-", "'", "'", '"', '"', ' ']];
		
		//html entities translation array
		var hents = new Array();
		hents['Â°'] = '&iexcl;';
		hents['Â¢'] = '&cent;';
		hents['Â£'] = '&pound;';
		hents['Â§'] = '&curren;';
		hents['â€¢'] = '&yen;';
		hents['Â¶'] = '&brvbar;';
		hents['ÃŸ'] = '&sect;';
		hents['Â®'] = '&uml;';
		hents['Â©'] = '&copy;';
		hents['â„¢'] = '&ordf;';
		hents['Â´'] = '&laquo;';
		hents['Â¨'] = '&not;';
		hents['â‰ '] = '&shy;';
		hents['Ã†'] = '&reg;';
		hents['Ã˜'] = '&macr;';
		hents['âˆž'] = '&deg;';
		hents['Â±'] = '&plusmn;';
		hents['â‰¤'] = '&sup2;';
		hents['â‰¥'] = '&sup3;';
		hents['Â¥'] = '&acute;';
		hents['Âµ'] = '&micro;';
		hents['âˆ‚'] = '&para;';
		hents['âˆ‘'] = '&middot;';
		hents['âˆ'] = '&cedil;';
		hents['Ï€'] = '&sup1;';
		hents['âˆ«'] = '&ordm;';
		hents['Âª'] = '&raquo;';
		hents['Âº'] = '&frac14;';
		hents['Î©'] = '&frac12;';
		hents['Ã¦'] = '&frac34;';
		hents['Ã¸'] = '&iquest;';
		hents['Â¿'] = '&Agrave;';
		hents['Â¡'] = '&Aacute;';
		hents['Â¬'] = '&Acirc;';
		hents['âˆš'] = '&Atilde;';
		hents['Æ’'] = '&Auml;';
		hents['â‰ˆ'] = '&Aring;';
		hents['âˆ†'] = '&AElig;';
		hents['Â«'] = '&Ccedil;';
		hents['Â»'] = '&Egrave;';
		hents['â€¦'] = '&Eacute;';
		hents['Â '] = '&Ecirc;';
		hents['Ã€'] = '&Euml;';
		hents['Ãƒ'] = '&Igrave;';
		hents['Ã•'] = '&Iacute;';
		hents['Å’'] = '&Icirc;';
		hents['Å“'] = '&Iuml;';
		hents['â€“'] = '&ETH;';
		hents['â€”'] = '&Ntilde;';
		hents['â€œ'] = '&Ograve;';
		hents['â€'] = '&Oacute;';
		hents['â€˜'] = '&Ocirc;';
		hents['â€™'] = '&Otilde;';
		hents['Ã·'] = '&Ouml;';
		hents['â—Š'] = '&times;';
		hents['Ã¿'] = '&Oslash;';
		hents['Å¸'] = '&Ugrave;';
		hents['â„'] = '&Uacute;';
		hents['â‚¬'] = '&Ucirc;';
		hents['â€¹'] = '&Uuml;';
		hents['â€º'] = '&Yacute;';
		hents['ï¬'] = '&THORN;';
		hents['ï¬‚'] = '&szlig;';
		hents['â€¡'] = '&agrave;';
		hents['Â·'] = '&aacute;';
		hents['â€š'] = '&acirc;';
		hents['â€ž'] = '&atilde;';
		hents['â€°'] = '&auml;';
		hents['Ã‚'] = '&aring;';
		hents['ÃŠ'] = '&aelig;';
		hents['Ã'] = '&ccedil;';
		hents['Ã‹'] = '&egrave;';
		hents['Ãˆ'] = '&eacute;';
		hents['Ã'] = '&ecirc;';
		hents['ÃŽ'] = '&euml;';
		hents['Ã'] = '&igrave;';
		hents['ÃŒ'] = '&iacute;';
		hents['Ã“'] = '&icirc;';
		hents['Ã”'] = '&iuml;';
		hents['ï£¿'] = '&eth;';
		hents['Ã’'] = '&ntilde;';
		hents['Ãš'] = '&ograve;';
		hents['Ã›'] = '&oacute;';
		hents['Ã™'] = '&ocirc;';
		hents['Ä±'] = '&otilde;';
		hents['Ë†'] = '&ouml;';
		hents['Ëœ'] = '&divide;';
		hents['Â¯'] = '&oslash;';
		hents['Ë˜'] = '&ugrave;';
		hents['Ë™'] = '&uacute;';
		hents['Ëš'] = '&ucirc;';
		hents['Â¸'] = '&uuml;';
		hents['Ë'] = '&yacute;';
		hents['Ë›'] = '&thorn;';
		hents['Ë‡'] = '&yuml;';
		hents['"'] = '&quot;';
		hents['<'] = '&lt;';
		hents['>'] = '&gt;';
		
		//allowed tags
		var tags = ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'h7', 'h8', 'ul', 'ol', 'li', 'u', 'i', 'b', 'a', 'table', 'tr', 'th', 'td', 'img', 'em', 'strong', 'br'];
		
		//tags which should be removed when empty
		var rempty = ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'h7', 'h8', 'ul', 'ol', 'li', 'u', 'i', 'b', 'a', 'table', 'tr', 'em', 'strong'];
		
		//allowed atributes for tags
		var aattr = new Array();
		aattr['a'] = ['href', 'name'];
		aattr['table'] = ['border'];
		aattr['th'] = ['colspan', 'rowspan'];
		aattr['td'] = ['colspan', 'rowspan'];
		aattr['img'] = ['src', 'width', 'height', 'alt'];
		
		//tags who's content should be deleted
		var dctags = ['head'];
		
		//Quote characters
		var quotes = ["'", '"'];
		
		//tags which are displayed as a block
		var btags = ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'h7', 'h8', 'ul', 'ol', 'li', 'table', 'tr', 'th', 'td', 'br'];
		
		//d = data, o = out, c = character, n = next character
		//in and out variables
		//var d = this.getContent();
		var o = '';
	
		o = '';
		var i;
		//Replace all whitespace characters with spaces
		d = d.replace(/(\s|&nbsp;)+/g, ' ');
		//replace weird word characters
		for (i = 0; i < rchars[0].length; i++)
			d = d.replace(new RegExp(rchars[0][i], 'g'), rchars[1][i]);
		
		//initialize flags
		//what the next character is expected to be
		var expected = '';
		//tag text
		var tag = '';
		//tag name
		var tagname = '';
		//what type of tag it is, start, end, or single
		var tagtype = 'start';
		//attribute text
		var attribute = '';
		//attribute name
		var attributen = '';
		//if the attribute has had an equals sign
		var attributeequals = false;
		//if attribute has quotes, and what they are
		var attributequotes = '';
		
		var c = '';
		var n = '';
		
		/*Parser format:
		The parser is divided into three parts:
		The first section is for when the current type of character is known
		The second is for when it is an unknown character in a tag
		The third is for anything outside of a tag
		*/
		
		//editing pass
		for (i = 0; i < d.length; i++)
		{
			//current character
			c = this.getc(i, d);
			//next character
			n = this.getc(i+1, d);
			
			//***Section for when the current character is known
			
			//if the tagname is expected
			if (expected == 'tagname')
			{
				tagname += c.toLowerCase();
				//lookahead for end of tag name
				if (n == ' ' || n == '>' || n == '/')
				{
					tag += tagname;
					expected = 'tag';
				}
			}
			//if an attribute name is expected
			else if (expected == 'attributen')
			{
				attributen += c.toLowerCase();
				//lookahead for end of attribute name
				if (n == ' ' || n == '>' || n == '/' || n == '=')
				{
					attribute += attributen;
					//check to see if its an attribute without an assigned value
					//determines whether there is anything but spaces between the attribute name and the next equals sign
					if (this.endOfAttr(i,d))
					{
						//if the attribute is allowed, add it to the output
						if (this.ae(attributen, aattr[tagname]))
							tag += attribute;
						
						attribute = '';
						attributen = '';
						attributeequals = false;
						attributequotes = '';
					}
					expected = 'tag';
				}
			}
			//if an attribute value is expected
			else if (expected == 'attributev')
			{
				attribute += c;
				
				//lookahead for end of value
				if ((c == attributequotes) || ((n == ' ' || n == '/' || n == '>') && !attributequotes))
				{
					//if the attribute is allowed, add it to the output
					if (this.ae(attributen, aattr[tagname]))
						tag += attribute;
					
					attribute = '';
					attributen = '';
					attributeequals = false;
					attributequotes = '';
					
					expected = 'tag';
				}
			}
			
			//***Section for when the character is unknown but it is inside of a tag
			
			else if (expected == 'tag')
			{
				//if its a space
				if (c == ' ')
					tag += c;
				//if its a slash after the tagname, signalling a single tag.
				else if (c == '/' && tagname)
				{
					tag += c;
					tagtype = 'single';
				}
				//if its a slash before the tagname, signalling its an end tag
				else if (c == '/')
				{
					tag += c;
					tagtype = 'end';
				}
				//if its the end of a tag
				else if (c == '>')
				{
					tag += c;
					//if the tag is allowed, add it to the output
					if (this.ae(tagname, tags))
						o += tag;
					
					//if its a start tag
					if (tagtype == 'start')
					{
						//if the tag is supposed to have its contents deleted
						if (this.ae(tagname, dctags))
						{
							//if there is an end tag, skip to it in order to delete the tags contents
							if (-1 != (endpos = d.indexOf('</' + tagname, i)))
							{
								//have to make it one less because i gets incremented at the end of the loop
								i = endpos-1;
							}
							//if there isn't an end tag, then it was probably a non-compliant single tag
						}
					}
					
					tag = '';
					tagname = '';
					tagtype = 'start';
					expected = '';
				}
				//if its an attribute name
				else if (tagname && !attributen)
				{
					attributen += c.toLowerCase();
					expected = 'attributen';
					//lookahead for end of attribute name, in case its a one character attribute name
					if (n == ' ' || n == '>' || n == '/' || n == '=')
					{
						attribute += attributen;
						//check to see if its an attribute without an assigned value
						//determines whether there is anything but spaces between the attribute name and the next equals sign
						if (this.endOfAttr(i,d))
						{
							//if the attribute is allowed, add it to the output
							if (this.ae(attributen, attributen))
								tag += attribute;
							
							attribute = '';
							attributen = '';
							attributeequals = false;
							attributequotes = '';
						}
						expected = 'tag';
					}
				}
				//if its a start quote for an attribute value
				else if (this.ae(c, quotes) && attributeequals)
				{
					attribute += c;
					attributequotes = c;
					expected = 'attributev';
				}
				//if its an attribute value
				else if (attributeequals)
				{
					attribute += c;
					expected = 'attributev';
					
					//lookahead for end of value, in case its only one character
					if ((c == attributequotes) || ((n == ' ' || n == '/' || n == '>') && !attributequotes))
					{
						//if the attribute is allowed, add it to the output
						if (this.ae(attributen, attributen))
							tag += attribute;
						
						attribute = '';
						attributen = '';
						attributeequals = false;
						attributequotes = '';
						
						expected = 'tag';
					}
				}
				//if its an attribute equals
				else if (c == '=' && attributen)
				{
					attribute += c;
					attributeequals = true;
				}
				//if its the tagname
				else
				{
					tagname += c.toLowerCase();
					expected = 'tagname';
					
					//lookahead for end of tag name, in case its a one character tag name
					if (n == ' ' || n == '>' || n == '/')
					{
						tag += tagname;
						expected = 'tag';
					}
				}
			}
			//if nothing is expected
			else
			{
				//if its the start of a tag
				if (c == '<')
				{
					tag = c;
					expected = 'tag';
				}
				//anything else
				else
					o += this.htmlentities(c, hents);
			}
		}
		
		//beautifying regexs
		//remove duplicate spaces
		o = o.replace(/\s+/g, ' ');
		//remove unneeded spaces in tags
		o = o.replace(/\s>/g, '>');
		//remove empty tags
		//this loops until there is no change from running the regex
		var remptys = rempty.join('|');
		var oo = o;
		while ((o = o.replace(new RegExp("\\s?<(" + remptys + ")>\s*<\\/\\1>", 'gi'), '')) != oo)
			oo = o;
		//make block tags regex string
		var btagss = btags.join('|');
		//add newlines after block tags
		o = o.replace(new RegExp("\\s?</(" + btagss+ ")>", 'gi'), "</$1>\n");
		//remove spaces before block tags
		o = o.replace(new RegExp("\\s<(" + btagss + ")", 'gi'), "<$1");
		
		//fix lists
		o = o.replace(/((<p.*>\s*(&middot;|&#9642;) .*<\/p.*>\n)+)/gi, "<ul>\n$1</ul>\n");//make ul for dot lists
		o = o.replace(/((<p.*>\s*\d+\S*\. .*<\/p.*>\n)+)/gi, "<ol>\n$1</ol>\n");//make ol for numerical lists
		o = o.replace(/((<p.*>\s*[a-z]+\S*\. .*<\/p.*>\n)+)/gi, "<ol style=\"list-style-type: lower-latin;\">\n$1</ol>\n");//make ol for latin lists
		o = o.replace(/<p(.*)>\s*(&middot;|&#9642;|\d+(\S*)\.|[a-z]+\S*\.) (.*)<\/p(.*)>\n/gi, "\t<li$1>$3$4</li$5>\n");//make li
		
		//extend outer lists around the nesting lists
		o = o.replace(/<\/(ul|ol|ol style="list-style-type: lower-latin;")>\n(<(?:ul|ol|ol style="list-style-type: lower-latin;")>[\s\S]*<\/(?:ul|ol|ol style="list-style-type: lower-latin;")>)\n(?!<(ul|ol|ol style="list-style-type: lower-latin;")>)/g, "</$1>\n$2\n<$1>\n</$1>\n");
		
		//nesting lists
		o = o.replace(/<\/li>\s+<\/ol>\s+<ul>([\s\S]*?)<\/ul>\s+<ol>/g, "\n<ul>$1</ul></li>");//ul in ol
		o = o.replace(/<\/li>\s+<\/ol>\s+<ol style="list-style-type: lower-latin;">([\s\S]*?)<\/ol>\s+<ol>/g, "\n<ol style=\"list-style-type: lower-latin;\">$1</ol></li>");//latin in ol
		o = o.replace(/<\/li>\s+<\/ul>\s+<ol>([\s\S]*?)<\/ol>\s+<ul>/g, "\n<ol>$1</ol></li>");//ol in ul
		o = o.replace(/<\/li>\s+<\/ul>\s+<ol style="list-style-type: lower-latin;">([\s\S]*?)<\/ol>\s+<ul>/g, "\n<ol style=\"list-style-type: lower-latin;\">$1</ol></li>");//latin in ul
		o = o.replace(/<\/li>\s+<\/ol>\s+<ol style="list-style-type: lower-latin;">([\s\S]*?)<\/ol>\s+<ol>/g, "\n<ol style=\"list-style-type: lower-latin;\">$1</ol></li>");//ul in latin
		o = o.replace(/<\/li>\s+<\/ul>\s+<ol style="list-style-type: lower-latin;">([\s\S]*?)<\/ol>\s+<ul>/g, "\n<ol style=\"list-style-type: lower-latin;\">$1</ol></li>");//ul in latin
		//remove empty tags. this is needed a second time to delete empty lists that were created to fix nesting, but weren't needed
		o = o.replace(new RegExp("\\s?<(" + remptys + ")>\s*<\\/\\1>", 'gi'), '');
		
		//this.setContent(o);
		return o;
	
	},
	
	ae:function(needle, haystack){
		if (typeof(haystack) == 'object')
			for (var i = 0; i < haystack.length; i++)
				if (needle == haystack[i])
					return true;
		
		return false;
	},
	
	getc:function(i, d){
		return d.charAt(i);
	},
	
	endOfAttr:function(i,d)
	{
		var between = d.substring(i+1, d.indexOf('=', i+1));
		if (between.replace(/\s+/g, ''))
			return true;
		else
			return false;
	},
	
	htmlentities:function(character, hents)
	{
		if (hents[character])
			return hents[character];
		else
			return character;
	}
	
	
};