(function($) {
	var editorTags = {
		iframe: "_greybackEditorIFrame",
		controls: "_greybackEditorControls",
		workspace: "_greybackEditorWorkspace",
		overlay: "_greybackEditorOverlay",
		waiting: "_greybackEditorWaiting",
		model: ""
	}
	
	var image = null;
	
	var linkrange;
	
	var charCount = 0;

	$.fn.greybackEditor = function(options) {
		this.opts = $.extend({},$.fn.greybackEditor.defaults,options);
		$.fn.greybackEditor.defaults = this.opts;
		self = this;

		this.each(function() {
			var textareaObj = this;
			var textarea = $(textareaObj);
			textarea.attr('class','greybackEditor_textarea');
			var tag = this.id;
			width = self.opts['max_width']+20;
			textarea.css('width',(self.opts['max_width']+15)+'px');

			//CREATE EDITOR
			var editor = $(document.createElement('div'));
			editor.attr('id',tag + "_greybackEditor");
			editor.attr('class','greybackEditor');
			if(width < 700) {
				width = 720;
			}
			editor.css('width',(width+20)+'px');

			//CREATE WORKSPACE
			var workspace = $(document.createElement('div'));
			workspace.attr("id",tag + editorTags.workspace);
			workspace.attr("class","greybackEditor_workspace");
			workspace.css('width',(width-20)+'px');
			editor.append(workspace);

			//CREATE WAITING PANEL
			var waiting = $(document.createElement('div'));
			waiting.attr("id",tag + editorTags.waiting);
			waiting.attr("class","greybackEditor_waiting");
			waiting.css('width',(width+20)+'px');
			editor.append(waiting);

			//CREATE CONTROLS
			var controls = document.createElement('ul');
			$(controls).attr("id",tag + editorTags.controls);
			$(controls).attr("class","greybackEditor_controls");
			$.each(self.opts['menu'], function(key, val) {
				var li = document.createElement('li');
				switch (val['type']) {
					case "label":
						var span = document.createElement('span');
						span.setAttribute('class','greybackEditorCommand_label');
						var text = document.createTextNode(val['val']);
						span.appendChild(text);
						li.appendChild(span);
						break;
					case "style":
						var link = document.createElement('a');
						var text = document.createTextNode(val['name']);
						link.setAttribute('href',val['val']);
						link.setAttribute('title',val['name']);
						link.setAttribute('class','greybackEditorCommand_style');
						link.id = 'greybackEditorCommand_'+val['id'];
						$(link).mousedown(function(event) {
							if (event.preventDefault) {
								event.preventDefault();
							}
						});
						$(link).click(function() {
							$.fn.greybackEditor.command(tag,val['val'],null);
							$.fn.greybackEditor.status(tag);
							return false;
						});
						link.appendChild(text);
						li.appendChild(link);
						break;
					case "select":
						li.setAttribute('class','greybackEditorCommand_select');
						var ul = document.createElement('ul');
						link = document.createElement('a');
						link.setAttribute('href','#');
						title = document.createTextNode(val['name']);
						link.appendChild(title);
						$(link).mousedown(function(event) {
							if (event.preventDefault) {
								event.preventDefault();
							}
						});
						$(link).click(function() {
							$(this).next().toggle();
							return false;
						});
						li.appendChild(link);
						$.each(val['val'], function(optkey, optval) {
							sub = document.createElement('li');
							link = document.createElement('a');
							text = document.createTextNode(optkey);
							link.appendChild(text);
							link.setAttribute('href','#');
							$(link).mousedown(function(event) {
								if (event.preventDefault) {
									event.preventDefault();
								}
							});
							$(link).click(function() {
								if(optval['type']=='formatblock') {
									$.fn.greybackEditor.command(tag,'formatblock',optval['val']);
								} else {
									$.fn.greybackEditor.command(tag,optval['val'],null);
								}
								$.fn.greybackEditor.status(tag);
								$(this).parent().parent().hide();
								return false;
							});
							sub.appendChild(link);
							ul.appendChild(sub);
						});
						li.appendChild(ul);
						break;
					case "command":
						var link = document.createElement('a');
						var text = document.createTextNode(val['name']);
						link.setAttribute('href',val['val']);
						link.setAttribute('title',val['name']);
						link.id = 'greybackEditorCommand_'+val['id'];
						$(link).mousedown(function(event) {
							if (event.preventDefault) {
								event.preventDefault();
							}
						});
						$(link).click(function() {
							if(image) {
								switch(val['val']) {
									case 'justifyLeft':
										image.css('float','left');
										image.css('padding','1em 1em 1em 0');
										break;
									case 'justifyRight':
										image.css('float','right');
										image.css('padding','1em 0 1em 1em');
										break;
									case 'justifyCenter':
										image.css('float','none');
										image.css('padding','0');
										break;
								}
								image = null;
								$('#greybackEditorCommand_image').removeClass('active');
							} else {
								$.fn.greybackEditor.command(tag,val['val'],null);
								$.fn.greybackEditor.status(tag);
							}
							
							return false;
						});
						link.appendChild(text);
						li.appendChild(link);
						break;
					case "link":
						var link = document.createElement('a');
						var text = document.createTextNode(val['name']);
						link.setAttribute('href',val['val']);
						link.setAttribute('title',val['name']);
						link.id = 'greybackEditorCommand_'+val['id'];
						$(link).mousedown(function(event) {
							if (event.preventDefault) {
								event.preventDefault();
							}
						});
						$(link).click(function() {
							if(val['val']=="createLink") {
								href = window.prompt("Enter an URL:","http://");
							} else {
								href = "";
							}
							$.fn.greybackEditor.command(tag,val['val'],href);
							$.fn.greybackEditor.status(tag);
							return false;
						});
						link.appendChild(text);
						li.appendChild(link);
						break;
					case "function":
						var link = document.createElement('a');
						var text = document.createTextNode(val['name']);
						link.setAttribute('href',val['val']);
						link.setAttribute('title',val['name']);
						link.id = 'greybackEditorCommand_'+val['id'];
						$(link).click(function() {
							try {
								eval(val['val']+'(tag)');
								$.fn.greybackEditor.status(tag);
								return false;
							} catch(e) {
								//alert(e);
								console.log(e);
								return false;
							}
							return false;
						})
						link.appendChild(text);
						li.appendChild(link);
						break;
					case "ajax":
						var link = document.createElement('a');
						var text = document.createTextNode(val['name']);
						link.setAttribute('href',val['val']);
						link.id = 'greybackEditorCommand_'+val['id'];
						$(link).click(function() {
							$.fn.greybackEditor.ajax(tag,val['val']);
							$.fn.greybackEditor.status(tag);
							return false;
						})
						link.appendChild(text);
						li.appendChild(link);
						break;
					default:
						debug("Unkown type "+val['type']);
						break;
				}
				controls.appendChild(li);
			});
			editor.append(controls);

			//CREATE IFRAME
			var iframe = $(document.createElement('div'));
			iframe.attr("id",tag + editorTags.iframe);
			iframe.attr("class","greybackEditor_iframe");
			iframe.attr("contentEditable","true");
			/*
			if(self.opts['max_width'] > 708) {
				width = 708;
			} else {
				width = self.opts['max_width']+20;
			}
			*/
			width = self.opts['max_width']+20;
			iframe.css('width',width+'px');
			iframe.html(textarea.get(0).value);
			if(iframe.html().length == 0) {
				iframe.html('<p><br /></p>');
			}
			charCount = iframe.html().length;
			editor.append(iframe);

			//CREATE OVERLAY
			var overlay = $(document.createElement('div'));
			overlay.attr("id",tag + editorTags.overlay);
			overlay.attr("class","greybackEditor_overlay");
			overlay.css('width',(width+20)+'px');
			editor.append(overlay);

			//ADD THE EDITOR TO PAGE
			$(textarea).hide();
			$(textarea).before(editor);

			//SET UP FUNCTIONS
			iframe.click(function() {
				$('.greybackEditorCommand_select').children('ul').hide();
				$.fn.greybackEditor.status(tag);
				image = null;
				$('#greybackEditorCommand_image').removeClass('active');
			});
			
			iframe.find('IMG').live('click',function() {
				var range = document.createRange();
				range.selectNode($(this).get(0));
				image = $(this);
				document.getSelection().removeAllRanges();
				document.getSelection().addRange(range);
				//$(this).addClass('highlighted');
				//$('#greybackEditorCommand_image').addClass('active');
			});
			
			iframe.find('IMG').live('dblclick',function() {
				$.fn.greybackEditor.editImage(tag, this);
			});
			
			iframe.find('IMG').live('mouseover',function() {
				//$(this).after('<div class="greybackImageEditLink"><a href="#">Edit</a></div>');
			});
			
			iframe.find('IMG').live('mouseout',function() {
				//$(this).next(".greybackImageEditLink").remove();
			});
			
			//KEYUP
			editor.keyup(function(e) {
				$.fn.greybackEditor.status(tag);
				image = null;
				$('#greybackEditorCommand_image').removeClass('active');
			});
			
			editor.get(0).onpaste = function(e){
				//console.log(e);
				waiting = $('#'+tag + editorTags.waiting);
				waiting.fadeIn();
				e.preventDefault();
				pasted = e.clipboardData.getData("text/html");
				if(!pasted) {
					pasted = e.clipboardData.getData("text/plain");
				}
				$.post(webroot+'sanitize',{html:pasted},function(data) {
					document.execCommand('inserthtml',false,data);
					$(textarea).val($(iframe).html());
					waiting.fadeOut();
				});	
			};
		});
	};

	$.fn.greybackEditor.defaults = {
		max_width: "300",
		menu: [
			{'name':'Style','id':'style','type':'label','val':'Style:'},
				{'name':'Bold','id':'bold','type':'style','val':'bold'},
				{'name':'Italic','id':'italic','type':'style','val':'italic'},
				{'name':'Underline','id':'underline','type':'style','val':'underline'},
				{'name':'FontIncrease','id':'fontincrease','type':'function','val':'$.fn.greybackEditor.fontIncrease'},
				{'name':'FontDecrease','id':'fontdecrease','type':'function','val':'$.fn.greybackEditor.fontDecrease'},
				{'name':'Format','id':'format','type':'select','val':{
					"Regular Text":{
						'type':'formatblock',
						'val':'<p>'
					},
					"Large Header":{
						'type':'formatblock',
						'val':'<h1>'
					},
					"Medium Header":{
						'type':'formatblock',
						'val':'<h2>'
					},
					"Small Header":{
						'type':'formatblock',
						'val':'<h3>'
					},
					"Quote":{
						'type':'formatblock',
						'val':'<blockquote>'
					},
					"Subscript":{
						'type':'style',
						'val':'subscript'
					},
					"Superscript":{
						'type':'style',
						'val':'superscript'
					}
				}},
			{'name':'Paragraph','id':'para','type':'label','val':'Paragraph:'},
				{'name':'Justify Left','id':'justleft','type':'command','val':'justifyLeft'},
				{'name':'Justify Center','id':'justcent','type':'command','val':'justifyCenter'},
				{'name':'Justify Full','id':'justfull','type':'command','val':'justifyFull'},
				{'name':'Justify Right','id':'justright','type':'command','val':'justifyRight'},
			{'name':'List','id':'list','type':'label','val':'List:'},
				{'name':'Numbered List','id':'ol','type':'command','val':'insertOrderedList'},
				{'name':'Bullet List','id':'ul','type':'command','val':'insertUnorderedList'},
				{'name':'Indent','id':'indent','type':'command','val':'indent'},
				{'name':'Outdent','id':'outdent','type':'command','val':'outdent'},
			{'name':'Links','id':'links','type':'label','val':'Links:'},
				//{'name':'Link','id':'link','type':'link','val':'createLink'},
				{'name':'Link','id':'link','type':'function','val':'$.fn.greybackEditor.link'},
				{'name':'Unlink','id':'unlink','type':'command','val':'unlink'},
			{'name':'Utility','id':'insert','type':'label','val':'Utility:'},
				{'name':'Image','id':'image','type':'function','val':'$.fn.greybackEditor.image'},
				{'name':'Html','id':'html','type':'function','val':'$.fn.greybackEditor.html'},
				{'name':'RemoveFormat','id':'removeformat','type':'command','val':'removeformat'}
		]
	};

	$.fn.greybackEditor.ajax = function(tag, href) {
		var workspace = "#"+tag+editorTags.workspace;

		$.get(href,function(data) {
			$(workspace).html(data);
			if($(workspace).css('display') == "none") {
				$(workspace).slideDown();
			}
			greybackCurrentEditor = {
				id:tag,
				max_width:$.fn.greybackEditor.defaults['max_width'],
				model:greybackCurrentEditor['model']
			};
		});
	}

	$.fn.greybackEditor.overlay = function(tag, href) {
		var workspace = "#"+tag+editorTags.overlay;

		$.get(href,function(data) {
			$(workspace).html(data);
			if($(workspace).css('display') == "none") {
				$(workspace).slideDown();
			}
			greybackCurrentEditor = {
				id:tag,
				max_width:$.fn.greybackEditor.defaults['max_width'],
				model:greybackCurrentEditor['model']
			};
		});
	}

	$.fn.greybackEditor.fullscreen = function(tag, href) {
		greybackCurrentEditor = {
			id:tag,
			max_width:$.fn.greybackEditor.defaults['max_width'],
			model:greybackCurrentEditor['model']
		};
		greybackFullscreen(href);
	}

	$.fn.greybackEditor.command = function(tag, command, value) {
		try {
			document.execCommand(command,false,value);
			$.fn.greybackEditor.status(tag);
		} catch(e) {
			alert(e);
		}
	}

	$.fn.greybackEditor.image = function(tag) {
		if(image) {
			$.fn.greybackEditor.editImage(tag,image);
		} else {
			//$.fn.greybackEditor.overlay(tag,webroot + 'greyback/plugin/media/media_images/rte');
			greybackCurrentEditor = {
				id:tag,
				max_width:$.fn.greybackEditor.defaults['max_width'],
				model:greybackCurrentEditor['model']
			};
			selectedImage = document.getSelection().getRangeAt(0);
			greybackFullscreen(webroot+"greyback/plugin/media/media_images/selector/rte:true");
		}
	}

	$.fn.greybackEditor.link = function(tag) {
		linkrange = document.getSelection().getRangeAt(0);
		if(false) {
			$.fn.greybackEditor.editImage(tag,image);
		} else {
			//$.fn.greybackEditor.overlay(tag,webroot + 'greyback/pages/rte_link');
			$.fn.greybackEditor.ajax(tag,webroot + 'greyback/pages/rte_link');
		}
	}

	$.fn.greybackEditor.insertLink = function(tag, link) {
		document.getSelection().removeAllRanges();
		document.getSelection().addRange(linkrange);
		newlink = document.createElement('a');
		newlink.href = link['url'];
		newlink.target = link['target'];
		linkrange.surroundContents(newlink);
		$.fn.greybackEditor.status(tag);
	}

	$.fn.greybackEditor.insertImage = function(tag,href,style) {
		image = document.createElement('img');
		$(image).attr('src',href);
		$(image).css(style);
		selectedImage.insertNode(image);
		var workspace = "#"+tag+editorTags.workspace;
		if($(workspace).css('display') == "block") {
			$(workspace).slideUp().html("");
		}
		var overlay = "#"+tag+editorTags.overlay;
		if($(overlay).css('display') == "block") {
			$(overlay).fadeOut().html("");
		}
		greybackFullscreenClose();
		$.fn.greybackEditor.status(tag);
	}

	$.fn.greybackEditor.editImage = function(tag, image) {
		greybackCurrentImage = image;
		selectedImage = document.getSelection().getRangeAt(0);
		$.fn.greybackEditor.fullscreen(tag, webroot+"greyback/images/crop/rte:true");
	}

	$.fn.greybackEditor.status = function(tag) {
		var iframe = "#" + tag + editorTags.iframe;
		var textarea = "#" + tag;
		if($(iframe).html().length == 0) {
			$.fn.greybackEditor.command(tag,'formatblock','<p>');
		}
		$(iframe).find('IMG').removeClass('highlighted');
		$(textarea).val($(iframe).html());
		style = ['bold','italic','underline'];
		$.each(style, function(key, val) {
			if(document.queryCommandState(val)) {
				$('#greybackEditorCommand_'+val).addClass('active');
			} else {
				$('#greybackEditorCommand_'+val).removeClass('active');
			}
		});
	}

	$.fn.greybackEditor.wrap = function() {
		range = document.getSelection().getRangeAt(0);
		newWrap = document.createElement('h1');
		range.surroundContents(newWrap);
	}

	$.fn.greybackEditor.fontIncrease = function(tag) {
		var size = document.queryCommandValue('fontsize');
		//size = size.substring(0,size.length-2);
		/*
if(size < 10) {
			newsize = 1;
		} else if((size >=10)&&(size < 13)) {
			newsize = 2
		}  else if((size >=13)&&(size < 16)) {
			newsize = 3
		} else if((size >=16)&&(size < 18)) {
			newsize = 4
		} else if((size >=18)&&(size < 24)) {
			newsize = 5
		} else if((size >=24)&&(size < 32)) {
			newsize = 6
		} else if((size >=32)&&(size < 48)) {
			newsize = 7
		} else {
			return true;
		}
*/
		size++;
		if(size > 7) {
			size = 7;
		}
		document.execCommand('FontSize',false,size);
	}

	$.fn.greybackEditor.fontDecrease = function(tag) {
		var size = document.queryCommandValue('fontsize');
		/*
		var newsize = 7;
		size = size.substring(0,size.length-2);
		if(size > 48) {
			newsize = 7;
		} else if((size <=48)&&(size > 32)) {
			newsize = 6
		} else if((size <=32)&&(size > 24)) {
			newsize = 5
		} else if((size <=24)&&(size > 18)) {
			newsize = 4
		} else if((size <=18)&&(size > 16)) {
			newsize = 3
		} else if((size <=16)&&(size > 13)) {
			newsize = 2
		} else if((size <=13)&&(size > 10)) {
			newsize = 1
		} else {
			return true;
		}
*/
		size--;
		if(size < 1) {
			size = 1;
		}
		document.execCommand('FontSize',false,size);
	}
	
	$.fn.greybackEditor.html = function(tag) {
		var iframe = "#" + tag + editorTags.iframe;
		if($(iframe).css('display')=="block") {
			$('#'+tag).val($(iframe).html());
			$(iframe).slideUp();
			$('#'+tag).slideDown();
		} else {
			$(iframe).html($('#'+tag).val());
			$(iframe).slideDown();
			$('#'+tag).slideUp();
		}
	}

})(jQuery);
