
var editable = { };

editable.hook = function(editbox)
{
	$(".btnEdit", editbox.container).click(function() { return editable.handlers.edit(editbox, this); });
	$(".btnSave", editbox.container).click(function() { return editable.handlers.save(editbox, this); });
	$(".btnCancel", editbox.container).click(function() { return editable.handlers.cancel(editbox, this); });
	$(".btnDelete", editbox.container).click(function() { return editable.handlers.del(editbox, this); });
	$(".btnAdd", editbox.container).click(function() { return editable.handlers.add(editbox, this); });
	
	// ESC and ENTER handlers
	//$("input.edit", container).keypress( function(event) { if(event.keyCode==13) editable.handlers.save(); });
	//$("input.edit", container).keypress( function(event) { if(event.keyCode==27) editable.handlers.cancel(); });
};

editable.handlers = { };
editable.handlers.edit = function(editbox, caller)
{
	var entry = editbox.entryConstructor(caller);
	editable.actions.edit(entry, editbox.editCallback);
	return false;
};

editable.handlers.save = function(editbox, caller)
{
	var entry = editbox.entryConstructor(caller);
	editable.actions.save(entry, editbox.saveCallback);
	return false;
};

editable.handlers.cancel = function(editbox, caller)
{
	var entry = editbox.entryConstructor(caller);
	editable.actions.cancel(entry, editbox.cancelCallback);
	return false;
};

editable.handlers.del = function(editbox, caller)
{
	var entry = editbox.entryConstructor(caller);
	editable.actions.del(entry, editbox.delCallback);
	return false;
};

editable.handlers.add = function(editbox, caller)
{
	editable.actions.add(editbox.container, editbox.newEntryTemplate, editbox.appendTo, editbox.entryConstructor)
	return false;
};

editable.actions = { };
editable.actions.edit = function(entry, callback)
{
	// if there is a callback and it failed
	if(callback && !callback(entry))
	{
		return;
	}
	
	// set edit values as current display values
	var change = function()
	{
		for(var fieldName in entry.fields)
		{
			var field = entry.fields[fieldName];
			var val;
			if(field.getDisplay)
				val = field.getDisplay();
			else
				val = field.display.html();
			switch(field.type)
			{
				case "text":
				case "textarea":
					field.edit.val(val);
					break;
				case "select":
					$("option", field.edit).each(function() { $(this).removeAttr("selected"); });
					$("option:contains("+val+")", field.edit).attr("selected", true);
					break;
			}
		}
		
		// focus first text box
		$("input", entry.edits.eq(0)).focus();
		$("input", entry.edits.eq(0)).select();
	};
	
	setTimeout(change, 0);
	
	// show edits and hide displays
	entry.displays.hide();
	entry.edits.show();

	//show correct buttons
	entry.btnDelete.hide();
	entry.btnEdit.hide();
	entry.btnSave.show();
	entry.btnCancel.show();
	
	// do edit callback
	//entry.callbackEdit();
};

editable.actions.save = function(entry, callback)
{
	// if there is a callback and it failed
	if(callback && !callback(entry))
	{
		return;
	}
	
	// update displays to saved edit vals
	for(var fieldName in entry.fields)
	{
		var field = entry.fields[fieldName];
		var val;
		switch(field.type)
		{
			case "text":
			case "textarea":
				val = field.edit.val();
				break;
			case "select":
				val = $("option:selected", field.edit).html();
				break;
		}
		if(field.setDisplay)
			field.setDisplay(val);
		else
			field.display.html(document.createTextNode(val));
	}
	
	// hide edits and show displays
	entry.edits.hide();
	entry.displays.show();
	
	// tell tablesorter the table data has been changed
	//entry.table.trigger("update");
	
	//show correct buttons
	entry.btnSave.hide();
	entry.btnCancel.hide();
	entry.btnEdit.show();
	entry.btnDelete.show();
	
	// if its a new entry
	if(entry.row.hasClass("pending-new-entry"))
	{
		entry.row.removeClass("pending-new-entry");
		entry.btnDelete.show();
	}
};

editable.actions.cancel = function(entry, callback)
{
	// if there is a callback and it failed
	if(callback && !callback(entry))
	{
		return;
	}
	
	
	// if it's a new entry, remove the row
	if(entry.row.hasClass("pending-new-entry"))
	{
		entry.row.remove();
		return;
	}
	
	// hide the edits and show displays
	entry.edits.hide();
	entry.displays.show();
	
	// show correct buttons
	entry.btnSave.hide();
	entry.btnCancel.hide();
	entry.btnEdit.show();
	entry.btnDelete.show();
};

editable.actions.del = function(entry, callback)
{
	entry.row.addClass("highlighted-warning");
	if(confirm("Are you sure you want to permanently delete this entry?"))
	{
		// if there is a callback and it failed
		if(callback && !callback(entry))
			return;
			
		entry.row.fadeOut("normal", function() { entry.row.remove(); } );
		$("*", entry.row).fadeOut("normal");
	}
	else
		entry.row.removeClass("highlighted-warning");
};

editable.actions.add = function(container, newEntryTemplate, appendTo, entryConstructor)
{
	// there's already a new entry being added
	var pendings = $(".pending-new-entry", container);
	if(pendings.length > 0)
	{
		// save the pending entry
		var entry = entryConstructor(pendings.eq(0));
		editable.actions.save(entry);
		return;
	}
	
	var clonedNew = newEntryTemplate.clone(true);
	clonedNew.addClass("pending-new-entry");
	appendTo.prepend(clonedNew);
	
	var entry = entryConstructor(clonedNew);
	
	// show edits and hide displays
	entry.displays.hide();
	entry.edits.show();

	//show correct buttons
	entry.btnEdit.hide();
	entry.btnSave.show();
	entry.btnCancel.show();
	entry.btnDelete.hide();

	clonedNew.show();
	
	// focus first text box
	$("input", entry.edits.eq(0)).focus();
};
