/***
 * conf can be either
 * A.) A callback function
 * or
 * B.) An object to configure a more detailed editable
 * con properties:
 * callback		: A function that receives the change in the format (new value, old value)
 * force 		: A string that defines the type of input eg: "<input type='text' />" or "<textarea />"
 * hoverStyle	: An jQuery style object to override the built in css for the hover effect, any tyle not specified in this
 * 				  will retain the builtin value
 * */
(function($){
	$.fn.editable = function(conf){
		this.each(function(){
		if(!$(this).attr('title'))
		{
			$(this).attr('title','Klik for at redigére.');
		}
		var margins = ["marginTop","marginBottom","marginRight","marginLeft"];
		var marginValues = [];
		for(i in margins)
		{
			marginValues.push(parseInt($(this).css(margins[i]),10));
			marginValues[i] = isNaN(marginValues[i])? 0 : marginValues[i];
		}
		var paddings = ["paddingTop","paddingBottom","paddingRight","paddingLeft"];
		var paddingValues = [];
		for(i in paddings)
		{
			paddingValues.push(parseInt($(this).css(paddings[i]),10));
			paddingValues[i] = isNaN(paddingValues[i])? 0 : paddingValues[i];
		}
				
		//Firefox for some reason reports this correctly, updates it correctly but doesnt work correctly
		//setting the same style again permits firefox to show the border without moving the content
		for(i in margins)
		{
			$(this).css(margins[i],marginValues[i]);
		}
		//$(this).css({marginTop:marginTop,marginBottom:marginBottom,marginLeft:marginLeft,marginRight,marginRight});
		$(this).hover(function(){
			//The P tag doesnt understand this properly in all browsers checked (FF3.6 and IE8)
			//*Edit left to avoid making major changes, solved by giving margins in the stylesheet
			var marginDiffTop = $(this)[0].nodeName === "P"? 0 : 0;
			var marginDiffBottom = $(this)[0].nodeName === "H2"? 0 : 0;
			var addedPadding = 4;
			var borderWidth = 1;
			var marginToSubstract = addedPadding + borderWidth*1;
			marginDiffTop = marginDiffTop + marginToSubstract;
			marginDiffBottom = marginDiffBottom + marginToSubstract;
			$(this).css("border",borderWidth + "px solid silver");
			$(this).css("backgroundColor","#F9F9F9");
			for(i in margins)
			{
				$(this).css(margins[i],marginValues[i]-marginToSubstract);
			}
			for(i in paddings)
			{
				$(this).css(paddings[i],paddingValues[i]+addedPadding);
			}
			//Allow the user to override the hover styles
			if(conf.hoverStyle)
			{
				$(this).css(conf.hoverStyle);
			}
			},function(){
				for(i in margins)
				{
					$(this).css(margins[i],marginValues[i]);
				}
				for(i in paddings)
				{
					$(this).css(paddings[i],paddingValues[i]);
				}
				$(this).css("border","");
				$(this).css("backgroundColor","");
			});
			$(this).click(function(){
			if(conf && conf.start)
			{
				this.cs = conf.start;
				this.cs();
			}
			//If no forced edit type has been given, try to determine a fitting one
			if(!conf.force)
			{
				if($(this)[0].nodeName === "P")
				{
					var editfield = $("<textarea />");
				}
				else
				{
					var editfield = $("<input type='text' />");
				}
			}
			else //A forced edit type has been given, use that
			{
				var editfield = $(conf.force);
			}
			var copystyles = ["width","height","display","marginTop","marginLeft","marginRight","marginBottom","fontFamily","fontSize","fontWeight","paddingTop","paddingBottom","paddingLeft","paddingRight","float","fontVariant","fontStyle"];
			var copiedstyles = [];
			for(i in copystyles)
			{
				copiedstyles.push($(this).css(copystyles[i]));
				if(typeof copiedstyles[i] === "number" && isNaN(copiedstyles[i]))
				{
					copiedstyles[i] = 0;
				}
			}
			//Width
			copiedstyles[0] = $(this).width();
			for(k in copiedstyles)
			{
				if(copystyles[k] === "paddingRight")
				{
					var stylename = copystyles[k];
					var stylevalue = copiedstyles[k];
					if($.browser.msie)
					{
						$(editfield).css(copystyles[k],0);
					}
					else
					{
						$(editfield).css(copystyles[k],-100);
					}
				}
				else
				{
					$(editfield).css(copystyles[k],copiedstyles[k]);
				}
			}
			$(editfield).css("borderWidth",1);
			$(editfield).css("borderStyle","solid");
			$(editfield).css("borderColor","black");
			$(editfield).css("backgroundColor","#EEEEEE");
			var oldvalue = $.trim($(this).html()).replace(/<br ?\/?>/gim,"\n");
			$(editfield).val(oldvalue);
			$(this).hide();
			$(this).before(editfield);
			var savebutton = $("<img src='/images/flueben.png' alt='Gem' title='Gem' class='inlinesave' />");
			$(this).parent().append(savebutton);
			$(savebutton).ready(function(){
				var pos = $(editfield).position();
				var top = parseInt(pos.top,10)
				var left = parseInt(pos.left,10) + parseInt($(editfield).width(),10) + 5;
				$(savebutton).css({position:"absolute",top:top,left:left,cursor:"pointer"});
			});
			$(editfield).focus();
			var orig = this;
			if($(orig).attr("id"))
			{
				
				$(editfield).keyup(function(){
					var newval = $(this).val();
					$("[rel=" + $(orig).attr('id') + "]").each(function(){
						if($(this)[0].nodeName === "IMG")
						{
							$(this).attr('title',newval);
							$(this).attr('alt',newval);
						}
						else
						{
							$(this).text(newval);
						}
						});
				});
			}
			$(editfield).keyup(function(){
				var newval = $(this).val();
				if(newval.match(/\n/g))
				{
					$(editfield).attr('rows',newval.match(/\n/g).length).css('height','');
				}
			})
			$(editfield).blur(function(){
				var newval = $(this).val();
				$(orig).html(newval.replace(/\n/gim,"<br />"));
				$(orig).show();
				$(this).remove();
				$(savebutton).remove();
				if(typeof conf == "function")
				{
					orig._edit_cb = conf;
					orig._edit_cb(newval,oldvalue);
				}
				else if(typeof conf === "object" && typeof conf.callback == "function")
				{
					orig._edit_cb = conf.callback;
					orig._edit_cb(newval,oldvalue);
				}
				$(orig).trigger('mouseout');
				});
			});
		});
		return this;
		};
})(jQuery);
