if(!window.Controller)
{
	window.Controller = {};
}

dojo.require("dojo.validate");
dojo.require("dojo.validate.web");


Controller.onLinkClick = function(e)
{
	try
	{
		Controller.dojoEvent = Object.clone(dojo.event.browser.fixEvent(e));
		
		var target = dojo.html.getEventTarget(e);
		while(target && target.tagName != "A" && target.parentNode)
		{
			target = target.parentNode; 	
		}
		
		if(!target || !target.hash)
		{
			throw "Controller.onLinkClick: not a link or no anchor";
		}
			
		var hash = target.hash.substring(1);
		arguments[0] = hash;
		Controller.executeAction.apply(this, arguments);
	}
	catch(error)
	{
		Controller.showMessage(error);
	}	
}

Controller.executeAction = function(name)
{
	var error_target;
	try
	{
		var action = this.actions[name];
		
		if(!action)
		{
			throw "Controller.onLinkClick: no action defined for anchor: " + name;	
		}

		var args = new Array();
		for(var i = 0; i < arguments.length; i++)
		{
			args.push(arguments[i]);
		}

		if(name != "authenticate" && Controller.execActionArgs == undefined)
		{
			Controller.execActionArgs = args;
		
			if(action.authenticate)
			{
				Controller.executeAction("authenticate");
				return;							
			}
		}
		
		args.shift();

		error_target = action.error_target;

		var args_conf = action.arguments;
		if(args_conf)
		{
			for(var i = 0; i < args_conf.length; i++)
			{
				args.push(dwr.util.getValue(args_conf[i]));
			}
		}
			
		var validators = action.validators;
		var error_messages = action.error_messages;
		
		if(validators)
		{
			for(var i = arguments.length - 1; i < args.length; i++)
			{
				var validator = validators[i];
				if(typeof(validator) == "function")
				{
					if(!validator.call(null, args[i]))
					{
						if(error_messages && error_messages[i])
						{
							throw error_messages[i];
						}
						
						throw "Controller.onLinkClick: no error messsage defined for anchor:" 
							+ name + ", argument:" + args_conf[i];								
					}
				}
			}
		}
		
		var validator = action.validator;
		if(typeof(validator) == "function")
		{
			validator.call(null, args);
		}
				
		if(action.type == "dwr")
		{
			var dwr_handler = action.dwr_handler;
			if(typeof(dwr_handler) != "function")
			{
				throw "Controller.onLinkClick: no dwr handler defined for anchor: " + name;					
			}

			var dwr_callback = action.dwr_callback;
			if(typeof(dwr_callback) != "function")
			{
				throw "Controller.onLinkClick: no dwr callback defined for anchor: " + name;	
			}

			args.push(function()
				{
					try
					{
						dwr_callback.apply(null, arguments);
						Controller.execActionArgs = undefined;
					}
					catch(error)
					{
						Controller.showMessage(error, error_target);
						Controller.execActionArgs = undefined;
					}
				}
			);

			dwr_handler.apply(null, args);
		}
		else if(action.type == "js")
		{
			var js_handler = action.js_handler;
			if(typeof(js_handler) != "function")
			{
				throw "Controller.onLinkClick: no js handler defined for anchor: " + name;					
			}
			
			js_handler.apply(null, args);								
			Controller.execActionArgs = undefined;
		}		
	}		
	catch(error)
	{
		Controller.execActionArgs = undefined;
		Controller.showMessage(error, error_target);		
	}
}

Controller.showMessage = function(key, target)
{
	var msg = this.messages[key];
	if(!msg)
	{
		msg = key;
	}

	if(target)
	{
		dwr.util.setValue(target, msg);			
	}
	else
	{
		alert(msg);
	}
}

function action()
{
	Controller.onLinkClick.apply(Controller, arguments);
}

function executeAction()
{
	return Controller.executeAction.apply(Controller, arguments);
}