/*
 * jQuery RichTextEditor
 * see example usage at the bottom of this file
 */
;(function($) {
$.fn.richTextEditor = function(options) {				
	var RTE = this;	
	RTE.options = $.extend(true, {}, $.fn.richTextEditor.defaults, options);	
	RTE.css(RTE.options.css);	
	RTE.commandBar = getCommandBar(RTE);	
	RTE.document = getDocument(RTE).designMode("on");	
	if(RTE.options.colorTable) {
		RTE.colorTable = getColorTable(RTE);	
		$(document).click(function() {
			RTE.colorTable.hide();
		});
		$(RTE.document.contentDocument()).click(function() {
			RTE.colorTable.hide();
		});	
	}
	
	return this;
};

$.fn.richTextEditor.defaults = {	
	css: {},
	colorTable: {
		css: {
			border: "solid 1px",
			display: "none",
			position: "absolute"			
		},
		colors: ["#000000","#000033","#000066","#000099","#0000CC","#0000FF","#003300","#003333","#003366","#003399","#0033CC","#0033FF","#006600","#006633","#006666","#006699","#0066CC","#0066FF","#009900","#009933","#009966","#009999","#0099CC","#0099FF","#00CC00","#00CC33","#00CC66","#00CC99","#00CCCC","#00CCFF","#00FF00","#00FF33","#00FF66","#00FF99","#00FFCC","#00FFFF","#330000","#330033","#330066","#330099","#3300CC","#3300FF","#333300","#333333","#333366","#333399","#3333CC","#3333FF","#336600","#336633","#336666","#336699","#3366CC","#3366FF","#339900","#339933","#339966","#339999","#3399CC","#3399FF","#33CC00","#33CC33","#33CC66","#33CC99","#33CCCC","#33CCFF","#33FF00","#33FF33","#33FF66","#33FF99","#33FFCC","#33FFFF","#660000","#660033","#660066","#660099","#6600CC","#6600FF","#663300","#663333","#663366","#663399","#6633CC","#6633FF","#666600","#666633","#666666","#666699","#6666CC","#6666FF","#669900","#669933","#669966","#669999","#6699CC","#6699FF","#66CC00","#66CC33","#66CC66","#66CC99","#66CCCC","#66CCFF","#66FF00","#66FF33","#66FF66","#66FF99","#66FFCC","#66FFFF","#990000","#990033","#990066","#990099","#9900CC","#9900FF","#993300","#993333","#993366","#993399","#9933CC","#9933FF","#996600","#996633","#996666","#996699","#9966CC","#9966FF","#999900","#999933","#999966","#999999","#9999CC","#9999FF","#99CC00","#99CC33","#99CC66","#99CC99","#99CCCC","#99CCFF","#99FF00","#99FF33","#99FF66","#99FF99","#99FFCC","#99FFFF","#CC0000","#CC0033","#CC0066","#CC0099","#CC00CC","#CC00FF","#CC3300","#CC3333","#CC3366","#CC3399","#CC33CC","#CC33FF","#CC6600","#CC6633","#CC6666","#CC6699","#CC66CC","#CC66FF","#CC9900","#CC9933","#CC9966","#CC9999","#CC99CC","#CC99FF","#CCCC00","#CCCC33","#CCCC66","#CCCC99","#CCCCCC","#CCCCFF","#CCFF00","#CCFF33","#CCFF66","#CCFF99","#CCFFCC","#CCFFFF","#FF0000","#FF0033","#FF0066","#FF0099","#FF00CC","#FF00FF","#FF3300","#FF3333","#FF3366","#FF3399","#FF33CC","#FF33FF","#FF6600","#FF6633","#FF6666","#FF6699","#FF66CC","#FF66FF","#FF9900","#FF9933","#FF9966","#FF9999","#FF99CC","#FF99FF","#FFCC00","#FFCC33","#FFCC66","#FFCC99","#FFCCCC","#FFCCFF","#FFFF00","#FFFF33","#FFFF66","#FFFF99","#FFFFCC","#FFFFFF"],
		button: {
			css: {				
				border: "none",
				cursor: "default",													
				width: "7px",
				height: "7px",
				lineHeight: "7px"
			}
		},
		zoom: {
			css: {
				border: "solid 1px",
				display: "none",
				position: "absolute",												
				width: "30px",
				height: "30px",
				left: "-32px",
				top: "-1px"
			}
		}
	},
	commandBar: {
		dropdowns: {
			formatBlock: [],
			fontName: [],
			fontSize: []
		},						
		commands: [],
		commandButton: {
			down: {
				css: {}
			},
			over: {
				css: {}
			},
			out: {
				css: {}
			},
			up: {
				css: {}
			}
		}
	},	
	document: {
		attr: {},
		css: {}
	}
};

//	*	PRIVATE METHODS:

function getColorTable(RTE) {
	var colorTable = $("<div></div>")
			.css(RTE.options.colorTable.css),		
		colorRollover = $("<div class='ColorRollover'></div>")
			.css(RTE.options.colorTable.zoom.css)
			.appendTo(colorTable);	
		
	$.each(RTE.options.colorTable.colors,														
		function(i, color) {
			if(i % 6 == 0 && i!= 0) {												
				colorTable.append("<BR />");
			}
			$("<button></button>")
				.attr("color", color)				
				.css($.extend(RTE.options.colorTable.button.css, {background: color}))					
				.hover(
					function() {
						colorTable.find(".ColorRollover")
							.css({
								background: $(this).css("background")
							})
							.show();							
					},
					function() {
						colorTable.find(".ColorRollover")							
							.hide();
					}
				)				
				.appendTo(colorTable);
		}
	);		
	return colorTable.appendTo(RTE);
}

function getCommandBar(RTE) {
	var commandBar = $("<div></div>")
			.css(RTE.options.commandBar.css || {}),
		blockFormatMap = {
			"Normal": "<P>",
			"Heading 1": "<H1>",
			"Heading 2": "<H2>",
			"Heading 3": "<H3>",
			"Heading 4": "<H4>",
			"Heading 5": "<H5>",
			"Heading 6": "<H6>",
			"Address": "<address>",
			"Formatted": "<pre>"
		};									
		
	if(RTE.options.commandBar.dropdowns) {
		for(dropdown in RTE.options.commandBar.dropdowns) {
			if(RTE.options.commandBar.dropdowns[dropdown].length > 0) {
				var _dropdown = $("<select></select>")
					.attr("command", dropdown);					
				
				$.each(RTE.options.commandBar.dropdowns[dropdown], function(i, option) {
					$("<option>" + option + "</option>")
						.appendTo(_dropdown);
				});
				
				_dropdown
					.change(function() {					
						RTE.document.execCommand($(this).attr("command"), $.browser.msie ? $(this).val() : blockFormatMap[$(this).val()]);
					})
					.appendTo(commandBar);
			}
		}
	}
	
	if(RTE.options.commandBar.commands) {					
		$.each(RTE.options.commandBar.commands, function(i, command) {
			var commandButton = $("<button></button>");
			switch(command.toUpperCase()) {
				case "BACKCOLOR":
				case "FORECOLOR":					
					commandButton
						.click(function() {																									
							RTE.colorTable
								.css({	
									left: ($(this).offset().left + 10 + ($.browser.msie ? -2 : 7)) + "px",
									top: ($(this).offset().top + 10 + ($.browser.msie ? -2 : 7)) + "px"
								})																	
								.show();								
							RTE.colorTable.find("button[color]")
								.unbind("click")
								.bind("click",
									function() {												
										RTE.document.execCommand(command, $(this).attr("color"));
										RTE.colorTable.find(".ColorRollover")
											.hide();	
									}
								);
							return false;
						});
					break;							
				default:				
					commandButton
						.click(function() {								
							RTE.document.execCommand(command, null);
							return false;								
						});						
					break;
			}
			commandButton
				.css(RTE.options.commandBar.commandButton.out.css)						
				.css((function() {
					return RTE.options.commandBar.imageDirectory
						?
						{
							background: "#C0C0C0 url(" + RTE.options.commandBar.imageDirectory + command.toLowerCase() + ".gif) no-repeat"
						}
						:
						(function() {
							commandButton.text(command);
							return {}
						})()						
				})())								
				.hover(
					function() {
						$(this)
							.css(RTE.options.commandBar.commandButton.over.css)
						return false;
					},
					function() {							
						$(this)
							.css(RTE.options.commandBar.commandButton.out.css)
						return false;
					}						
				)						
				.mousedown(function() {
					$(this)
						.css(RTE.options.commandBar.commandButton.down.css)
				})						
				.mouseup(function() {
					$(this)
						.css(RTE.options.commandBar.commandButton.up.css)
				})
				.appendTo(commandBar);					
		});
	}	
	return commandBar.appendTo(RTE);
}
function getDocument(RTE) {
	var width = RTE.options.css.width
		?
		(RTE.css("width").replace("px", "")-0 + ($.browser.msie ? 1 : -4)) + "px"
		:
		"",	
		document = $("<iframe></iframe>")			
			.attr(RTE.options.document.attr)
			.css("background", "#ffffff")	
			.css($.extend(RTE.options.document.css, {width: width}));		
	return document.wrap("<div></div>").appendTo(RTE);
}
/**
 * designMode $ plugin v0.1, by Emil Konow.
 * This plugin allows you to handle functionality related to designMode in a cross-browser way.
 */
$.fn.contentDocument = function() {
	var frame = this[0];	
	if (frame.contentDocument) {
		return frame.contentDocument;
	} else if (frame.contentWindow && frame.contentWindow.document) {
		return frame.contentWindow.document;
	} else if (frame.document) {
		return frame.document;
	} else {
		return null;
	}
}
$.fn.designMode = function(mode) {	
	// Default mode is 'on'
	mode = mode || 'on';
	this.each(function() {
		if(mode.toUpperCase() == "OFF") {			
			if($.browser.msie) {				
				$(this).contentDocument().body.contentEditable = false;
			} else {
				$(this).contentDocument().designMode = mode;
			}
			
		} else {
			if($.browser.msie) {
				try {	
					$(this).contentDocument().body.contentEditable = true;
				} catch(err) {
					$(this).load(function() {
						$(this).contentDocument().body.contentEditable = true;
					});
				}
			} else {
				$(this).contentDocument().designMode = mode;
				$(this).load(function() {
					$(this).contentDocument().designMode = mode;
				});				
			}
		}
	});
	return this;
}
$.fn.execCommand = function(cmd, param) {	
	this.each(function() {
		var doc = $(this).contentDocument();		
		if (doc) {
			// Use try-catch in case of invalid or unsupported commands
    		try {
				// Non-IE-browsers requires all three arguments				
				doc.execCommand(cmd, false, param);
			} catch (e) {
			}
		}
	});
	return this;
}
$.fn.richText = function() {
	if(arguments[0]) {
		if($(this).find("iframe").length > 0) {
			$(this).find("iframe").contentDocument().body.innerHTML = arguments[0].replace(/\"/g,"'");
		}
	} else {
		if($(this).find("iframe").length > 0) {
			return $(this).find("iframe").contentDocument().body.innerHTML.replace(/\"/g,"'");
		} else {
			return "";
		}
	}
}
})(jQuery);
/*
	*	EXAMPLE USAGE:
	
	*	use jQuery("#richTextContainer").richTextEditor([options]) to create Rich Text Editor
	*	use jQuery("#richTextContainer").richText() to retrieve innerHTML of Rich Text Editor

	*	use the css sub-objects to adjust layout
		eg.	use absolute position to move document(iframe) object above commandBar object
		
	*	alter the commandBar's controls by modifying/removing the dropdowns/commands arrays
		eg. remove the commandBar.dropdowns.fontName array to remove that control from commandBar
		
	*	you must specify the colorTable object to include the colorTabel (to avoid unnecessary processing time)
		provide custom color pallatte by adding a "colorTable.colors" array at the root level
		eg.	colorTable: { colors: ["#000000", "White", etc...] }

	jQuery("#richTextContainer").richTextEditor({		
		css: {			
			position: "absolute",
			width: "520px"
		},		
		colorTable: {},
		commandBar: {			
			imageDirectory: "http://ak.imgfarm.com/images/fwp/myfuncards/RichTextEditor/",
			css: {
				background: "#C0C0C0",
				border: "solid 1px Black",
				borderBottom: "none",				
				padding: "2px"
			},
			dropdowns: {
				formatBlock: [
					"Normal",
					"Paragraph",
					"Heading 1",
					"Heading 2",
					"Heading 3",
					"Heading 4",
					"Heading 5",
					"Heading 6",
					"Address",
					"Formatted"
				],
				fontName: [
					"Arial",
					"Courier",
					"Times New Roman"
				],
				fontSize: [
					"1",
					"2",
					"3",
					"4",
					"5",
					"6",
					"7"
				]
			},	
			commands: [
				"bold",
				"italic",
				"underline",
				"forecolor",
				"backcolor",
				"justifyleft",
				"justifycenter",
				"justifyright",
				"outdent",
				"indent"
			],
			commandButton: {
				down: {
					css: {
						border: "inset 1px",
						width: "23px",
						height: "22px"
					}
				},
				out: {
					css: {
						border: "solid 1px #C0C0C0",
						width: "23px",
						height: "22px"
					}
				},
				over: {
					css: {
						border: "outset 1px",
						width: "23px",
						height: "22px"
					}
				},				
				up: {
					css: {
						border: "solid 1px #C0C0C0",
						width: "23px",
						height: "22px"
					}
				}
			}
		},	
		document: {
			attr: {
				frameBorder: "1"					
			},
			css: {
				background: "#ffffff",						
				height: "300px"
			}
		}		
	});

	*	COMMAND REFERENCE:
	
	var commands = [
		"2D-Position",
		"AbsolutePosition",
		"BackColor",
		"BlockDirLTR",
		"BlockDirRTL",
		"Bold",
		"BrowseMode",
		"ClearAuthenticationCache",
		"Copy",
		"CreateBookmark",
		"CreateLink",
		"Cut",
		"Delete",
		"DirLTR",
		"DirRTL",
		"EditMode",
		"FontName",
		"FontSize",
		"ForeColor",
		"FormatBlock",
		"Indent",
		"InlineDirLTR",
		"InlineDirRTL",
		"InsertButton",
		"InsertFieldset",
		"InsertHorizontalRule",
		"InsertIFrame",
		"InsertImage",
		"InsertInputButton",
		"InsertInputCheckbox",
		"InsertInputFileUpload",
		"InsertInputHidden",
		"InsertInputImage",
		"InsertInputPassword",
		"InsertInputRadio",
		"InsertInputReset",
		"InsertInputSubmit",
		"InsertInputText",
		"InsertMarquee",
		"InsertOrderedList",
		"InsertParagraph",
		"InsertSelectDropdown",
		"InsertSelectListbox",
		"InsertTextArea",
		"InsertUnorderedList",
		"Italic",
		"JustifyCenter",
		"JustifyFull",
		"JustifyLeft",
		"JustifyNone",
		"JustifyRight",
		"LiveResize",
		"MultipleSelection",
		"Open",
		"Outdent",
		"OverWrite",
		"Paste",
		"PlayImage",
		"Print",
		"Redo",
		"Refresh",
		"RemoveFormat",
		"RemoveParaFormat",
		"SaveAs",
		"SelectAll",
		"SizeToControl",
		"SizeToControlHeight",
		"SizeToControlWidth",
		"Stop",
		"StopImage",
		"StrikeThrough",
		"Subscript",
		"Superscript",
		"UnBookmark",
		"Underline",
		"Undo",
		"Unlink",
		"Unselect"
	];

*/
