var _ActualRequest = null;

/**
Loads html content into a modal div (must receive a ZaveeAjaxPageContent to work)
url 		= The default URL to be used for requests to the server
config		= Identical to loadAjaxPage, except navigation is disabled
there are some extra params:
	- width: defines width for the modal
	- buttons: define a set of buttons for the modal (ej, [{text: 'OK', color: 'green(default)/red', action: FunctionPointer, closeAfterAction: true(default)/false, actionParams: [param, param2,..], type: 'cancel/normal(default)', width: 84(default)},..])
	- buttonsAlignment: defines position for buttons (default is right)
*/
function loadAjaxPageModal(url, config)
{
	if (typeof(config) == 'undefined')
	{
		config = {};
	}
	
	if (typeof(config.buttons) == 'undefined')
	{
		config.buttons = [];
	}
	
	if (typeof(config.width) == 'undefined')
	{
		config.width = undefined;
	}
	
	if (typeof(config.buttonsAlignment) == 'undefined')
	{
		config.buttonsAlignment = 'right';
	}
	
	if (typeof(config.title) == 'undefined')
	{
		config.title = '';
	}
	
	if (typeof(config.centerAfterRender) == 'undefined')
	{
		config.centerAfterRender = false;
	}
	
	if (typeof(config.closeCross) == 'undefined')
	{
		config.closeCross = true;
	}
	
	if (typeof(config.closeCrossCallback) == 'undefined')
	{
		config.closeCrossCallback = null;
	}
	
	if (config.ajaxParams == undefined)
	{
		config.ajaxParams = {};
	}
	
	var modalDiv = new ModalDiv(config.width, config.backgroundOnClick);
	
	modalDiv.AddButtons(config.buttons);
	modalDiv.SetButtonsAlign(config.buttonsAlignment);
	modalDiv.SetTitle(config.title);
	modalDiv.SetCenterAfterRender(config.centerAfterRender);
	modalDiv.SetCloseCross(config.closeCross, config.closeCrossCallback);
	
	if (typeof(config.onCompleteFn) == 'function')
	{
		var originalOnCompleteFn = config.onCompleteFn;
		
		config.onCompleteFn = function()
		{
			originalOnCompleteFn.apply();
			modalDiv.RenderContent();
		}
	}
	else
	{
		config.onCompleteFn = function () { modalDiv.RenderContent(); };
	}
	
	config.navigation 	= false;
	config.modalDiv		= modalDiv;
	
	loadAjaxPage(url, modalDiv.GetContentId(), config);
	
	return modalDiv;
}

/**
Carga contenido html en un elemento usando ajax (debe recibir un EYEPageContent para funcionar)

url 		= La url para hacer el pedido al servidor
elementId 	= Id del elemento donde se va a cargar el html
config		= Identico al de la funcion ajax, exepto que callbackParams esta deshabilitado	
hay algunos parametros extra de config:
	- navigation: boolean, si esta en true la pagina sera guardada en el historial de navegacion del navegador, notar que usando navigation se forzara que los parametros al ajax le lleguen por GET
	- onCompleteFn: function que sera llamada despues de que el contenido se cargue en el elemento. Si navigation ssta en true, es necesario que onCompleteFn sea el nombre de una funcion y no un puntero a la misma
	- onBeforeFn: funcion que sea llamada antes de que el contenido sea cargado en la pagina
	- overwriteHTML: booleano, si esta en true reescribe todo el contenido del elemento, por defualt esta en true (no funciona con navigation)
	- scope: scope para onComplete y onBefore
*/

_pendingOnCompleteFn 		= '';
_pendingOnCompleteFnScope 	= '';

function loadAjaxPage(url, elementId, config)
{	
	if (config == undefined)
	{
		config = {};
	}

	if (config.killModal == undefined)
	{
		config.killModal = true;
	}

	if (config.overwriteHTML == undefined)
	{
		config.overwriteHTML = true;
	}
	
	if (config.onBeforeFn != undefined)
	{
		if (config.scope == undefined)
		{
			scope = this;
		}
		else
		{
			scope = config.scope;
		}
		
		config.onBeforeFn.apply(scope);
	}
	
	if (config.navigation == true)
	{
		if (config.killModal)
		{
			KillModalDiv();
		}
		
		config.method = 'get';
		
		if (config.onCompleteFn != undefined)
		{
			if (config.scope == undefined)
			{
				scope = this;
			}
			else
			{
				scope = config.scope;
			}
			
			if (typeof(config.onCompleteFn) != 'string')
			{
				alert('ERROR: Usar navegacion requiere que no escribas una funcion asi: "function(){..}", sino que solo escribas el nombre de la funcion en un string');
				return;
			}
		}
		
		AddHistory(url, elementId, config.ajaxParams, config.onCompleteFn);
	}
	else
	{
		if (config.ajaxParams == undefined)
		{
			config.ajaxParams = {};
		}
		
		if (typeof(config.modalDiv) != 'undefined')
		{
			var mDiv = config.modalDiv;
		}
		else
		{
			var mDiv = undefined;
		}
		
		config.callbackParams 				= [elementId, config.onCompleteFn, config.scope, mDiv, config.overwriteHTML];
		config.scope 						= this;
		config.ajaxParams['esPedidoAjax']	= true;
		
		ShowLoading();
		
		ajax(url, receiveLoadAjaxPage, config);
	}
}

/**
Llama a un metodo estatico (service) en PHP que devuelve un json.

- staticMethod: el nombre del metodo estatico (ServiceTest::MiFunction)
- staticMethodParams: array de parametros que le tienen que llegar al method ['foo', 2, 'test']
- callback: funcion que sera llamada luego de recibir los datos del metodo estatico
- config: identico al de ajax
*/
function callPHPMethod(staticMethod, staticMethodParams, callback, config)
{
	if (typeof(config) == 'undefined')
	{
		config = {};
	}
	
	if (typeof(config.ajaxParams) == 'undefined')
	{
		config.ajaxParams = {};
	}
	
	if (typeof(config.callbackParams) == 'undefined')
	{
		var callbackParams = [];
	}
	else
	{
		var callbackParams = config.callbackParams;
	}
	
	config.callbackParams = [];
	
	if (typeof(config.scope) == 'undefined')
	{
		var scope = this;
	}
	else
	{
		var scope = config.scope;
	}
	
	config.scope = this;
	
	config.ajaxParams['method'] 	= staticMethod;
	config.ajaxParams['params'] 	= Ext.util.JSON.encode(staticMethodParams);
	config.method 					= 'post';
	
	config.callbackParams.unshift(callbackParams);
	config.callbackParams.unshift(scope);
	config.callbackParams.unshift(callback);
	
	var url = '/pedidosajax/callphpmethod.php';
	
	ajax(url, receivecallPHPMethod, config);
}

function receivecallPHPMethod(o, callback, scope, callbackParams)
{
	var json = eval('(' + o + ')');
	
	callbackParams.unshift(json);
	
	callback.apply(scope, callbackParams);
}

/**
Hace un pedido ajax

parametros:
	- url = la url a la que se le hara el pedido
	- callback = la funcion que sera llamada luego del pedido ajax
	- config: -- config es un objeto que contiene parametros opcionales
		- callbackParams = parametros que seran enviados a la funcion de callback (ej, [var1, var2, var3])
		- ajaxParams = parametros que seran enviados en el pedido ajax (ej, {foo: 'var', foo2: 'var2'})
		- method = el metodo HTTP por el cual sera hecho el pedido (por defecto es GET)
		- xml = buleano, si es true al callback se le enviara el objeto responseXML, si es false, se le enviara responseText
		- scope = el scope para el callback
		- form = id de un formulario, si se envia entonces todo el formulario sera enviado por ajax
		- isUpload = buleano, si es true se sabra que el formulario (enviado en form) sube archivos

ejemplos:
	simple:
		ajax('/test.php', ajaxTestCallback);

	complejo:
		ajax('/test.php', ajaxTestCallback, {callbackParams: ["param1", [1,2,3]], ajaxParams: {foo: 'var'}, method: 'POST', xml: true, scope: this, form: 'formId'});
*/
function ajax(url, callback, config)
{
	if (typeof(url) == 'undefined')
	{
		throw "url no esta definido";
	}
	
	if (typeof(callback) == 'undefined')
	{
		throw "callback no esta definido";
	}
	
	if (typeof(config) == 'undefined')
	{
		config = {};
	}
	
	if (typeof(config.ajaxParams) == 'undefined')
	{
		config.ajaxParams = {};
	}
	
	if (typeof(config.xml) == 'undefined')
	{
		config.xml = false;
	}
	
	config.ajaxParams['esPedidoAjax'] = true;

	_ActualRequest = Ext.Ajax.request(
		{
			url: url,
			success: function (o) {
				succesAjaxRequest(o, config.xml, callback, config.callbackParams, config.scope);
				_ActualRequest = null;
				
				if (_BtnFinEjecutar != null)
				{
					_BtnFinEjecutar.apply(this);
				}
			},
			failure: failAjaxRequest,
			params: config.ajaxParams,
			method: (config.method == undefined) ? 'GET' : config.method.toUpperCase(),
			form: config.form,
			isUpload: config.isUpload
		}
	);
}

function AbortActualAjaxRequest()
{
	if (_ActualRequest != null)
	{
		Ext.Ajax.abort(_ActualRequest.tId);
		
		_ActualRequest = null;
	}
}

function receiveLoadAjaxPage(json, elementId, onCompleteFn, scope, mDiv, overwriteHTML)
{
	var json = eval('(' + json + ')');
	
	if ((typeof(json.reDoModalDivButtons) != 'undefined') && (typeof(mDiv) == 'object'))
	{
		mDiv.RemoveButtons();
		
		if (json.reDoModalDivButtons.length > 0)
		{
			mDiv.AddButtons(json.reDoModalDivButtons);
		}
	}
	
	if ((typeof(json.overridePage) != 'undefined'))
	{
		location.href = json.overridePage;
		return;
	}
	
	if (typeof(json.forceDataCompletion) == 'boolean')
	{
		if (json.forceDataCompletion)
		{
			LoadDataCompletionPopUp();
		}
	}

	if (typeof(json.pageTitle) == 'string')
	{
		if (json.pageTitle != '')
		{
			document.title = json.pageTitle;
		}
	}
	
	var targetElement = document.getElementById(elementId);
	
	if (targetElement == null)
	{
		throw 'El elemento (targetElement) no existe';
	}
	
	if (typeof(targetElement) != 'undefined')
	{
		if (overwriteHTML == true)
		{
			targetElement.innerHTML = json.html;
		}
		else
		{
			targetElement.innerHTML += json.html;
		}
		
		if (json.jslibraries.length > 0)
		{
			var _libsToLoad = json.jslibraries.length;
			
			for (i = 0; i < json.jslibraries.length; i++)
			{
				AddScript(json.jslibraries[i].lib, json.jslibraries[i].force, function()
				{
					_libsToLoad--;
					
					if (_libsToLoad == 0)
					{
						if (onCompleteFn != undefined)
						{
							if (scope == undefined)
							{
								scope = this;
							}
							
							if (typeof(onCompleteFn) != 'string')
							{
								onCompleteFn.apply(scope);
							}
							else
							{
								eval(onCompleteFn + '();');
							}
						}
						
						eval(json.jsToExcecute);
					}
				});
			}
		}
		else
		{
			if (onCompleteFn != undefined)
			{
				if (scope == undefined)
				{
					scope = this;
				}
				
				if (typeof(onCompleteFn) != 'string')
				{
					onCompleteFn.apply(scope);
				}
				else
				{
					eval(onCompleteFn + '();');
				}
			}
			
			eval(json.jsToExcecute);
		}
		
		for (i = 0; i < json.stylesheets.length; i++)
		{
			AddStyleSheet(json.stylesheets[i]);
		}
	}
	else
	{
		ForceCompleteHistoryLoad();
	}
	
	if (typeof(json.mostrarBuscador) != 'undefined')
	{
		
		if (json.mostrarBuscador === true)
		{
			MostrarBuscadorGeneral();
		}
		else if (json.mostrarBuscador === false)
		{
			OcultarBuscadorGeneral();
		}
	}
	
	if (typeof(json.mostrarSubBotonera) != 'undefined')
	{
		if (json.mostrarSubBotonera === true)
		{
			MostrarSubBotoneraHeader();
		}
		else if (json.mostrarSubBotonera === false)
		{
			OcultarSubBotoneraHeader();
		}
	}
	
	if (typeof(json.botoneraSeleccionado) != 'undefined' && json.botoneraSeleccionado !== null)
	{
		SeleccionarItemMenuHeader(json.botoneraSeleccionado);
	}
	
	if (typeof(json.subBotoneraSeleccionado) != 'undefined' && json.subBotoneraSeleccionado !== null)
	{
		SeleccionarItemSubMenuHeader(json.subBotoneraSeleccionado);
	}
	
	if (typeof(json.ocultarMigajas) != 'undefined' && json.ocultarMigajas !== null && json.ocultarMigajas == true)
	{
		OcultarCajaMigajas();
	}
	
	if (typeof(json.migajas) != 'undefined' && json.migajas.length > 0)
	{
		BorrarMigajas();
		
		for (var i = 0; i < json.migajas.length; i++)
		{
			AgregarMigaja(json.migajas[i].texto, json.migajas[i].link);
		}
	}
	
	HideLoading();
	
	// funcion definida en general.js
	// transforma todos los <SELECT> en EXT Combo Box
	setTimeout(transformExtComboBoxes, 700);
}

function succesAjaxRequest(o, xml, callback, callbackParams, scope)
{
	if (xml == true)
	{
		var content = o.responseXML;
	}
	else
	{
		var content = o.responseText;
	}

	//reviso si hay que redirigir
	if (xml == false)
	{
		var json = eval('(' + content + ')');
	
		if ((typeof(json.overridePage) != 'undefined'))
		{
			location.href = json.overridePage;
			return;
		}
	}
	
	if (scope == undefined)
	{
		scope = this;
	}
	
	if (callbackParams == undefined)
	{
		callbackParams = [];
	}
	
	callbackParams.unshift(content);

	callback.apply(scope, callbackParams);
}

function failAjaxRequest()
{
	_ActualRequest = null;
	
	throw "ajax load error";
}
