// ----------------------------------------------------------------------------
// markItUp! Universal MarkUp Engine 1.1.9
// Dual licensed under the MIT and GPL licenses.
// ----------------------------------------------------------------------------
// © 2007-2009 Jay Salvat
// http://markitup.jaysalvat.com/
// ----------------------------------------------------------------------------
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
// ----------------------------------------------------------------------------
(function($) {
	$.fn.markItUp = function(options) {
		var ctrlKey = false, shiftKey = false, altKey = false;

		var settings = $.extend({
			className:		"",
			root:			"",
			previewInWindow:	"",		// "width=800, height=600, resizable=yes, scrollbars=yes"
			previewAutoRefresh:	true,
			previewPosition:	"after",	// before, after
			previewTemplatePath:	"~/templates/preview.html",
			previewParserPath:	"",
			previewParserVar:	"data",
			resize:			"auto",		// auto, manual, disabled
			minHeight:		20,
			maxHeight:		-1,		// -1 - use window height, 0 - no maximum
			onEnter:		{},
			onShiftEnter:		{},
			onCtrlEnter:		{},
			onTab:			{},
			markupSet:		[ { /* set */ } ]
		}, options);

		// compute markItUp! path
		if (!settings.root) {
			$("script").each(function(a, tag) {
				var miuScript = $(tag).get(0).src.match(/(.*)markitup(\.pack)?\.js$/i);
				if (miuScript !== null) {
					settings.root = miuScript[1];
				}
			});
		}

		return this.each(function() {
			var $$ = $(this), textarea = this, selectedText, selectionStart = 0, originalHeight = 0, header, footer, previewWindow, template, iFrame;
			var prevDocumentScrollPos = -1, documentScrollPos = -1, lastChange = new Date(0);

			settings.previewParserPath = localize(settings.previewParserPath);
			settings.previewTemplatePath = localize(settings.previewTemplatePath);

			// apply the computed path to ~/
			function localize(data) {
				return data.replace(/^~\//, settings.root).replace(/(["'])~\//g, "$1" + settings.root);
			}

			// init and build editor
			function init() {
				var className = "";
				if (settings.className) className = ' ' + settings.className;

				$$
					.addClass("markItUpEditor")
					.wrap('<div class="markItUp' + className + '"></div>')
					.wrap('<div class="markItUpContainer"></div>');

				// add the header before the textarea
				header = $('<div class="markItUpHeader"></div>')
					.insertBefore($$)
					.append(dropMenus(settings.markupSet));

				// add the footer after the textarea
				footer = $('<div class="markItUpFooter"></div>').insertAfter($$);

				$("li.shrink", header).hide();

				void(textarea.scrollHeight); // scrollHeight returns the wrong value the first time it is called
				originalHeight = $$.height();

				$$.bind("change propertychange", checkOverflow);

				if (settings.resize === "auto") {
					setHeight(-1);

					$$.bind("change propertychange", autoSetHeight);
				} else if (settings.resize === "manual" && !$.browser.safari) {
					// add the resize handle
					$('<div class="markItUpResizeHandle"></div>')
						.appendTo(footer)
						.bind("mousedown", function(e) {
							var h = $$.height(), y = $(document).scrollTop() + e.clientY;
							var mouseMove = function(e) {
								setHeight(Math.max(settings.minHeight, h + e.clientY - $(document).scrollTop() - y));
								return false;
							};
							var mouseUp = function(e) {
								$(document)
									.unbind("mousemove", mouseMove)
									.unbind("mouseup", mouseUp);
								return false;
							};
							$(document)
								.bind("mousemove", mouseMove)
								.bind("mouseup", mouseUp);
						})
						.bind("dblclick", autoSetHeight);
				}

				$(window).bind("scroll", function() {
					if (new Date() - lastChange < 500 && prevDocumentScrollPos > -1) {
						$(document).scrollTop(prevDocumentScrollPos);
						documentScrollPos = prevDocumentScrollPos;

						/*if (document.selection) {
							var range = document.selection.createRange(), rangeCopy = range.duplicate();
							rangeCopy.moveToElementText(textarea);
							if (rangeCopy.inRange(range)) {
								range.scrollIntoView();
							}
						}*/
					} else {
						prevDocumentScrollPos = documentScrollPos;
						documentScrollPos = $(document).scrollTop();
					}
				});

				$$
					.bind("keydown keyup", keyPressed)
					.bind("insertion", function(e, options) {
						// catch external calls
						if (options.target !== false) {
							getSelection();
						}
						if (textarea === $.markItUp.focused) {
							markup(options);
						}
					})
					.bind("focus", function() {
						// remember the last focus
						$.markItUp.focused = this;
					});
			}

			function checkOverflow() {
				$$.css("overflow", ($$.height() < textarea.scrollHeight) ? "auto" : "hidden");
			}

			function setHeight(h) {
				if ($$.parent().parent().hasClass("expanded")) return;

				if (h < 0) h = Math.max(originalHeight, textarea.scrollHeight);

				if (settings.maxHeight < 0) {
					h = Math.min(h, $(window).height() - header.height() - 70);
				} else if (settings.maxHeight > 0) {
					h = Math.min(h, settings.maxHeight);
				}

				$$.height(h + "px");
			}

			function autoSetHeight() {
				lastChange = new Date();

				setHeight(-1);
			}

			function resize() {
				if (!$$.parent().parent().hasClass("expanded")) return;

				$$.width($(window).width() - $$.position().left * 2 - $$.outerWidth() + $$.width());
				$$.height($(window).height() - $$.position().top - $$.position().left - $$.outerHeight() + $$.height());
			}

			function expand() {
				if ($$.parent().parent().hasClass("expanded")) return;

				$(document.body).css("overflow", "hidden");
				if (document.documentElement) $(document.documentElement).css("overflow", "hidden");

				textarea.oldWidth = $$.width();
				textarea.oldHeight = $$.height();

				$(window).bind("resize", resize);
				$$.parent().parent().addClass("expanded");

				$("div.markItUpResizeHandle", $$.parent().parent()).hide();

				resize();

				$("li.expand", header).hide();
				$("li.shrink", header).show();
			}

			function shrink() {
				if (!$$.parent().parent().hasClass("expanded")) return;

				$(document).css("overflow", "auto");
				if (document.documentElement) $(document.documentElement).css("overflow", "auto");

				$(window).unbind("resize", resize);
				$$.parent().parent().removeClass("expanded");
				$("div.markItUpResizeHandle", $$.parent().parent()).show();

				$$.width(textarea.oldWidth);
				$$.height(textarea.oldHeight);

				$("li.shrink", header).hide();
				$("li.expand", header).show();

				textarea.scrollIntoView();
			}

			// recursively build header with dropMenus from markup set
			function dropMenus(markupSet) {
				var ul = $('<ul></ul>');
				$("li:hover > ul", ul).css("display", "block");
				$.each(markupSet, function() {
					var button = $.extend({
						name: "",
						className: ""
					}, this);

					var title = (button.key) ? button.name + ' [Ctrl+' + button.key + ']' : button.name;
					var key   = (button.key) ? ' accesskey="' + button.key + '"' : "";

					if (button.separator) {
						$('<li class="markItUpSeparator">&nbsp;</li>').appendTo(ul);
					} else {
						var li = $('<li class="markItUpButton ' + button.className + '"><a href="javascript:"' + key + ' title="' + title + '" tabindex="-1">' + button.name + '</a></li>')
							.bind("contextmenu", function() { // prevent context menu on Mac and allow ctrl + click
								return false;
							})
							.bind("click", function() {
								markup(button);
							})
							.bind("mouseenter", function() {
								$("> ul", this).show();
								$(document).one("click", function() {
									 // close dropmenu if click outside
									$("ul ul", header).hide();
								});
							})
							.bind("mouseleave", function() {
								$("> ul", this).hide();
							})
							.appendTo(ul);

						if (button.dropMenu) {
							li.addClass("markItUpDropMenu").append(dropMenus(button.dropMenu));
						}
					}
				});
				return ul;
			}

			// insert markup
			function markup(options) {
				getSelection();

				options = $.extend({
					openTag: "",
					closeTag: "",
					openTagRegExp: null,
					closeTagRegExp: null,
					placeHolder: "",
					replaceWith: null,
					multiLine: false
				}, options, {
					root: settings.root,
					textarea: textarea,
					selectedText: selectedText,
					selectionStart: selectionStart,
					select: select,
					ctrlKey: ctrlKey,
					shiftKey: shiftKey,
					altKey: altKey
				});

				if (options.call) {
					if ($.isFunction(options.call)) {
						options.call(options);
					} else {
						eval(options.call)(options);
					}
				}

				if ($.isFunction(options.replaceWith)) {
					options.replaceWith = options.replaceWith(options);
					if (!options.replaceWith) options.replaceWith = null;
				}

				options.openTag = options.openTag.replace(/(\r\n|\r|\n)/g, "\n");
				options.closeTag = options.closeTag.replace(/(\r\n|\r|\n)/g, "\n");
				options.placeHolder = options.placeHolder.replace(/(\r\n|\r|\n)/g, "\n");
				if (options.replaceWith !== null) options.replaceWith = options.replaceWith.replace(/(\r\n|\r|\n)/g, "\n");

				if (!options.openTagRegExp && options.openTag) options.openTagRegExp = new RegExp(options.openTag.replace(/([\\\(\)\[\]\{\}\.\*\+\?\^\$])/g, "\\$1"), "i");
				if (!options.closeTagRegExp && options.closeTag) options.closeTagRegExp = new RegExp(options.closeTag.replace(/([\\\(\)\[\]\{\}\.\*\+\?\^\$])/g, "\\$1"), "i");

				var oldText = textarea.value.replace(/(\r\n|\r|\n)/g, "\n"), text = oldText, string = selectedText;

				selectionStart += selectedText.length;
				selectedText = selectedText.replace(/^(\r\n|\r|\n)+/, "");
				selectionStart -= selectedText.length;
				selectedText = selectedText.replace(/(\r\n|\r|\n)+$/, "");

				var tags = [], doneTags = false;

				function recalc(index, start, len, moveIfEqual) {
					var i = start;
					if (len < 0) i -= len;

					if (index > i || (index == i && moveIfEqual)) return index + len;
					return Math.min(index, start);
				}

				function insert(string, start, isOpenTag) {
					text = text.substr(0, start) + string + text.substr(start);

					var end = recalc(selectionStart + selectedText.length, start, string.length, isOpenTag && selectedText.length < 1);
					selectionStart = recalc(selectionStart, start, string.length, isOpenTag);
					selectedText = text.substring(selectionStart, end);

					$.each(tags, function() {
						var end = recalc(this.open.index + this.open.string.length, start, string.length, isOpenTag && this.open.string.length < 1);
						this.open.index = recalc(this.open.index, start, string.length, isOpenTag);
						this.open.string = text.substring(this.open.index, end);

						if (this.close) {
							end = recalc(this.close.index + this.close.string.length, start, string.length, isOpenTag && this.close.string.length < 1);
							this.close.index = recalc(this.close.index, start, string.length, isOpenTag);
							this.close.string = text.substring(this.close.index, end);
						}
					});
				}

				function remove(start, len) {
					text = text.substr(0, start) + text.substr(start + len);

					var end = recalc(selectionStart + selectedText.length, start, -len);
					selectionStart = recalc(selectionStart, start, -len);
					selectedText = text.substring(selectionStart, end);

					$.each(tags, function() {
						end = recalc(this.open.index + this.open.string.length, start, -len);
						this.open.index = recalc(this.open.index, start, -len);
						this.open.string = text.substring(this.open.index, end);

						if (this.close) {
							end = recalc(this.close.index + this.close.string.length, start, -len);
							this.close.index = recalc(this.close.index, start, -len);
							this.close.string = text.substring(this.close.index, end);
						}
					});
				}

				function insertTags(openIndex, openTag, closeIndex, closeTag) {
					if (openIndex > closeIndex) return;

					insert(closeTag, closeIndex, false);
					insert(openTag, openIndex, true);

					if (tags) tags.push({
						open: {
							index: openIndex,
							string: openTag
						},
						close: {
							index: closeIndex + openTag.length,
							string: closeTag
						}
					});
				}

				function removeTags(i) {
					remove(tags[i].open.index, tags[i].open.string.length);
					remove(tags[i].close.index, tags[i].close.string.length);

					tags.splice(i, 1);
				}

				function moveTags(i, openIndex, closeIndex) {
					j = (tagsMatch) ? selectionStart : selectionStart + selectedText.length;
					insert(tags[i].open.string, j, tagsMatch);
					k = tags[i].open.index;
					tags[i].open.index = j;
					remove(k, tags[i].open.string.length);
				}

				if (options.openTagRegExp && options.closeTagRegExp) {
					var tag, i = 0, j, k, found;
					while (true) {
						tag = text.substr(i).match(options.openTagRegExp);
						if (!tag) break;

						tags.push({
							open: {
								index: tag.index + i,
								string: tag[0]
							},
							close: null
						});

						i += tag.index + tag[0].length;
					}

					i = 0;
					while (true) {
						tag = text.substr(i).match(options.closeTagRegExp);
						if (!tag) break;

						found = false;

						for (j = tags.length - 1; j >= 0; j--) {
							if (!tags[j].close && tags[j].open.index < tag.index + i) {
								tags[j].close = {
									index: tag.index + i,
									string: tag[0]
								};
								found = true;
								break;
							}
						}

						if (found) {
							i += tag.index + tag[0].length;
						} else {
							remove(tag.index + i, tag[0].length);
						}
					}

					for (i = tags.length - 1; i >= 0; i--) {
						if (!tags[i].close) {
							if (options.closeTag != "") {
								tags[i].close = {
									index: text.length,
									string: options.closeTag
								};
								text += options.closeTag;
							} else {
								remove(tags[i].open.index, tags[i].open.string.length);
								tags.splice(i, 1);
							}
						}
					}

					var tagsMatch, startInside, endInside;

					while (true) {
						found = false;

						for (i = tags.length - 1; i >= 0; i--) {
							for (j = tags.length - 1; j >= 0; j--) {
								if (j != i && tags[j].open.string.toLowerCase() == tags[i].open.string.toLowerCase() && tags[j].close.string.toLowerCase() == tags[i].close.string.toLowerCase() && tags[j].open.index >= tags[i].open.index && tags[j].open.index <= tags[i].close.index + tags[i].close.string.length) {
									remove(tags[j].open.index, tags[j].open.string.length);

									if (tags[i].close.index + tags[i].close.string.length < tags[j].close.index + tags[j].close.string.length) {
										remove(tags[i].close.index, tags[i].close.string.length);

										tags[i].close = tags[j].close;
									} else {
										remove(tags[j].close.index, tags[j].close.string.length);
									}

									tags.splice(j, 1);

									found = true;
									break;
								}
							}

							if (found) break;

							if (!doneTags) {
								tagsMatch = tags[i].open.string.toLowerCase() == options.openTag.toLowerCase() && tags[i].close.string.toLowerCase() == options.closeTag.toLowerCase();
								startInside = selectionStart >= tags[i].open.index && selectionStart <= tags[i].close.index + tags[i].close.string.length;
								endInside = selectionStart + selectedText.length >= tags[i].open.index && selectionStart + selectedText.length <= tags[i].close.index + tags[i].close.string.length;

								if (startInside && endInside) {
									startInside = selectionStart <= tags[i].open.index + tags[i].open.string.length;
									endInside = selectionStart + selectedText.length >= tags[i].close.index;

									if (startInside && endInside) {
										removeTags(i);
									} else if (startInside) {
										insert(tags[i].open.string, selectionStart + selectedText.length, false);
										j = tags[i].open.index;
										tags[i].open.index = selectionStart + selectedText.length;
										remove(j, tags[i].open.string.length);
									} else if (endInside) {
										j = selectionStart;
										insert(tags[i].close.string, selectionStart, true);
										k = tags[i].close.index;
										tags[i].close.index = j;
										remove(k, tags[i].close.string.length);
									} else {
										j = selectionStart;
										insert(tags[i].close.string, selectionStart, true);
										insert(tags[i].open.string, selectionStart + selectedText.length, false);

										tags.push({
											open: {
												index: selectionStart + selectedText.length,
												string: tags[i].open.string
											},
											close: {
												index: tags[i].close.index,
												string: tags[i].close.string
											}
										});
										tags[i].close.index = j;
									}

									doneTags = tagsMatch;
									break;
								} else if (startInside) {
									j = (tagsMatch) ? selectionStart + selectedText.length : selectionStart;
									insert(tags[i].close.string, j, !tagsMatch);
									k = tags[i].close.index;
									tags[i].close.index = j;
									remove(k, tags[i].close.string.length);

									doneTags = tagsMatch;
									found = tagsMatch;
									break;
								} else if (endInside) {
									j = (tagsMatch) ? selectionStart : selectionStart + selectedText.length;
									insert(tags[i].open.string, j, tagsMatch);
									k = tags[i].open.index;
									tags[i].open.index = j;
									remove(k, tags[i].open.string.length);

									doneTags = tagsMatch;
									found = tagsMatch;
									break;
								} else if (selectionStart <= tags[i].open.index && selectionStart + selectedText.length >= tags[i].close.index + tags[i].close.string.length) {
									if (tagsMatch) removeTags(i);
								}
							}
						}

						if (!doneTags) {
							insertTags(selectionStart, options.openTag, selectionStart + selectedText.length, options.closeTag);

							doneTags = true;
							found = true;
						}

						if (!found) break;
					}
				}

				if (options.replaceWith !== null) {
					string = options.replaceWith;
				} else if (selectedText === "" && !doneTags) {
					string = options.placeHolder;
				} else {
					string = selectedText;
				}

				if (!doneTags) {
					insertTags(selectionStart, options.openTag, selectionStart + selectedText.length, options.closeTag);
				}

				if (!options.multiLine) {
					string = string.replace(/(\r\n|\r|\n)/g, options.closeTag + "$1" + options.openTag);
				}

				if (options.prependLine) {
					var i = text.lastIndexOf("\n", selectionStart - 1);
					text = text.substr(0, i + 1) + options.prependLine + text.substring(i + 1, selectionStart + string.length).replace(/(\r\n|\r|\n)/g, "\n" + options.prependLine) + text.substr(selectionStart + string.length);
					string = string.replace(/(\r\n|\r|\n)/g, "\n" + options.prependLine);
					selectionStart += options.prependLine.length;
				} else {
					text = text.substr(0, selectionStart) + string + text.substr(selectionStart + selectedText.length);
				}

				if (text !== oldText) {
					var documentScrollPos = $(document).scrollTop(), scrollPos = $$.scrollTop();

					if (textarea.createTextRange) {
						var range = textarea.createTextRange();
						range.collapse(true);
						range.moveEnd("character", oldText.length);
						range.text = text;
					} else {
						textarea.value = text;
					}

					select(selectionStart, string.length);

					// refresh preview if open
					if (previewWindow && settings.previewAutoRefresh) {
						refreshPreview();
					}

					lastChange = new Date(0);
					$$.scrollTop(scrollPos);
					$(document).scrollTop(documentScrollPos);
				}

				shiftKey = altKey = ctrlKey = false;
			}

			// insert text
			function insert(string) {
				if (document.selection) {
					var range = document.selection.createRange();
					range.text = string;
				} else {
					var text = textarea.value.replace(/(\r\n|\r|\n)/g, "\n");
					textarea.value = text.substr(0, selectionStart) + string + text.substr(selectionStart + selectedText.length);
				}
			}

			// select text
			function select(start, len) {
				var documentScrollPos = $(document).scrollTop(), scrollPos = $$.scrollTop();

				textarea.focus();

				if (textarea.createTextRange) {
					var range = textarea.createTextRange();
					range.collapse(true);
					range.moveStart("character", start);
					range.moveEnd("character", len);
					range.select();
				} else if (textarea.setSelectionRange) {
					textarea.setSelectionRange(start, start + len);
				}

				lastChange = new Date(0);
				$$.scrollTop(scrollPos);
				$(document).scrollTop(documentScrollPos);
			}

			// get the selection
			function getSelection() {
				var documentScrollPos = $(document).scrollTop(), scrollPos = $$.scrollTop();

				textarea.focus();

				var text = textarea.value.replace(/(\r\n|\r|\n)/g, "\n"), selectionEnd;

				if ($.browser.msie) {
					var range = document.selection.createRange(), rangeCopy = range.duplicate();
					rangeCopy.moveToElementText(textarea);
					rangeCopy.setEndPoint("EndToEnd", range);
					selectionStart = textarea.value.substr(0, rangeCopy.text.length - range.text.length).replace(/(\r\n|\r|\n)/g, "\n").length;
					selectionEnd = textarea.value.substr(0, rangeCopy.text.length).replace(/(\r\n|\r|\n)/g, "\n").length;
				} else {
					selectionStart = textarea.selectionStart;
					selectionEnd = textarea.selectionEnd;
				}

				lastChange = new Date(0);
				$$.scrollTop(scrollPos);
				$(document).scrollTop(documentScrollPos);

				selectedText = text.substring(selectionStart, selectionEnd);

				return selectedText;
			}

			// open preview window
			function preview() {
				if (!previewWindow || previewWindow.closed) {
					if (settings.previewInWindow) {
						previewWindow = window.open("", "preview", settings.previewInWindow);
						$(window).bind("unload", function() {
							previewWindow.close();
						});
					} else {
						iFrame = $('<iframe class="markItUpPreviewFrame"></iframe>');
						if (settings.previewPosition == "after") {
							iFrame.insertAfter(footer);
						} else {
							iFrame.insertBefore(header);
						}
						previewWindow = iFrame[0].contentWindow || iFrame[0];
					}
				} else if (altKey) {
					// Thx Stephen M. Redd for the IE8 fix
					if (iFrame) {
						iFrame.remove();
					} else if (previewWindow) {
						previewWindow.close();
					}

					previewWindow = iFrame = null;
				}

				if (!settings.previewAutoRefresh) refreshPreview();

				if (settings.previewInWindow) previewWindow.focus();
			}

			// refresh Preview window
			function refreshPreview() {
				if (settings.previewParserPath !== "") {
					$.ajax({
						type: "POST",
						url: settings.previewParserPath,
						data: settings.previewParserVar + "=" + encodeURIComponent(textarea.value),
						success: function(data) {
							writePreview(localize(data));
						}
					});
				} else {
					if (template) {
						writePreview(template.replace(/<!-- content -->/g, textarea.value));
					} else {
						$.ajax({
							url: settings.previewTemplatePath,
							success: function(data) {
								template = localize(data);
								writePreview(template.replace(/<!-- content -->/g, textarea.value));
							}
						});
					}
				}
			}

			function writePreview(data) {
				if (previewWindow.document) {
					var sp;
					try {
						sp = previewWindow.document.documentElement.scrollTop;
					} catch (e) {
						sp = 0;
					}
					previewWindow.document.open();
					previewWindow.document.write(data);
					previewWindow.document.close();
					previewWindow.document.documentElement.scrollTop = sp;
				}
			}

			function keyPressed(e) {
				shiftKey = e.shiftKey;
				altKey = e.altKey;
				ctrlKey = e.ctrlKey && !e.altKey;

				if (e.type === "keydown") {
					if (ctrlKey) {
						var li = $("a[accesskey='" + escape(String.fromCharCode(e.keyCode)) + "']", header).parent("li");
						if (li.length !== 0) {
							ctrlKey = false;
							li.triggerHandler("click");
							return false;
						}
					}

					switch (e.keyCode) {
						case 13:
						case 10:
							if (ctrlKey) {
								ctrlKey = false;
								markup(settings.onCtrlEnter);
								return settings.onCtrlEnter.keepDefault;
							} else if (shiftKey) {
								shiftKey = false;
								markup(settings.onShiftEnter);
								return settings.onShiftEnter.keepDefault;
							} else {
								markup(settings.onEnter);
								return settings.onEnter.keepDefault;
							}

							break;
						case 9:
							if (ctrlKey || altKey) return false;	// Thx Dr Floob

							markup(settings.onTab);
							return settings.onTab.keepDefault;
					}
				}
			}

			init();
		});
	};

	$.fn.markItUpRemove = function() {
		return this.each(function() {
			var $$ = $(this).unbind().removeClass("markItUpEditor");
			$$.parent().parent().replaceWith($$);
		});
	};

	$.markItUp = function(options) {
		options = $.extend({
			target: null
		}, options);

		if (options.target) {
			return $(options.target).each(function() {
				$(this).trigger("insertion", [options]);
			});
		} else {
			$("textarea").trigger("insertion", [options]);
		}
	};
})(jQuery);

