var Editor = new Class({

	Implements: Options,

	options: {
		className: 'wysiwyg',
		buttons: ['strong','em','u','superscript','subscript',null,'left','center','right','indent','outdent',null,'h1','h2','h3','p','ul','ol',null,'img','link','unlink'],
		iFrameSrc: '/iframe'
	},

	initialize: function(form,textarea,options){
		this.setOptions(options);
		if(this.form = $(form)){
			this.textarea = $(textarea);
			this.toolbar = new Element('div',{
				'class':'toolbar'
			});
			this.iframe = new IFrame({
				'frameborder':0,
				'src': this.options.iFrameSrc,
				'events':{
					'load':function(){
						this.doc = this.iframe.contentWindow.document;
						this.doc.designMode = 'on';
						this.toggleView();
					}.bind(this)
				}
			});
			this.container = new Element('div',{'class':(this.options.className||'wysiwyg')}).injectBefore(this.textarea).adopt(this.toolbar,this.iframe,this.textarea);
	
			this.open = false;
	
			$each(this.options.buttons,function(b){
				if(!b){
					new Element('span',{
						'class':'spacer'
					}).inject(this.toolbar);
				}else if(Browser.Engine.trident){
					new Element('a',{
						'class':b,'href':'//'+b
					}).addEvent('click',function(e){
						var ev = new Event(e); ev.stop();
						if(b=='toggle'){
							this.toggleView();
						}else{
							this.exec(b);
						}
					}.bind(this)).inject(this.toolbar);
				}else{
					new Element('span',{
						'class':b
					}).addEvent('click',(b=='toggle'?this.toggleView.bind(this):this.exec.bind(this,[b]))).inject(this.toolbar);
				}
			},this);
			this.form.addEvent('submit',function(event){
				if(this.open){
					this.toTextArea();
				}
			}.bind(this));
		}
	},

	toggleView: function(){
		if($try(function(){
				if(this.doc.body){
					return true;
				}
			}.bind(this))){
			if(this.open){
				this.toTextarea(true);
			}else{
				this.toEditor(true);
			}
			this.open = !this.open;
		}
	},

	toTextArea: function(view){
		this.textarea.value = this.clean(this.doc.body.innerHTML);
		if(view){
			this.textarea.removeClass('hidden');
			this.iframe.addClass('hidden');
			this.toolbar.addClass('disabled');
			this.textarea.focus();
		}
	},

	toEditor: function(view){
		var val = this.textarea.value.trim();
		this.doc.body.innerHTML = val==''?'<p>&nbsp;</p>':val;
		if(view){
			this.textarea.addClass('hidden');
			this.iframe.removeClass('hidden');
			this.toolbar.removeClass('disabled');
		}
	},

    exec: function(b,v){
		if(this.open){
			this.iframe.contentWindow.focus();
			but = _BUTTONS[b];
			var val = v || but[1];
			if(!v && but[2]){
				if(!(val=prompt(but[1],but[2]))){return;}
			}
			this.doc.execCommand(but[0],false,val);
		}
    },

	clean: function(html){
		return html
		.replace(/&nbsp;/g,'')
		.replace(/\s{2,}/g,' ')
		.replace(/^\s+|\s+$/g,'')
		.replace(/\n/g,'')
		.replace(/<[^> ]*/g,function(s){return s.toLowerCase()})
		.replace(/<[^>]*>/g,function(s){s=s.replace(/ [^=]+=/g,function(a){return a.toLowerCase()});return s})
		.replace(/<[^>]*>/g,function(s){s=s.replace(/( [^=]+=)([^"][^ >]*)/g,"$1\"$2\"");return s})
		.replace(/<[^>]*>/g,function(s){s=s.replace(/ ([^=]+)="[^"]*"/g,function(a,b){if(b=='alt'||b=='href'||b=='src'||b=='title'||b=='style'){return a}return''});return s})
		.replace(/<b(\s+|>)/g,"<strong$1")
		.replace(/<\/b(\s+|>)/g,"</strong$1")
		.replace(/<i(\s+|>)/g,"<em$1")
		.replace(/<\/i(\s+|>)/g,"</em$1")
		.replace(/<span style="font-weight: normal;">(.+?)<\/span>/gm,'$1')
		.replace(/<span style="font-weight: bold;">(.+?)<\/span>/gm,'<strong>$1</strong>')
		.replace(/<span style="font-style: italic;">(.+?)<\/span>/gm,'<em>$1</em>')
		.replace(/<span style="(font-weight: bold; ?|font-style: italic; ?){2}">(.+?)<\/span>/gm,'<strong><em>$2</em></strong>')
		.replace(/<img src="([^">]*)">/g,'<img alt="Image" src="$1" />')
		.replace(/(<img [^>]+[^\/])>/g,"$1 />")
		.replace(/<u>(.+?)<\/u>/gm,'<u">$1</u>')
		.replace(/<font[^>]*?>(.+?)<\/font>/gm,'$1')
		.replace(/<font>|<\/font>/gm,'')
		.replace(/<br>\s*<\/(h1|h2|h3|h4|h5|h6|li|p)/g,'</$1')
		.replace(/<br>/g,'<br />')
		.replace(/<(table|tbody|tr|td|th)[^>]*>/g,'<$1>')
		.replace(/<\?xml[^>]*>/g,'')
		.replace(/<[^ >]+:[^>]*>/g,'')
		.replace(/<\/[^ >]+:[^>]*>/g,'')
		.replace(/(<[^\/]>|<[^\/][^>]*[^\/]>)\s*<\/[^>]*>/g,'');
	}
});

var _BUTTONS = {
	strong: ['bold',null],
	em: ['italic',null],
	u: ['underline',null],
	superscript: ['superscript',null],
	subscript: ['subscript',null],
	left: ['justifyleft',null],
	center: ['justifycenter',null],
	right: ['justifyright',null],
	indent: ['indent',null],
	outdent: ['outdent',null],
	h1: ['formatblock','<H1>'],
	h2: ['formatblock','<H2>'],
	h3: ['formatblock','<H3>'],
	p: ['formatblock','<P>'],
	ul: ['insertunorderedlist',null],
	ol: ['insertorderedlist',null],
	link: ['createlink','Insert a URL:','http://'],
	unlink: ['unlink',null],
	img: ['insertimage','Insert a URL for an image:','http://'],
	clean: ['removeformat',null],
	toggle: ['toggleview']
};