var errRangeVerify;
var errRangeVerifyButtonValue;
var closeButtonValue;

var cssDesktop = {
	id: 'Desktop'
};
var cssContenedorVtns = {
	id: 'Vtns'
};
var cssLstVtns = {
	id: 'deskLstVtns',
	cls: 'SB_Vtn',
	clsDivCabecera: 'SB_Vtn_Head',
	clsDivCuerpo: 'SB_Vtn_Body',
	clsDivPie: 'SB_Vth_Foot'
};
/* Venta incrustada en cssVtns.id*/
var cssVtn = {
	id: function(num){return 'idc_'+num.toString();},
	cls: 'Vtn',
	cls_SinDecoracion: 'Vtn SinDecoracion',
	clsDivT: 'T',	clsDivC: 'C', clsDivB:	'B',
	/* Reloj animado */
	clsDivWait: 'Vtn_Wait',	clsDivNoWait: 'Vtn_NoWait',
	/* Botón de cierre */
	clsDivClose: 'Vtn_Close',	clsDivNoClose: 'Vtn_NoClose',
  /* Cabecera */
  clsDivCabecera: 'Vtn_Head', clsDivCabecera_Icon: 'Vtn_Head_Icon', clsDivCabecera_Title: 'Vtn_Head_Title',
  /* Cuerpo */	
  clsDivCuerpo: 'Vtn_Body',
  /* Pie */
  clsDivPie: 'Vtn_Foot'
}; 
/* Items de la Lst de Vtns activas */
var cssSB_Vtn_Item = {
	clsSelected: 'SB_Vtn_ItemSel',
  clsNoSelected: 'SB_Vtn_Item',
  clsDiv_Icon: 'SB_Vtn_Item_Icon',
  clsDiv_Title: 'SB_Vtn_Item_Title'
};

var cssField = {
	cls:'fld'
};
/* Gestor de Entorno */
var cGestorEntorno = Class.create();
cGestorEntorno.prototype = {
	initialize: function() {
		this.GestorEscritorio = null;
		this.VtnsAbiertas = null;
	}	
}
var oGestorEntorno = new cGestorEntorno();
/* Gestor de Escritorio */
var cGestorEscritorio = Class.create();
cGestorEscritorio.prototype = {
	initialize: function(divMainContainer) {
		this.divMainContainer = divMainContainer; // Contenedor principal en el que se incrustan los formularios.
		this.NextDivId = 1; // Identificador que se usará para el próximo DIV que se genere.
		this.aDivsAbiertos = $A(); 
	},
	// Array (copia) con los contenedores actualmente abiertos según orden de apertura.
	Contenedores: function() {
		var atmp;
		atmp = $A();
		for(var i=0;	i<this.aDivsAbiertos.length;	i++)
			atmp.push( this.aDivsAbiertos[i] );
		return atmp;
	},
	// Crea un nuevo contenedor (DIV) oculto con un identificador único.
	// Devuelve el identificador del contenedor.
	CrearContenedor: function() {
		var divContenedorId = this._p_CrearContenedor();
		this.aDivsAbiertos.push( divContenedorId );
		return divContenedorId ;
	},
	// Borra el contenedor indicado.
	BorrarContenedor: function(theDivId) {
		var lng = this.aDivsAbiertos.length;
		this.aDivsAbiertos = this.aDivsAbiertos.without( theDivId );
		if(lng==this.aDivsAbiertos.length) 
			throw 'cGestorEscritorio.CerrarContenedor: El contenedor no está registrado';
		else
			this._p_BorrarContenedor(theDivId);
	},
	_p_CrearContenedor: function() {
		var theDiv = document.createElement("div");	
		theDiv.id = cssVtn.id( this.NextDivId );
		//theDiv.className = cssVtn.cls;
		this.divMainContainer.appendChild( theDiv );
		
		this.NextDivId++;
		return theDiv.id;
	},
	_p_BorrarContenedor: function(theDivId){
		var theDiv=$(theDivId);
		this.divMainContainer.removeChild( theDiv );
	}
}

/* Gestor de una Vtn: Utilizable como base y soporte para gestores de Vtns
	específicos.
	Si se sobreescribe uno de los métodos principales, se puede usar los métodos _base_xxx para
	realizar la llamada correspondiente de este objeto.
*/
var enumVtnStatus = {nil:0, loading:1, loaded:2, erroneous:3}
/* Estilo gráfico de la Vtn */
var enumVtnStl = { 
	cabecera: 1,
	icono: 2, 
	titulo: 4, 
	cerrable: 8, 
	decoracion: 16, 
	sinEstilo: 0, 
	estandard: 1+2+4+8+16, 
	noCerrable: 1+2+4+16
} 

var cVtn = Class.create()
cVtn.prototype = {
  initialize: function(estilo, icon, title, siempreVisible, anclarTop) {
		this._base_initialize(estilo, icon, title, siempreVisible, anclarTop);
  } ,  
  Dormir: function() {
		this._base_Dormir();
  } ,
  Despertar: function() {
		this._base_Despertar();
  } ,
  Destruir: function() {
		this._base_Destruir();
	},
	// Pagina controladora actual colgada de la Vtn.
	RegistrarPagina: function(oPagina) {
		if(oPagina==undefined)
			this._Pagina = null;
		else
			this._Pagina = oPagina;
	},
	GetPagina: function() {
		return this._Pagina; // null si no hay página.
	},
  _base_initialize: function(estilo, icon, title, siempreVisible, anclarTop) {
		if(estilo==undefined) 
			this._Estilo = enumVtnStl.estandard;
		else
			this._Estilo = estilo;
		
		this.Title=coalesce(title,'&nbsp;');
		this._PuedeCerrarse = bitTst(this._Estilo, enumVtnStl.cerrable) ;
		this._SiempreVisible = coalesce(siempreVisible,false);
		this._AnclarTop = coalesce( anclarTop, false);
		
		this.Icon = this._p_Path2imageURL(icon);
		this.Status = enumVtnStatus.nil;
  	this.ContenedorId = oGestorEntorno.GestorEscritorio.CrearContenedor(); 
  	this._p_VtnLayOut(this._Estilo);
		// Vincluar el contenedor al objeto Vtn.
  	$(this.ContenedorId).Vtn = this;
  	// De momento no tenemos página registrada
  	this._Pagina = null;
  	// Movemos el contenedor al principio de la Lst de contenedores
  	this._SerPrimera();
  	// Semáforo para admitir una única petición por Vtn
  	this.Cargando=false;
	},
	_SerPrimera: function() {
		var contenedor = $(this.ContenedorId);
		var pNod = contenedor.parentNode;
		// Buscar el último "hijo" que no seamos nosotros y que esté anclado.
		for(var iHijo=0;iHijo<pNod.childNodes;iHijo++) {
			var child = pNod.childNodes[iHijo];
			
			if(child==contenedor) // Soy yo... ya estamos bien situados
				return; 
			if( !child._AnclarTop) { // Es un nodo no anclado... nos ponemos encima.
				var ndAux = pNod.removeChild( contenedor );
				pNod.insertBefore( ndAux, child );
				return;
			}
		}
	},
  _base_Dormir: function() {
		// Es posible que la página tenga que hacer algo cuando antes de ser dormida
		if(this._Pagina!=null)	this._Pagina.Dormir();
		
		var contenedor = $(this.ContenedorId)
		if( !this._SiempreVisible) {
			contenedor.style.display='none';
			contenedor.disabled = 'true';
			return true;
		} else {
			// La Vtn no puede ser dormida.
			return false;
		}
  },
  _base_Despertar: function() {
		var contenedor = $(this.ContenedorId)
		if( !this._SiempreVisible) {
			contenedor.style.display='';
			contenedor.disabled = '';
		}
		this._SerPrimera();
		// Es posible que la página tenga que hacer algo cuando es despertada.
		if(this._Pagina!=null) this._Pagina.Despertar();
  },
  _base_Destruir: function() {
		// Desvincular el objeto Vtn de su contenedor.
		$(this.ContenedorId).Vtn=null;
		oGestorEntorno.GestorEscritorio.BorrarContenedor( this.ContenedorId );
		this.ContenedorId = null;		
  },
	SetIcon: function( newIcon ) {
		newIcon = this._p_Path2imageURL(coalesce(newIcon,''));		
		if( bitTst(this._Estilo, enumVtnStl.icono) ) {
			var theDiv = document.getElementsByClassName(cssVtn.clsDivCabecera_Icon, this.ContenedorId)[0];
			theDiv.style.backgroundImage = newIcon;
		}
		this.Icon = newIcon;		
			
		if(oGestorEntorno.VtnsAbiertas) 
			oGestorEntorno.VtnsAbiertas._RefrescarItems();
	},
  SetTitle: function( newTitle) {
		this.Title = newTitle;
		if( bitTst(this._Estilo, enumVtnStl.titulo)) {
			// Cambiar el título de la Vtn.
			var theDiv = document.getElementsByClassName(cssVtn.clsDivCabecera_Title, this.ContenedorId)[0];
			if(theDiv.innerText) // IE
				theDiv.innerText = newTitle;
			else // FireFox/Mozzilla
				theDiv.textContent = newTitle;
		}
		// Vtns activas
		if(oGestorEntorno.VtnsAbiertas) 
			oGestorEntorno.VtnsAbiertas._RefrescarItems();
  },	
  SetHead: function( sNewIcon, sNewTitle) {
		
		sNewIcon = this._p_Path2imageURL(coalesce(sNewIcon,''));
		this.Icon = sNewIcon;
		this.Title = sNewTitle;
		
		if( bitTst(this._Estilo, enumVtnStl.icono) ) {		
			var theDivIcon = document.getElementsByClassName(cssVtn.clsDivCabecera_Icon, this.ContenedorId)[0];
			if(sNewIcon.length!=0) {
				theDivIcon.style.display = '';
				theDivIcon.style.backgroundImage = sNewIcon;
			} else {
				theDivIcon.style.backgroundImage = 'none';
				theDivIcon.style.display = 'none';
			}
		}
		if( bitTst(this._Estilo, enumVtnStl.titulo) ) {
			var theDivTitle = document.getElementsByClassName(cssVtn.clsDivCabecera_Title, this.ContenedorId)[0];
			if(theDivTitle.innerText){ // IE
				theDivTitle.innerText = sNewTitle;
			}	else {// FireFox/Mozzilla
				theDivTitle.textContent = sNewTitle;
			}
		}
		
		if(oGestorEntorno.VtnsAbiertas)
			oGestorEntorno.VtnsAbiertas._RefrescarItems();
		
  },
  Cargar: function( url, arrParameters, incluirInputs ) {
		this._base_Cargar(url, arrParameters, incluirInputs);
  },
  CargarHTML: function( html ) {
		this._base_CargarHTML( html );	
  },
  PuedeCerrarse: function() {
		return this._PuedeCerrarse;
  },
  SiempreVisible: function() {
		return this._SiempreVisible;
  },
  // Realiza una llamada a la URL indicada pasando los parámetros.
  // La llamada se efectúa de forma asíncrona.
  _base_Cargar: function( url, arrParameters, incluirInputs ) {
		if(this.Status != enumVtnStatus.loading){
			this.Status = enumVtnStatus.loading;
			var sParams= '';
			
			sParams += "ContenedorId=" + this.ContenedorId;
			if( arrParameters != undefined ) {
				for( var ipar=0 ; ipar < arrParameters.length ; ipar+=2 ) {
					sParams+="&"+encodeURIComponent(arrParameters[ipar]) + '=' + encodeURIComponent(arrParameters[ipar+1]);
				}
			}
			
			incluirInputs=coalesce(incluirInputs,true);
			if( incluirInputs )
				sParams+="&"+Form.serialize( this.ContenedorId );
			
			// Visualizar Reloj
			try {
				document.getElementsByClassName(cssVtn.clsDivNoWait, this.ContenedorId)[0].className = cssVtn.clsDivWait;
			} catch( e ){}
			// Ocultar botón de cierre
			try {
				document.getElementsByClassName(cssVtn.clsDivClose, this.ContenedorId)[0].className = cssVtn.clsDivNoClose;
			} catch( e ){}		
			// Incrustar el identificador del contenedor (Nombre único).
			
			
			var contenedor;
			var arr = document.getElementsByClassName(cssVtn.clsDivCuerpo, this.ContenedorId);
			if(arr.length==0) 
				contenedor = this.ContenedorId;
			else
				contenedor = arr[0];
			
			var ajxReq = new Ajax.Updater(
				contenedor,
				url,   
				{ method: 'post', 
					asynchronous:true,
					postBody: sParams,
					evalScripts: true,
					onComplete: this._p_OnCargado.bind(this), 
					onFailure: this._p_OnError.bind(this)					
				}
			);
		} 
  },
  _base_CargarHTML: function( html ) {
  	try {
			var divCont = document.getElementsByClassName(cssVtn.clsDivCuerpo, this.ContenedorId)[0];
			new Insertion.Top(divCont, html);
			try {
				document.getElementsByClassName(cssVtn.clsDivWait, this.ContenedorId)[0].className=cssVtn.clsDivNoWait; // Podría no existir
			} catch(e) {}
			try {
				document.getElementsByClassName(cssVtn.clsDivNoClose, this.ContenedorId)[0].className=cssVtn.clsDivClose;
			} catch(e) {}
		} finally {
			this.Status = enumVtnStatus.loaded;
		}
  },
  _p_Path2imageURL:function(path) {
		if (path==undefined || path==null || path=='')
			return '';
		else if ( path.indexOf("url(")!=-1 ) 
			return path;
		else 
			return 'url('+path+')';
  },
  _p_VtnLayOut: function(EstiloVtn) {
		var theDiv = $(this.ContenedorId);
		if( EstiloVtn != enumVtnStl.sinEstilo ) {
			var html = "";
			if( bitTst(EstiloVtn, enumVtnStl.decoracion) ) html += 
				"<div class='" + cssVtn.clsDivT + "'></div>" +
				"<div class='" + cssVtn.clsDivC + "'>" ;
			
			if( bitTst(EstiloVtn, enumVtnStl.cabecera) ) {
			
				html +=	"<div class='" + cssVtn.clsDivCabecera + "' >";
				
				if(bitTst(EstiloVtn, enumVtnStl.icono) )	html+= 
					"<div class='" + cssVtn.clsDivCabecera_Icon + "'></div>";
				if( bitTst(EstiloVtn, enumVtnStl.cerrable) )				
				{				    
				    if (closeButtonValue==null || closeButtonValue=='undefined'){
				        closeButtonValue="Cerrar";
				    }
				    
				 html += "<a href='#' class='" + cssVtn.clsDivNoClose + "' onclick=\"oGestorEntorno.VtnsAbiertas.DestruirVtn($('" + this.ContenedorId + "').Vtn);\">" + closeButtonValue + "</a>";
	            }
	            
				html += 
					"<div class='" + cssVtn.clsDivWait + "'></div>";
				
				if( bitTst(EstiloVtn, enumVtnStl.titulo) )
					html+= "<div class='" + cssVtn.clsDivCabecera_Title + "'>" + this.Title + "</div>";

				html +=	"</div>";
			}
			
			html+=
				"<div class='" + cssVtn.clsDivCuerpo + "'></div>" + 
				"<div class='" + cssVtn.clsDivPie + "'></div>"
					
			if( bitTst(EstiloVtn, enumVtnStl.decoracion) )	html += 
				"</div>" +
				"<div class='" + cssVtn.clsDivB + "'></div>";
			
			theDiv.innerHTML = html;
			if( bitTst(EstiloVtn, enumVtnStl.icono) ) {
				var theIconDiv = document.getElementsByClassName(cssVtn.clsDivCabecera_Icon, theDiv)[0];
				theIconDiv.style.backgroundImage = this.Icon;
			}
			
			if( bitTst(EstiloVtn, enumVtnStl.decoracion) )
				theDiv.className = cssVtn.cls;
			else
				theDiv.className = cssVtn.cls_SinDecoracion;
				
		}
  },
  _p_OnCargado: function(xmlhttprequest,xjson) {
		try {
			if(this.OnCargado!=undefined)	this.OnCargado(xmlhttprequest,xjson);
		
			try {
				document.getElementsByClassName(cssVtn.clsDivWait, this.ContenedorId)[0].className=cssVtn.clsDivNoWait; // Podría no existir
			} catch(e) {}
			try {
				document.getElementsByClassName(cssVtn.clsDivNoClose, this.ContenedorId)[0].className=cssVtn.clsDivClose;
			} catch(e) {}
			
		} finally {
			this.Status = enumVtnStatus.loaded;
		}
  },
  _p_OnError: function(xmlhttprequest) {
		this.Status = enumVtnStatus.erroneous;
		try {
			document.getElementsByClassName(cssVtn.clsDivWait, this.ContenedorId)[0].className=cssVtn.clsDivNoWait; // Podría no existir
		} catch(e) {	
		}
		try {
			document.getElementsByClassName(cssVtn.clsDivNoClose, this.ContenedorId)[0].className=cssVtn.clsDivClose;
		} catch(e) {
		}
		if(this.OnErrorCargando!=undefined)	this.OnErrorCargando();
  },
  L2G: function(lName){
		return this._p_L2G(this.ContenedorId ,lName );
  },
  G2L: function(gName) {
		// Devuelve el nombre local correspondiente al nombre global indicado.
		// Se admite un Elemento DOM.  Se usará su propiedad Id y se extraerá el nombre local.
		if(typeof(gName)=='object') {
			gName = gName.Id;
		}
		return _p_G2L(this.ContenedorId, gName);
  },
  $: function(lName) {
		// Devuelve el elemento DOM cuyo nombre "local" es el indicado.
		return $(this._p_L2G(this.ContenedorId,lName));
	},
	$F: function(lName) {
		return $F(this._p_L2G(this.ContenedorId,lName));
	},
	// Extiende los elementos de la clase indicada contenidos en el contenedor del formulario
	// con los métodos y propiedades indicados en arrExtend.
	SetBehaviour: function(ClassName, arrExtend) {
		var aElementos = document.getElementsByClassName(ClassName, this.ContenedorId);
			for(var ix=0; ix<aElementos.length; ix++) {
				Object.extend( aElementos[ix], arrExtend	);
			}
	},
	_p_L2G: function(GPrefix, LName) {
		switch( LName.charAt(0) ) {
			case '#':	return '#' + GPrefix + '_' + LName;
			case '.':	return '.' + GPrefix + '_' + LName;
			default:	return GPrefix + '_' + LName;
		}
	},
	_p_G2L: function(GPrefix, GName) {
		switch( GName.charAt(0) ) {
			case '#': return '#' + GName.substring(1+GPrefix.length+1, GName.length-1);
			case '.': return '.' + GName.substring(1+GPrefix.length+1, GName.length-1);
			default : return GName.substring(GPrefix.length+1, GName.length-1);
		}
	}	
};

/* Contexto */
var cContexto = Class.create();
cContexto.prototype = {
    initialize: function(nNumVtnsMax){
        if( nNumVtnsMax==undefined || nNumVtnsMax==null )
            this.NumVtnsMax= 1;
        else
            this.NumVtnsMax = nNumVtnsMax;         
    },
    
    onActivar: function(){},
    
    onDesactivar: function(){}    
};


/* Gestor de Vtns activas */
var cVtnsAbiertas = Class.create();
cVtnsAbiertas.prototype = {
	/*
	    numVtnsMax: límite de ventanas abiertas en el Contexto por defecto.
	    bOcultarSiSoloUna: Visor de Ventanas activas debe ocultarse si hay 1 o 0 ventanas abiertas.
	*/
	initialize: function(numVtnsMax, bOcultarSiSoloUna) {
		
		this.divVtn = $(cssLstVtns.id);
		this.divLst = document.getElementsByClassName(cssLstVtns.clsDivCuerpo, this.divVtn)[0];
		// 
		if(numVtnsMax==undefined)
			this.numVtnsMax = 10;
		else if(numVtnsMax<1)
			this.numVtnsMax = 1
		else
			this.numVtnsMax = numVtnsMax;
		
		if( bOcultarSiSoloUna==undefined )
		    this._OcultarSiSoloUna = true;
		else
		    this._OcultarSiSoloUna = bOcultarSiSoloUna;
		    
		// Orden en el que se han activado los formularios.
		this.aOrdenActivacion = $A();
		// todas las Vtns abiertas actualmente.
		this.aVtnsAbiertas = $A();
		// contextos
		this.aCtxsActivos = $A();
		// Inicialmente, la Lst estará vacía: se ocultará
		this._ShowOrHide();
	},
	
	RegistrarCtx: function( oCtx, sContexto ) {
	    this.aCtxsActivos[sContexto]=oCtx;

	},
	
	RegistrarVtn: function( oVtn, sContexto) {
		// Si la Vtn es "siempre visible", no es necesario dormir la Vtn activa "visible"
		if( !oVtn.SiempreVisible() ) 
			this._DormirActivo();
		// Cualquier ventana de otro contexto, debe ser destruida
        var oCtx;    
        var iNumVtnsMax;            
        
        if( sContexto!= undefined ) {
            oVtn.Contexto = sContexto;                                     
        } else {
            oVtn.Contexto = "";
        }
        oCtx = this.aCtxsActivos[sContexto];  
           
        if( oCtx != undefined ) {
           iNumVtnsMax = oCtx.NumVtnsMax
        } else {
           iNumVtnsMax = this.numVtnsMax;
        }

        // Debemos recordar el contexto de la ventana activa actual... por si hay que ejecutar
        // la desactivación del contexto.
		var sNomCtxADesactivar = "";
		var oCtxADesactivar;
		if(this.aVtnsAbiertas.length!=0) {
		    sNomCtxADesactivar = this.aVtnsAbiertas[ this.aOrdenActivacion[ this.aOrdenActivacion.length-1 ]].Contexto;
		    oCtxADesactivar = this.aCtxsActivos[ sNomCtxADesactivar ];
		}
		// Cerrar las ventanas de otros contextos
		this.CerrarOtrosContextos(oVtn.Contexto);
		// Seguridad: Un máximo de Vtns abiertas.
		if( this.aVtnsAbiertas.length==iNumVtnsMax) {
			// Cerrar la Vtn activa más antigua que no sea cerrable.
			for( var ix=0; ix<this.aOrdenActivacion.length;ix++) {
				if( this.aVtnsAbiertas[ this.aOrdenActivacion[ix] ].PuedeCerrarse() ) {
					this._CerrarVtn( this.aOrdenActivacion[ix] );
					break;
				}
			}
			// Si ninguna Vtn es cerrable, forzamos el cierre de la más antigua.
			if(this.aVtnsAbiertas.length==iNumVtnsMax) 
				this._CerrarVtn( this.aOrdenActivacion[0] );
		}
		
//		if(sNomCtxADesactivar!=oVtn.Contexto) {
//		    if(oCtxADesactivar!=undefined)
//		        oCtxADesactivar.onDesactivar();
//		    if(oCtx!=undefined) 
//		        oCtx.onActivar();
//		}
		
		if(sNomCtxADesactivar!=oVtn.Contexto) {
		    if(oCtx!=undefined) 
		        oCtx.onActivar();
		}
		
		// Registrar nuestra ventana como la nueva activa
		this.aVtnsAbiertas.push(oVtn);
		this.aOrdenActivacion.push( this.aVtnsAbiertas.length-1);
		this._CrearItemLst(this.aVtnsAbiertas.length-1);		
		this._RefrescarItems();
		
		// Cuando no hay elementos, la Lst debe ocultarse.
		this._ShowOrHide();
	},
	DestruirVtn: function( oVtn ) {
		for(var ix=0;ix<this.aVtnsAbiertas.length;ix++) {
			if(this.aVtnsAbiertas[ix]==oVtn) {
				this._CerrarVtn(ix); 
				this._RefrescarItems(); 
				if(this.aVtnsAbiertas.length==0) {				    
				    if (oVtn.Contexto!=""){				        
				        var oCtxADesactivar = this.aCtxsActivos[oVtn.Contexto];
				        oCtxADesactivar.onDesactivar();
				    }
				}
				this._ShowOrHide();
				return;
			}
		}
		// Si llegamos aquí, es que la Vtn no está en la Lst de abiertas... le ordenamos que se destruya y punto.
		oVtn.Destruir();
	},
	DestruirVtns: function( ) {
	    while(this.aVtnsAbiertas.length!=0) {
	        this.DestruirVtn(this.aVtnsAbiertas[0]);
	    }
	},
	CerrarOtrosContextos: function( sNomContexto ) {
	 var arrACerrar = new Array();
	 // Descubrir las ventanas que pertenecen a otro contexto
	 for(var ix=0;ix<this.aVtnsAbiertas.length;ix++) {
       var oVtn = this.aVtnsAbiertas[ix];
       if(oVtn.Contexto != sNomContexto) arrACerrar.push( oVtn );
     }
     // Destruir las ventanas de otros contextos
     for(var ix=0;ix<arrACerrar.length; ix++) {
        this.DestruirVtn( arrACerrar[ix] );
     }     
     
	},
	_DormirActivo: function() {
		// Dormir la Vtn activa que no sea "siempre visible";
		var ixActivo = this._get_VtnActiva( true );
		if(ixActivo!=-1) this.aVtnsAbiertas[ixActivo].Dormir();

	},
	_DespertarDormido: function(ix) {
		// Si no es una Vtn "siempre visible" y no es la actual activa, debe dormirse la actual activa.
		if(!this.aVtnsAbiertas[ix].SiempreVisible() &&  this._get_VtnActiva( true ) != ix) {		
			// Dormir el activo
			this._DormirActivo();
		}
		// Si no es la primera en el orden de activación... la ponemos.
		if(this.aOrdenActivacion[ this.aOrdenActivacion.length-1 ]!=ix) {
			this.aOrdenActivacion = this.aOrdenActivacion.without(ix);
			this.aOrdenActivacion.push(ix);			
		}
		// Se le ordena a la Vtn que sea visible y se ponga la primera de la Lst
		this.aVtnsAbiertas[ ix ].Despertar();
		
	},
	_CerrarVtn: function(ix) {
		// Si la Vtn NO es siempre visible, significa que su espacio puede ser ocupado por otra Vtn del mismo tipo.
		var DespertarOtra = this._get_VtnActiva( true )==ix;
		// Destruir la Vtn abierta 
		this.aVtnsAbiertas[ ix ].Destruir();	delete this.aVtnsAbiertas[ ix ];
		// Destruir el ITEM que representa a la Vtn
		this._BorrarItemLst(ix);
		// Eliminar de la Lst de Vtns abiertas.
		this.aVtnsAbiertas[ ix ] = null; this.aVtnsAbiertas = this.aVtnsAbiertas.compact();
		// Eliminar la Vtn de la Lst de activación
		var aTMP;
		aTMP= $A(); 
		for(var i=0; i<this.aOrdenActivacion.length; i++) {
			if(this.aOrdenActivacion[i]<ix) {
				aTMP.push( this.aOrdenActivacion[i] );
			} else if( this.aOrdenActivacion[i]>ix ) {
				aTMP.push( this.aOrdenActivacion[i]-1 );
			}
		}
		this.aOrdenActivacion = aTMP;
		//

		// Si se ha cerrado la Vtn activa y quedan Vtns, se activa la que corresponda.
		if(DespertarOtra) {
			var i= this._get_VtnActiva(true);
			if(i!=-1)	this.aVtnsAbiertas[ i ].Despertar();
		};
		// 
		this._ShowOrHide();
	},
	_get_VtnActiva: function(bSoloOcultables) {
		for(var ix=this.aOrdenActivacion.length-1; ix>=0; ix--) {
			if(!bSoloOcultables) {
				return this.aOrdenActivacion[ ix ];
			} else if(bSoloOcultables && ! this.aVtnsAbiertas[ this.aOrdenActivacion[ix] ].SiempreVisible() ) {
				return this.aOrdenActivacion[ ix ];
			}
		}
		return -1;
	},
	onItemClick: function(event) {
		if (!event) var event = window.event;
		var tg = (window.event) ? event.srcElement : event.target;
		while(tg!=undefined && tg!=null && tg.numItem==undefined && tg.className!=cssSB_Vtn_Item.clsItem )
			tg=tg.parentNode;
		if(tg.numItem!=undefined) {
			this._DespertarDormido(tg.numItem);
			this._RefrescarItems();
		}
	},
	_CrearItemLst: function(numItem) {
	
		var theItem = document.createElement("a");	
		theItem.href = "#";
		try {theItem.hideFocus = true;}catch(e){}
		
		theItem.innerHTML="<span class='" + cssSB_Vtn_Item.clsDiv_Icon + "'></span><div class='" + cssSB_Vtn_Item.clsDiv_Title + "' >&nbsp;</div>";
		theItem.classname = cssSB_Vtn_Item.clsSelected;
		
		var childs = this.divLst.childNodes;
		if(childs.length==0)
			this.divLst.appendChild( theItem );
		else
			this.divLst.insertBefore( theItem, childs[0] );
		
		theItem.numItem = numItem;
		theItem.onclick = this.onItemClick.bindAsEventListener(this);
		
		return theItem;
	},
	_BorrarItemLst: function(numItem) {
		var childs = $A(this.divLst.childNodes)
		var toDelete = null;
		for(var ix=0; ix<childs.length; ix++) {
			if( childs[ix].numItem != undefined) {
				if(childs[ix].numItem == numItem) {
					toDelete = childs[ix];
				} else if(childs[ix].numItem > numItem){
					childs[ix].numItem--;
				}
			}
		}
		if(toDelete!=null) {
			this.divLst.removeChild( toDelete );
			delete toDelete;
		}
		
	},
	_RefrescarItems: function() {
		if(this.aOrdenActivacion.length!=0) {
			var ixActiva = this.aOrdenActivacion[ this.aOrdenActivacion.length-1 ];
		
			var childs = this.divLst.childNodes;
			var divIcon = null;
			var divTitle = null;

			for(var ix=0; ix<childs.length; ix++) {

				if( childs[ix].numItem != undefined) {

					divIcon = document.getElementsByClassName(cssSB_Vtn_Item.clsDiv_Icon, childs[ix])[0];
					if(divIcon.style.backgroundImage != this.aVtnsAbiertas[ childs[ix].numItem ].Icon);
						divIcon.style.backgroundImage = this.aVtnsAbiertas[ childs[ix].numItem ].Icon;

					divTitle = document.getElementsByClassName(cssSB_Vtn_Item.clsDiv_Title, childs[ix])[0];
					
					var newTitle = this.aVtnsAbiertas[ childs[ix].numItem ].Title;
					if(newTitle=='&nbsp;') newTitle=' ';
					
					if(divTitle.innerText) {// IE
						if(divTitle.innerText != newTitle) 
							divTitle.innerText = newTitle;
					} else {// FireFox/Mozzilla
						if(divTitle.textContent != newTitle) 
							divTitle.textContent = newTitle;
					}
					
					divTitle.title = newTitle; // Tooltip
					
					if(childs[ix].numItem == ixActiva) {
						if(	childs[ix].className != cssSB_Vtn_Item.clsSelected) 
							childs[ix].className = cssSB_Vtn_Item.clsSelected;
					} else {
						if(	childs[ix].className != cssSB_Vtn_Item.clsNoSelected) 
							childs[ix].className = cssSB_Vtn_Item.clsNoSelected;
					}
					
					// 
					if(  this.aVtnsAbiertas[ childs[ix].numItem ].SiempreVisible() )
						Element.hide( childs[ix] );
					else 
						Element.show( childs[ix] );
						
				}
			}
		} 
	},
	_ShowOrHide: function() {		// Oculta la barra si no hay más de 1 Vtns abiertas que no sean del tipo "Siempre visible" 
		var iCnt=0;
		for(var ix=0; ix<this.aVtnsAbiertas.length; ix++) {
			if(! this.aVtnsAbiertas[ix].SiempreVisible() ) 
				iCnt++;
		}
		
		if( (iCnt==0) ||  (iCnt==1 && this._OcultarSiSoloUna) )
		    Element.hide(this.divVtn);
		else
			Element.show(this.divVtn);
		
			
	}
	
};
// Cuando una página se carga, debe ejecutar un script que construya su objeto "cPagina"
// correspondiente.
var cPagina = Class.create();
	cPagina.prototype={
	initialize: function( sContenedorId, sPaginaPost, arrParamsComunesPost) {
		this._base_initialize( sContenedorId, sPaginaPost, arrParamsComunesPost);
	},
	DestruirVtn: function(){ 
		oGestorEntorno.VtnsAbiertas.DestruirVtn(this.Vtn()); 
		this._ContenedorId = null; 
	},	
	Dormir:function(){/*Nada que hacer*/},	
	AddDespertar:function(fx){this._base_addDespertar(fx);},
	Despertar:function(){this._base_despertar();},	
	
	StopObservers:function(){/*Nada que hacer: La página está siendo destruida (Sucede cuando destruyen a su Vtn)*/},
	
	doPost: function(arrParams, bVerificarCampos) {
		this._base_doPost( arrParams, bVerificarCampos );
	},
	doPostRefresh: function(arrParams, bVerificarCampos) {
		var tmpPars;
		tmpPars=$A();
		if(arrParams!=undefined) 
			for(var i=0; i<this.arrParams; i+=2) {
				tmpPars.push( arrParams[i], arrParams[i+1] );
			}
		tmpPars.push( 'EVT', 'REFRESH' );
		this._base_doPost( tmpPars, bVerificarCampos );
	},		
	doPostEvent: function(sEvento, bVerificarCampos) {
		this._base_doPost( ['EVT', sEvento ], bVerificarCampos );
	},
	_base_addDespertar: function(fx){
	    this._arrDespertar.push(fx);
	},
	_base_despertar: function(){
	    for(var i=0; i<this._arrDespertar.length; i++)	    	
	        this._arrDespertar[i]();
	},	
	_base_doPost: function(arrParams, bVerificarCampos) {
		
		if( typeof(bVerificarCampos) == 'undefined' || typeof(_DataRangeVerify) == 'undefined')
			 bVerificarCampos = false;
			 
		if( bVerificarCampos) {
			if( !eval("_DataRangeVerify('" + this._sContenedorId + "',errRangeVerify, errRangeVerifyButtonValue);")) 
				return;
		}
				
		var tmpPars;
		if(arrParams!=undefined) {
			tmpPars = $A();
			for(var i=0;	i<this._arrParamsComunesPost.length;	i++)
				tmpPars.push( this._arrParamsComunesPost[i] );
			for(var i=0; i<arrParams.length;i+=2) {
				tmpPars.push( arrParams[i], arrParams[i+1] );
			}
		} else 
			tmpPars = this._arrParamsComunesPost;
		
		this.StopObservers(); // Antes de lanzar la actualización, se deberían eliminar los eventos.
		
		this.Vtn().Cargar( this._sPaginaPost, tmpPars );

	},
	_base_initialize: function(sContenedorId, sPaginaPost, arrParamsComunesPost) {
		this._sContenedorId = sContenedorId;
		this._sPaginaPost = toAbsolutePath(sPaginaPost);
		this._arrParamsComunesPost = $A();
		this._arrDespertar = $A();
		
		for(var i=0; i<arrParamsComunesPost.length; i+=2){
			this._arrParamsComunesPost.push( arrParamsComunesPost[ i ] );
			this._arrParamsComunesPost.push( arrParamsComunesPost[ i + 1 ] );
		}
		
		this.Vtn().RegistrarPagina( this );
		// Revisión de controles que deban ser reconstruidos en tiempo cliente.
		if(typeof(_ConstruirControles)!='undefined') eval("_ConstruirControles('"+this._sContenedorId+"');");
	
	},

	Vtn: function() {
		return $(this._sContenedorId).Vtn;
	},
	SetIcon: function( sNewIcon ) {
		this.Vtn().SetIcon( toAbsolutePath(sNewIcon) );
	},
	SetTitle: function( sNewTitle ) {
		this.Vtn().SetTitle(sNewTitle);
	},
	SetHead: function( sNewIcon, sNewTitle) {
		this.Vtn().SetHead( sNewIcon, sNewTitle);
	},
	$: function(lName) {
		return this.Vtn().$(lName);
	},
	$F: function(lName) {
		return this.Vtn().$F(lName);
	}, 
	L2G: function(lName) {
		return this.Vtn().L2G(lName);
	}
};

// Función genérica de postback a partir del contenedorId
function doPost(ContainerId, arrParametros, bVerificarCampos) {
	var oContenedor = $(ContainerId);
	if(oContenedor!=null) {
		if( typeof(oContenedor.Vtn) != 'undefined' ) {
			if( oContenedor.Vtn != null ) {
				if( oContenedor.Vtn.GetPagina()!=null )
						oContenedor.Vtn.GetPagina().doPost(arrParametros, bVerificarCampos);
			}
		}
	}
}
function doPostEvent(element, sEvent, bVerificarCampos) {
	element=$(element);
	if(typeof(element) != 'undefined') {
		while(element!=null && element!=document) {
			if( typeof(element.Vtn) != 'undefined' ) {
				element.Vtn.GetPagina().doPostEvent(sEvent, bVerificarCampos);
				return;
			}
			element=element.parentNode;
		}
	}
}
function doPostRefresh(element, arrParams, bVerificarCampos) {
	element=$(element);
	if(typeof(element) != 'undefined') {
		while(element!=null && element!=document) {
			if( typeof(element.Vtn) != 'undefined' ) {
				element.Vtn.GetPagina().doPostRefresh(arrParams, bVerificarCampos);
				return;
			}
			element=element.parentNode;
		}
	}
}

