Controller = function() { };

// Sets the number of attempts on Ajax Request failure
Controller.maxAttempts = 3;
// Current number of attempts
//Controller.attempts = 0;

//Número máximo de requisições simultâneas.
Controller.maxRequests = 7;

Controller.requests = new Array(Controller.maxRequests);
Controller.treeRequestObject = null;
Controller.actions = new Array(Controller.maxRequests);
Controller.attempts = new Array(Controller.maxRequests);
//Controller.timeouts = new Array(Controller.maxRequests);

/*Controller.nextAction = null;
Controller.nextOptions = null;*/

// Controle de carregamneto do "Carregando..."
Controller.scrollX, scrollY = -1;
Controller.waitElement;

Controller.getLoading = function()
{
	var ret = null;
	if (document.getElementById('loading_content'))
	{
		ret = document.getElementById('loading_content');
	}
	else
	{
//		var el = new Element('div');
//		el.id = 'loading';
//		el.setHTML('loading...');
//		el.injectBefore(document.body);
//		ret = $('loading');
	} 
	
	return ret;
}

Controller.showLoading = function() {	
	Controller.waitElement = Controller.getLoading()

	Controller.waitElement.style.display = 'block';

	window.addEvent('scroll', function() {
		var scrollYT;
		var scrollXT;
		
		if (typeof(window.pageYOffset) == "number") { 
			scrollYT = window.pageYOffset; 
			scrollXT = window.pageXOffset; 
		} 
		else if (document.body && document.documentElement && document.documentElement.scrollTop) { 
			scrollYT = document.documentElement.scrollTop; 
			scrollXT = document.body.scrollLeft;
		}
		else if (document.body && typeof(document.body.scrollTop) == "number") { 
			scrollYT = document.body.scrollTop; 
			scrollXT = document.body.scrollLeft; 
		}
		if (Controller.scrollX != scrollXT || Controller.scrollY != scrollYT) {
			Controller.scrollX = scrollXT;
			Controller.scrollY = scrollYT;
			var width = document.body.clientWidth;
			Controller.waitElement.style.top = scrollYT + 100 + "px";
			Controller.waitElement.style.right = scrollXT +  "px";
			//alert(window.$events);
		}
	});
}

Controller.hideLoading = function() {
	Controller.waitElement = Controller.getLoading();
	
	var i;
	var cont = true;
	for(i=0; i < Controller.requests.length; i++)
	{
		if(Controller.requests[i]
		&& Controller.requests[i].running)
		{
			cont = false;
		}
	}
	
	/*if (cont)
	{
		if (nextAction)
		{
			new Feature(nextAction, nextOptions);
		}
	}*/
	
	if (cont)
	{
		//Controller.waitElement.style.display = 'none';
		window.removeEvents('scroll');
	}
}

//Controle de cache - declaração
Controller.cache = [];

/*
Função para receber uma série de ações(inserir, editar, listar, excluir...) 
para inicializar as requisições AJAX, através do caminho atribuído pela variável "file". 

---Exemplo de como utilizar a feature:----

	>var action1 = {
	>	action: "section.insert.php",	//exemplo de action (o controlador interpreta em um arquivo) 
	>	parameters: {
	>		arg: '',					//parâmtros
	>		arg2: ''
	>	},
	>	form: "form0",					//formulário enviando junto com os parâmetros
	>	onComplete: function(request)	//request é o conteúdo retornado pela requisição
	>	{
	>		$('content').setHTML(request);
	>	}
	>}
	>
	>var action2 = {
	>	action: "section.remove.php", 
	>	onComplete: function(response)	//response é o conteúdo retornado pela requisição
	>	{
	>		$('content').setHTML(request);
	>	},
	>	onFailure: function()			//função personalizada para erro numa requisição
	>	{
	>		$('content').setHTML('Ocorreu um erro');
	>	}
	>}
	>
	>var action3 = {
	>	action: "section.update.php",
	>	form: $("form1")
	>}
	>
	>new Feature([action1, action2]);//executa as ações passadas PARALELAMENTE
	>
	
---Exemplo de utilização do Feature com opções:----

	>var action = {
	>	action: "updateTree.php"
	>};
	>
	>new Feature(action, {
	>	'treeUpdate' : 1,
	>	'notShowLoading' : 1
	>});	//executa a(s) ações levando em consideração as opções
	
	
	Obs: só é possível criar 1 (UM) Feature por chamada a função, pois cada chamada cancela
		todas as requisições anteriores ainda não concluídas.
	
	Options:
		--> isTreeRequest - parâmetro que não cancela as requisições anteriores (usado na atualização
		da árvore de caminho do menu)
		--> notShowLoading - parâmetro que informa ao Controller para não mostrar o loading no meio da tela
		--> isLogged - parâmetro que força as requisições a serem feitas apenas se o usuário estiver logado no sistema
		--> ignoreRequests - parâmetro para que esta requisição ignore quaisquer requisições em
		andamento e também não possa ser cancelada. Essa opção ativa automaticamente notShowLoading.
		
--- Fim exemplo ---	
	
*/
Controller.Feature = new Class(
	{
		//initialize: function(actions, isTreeRequest, notShowLoading, synchronous)
		initialize: function(actions, options)
		{
			//Opções da execução
			var isTreeRequest = false;
			var notShowLoading = true;
			var checkIsLogged = false;
			var ignoreRequests = false;
			var chain = false;
			
			if (options)
			{
				if (options.treeRequest
				&& options.treeRequest == 1)
				{
					isTreeRequest = true;
					notShowLoading = true;
				}
				if (options.notShowLoading
				&& options.notShowLoading == 1)
				{
					notShowLoading = true;
				}
				
				if (options.isLogged
				&& options.isLogged == 1)
				{
					checkIsLogged = true;
				}
				
				if (options.ignoreRequests
				&& options.ignoreRequests == 1)
				{
					ignoreRequests = true;
					notShowLoading = true;
				}
				
				/*if (options.chain
				&& options.chain == 1)
				{
					chain = true;
				}*/
			}
		
			//Checagem que permite a passagem de apenas um objeto (sem precisar ser um array)
			if (!actions.length)
				actions = [actions];
			
			for (i in actions)
			{
				if (typeof(actions[i]) == 'object')
				{
					if (typeof(actions[i].controllerId) == 'undefined'
					&& actions[i].action != null)
					{
						actions[i].controllerId = actions[i].action;
						Controller.actions[actions[i].controllerId] = actions[i];
						Controller.attempts[actions[i].controllerId] = 0;
					}
				}
			}
		
			//
			/*if (chain)
			{
				var newActions = new Array();
				var len = actions.length;
				for (i = 0; i < len - 1; i++)
				{
					newActions[i] = actions.pop();//actions[i];
					//delete actions[i];
				}
				newActions.reverse();
				if (newActions.length > 0)
				{
					Controller.nextAction = newActions;
					Controller.nextOptions = options;
				} else
				{
					Controller.nextAction = null;
					Controller.nextOptions = null;
				}
			} else
			{
				Controller.nextAction = null;
				Controller.nextOption = null;
			}*/
			
			//Conjtrole de carregamento do "Loading..."
			
			if (!notShowLoading) {
				Controller.showLoading();
			}
			
			var requestsCount = 0;
			var completedRequests = 0;
			
			this.addEvent('endRequest', function()
			{
				completedRequests++;
				if (completedRequests >= requestsCount) {
					//if (!notShowLoading) {
						Controller.hideLoading();
					//}	
				}
			});
			
			for (i = 0; i < actions.length; i++)
				if (actions[i].action != null)
					requestsCount++;
			//Fim do controle de carregamento.
			
			//Controle de requisições Ajax					
			
			//cacelamento de requisições pendentes.
			//exceção para o caso de ser uma requisição da árvore de uma subseção
			if (isTreeRequest) {
				if (Controller.treeRequestObject)
					Controller.treeRequestObject.cancel();
			} else if (!ignoreRequests) {
				for(i=0; i < Controller.requests.length; i++) {
					if(Controller.requests[i]) {
						Controller.requests[i].cancel();
					}
				}
			}
			//Fim do cancelamento de requisições pendentes.
			
			if (checkIsLogged)
			{
				var _actions = actions;
				var _options = options;
				var _index = indexURL;
				var checkAndExec = {
					action		:	"ajaxRequests/checkLoggedIn.php",
					onComplete	:	function(response)
									{
										if (response == 1) {
											var newOptions = { };
											for (i in _options)
											{
												if (i != 'isLogged')
												{
													eval("newOptions." + i + " = " + _options[i] + ";");
												}
											}
											
											new Feature(_actions, newOptions); 
										} else
										{
											document.location = _index;
										}
									}
				};
				
				new Feature(checkAndExec);
			} else
			{
				for (i = 0; i < actions.length; i++)
				{
					var action = actions[i].action;
					var parameters = actions[i].parameters;
					var form = actions[i].form;
					//Controle de cache: carregando variáveis da ação
					var cacheable = actions[i].cacheable;
					var overwriteCache = actions[i].overwriteCache;

					if (action != null)
					{
						if(action != "")
						{
							var _method = 'GET';
							var _body = "";
							if (form != null)
							{
								_method = 'POST'
								_body = $(form).toQueryStringABA(); 
							}
							if (parameters != null)
							{
								_method = 'POST'
								if (_body != '')
									_body += '&';
								_body += Object.toQueryStringABA(parameters);
							}
							
							var onCompleteFunction = actions[i].onComplete;
							var onFailureFunction = actions[i].onFailure;
							var controllerId = actions[i].controllerId;
							var obj = this;
							
							var _options = options;
							
							if (_options)
							{
								_options.ignoreRequests = '1';
							}
							
							//Controle de cache: verifica se a requisição precisa ser feita
							var makeAjax = 1;
							
							//Controle de cache: verifica se o resultado está na cache
							if (cacheable && Controller.cache[action])
							{
								if (Controller.cache[action][_body])
								{
									this_cache = Controller.cache[action][_body]
									if (this_cache.onCompleteFunction)
									{
										this_cache.onCompleteFunction(this_cache.response);
									}
									//if (!notShowLoading)
									{
										obj.fireEvent('endRequest');
									}
									
									makeAjax = 0;
								}
							}
							
							if (makeAjax == 1)
							{
								var tmp = new Ajax(action,
								{
									postBody			:	_body,
									method				:	_method,
									onCompleteFunction	:	onCompleteFunction,
									onFailureFunction	:	onFailureFunction,
									controllerId		:	controllerId,
									onComplete			:	function(response)
															{
																//console.warn('Request %s completed', this.url);
																if (cacheable || overwriteCache)
																{
																	if (!Controller.cache[action])
																		Controller.cache[action] = [];
																	Controller.cache[action][_body] = {
																		'onCompleteFunction': onCompleteFunction,
																		'response': response
																	};
																}
																
																if (this.options.onCompleteFunction)
																{
																	this.options.onCompleteFunction(response);
																}
																/*if (Controller.nextAction != null)
																{
																	new Feature(Controller.nextAction, Controller.nextOptions);
																}*/
																
																//if (!notShowLoading)
																{
																	obj.fireEvent('endRequest');
																}
																
																Controller.actions[this.options.controllerId] = null;
															},
									onFailure			:	function() 
															{
																//console.error('Request %s (index %s) failed (attempt %s)', this.url, this.options.controllerId, Controller.attempts[this.options.controllerId]);
																if (Controller.attempts[this.options.controllerId]++ < Controller.maxAttempts)
																{
																	//feature(action, parameters);
																	new Feature(Controller.actions[this.options.controllerId], _options);
																} 
																else 
																{
																	//if (!notShowLoading)
																	{
																		obj.fireEvent('endRequest');
																	}
																	if (this.options.onFailureFunction)
																	{
																		this.options.onFailureFunction();
																		if (Controller.nextAction != null)
																		{
																			new Feature(Controller.nextAction, Controller.nextOptions);
																		}
																	} else
																	{
																		/*if (Controller.nextAction != null)
																		{
																			new Feature(Controller.nextAction, Controller.nextOptions);
																		}*/
																		alert("Ocorreu um erro durante a execução");
																	}
																	//Controller.attempts = 0;
																	//window.location.reload();
																}
															}
								}).request();
								//exceção para o caso de ser uma requisição da árvore de uma subseção
								if (isTreeRequest)
									treeRequestObject = tmp;
								else if (!ignoreRequests)
									Controller.requests[i] = tmp;
							}
						}
						else 
						{
							alert("Erro ao acessar a página");
							//window.location.reload();
						}
						
					}
				}
				//Fim do controle de requisições Ajax.
			}
		}
	});
	Controller.Feature.implement(new Events);




/*function feature(action, parameters) {
	var file = null;

	// Switch Casa
	switch(action) {
		// Section Objects
		case 'section.insert': {
			file = "Portal/AjaxRequest/insertSection.php";
			break;
		}
		
		case 'intercambio.insertNews': {
			file = "Intercambio/AjaxRequest/inserNews.php";
			break;
		}
		
		case 'teste.insert':{
		
			file = "teste.insert.php";
			break;
		}
		

	}
	// END Switch Case
	
	if (file != null) {
		// Start loading image
		//document.getElementById('loading_absol').style.display = "block";
		if (parameters != '') {
			var metodo = 'post';
		} else {
			var metodo = 'get';
		}
	
		var test = new Ajax(file, {
			method: metodo,
			postBody: Object.toQueryString(parameters),
			onFailure: function() {
				if (attempts++ < maxAttempts) {
					feature(action, parameters);
				} else {
					alert("Ocorreu um erro durante a execução");
					window.refresh();
				}
			},
			onComplete: function(request){
				attempts = 0;
				return request;				
			}
		}).request();
	} else {
		alert("Ocorreu um erro durante a execução");
		window.refresh();
	}
}*/

var Feature = Controller.Feature

function checkRadio(obj)
{
	var elements = document.getElementsByName(obj.name);
	for(i in elements)
		if (elements[i])
			if (elements[i].checked)
				elements[i].checked = 'false';
	
	obj.checked = 'true';
}

