function makeEditable(id, plugin, emptyValue, params){
    $(id).emptyValue = emptyValue;
	Event.observe(id, 'click', function(){edit($(id), plugin, params)}, false);
	Event.observe(id, 'mouseover', function(){showAsEditable($(id))}, false);
	Event.observe(id, 'mouseout', function(){showAsEditable($(id), true)}, false);
}

function edit(obj, plugin, params){
	Element.hide(obj);

	var inPlaceElements = plugin(obj, params);
	var inplaceHtml = '';
	for (var i = 1; i < inPlaceElements.length; i++) {
	    inplaceHtml += inPlaceElements[i];
	}

	new Insertion.After(obj, inplaceHtml);
	$(obj.id + '_edit').focus();

	Event.observe(obj.id+'_save', 'click', function(){saveChanges(obj, inPlaceElements[0])}, false);
	Event.observe(obj.id+'_cancel', 'click', function(){cleanUp(obj)}, false);

}

function showAsEditable(obj, clear){
	if (!clear){
		Element.addClassName(obj, 'editable');
	}else{
		Element.removeClassName(obj, 'editable');
	}
}

function saveChanges(obj, targetUrl){

	var new_content	=  encodeURI($F(obj.id+'_edit'));

	obj.innerHTML	= "Saving...";
	cleanUp(obj, true);

	var success	= function(t){editComplete(t, obj);}
	var failure	= function(t){editFailed(t, obj);}
  	var url = targetUrl;
	var pars = 'id='+obj.id+'&content='+new_content;

	var myAjax = new Ajax.Request(url, {method:'post', postBody:pars, onSuccess:success, onFailure:failure});
}

function cleanUp(obj, keepEditable){
	Element.remove(obj.id+'_editor');
	Element.show(obj);
	if (!keepEditable) showAsEditable(obj, true);
}

function editComplete(t, obj){
	obj.innerHTML	= trim(t.responseText)

	if (obj.innerHTML == ""){
	    obj.innerHTML = obj.emptyValue;
		Element.addClassName(obj, 'emptyvalue');
	}else{
		Element.removeClassName(obj, 'emptyvalue');
	}

	showAsEditable(obj, true);
}

function editFailed(t, obj){
	obj.innerHTML	= 'Sorry, the update failed.';
	cleanUp(obj);
}

function trim(str) {
	return str.replace(/^\s+/, '').replace (/\s+$/, '');
}