(function($) {

	$.rapidEdit = function(saveTo, options) {
		var settings = $.extend({}, $.rapidEdit.defaults, options);
		settings.saveTo = saveTo;
		$.rapidEdit.settings = settings;
		
		return $("." + $.rapidEdit.settings.rapidEditClass).each(function() {
			$this = $(this);
			$.rapidEdit.attachEditLink($this);
		});
	};
	
	$.rapidEdit.bindClick = function(element) {
		var settings = $.rapidEdit.metadata(element);
		$(element).find("."+settings.editLinkClass).bind('click', function() {
			$("." + settings.editLinkClass).hide();
			$.rapidEdit.editElement(element);
		});
		if (settings.editLinkHoverAttribute != false && settings.editLinkHoverValue != false) {
			$(element).children("."+settings.editLinkClass).hover( function() {
				$(element).css(settings.editLinkHoverAttribute, settings.editLinkHoverValue);
			}, function() {
				$.rapidEdit.resetHover(element);
			});
		}
	};
	
	$.rapidEdit.bindSubmit = function(element) {
		var settings = $.rapidEdit.metadata(element);
		$(element).children("." + settings.submitButtonClass).bind('click', function() {
			if (settings.tinymce == true) {
				value = tinyMCE.get(settings.textareaClass).getContent();
			} else {
				value = $(element).children("textarea").val();
			}
			id = $(element).attr("id") ? $(element).attr("id") : null;
			classes = $(element).attr("class");
			$.ajax({
				url: settings.saveTo,
				type: settings.saveType,
				dataType: "json",
				data: "id=" + id + "&class=" + classes + "&content=" + escape(value),
				success: function(json) {
					$.rapidEdit.restoreElement(value, element);
				},
				error: function(error) {
					alert("Something went wrong. Save was unsuccessful. ("+error.status+": "+error.statusText+")");
				}
			});
			
		});
	};
	
	$.rapidEdit.bindCancel = function(oldContent, element) {
		var settings = $.rapidEdit.settings;
		$(element).children("." + settings.cancelButtonClass).bind('click', function() {
			$.rapidEdit.restoreElement(oldContent, element);
		});
	};
	
	$.rapidEdit.resetHover = function(element) {
		var settings = $.rapidEdit.settings;
		$(element).css(settings.editLinkHoverAttribute, "");
	};

	$.rapidEdit.attachEditLink = function(element) {
		var settings = $.rapidEdit.metadata(element);
		if (settings.setParentPositionRelative == true) {
			//To make sure the link will position correctly we set the current element position to relative
			$(element).css("position", "relative");
		}
		var editLink = '<div class="' + settings.editLinkClass + '" style="cursor: pointer; position: absolute; ' + settings.editLinkPosY + ': ' + settings.editLinkDistY + '; ' + settings.editLinkPosX + ': ' + settings.editLinkDistX + ';"><img src="../' + settings.editLinkImagePath + '" alt="' + settings.editLinkImageTitle + '" title="' + settings.editLinkImageTitle + '" /></div>';
		$(element).append(editLink);
		$.rapidEdit.bindClick(element);
	};
	
	$.rapidEdit.editElement = function(element) {
		var settings = $.rapidEdit.metadata(element);
		$.rapidEdit.resetHover(element);
		$(element).find("." + settings.editLinkClass).remove();
		if (settings.textareaWidth == 'element') {
			var width = $(element).width();
		} else {
			var width = settings.textareaWidth;
		}
		if (settings.textareaHeight == 'element') {
			var height = $(element).height();
		} else {
			var height = settings.textareaHeight;
		}
		
		if (width < settings.textareaMinWidth) {
			width = settings.textareaMinWidth;
		}
		
		if (height < settings.textareaMinHeight) {
			height = settings.textareaMinHeight;
		}
		
		var oldContent = $(element).html();
		var textarea = '<textarea id="'+settings.textareaClass+'" name="'+settings.textareaClass+'" class="' + settings.textareaClass + '" style="width: ' + width + 'px; height: ' + height + 'px;">' + oldContent + '</textarea>';
		var submitButton = '<input type="submit" class="' + settings.submitButtonClass + '" value="' + settings.submitButtonValue +'" />';
		var cancelButton = '<input type="button" class="' + settings.cancelButtonClass + '" value="' + settings.cancelButtonValue + '" />';
		if (settings.animation == true) {
			$(element).slideUp(settings.animationSpeed, function() {
				$(element).html(textarea);
				$(element).append(submitButton);
				$(element).append(cancelButton);
				$.rapidEdit.bindSubmit(element);
				$.rapidEdit.bindCancel(oldContent, element);
				if (settings.tinymce == true) {
					tinyMCE.execCommand('mceAddControl', false, settings.textareaClass);
				}
				$(element).slideDown(settings.animationSpeed, function() {
					$(element).find("."+settings.textareaClass).css({"z-index": settings.zindex, "position": "relative"});
					$(element).find("."+settings.submitButtonClass).css({"z-index": settings.zindex, "position": "relative"});
					$(element).find("."+settings.cancelButtonClass).css({"z-index": settings.zindex, "position": "relative"});
				});
			});
		} else {
			$(element).html(textarea);
			$(element).append(submitButton);
			$(element).append(cancelButton);
			$.rapidEdit.bindSubmit(element);
			$.rapidEdit.bindCancel(oldContent, element);
		}
	};
	
	$.rapidEdit.restoreElement = function(content, element) {
		var settings = $.rapidEdit.metadata(element);
		if (settings.animation == true) {
			$(element).slideUp(settings.animationSpeed, function() {
				if (settings.tinymce == true) {
					tinyMCE.execCommand('mceFocus', false, settings.textareaClass);                    
					tinyMCE.execCommand('mceRemoveControl', false, settings.textareaClass);
				}
				$(element).html(content);
				$(element).slideDown(settings.animationSpeed, function() {
					$(element).find("." + settings.rapidEditClass).each( function () {
						$.rapidEdit.attachEditLink(this);
					});
					$.rapidEdit.attachEditLink(element);
					$("." + settings.editLinkClass).show();
				});
			});
		} else {
			$(element).html(content);
			$(element).find("." + settings.rapidEditClass).each( function () {
				$.rapidEdit.attachEditLink(this);
			});
			$.rapidEdit.attachEditLink(element);
			$("." + settings.editLinkClass).show();
		}
	};
	
	$.rapidEdit.metadata = function(element) {
		var settings = $.rapidEdit.settings;
		return $.metadata ? $.extend({}, settings, $(element).metadata()) : settings;
	};
	
	$.rapidEdit.settings = {};
	
	$.rapidEdit.defaults = {
		rapidEditClass: 'editable',
		saveTo: '',
		saveType: 'POST',
		editLinkImagePath: '~armourco/cms/edit.png',
		editLinkImageTitle: 'Edit',
		editLinkClass: 'rapidEdit-link',
		editLinkHoverAttribute: false,
		editLinkHoverValue: false,
		editLinkPosX: 'right',
		editLinkPosY: 'top',
		editLinkDistX: '0',
		editLinkDistY: '0',
		tinymce: false,
		textareaMinWidth: '50',
		textareaWidth: 'element',
		textareaMinHeight: '50',
		textareaHeight: 'element',
		textareaClass: 'rapidEdit-textarea',
		submitButtonClass: 'rapidEdit-submit',
		submitButtonValue: 'Save',
		cancelButtonClass: 'rapidEdit-cancel',
		cancelButtonValue: 'Cancel',
		setParentPositionRelative: true,
		animation: true,
		animationSpeed: 'fast'
	};

})(jQuery);
