//--- Global constants
var ajaxActive = true;

var imgAElementToPopulate = null;	//used for ajax load related
var selectAElementToPopulate = null;//used for ajax load template search sections

var ajaxTimeout1 = null; //timeout function 1
var ajaxTimeout2 = null; //timeout function 2
var ajaxTimeout3 = null; //timeout function 3

var AjAX_POOL = null;	//Object that represents a pool of ajax call
var AJAX_PANEL = null;	//Object with visual functions for ajax result controll

/** Constants types **/
var LOAD_TEXT		= "text";
var LOAD_FORM		= "form";
var LOAD_TABLE		= "table";
var LOAD_FUNCTION	= "function";

/** Definición de objetos **/
/**
 * AjaxCaller contains all the information for makeing an ajax call and sending the 
 * result to the corresponding handler.
 * 
 * @param method		The method to use: GET or POST
 * @param url			The url to call
 * @param toSend		The parameters names and values to send
 * @param xmlHandler	The function to call when the xml information is recived (recives as parameter the xml response)
 * @param doAsync		Indicates if the call must be syncronic or asyncronic (default value es true)
 * @param showLoading	Indicates if the call must show the loading/wait message (default value es true)
 */
function AjaxCaller(method, url, toSend, aProcessXmlHandler, doAsync, showLoading, aBeforeXmlHandler) {
	this.method				= method;
	this.url				= url;
	this.toSend				= toSend;
	this.aProcessXmlHandler	= aProcessXmlHandler;
	this.aBeforeXmlHandler	= aBeforeXmlHandler;
	
	this.doAsync 			= (doAsync == null) ? true : toBoolean(doAsync);
	this.showLoading		= (showLoading == null) ? true : toBoolean(showLoading);
	
	function functionDoCall() {
		var req = null;
		var isActiveX = false;
		if (window.XMLHttpRequest) {
			// browser has native support for XMLHttpRequest object
			req = new XMLHttpRequest();
		} else if (window.ActiveXObject) {
			// try XMLHTTP ActiveX (Internet Explorer) version

			try {
				req = new ActiveXObject("Msxml2.XMLHTTP");
			} catch (e1) {
				try {
					req = new ActiveXObject("Microsoft.XMLHTTP");
				} catch (e2) {
					req = null;
				}
			}

			//req = new ActiveXObject("Microsoft.XMLHTTP");
			isActiveX = true;
		}
		
		if(req) {
			if (this.doAsync || isActiveX || IS_MSIE7 || IS_MSIE8) {
				req.onreadystatechange = function () {
					if (req != null) {
						if (req.readyState == 4) {
							// Make sure the status is "OK"
							try {
								if (req.status == 200) {
									var xml = req.responseXML;
									if (aBeforeXmlHandler != null) aBeforeXmlHandler();
									if (aProcessXmlHandler != null) aProcessXmlHandler(xml);
									req = null;
									delete req;
									if (IS_MSIE) {
										setTimeout("ajaxPoolProcessNext()",100);
									} else {
										AjAX_POOL.processNext(null);
									}
								} else if (req.status == 0) {
									//do nothing the connection was close
									//document.title = document.title.substring(document.title.indexOf("]") + 2);
								} else {
									alert(LBL_ERR_LOADING);
									AJAX_POOL.processNext(null);
								}
							} catch (e) {
								showAjaxComunicationError();
							}
						}
					} else {
						alert('Your browser or configuration does not allow ajax. Ajax is required.');
					}
				};
			} else {
				req.onload = function() {
					var xml = req.responseXML;
					if (aBeforeXmlHandler != null) aBeforeXmlHandler(xml);
					if (aProcessXmlHandler != null) aProcessXmlHandler(xml);
					delete req;
					AjAX_POOL.processNext(null);
				}
			}
			
			if (IS_MSIE) {
				var extraUrl = (this.url.indexOf("?") == -1) ? "?" : "&";
				extraUrl += "_ieTime=" + (new Date()).getTime();
				this.url += extraUrl;
			}
			
			req.open(this.method, this.url, this.doAsync);
			req.setRequestHeader("content-type","application/x-www-form-urlencoded; charset=utf-8");
			req.send(this.toSend);
		} else {
			alert('Your browser does not seem to support XMLHttpRequest.');
		}
	}
	
	this.doCall = functionDoCall;
}

function ajaxPoolProcessNext() {
	AjAX_POOL.processNext(null);
}

function AjaxPanel() {
	this.panel			= new Array();
	this.wait			= new Array();
	
	this.showingLoading = false;
	
	function fncHasActive() {
		return this.panel.length > 0;
	}
	
	function fncGetActive() {
		if (this.panel.length == 0) this.newPanel();
		changeFlashVisibility(false);
		this.showingLoading = false;
		return this.panel[this.panel.length - 1];
	}
	
	function fncCloseActive() {
		if (this.panel.length != 0) {
			var elePanel = this.panel.pop();
			var eleWait = this.wait.pop();
		
			if (elePanel.onclose) elePanel.onclose();

			try { Effect.Fade(elePanel, {duration: 0.5}); } catch (e) { removeElement(elePanel); }
			try { Effect.Fade(eleWait, {duration: 0.5}); } catch (e) { removeElement(eleWait); }
			
			this.showingLoading = false;
			
			if (this.panel.length == 0) changeFlashVisibility(true);
			
			cancelAjaxHidde();
		}
	}
	
	function fncCloseLoading() {
		if (this.showingLoading != null && this.showingLoading) this.closeActive();
	}
	
	function fncHiddeActive() {
		var elePanel = this.getActive();

		if (elePanel.onclose) elePanel.onhidde();
		hiddeElement(elePanel);
		
		if (this.panel.length == 0) changeFlashVisibility(true);
	}
	
	function fncCloseAll() {
		while (this.panel.length != 0) {
			var elePanel = this.panel.pop();
			var eleWait = this.wait.pop();
		
			if (elePanel.onclose) elePanel.onclose();
			
			try { Effect.Fade(elePanel, {duration: 0.5}); } catch (e) { removeElement(elePanel); }
			try { Effect.Fade(eleWait, {duration: 0.5}); } catch (e) { removeElement(eleWait); }
		}

		this.showingLoading = false;
		
		changeFlashVisibility(true);
		
		cancelAjaxHidde();
	}
	
	function fncNewError() {
		this.wait.push(this.prvCreateDiv("ajaxBlock",false,true));
		this.panel.push(this.prvCreateDiv("ajaxError",true,false));
		
		return this.getActive();
	}
	
	function fncNewPanel() {
		this.wait.push(this.prvCreateDiv("ajaxBlock",false,true));
		this.panel.push(this.prvCreateDiv("ajaxResult",true,false));
		
		return this.getActive();
	}
	
	function fncRefresh(autoExpand) {
		this.adjustVisual(autoExpand);
		
		for (var i = 0; i < this.panel.length; i++) {
			var elePanel = this.panel[i];
			reShowElementCenter(elePanel);
		
			if (elePanel.onrefresh) elePanel.onrefresh();
		}
		
		return true;
	}
	
	function fncCreateDiv(aClassName, mustCenter, isFull) {
		var newDiv = document.createElement("div");
		
		newDiv.className = aClassName;
		newDiv.style.zIndex=9999999;
		
		document.body.appendChild(newDiv);
		
		if (mustCenter) showElementCenter(newDiv,null);
		if (isFull) showElementFull(newDiv,null);
		
		return newDiv;
	}
	
	function fncShowLoading() {
		if (this.showingLoading == null || ! this.showingLoading) {
			var section = this.getActive();
			this.showingLoading = true;
			section.innerHTML = generateModalCloseAjax(true,false,false);
			showElementCenter(section);
			
			return this.refresh();
		}
	}
	
	function fncAdjustWidthHeightAjaxResult(autoExpand) {
		var element = (this.panel.length == 0) ? null : this.getActive();
		
		if (element == null) return;
		
		var ajaxResultContent = getElementOfElementById(element,"ajaxResultContent");
		
		autoExpand = toBoolean(autoExpand);
		autoExpand = true;
	
		if (element != null && ajaxResultContent != null && autoExpand ) {
			var maxWidth = Math.round(getStageWidth() * .85);
			var maxHight = Math.round(getStageHeight() * .70);

			if (ajaxResultContent.scrollHeight > maxHight) {
				ajaxResultContent.style.height = maxHight + "px";
			} else if (ajaxResultContent.scrollHeight > element.offsetHeight) {
				ajaxResultContent.style.height = ajaxResultContent.offsetHeight + "px";
			}

			if (ajaxResultContent.scrollWidth > maxWidth) {
				element.style.width = maxWidth + "px";
			} else if (ajaxResultContent.scrollWidth > element.offsetWidth) {
				element.style.width = ajaxResultContent.scrollWidth + "px";
			}
		}
	}
	
	this.getActive		= fncGetActive;						//Retrieves the active panel, if no one is active, creates one
	this.hasActive		= fncHasActive;						//Returns true if the there is an active panel
	this.closeActive	= fncCloseActive;					//Close de active panel, closeing the shadow shape
	this.hiddeActive	= fncHiddeActive;					//Hiddes the active panel, leaving the shadow shape
	this.closeAll		= fncCloseAll;						//Close all panels, closeing all the shadow shapres
	this.newError		= fncNewError;						//Generates a new error panel
	this.newPanel		= fncNewPanel;						//Generates a new comun panel
	this.refresh		= fncRefresh;						//Refresh all panels locations
	
	this.adjustVisual	= fncAdjustWidthHeightAjaxResult;	//Adjusts all panels to fit visual properties
	
	this.showLoading	= fncShowLoading;					//Shows the loading panel in the active panel
	this.closeLoading	= fncCloseLoading;					//Close the loading panel, only if it is showing
	this.prvCreateDiv	= fncCreateDiv;						//Creates an internal div panel (private)
}

function AjaxPool() {
	this.pool = new Array();
	this.ajaxCallOpen = false;
	function fncAdd(obj) {
		this.pool.push(obj);
		return true;
	}
	
	function fncGet() {
		return this.pool.shift();
	}
	
	function fncHasElements() {
		return this.pool.length != 0;
	}
	
	function fncLength() {
		return this.pool.length;
	}
	
	function processNextAjaxCall(aAjaxCaller) {
		if (aAjaxCaller != null) {
			if (aAjaxCaller.showLoading) {
				this.pool.unshift(aAjaxCaller);
			} else {
				this.pool.push(aAjaxCaller);
			}
		} else {
			//document.title = document.title.substring(document.title.indexOf("]") + 2);
			this.ajaxCallOpen = false;
		}
		
		if (! this.ajaxCallOpen && this.hasElements() && ajaxActive) {
			this.ajaxCallOpen = true;
			//document.title = "[" + LBL_LOADING + "] " + document.title;
			aAjaxCaller = this.get();
			if (aAjaxCaller.showLoading) AJAX_PANEL.showLoading();
			aAjaxCaller.doCall(true);
		}
	
	}
	
	this.add = fncAdd;
	this.get = fncGet;
	this.hasElements = fncHasElements;
	this.length = fncLength;
	this.processNext = processNextAjaxCall;
}

AjAX_POOL	= new AjaxPool();
AJAX_PANEL	= new AjaxPanel();

function suspendAjax() {
	ajaxActive = true;
}

/**
 * Cancels all timeout functions
 */
function cancelAjaxHidde() {
	if (ajaxTimeout1 != null) clearTimeout(ajaxTimeout1);
	if (ajaxTimeout2 != null) clearTimeout(ajaxTimeout2);
	if (ajaxTimeout3 != null) clearTimeout(ajaxTimeout3);

	ajaxTimeout1 = null;
	ajaxTimeout2 = null;
	ajaxTimeout3 = null;
}

function closeConnectionErrorNotification(event) {
	AJAX_PANEL.closeActive();
	document.title = document.title.substring(document.title.indexOf("]") + 2);
	
	return false;
}

/**
 * Executes the doAjax method with the corresponding URL passed as parameter.
 * @param string with url to call
 */
function doModalAjaxTimed(url) {
	doModalAjax(url,null);
}

function doModalAjaxTimedNoWait(url) {
	doModalAjaxNoWait(url,null);
}

function doModalAjax(url,event) {
	AjAX_POOL.processNext(new AjaxCaller('GET',url,null,processModalXml,true,true));
}

function doModalAjaxNoWait(url,event) {
	AjAX_POOL.processNext(new AjaxCaller('GET',url,null,processModalXml,true,false));
}

//--------------------------------------------------------------------------
function generateModalCloseAjax(addText,showClose,closeAll) {
	if (showClose == null) showClose = true;
	closeAll = toBoolean(closeAll);
	
	var srcImage = showClose?"":"<img src=\"" + IMG_AJAX_WAIT + "\"> ";
	var srcClose = showClose?("<div onClick=\"" + (closeAll?"AJAX_PANEL.closeAll()":"AJAX_PANEL.closeActive()") + ";\" class=\"ajaxResultClose\">" + TXT_CLICK_TO_CLOSE + "</div>"):"";
	var srcText = addText?(LBL_LOADING + "<hr width=\"50%\" align=\"left\">"):"";

	//ocultar el advance serach por las dudas
	hiddeElement("advanceSearchContainer",null);

	return srcImage + srcClose + srcText;
}

function processXmlTagAttributes(xmlTag) {
	var result = "";
	for (var x = 0; xmlTag.attributes != null && x < xmlTag.attributes.length; x++) {
		result+= xmlTag.attributes.item(x).nodeName;
		result+= "=\"";
		result+= xmlTag.attributes.item(x).nodeValue;
		result+= "\"";
	}
	
	return result;
}

//--- Llamados a los distintos métodos ajax
function showAjaxComunicationError() {
	AJAX_PANEL.closeActive();
	if (ajaxActive && false) {
		showElementFull(ajaxBlockName,null);
		showElementCenter(ajaxErrorName,null);
	}
}

function doAjaxSubmit(form,newPanel,event,showLoading) {
	//if (! validateForm(form)) return false;
	if (showLoading == null) showLoading = true;
	
	var url = form.getAttributeNode("action").value;
	var params = "";
	
	if (form.childNodes.length > 0) {
		for (var i = 0; i < form.elements.length; i++) {
			var formElement = form.elements[i];
			
			var formEleName = formElement.name;
			var formEleValue = formElement.value;
			
			if (formElement.type == "select-multiple") {
				for ( var j = 0; j < formElement.options.length; j++) {
					if (formElement.options[j].selected) {
						if (params != "") params += "&";
						params += formEleName + "=" + formElement.options[j].value;
					}
				}
				
			} else if ((formElement.type == "checkbox" && formElement.checked) || (formElement.type == "radio" && formElement.checked) || (formElement.type != "radio" && formElement.type != "checkbox"))  {
				if (params != "") params += "&";
				params += formEleName + "=" + formEleValue;
			}
		}
	}

	if (newPanel == null) newPanel = false;
	if (newPanel) AJAX_PANEL.newPanel();
	
	AjAX_POOL.processNext(new AjaxCaller('POST',url,params,processModalXml,true,showLoading));
	
	return false;
}

function showWait(event) {
	AJAX_PANEL.showLoading();
	return true;
}

function ajaxUploadStartStatus() {
	AJAX_PANEL.newPanel();
	var panel = AJAX_PANEL.getActive();
	
	var html = "";
	
	html += "<div style='border: thin #FFFFFF solid; width: 200px;' id='progressBarContainer'><img id='progressBar' src='" + SITE_SKIN_CONTEXT + "/images/progress.gif' height='10px' width='0px'></div>";

	panel.innerHTML = html;
	
	ajaxUploadCallStatusUrl();
}

function ajaxUploadCallStatusUrl() {
	AjAX_POOL.processNext(new AjaxCaller('GET',URL_START_UPLOAD_PROGRESS,null,processModalXml,true,false));
}

function ajaxUploadUpdateStatus() {
	var doCall = false;

	if (lastFunctionAjaxCall != null) {
		var messages = lastFunctionAjaxCall.getElementsByTagName("messages");
		
		if (messages != null && messages.length > 0 && messages.item(0) != null) {
			messages = messages.item(0).getElementsByTagName("message");
			
			var status		= null;
			var totalRead	= null;
			var totalSize	= null;
			
			for(var i = 0; i < messages.length; i++) {
				var message = messages.item(i);
				var param	= message.getAttribute("name");
				var text 	= "";
				
				if (message.firstChild != null) text = message.firstChild.nodeValue;
				
				if ("status" == param) {
					status = text;
				
				} else if ("totalRead" == param) {
					totalRead = text;
				
				} else if ("totalSize" == param) {
					totalSize = text;
				}
			}

			var progressMessages		= getElementById("progressMessages");
			var progressBar				= getElementById("progressBar");
			var progressBarContainer	= getElementById("progressBarContainer");

			if (progressBar != null && progressBarContainer != null)	progressBar.style.width = (progressBarContainer.offsetWidth * parseInt((totalRead / totalSize) * 100) / 100) + "px";
			
			doCall = status == -1 || status == 1;
		}
		
		lastFunctionAjaxCall = null;
	}
	
	if (doCall) { 
		setTimeout("ajaxUploadCallStatusUrl()",200);
	} else {
		AJAX_PANEL.closeAll();
	}
	
	return true;
}