
var editable = { };

editable.hook = function(editbox)
{
	if(editbox.entryConstructor == null)
	{
		editbox.entryConstructor = function(element)
		{
			entry = { };
			entry.container = editbox.container;
			entry.row = editbox.container;
			
			// fields
			entry.fields = { };
			$(":input", entry.row).each(function()
			{
				el = $(this);
				var type;
				if(this.tagName == "INPUT")
				{
					if(el.attr("type") == "hidden")
						return;
					type = el.attr("type");
				}
				else if(this.tagName == "SELECT")
					type = "select";
				else if(this.tagName == "TEXTAREA")
					type = "textarea";
				
				var name = el.attr("name");
				entry.fields[name] = { };
				entry.fields[name].type = type;
				entry.fields[name].edit = el;
				entry.fields[name].display = $(".display-" + name, entry.row);
				if(type == "select")
				{
					entry.fields[name].setDisplay = function(val)
					{
						var text = $("option[value="+val+"]", entry.fields[name].edit).html()
						entry.fields[name].display.html(text);
					};
				}
			});
			
			// ajax loader icon
			entry.ajaxLoader = $(".ajax-loader", entry.row);
			
			// collections
			entry.edits = $(".edit", entry.row);
			entry.displays = $(".display", entry.row);
			
			// buttons
			entry.buttons = $(".buttons", entry.row);
			entry.btnSave = $(".btnSave", entry.row);
			entry.btnCancel = $(".btnCancel", entry.row);
			entry.btnEdit = $(".btnEdit", entry.row);
			entry.btnDelete = $(".btnDelete", entry.row);
			
			return entry;
		};
	}
	$(".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);
	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);
	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)
{
	// set edit values as current display values
	var change = function()
	{
		for(var fieldName in entry.fields)
		{
			var field = entry.fields[fieldName];
			if(field.edit.length == 0)
				continue;
			var val;
			if(field.getDisplay)
				val = field.getDisplay();
			else
				val = field.display.text();
			switch(field.type)
			{
				case "file":
					break;
				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
	for(i in entry.fields)
	{
		// only hide the display if there is an edit
		if(entry.fields[i].edit.length > 0)
		{
			entry.fields[i].display.hide();
		}
	}
	entry.edits.show();

	//show correct buttons
	entry.btnEdit.hide();
	entry.btnSave.show();
	entry.btnCancel.show();
};

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 "file":
			case "text":
			case "textarea":
				val = field.edit.val();
				break;
			case "select":
				val = field.edit.val();
				break;
		}
		if(field.setDisplay)
			field.setDisplay(val);
		else
			field.display.text(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();
	
	// 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)
{
	// 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();
};

editable.actions.del = function(entry, callback)
{
	entry.row.addClass("highlighted-error");
	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-error");
};

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.attr("class", "pending-new-entry");
	appendTo.append(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();
};

editable.helpers = { };