/*
	Título..: xwin - mr.xkr's JavaScript Windows, implementación de ventanas DHTML
	Licencia: GPL (http://www.gnu.org/licenses/gpl.txt)
	Autor...: Pablo Rodríguez Rey (mr -en- xkr -punto- es)
	          http://mr.xkr.es/
	Usa libremente esta librería bajo los términos de la licencia GPL, pero por favor,
	deja la autoría intacta, es lo único que te pido, sólo son 397 bytes de carga ;-)
*/

// rutas por defecto
var xwinImagePath="images/";
var xwinImageMin="xwin_bmin.gif";
var xwinImageMax="xwin_bmax.gif";
var xwinImageRestore="xwin_bres.gif";
var xwinImageClose="xwin_bclose.gif";
var xwinImageGenIcon="xwin_igen.gif";
var xwinImageTrans="xwin_trans.gif";

// opciones por defecto
var xwinBorderSize=4;
var xwinBorderResize=10;
var xwinShadowSizeLeft=5;
var xwinShadowSizeTop=9;
var xwinMoveMinSize=4;
var xwinMinWidth=150;
var xwinMinHeight=24;

// variables de las ventanas
var xwin=new Array();
var xwinMax=0;

// estado de las ventanas
var xwinActive=0;
var xwinActiveAction=0;
var xwinForeground=0;
var xwinIsTitle=false;
var xwinIsMain=false;
var xwinMoving=false;
var xwinResizing=false;
var xwinMaximized=false;
var xwinMoveMinSizeReached=false;
var xwinAlphaShadow=false;
var xwinNoSelect=false;

// posiciones iniciales en movimientos/redimensionamiento
var xwinStartL;
var xwinStartT;
var xwinStartX;
var xwinStartY;
var xwinStartW;
var xwinStartH;
var xwinLastScrollX;
var xwinLastScrollY;
var xwinCreateL=0;
var xwinCreateT=0;
var xwinZIndex=100;

// constantes de redimensionamiento
var xwinRESLEFT=1;
var xwinRESRIGHT=2;
var xwinRESTOP=3;
var xwinRESBOTTOM=4;
var xwinRESTOPLEFT=5;
var xwinRESTOPRIGHT=6;
var xwinRESBOTTOMLEFT=7;
var xwinRESBOTTOMRIGHT=8;

// constantes de títulos
var xwinTMINIMIZE="Minimizar";
var xwinTRESTORE="Restaurar";
var xwinTMAXIMIZE="Maximizar";
var xwinTCLOSE="Cerrar";

// caché de imágenes
var xwinImageCache=false;


// traer una ventana al frente
function xwinFocus(wid) {
	xwinForeground=wid;
	for (i=1;i<=xwinMax;i++) {
		if (xwin[i] && i!=wid) {
			if (xwin[i].xwinMain.className!="xwinmain xwinmaindisabled") xwin[i].xwinMain.className="xwinmain xwinmaindisabled";
			if (xwin[i].xwinTitle.className!="xwintitle xwintitledisabled") xwin[i].xwinTitle.className="xwintitle xwintitledisabled";
		}
	}
	if (!xwin[wid]) return;
	xwin[wid].xwin.style.zIndex=++xwinZIndex;
	xwin[wid].xwinShadow.style.zIndex=++xwinZIndex;
	xwin[wid].xwinMain.style.zIndex=++xwinZIndex;
	if (!xwin[wid].disabled) {
		xwin[wid].xwinMain.className="xwinmain";
		xwin[wid].xwinTitle.className="xwintitle";
	}
	for (i=1;i<=xwinMax;i++) {
		if (xwin[i]) {
			if (xwin[i].ontop) {
				xwin[i].xwin.style.zIndex=++xwinZIndex;
				xwin[i].xwinShadow.style.zIndex=++xwinZIndex;
				xwin[i].xwinMain.style.zIndex=++xwinZIndex;
			}
		}
	}
}

// comprobar si el ratón se encuentra en los bordes
// y actuar en caso de estar en un borde de cambio de tamaño
function xwinMouseMoveCheck(e) {
	var x,y,wid=xwinActive;
	if (!wid) return;
	if (!xwin[wid] || xwinResizing || xwinMoving) return;
	if (xwin[wid].xwinMaximized || xwin[wid].xwinMinimized || xwin[wid].disabled) return;
	if (!e) e=window.event;

	xwinResizeAction=0;

	if (!xwin[wid].noresize) {
		if (e.clientX>=parseInt(xwin[wid].xwinMain.style.left)
			&& e.clientX<=(parseInt(xwin[wid].xwinMain.style.left)+parseInt(xwin[wid].xwinMain.style.width))
			&& e.clientY>=parseInt(xwin[wid].xwinMain.style.top)
			&& e.clientY<=(parseInt(xwin[wid].xwinMain.style.top)+parseInt(xwin[wid].xwinMain.style.height))
			) {

		  var sx=ietruebody().scrollLeft;
			var sy=ietruebody().scrollTop;

			x1=(e.clientX-parseInt(xwin[wid].xwinMain.style.left))-sx;
			x2=-(e.clientX-parseInt(xwin[wid].xwinMain.style.left)-parseInt(xwin[wid].xwinMain.style.width))+1-sx;
			y1=(e.clientY-parseInt(xwin[wid].xwinMain.style.top))-sy;
			y2=-(e.clientY-parseInt(xwin[wid].xwinMain.style.top)-parseInt(xwin[wid].xwinMain.style.height))+1-sy;

			if (x1>=0 && x1<=xwinBorderSize) xwinResizeAction=xwinRESLEFT;
			if (x2>=0 && x2<=xwinBorderSize) xwinResizeAction=xwinRESRIGHT;
			if (y1>=0 && y1<=xwinBorderSize) xwinResizeAction=xwinRESTOP;
			if (y2>=0 && y2<=xwinBorderSize) xwinResizeAction=xwinRESBOTTOM;

			if (x1>=0 && x1<=xwinBorderResize && y1>=0 && y1<=xwinBorderResize) xwinResizeAction=xwinRESTOPLEFT;
			if (x2>=0 && x2<=xwinBorderResize && y1>=0 && y1<=xwinBorderResize) xwinResizeAction=xwinRESTOPRIGHT;
			if (x1>=0 && x1<=xwinBorderResize && y2>=0 && y2<=xwinBorderResize) xwinResizeAction=xwinRESBOTTOMLEFT;
			if (x2>=0 && x2<=xwinBorderResize && y2>=0 && y2<=xwinBorderResize) xwinResizeAction=xwinRESBOTTOMRIGHT;

			if (xwinResizeAction) {
				switch (xwinResizeAction) {
				case xwinRESTOPLEFT: xwin[wid].xwinTitle.style.cursor="NW-resize"; break;
				case xwinRESTOPRIGHT: xwin[wid].xwinTitle.style.cursor="NE-resize"; break;
				case xwinRESBOTTOMRIGHT: xwin[wid].xwinMain.style.cursor="NW-resize"; break;
				case xwinRESBOTTOMLEFT: xwin[wid].xwinMain.style.cursor="NE-resize"; break;
				case xwinRESLEFT: xwin[wid].xwinMain.style.cursor="E-resize"; break;
				case xwinRESRIGHT: xwin[wid].xwinMain.style.cursor="E-resize"; break;
				case xwinRESTOP: xwin[wid].xwinTitle.style.cursor="N-resize";	break;
				case xwinRESBOTTOM: xwin[wid].xwinMain.style.cursor="N-resize";	break;
				}
				return(false);
			}
		}
	}
	
	xwin[wid].xwinMain.style.cursor="default";
	xwin[wid].xwinTitle.style.cursor="default";
	
}

// hacer click con el ratón... ¿mover? ¿redimensionar?
function xwinMouseDown(e) {
	var wid=xwinActive;

	// comprobar si se ha especificado al sistema
	// que no se permita la selección de texto temporalmente
	if (xwinNoSelect) {
		xwinNoSelect=false;
		return(false);
	}

	// comprobar si hay una ventana seleccionada
	if (!wid) return;
	if (!xwin[wid] || xwinResizing) return;
	if (xwin[wid].disabled || xwin[wid].xwinMaximized) return;
	if (!e) e=window.event;

	xwinStartX=e.clientX;
	xwinStartY=e.clientY;
	xwinStartL=(parseInt(xwin[wid].xwinMain.style.left)!=NaN?parseInt(xwin[wid].xwinMain.style.left):0);
	xwinStartT=(parseInt(xwin[wid].xwinMain.style.top)!=NaN?parseInt(xwin[wid].xwinMain.style.top):0);

	if (xwinIsTitle && !xwinResizeAction && !xwin[wid].nomobile) {
		xwinActiveAction=wid;
		xwinMoving=true;
		xwinMoveMinSizeReached=false;
		return(false);
	}

	if (xwinResizeAction) {
		xwinActiveAction=wid;
		xwinStartW=xwin[wid].xwinMain.offsetWidth;
		xwinStartH=xwin[wid].xwinMain.offsetHeight;
		xwinResizing=true;
		return(false);	
	}

	// comprobar si está dentro de una ventana
	if (!xwinIsMain && !xwinIsTitle) {
		xwinFocus(0);
	}

}

// desplazar el ratón... ¿moviendo? ¿redimensionando?
function xwinMouseMove(e) {
	var wid=xwinActiveAction;
	if (!e) e=window.event;

	// si se está moviendo la ventana
	if (xwinMoving) {
		var x=(e.clientX-xwinStartX);
		var y=(e.clientY-xwinStartY);
		if (xwinMoveMinSizeReached || x>xwinMoveMinSize || y>xwinMoveMinSize || x<-xwinMoveMinSize || y<-xwinMoveMinSize) {
			xwinMoveMinSizeReached=true;
			var newL=(xwinStartL+x),newT=(xwinStartT+y);
			xwin[wid].xwinMain.style.left=newL;
			xwin[wid].xwinMain.style.top=(newT>0?newT:0);
			xwinUpdate(wid);
			xwinMouseMoveCheck(e);
		}
		return(false);
	}

	// si cambiando el tamaño
	if (xwinResizing) {
		var newT=0;
		var minL=0,minT=0;
		var newW=0,newH=0;
		switch (xwinResizeAction) {
		case xwinRESTOPLEFT:
			newL=xwinStartL+(e.clientX-xwinStartX);
			newW=xwinStartW-(e.clientX-xwinStartX);
			newT=xwinStartT+(e.clientY-xwinStartY);
			newH=xwinStartH-(e.clientY-xwinStartY);
			break;
		case xwinRESTOPRIGHT:
			newW=xwinStartW+(e.clientX-xwinStartX);
			newT=xwinStartT+(e.clientY-xwinStartY);
			newH=xwinStartH-(e.clientY-xwinStartY);
			break;
		case xwinRESBOTTOMLEFT:
			newL=xwinStartL+(e.clientX-xwinStartX);
			newW=xwinStartW-(e.clientX-xwinStartX);
			newH=xwinStartH+(e.clientY-xwinStartY);
			break;
		case xwinRESBOTTOMRIGHT:
			newW=xwinStartW+(e.clientX-xwinStartX);
			newH=xwinStartH+(e.clientY-xwinStartY);
			break;
		case xwinRESLEFT:
			newL=xwinStartL+(e.clientX-xwinStartX);
			newW=xwinStartW-(e.clientX-xwinStartX);
			break;
		case xwinRESRIGHT:
			newW=xwinStartW+(e.clientX-xwinStartX);
			break;
		case xwinRESTOP:
			newT=xwinStartT+(e.clientY-xwinStartY);
			newH=xwinStartH-(e.clientY-xwinStartY);
			break;
		case xwinRESBOTTOM:
			newH=xwinStartH+(e.clientY-xwinStartY);
			break;
		}
		
		// hacer efectivas las nuevas posiciones
		if (newL) xwin[wid].xwinMain.style.left=newL;
		if (newT) xwin[wid].xwinMain.style.top=(newT>minT?newT:minT);
		if (newW) {
			if (newW<xwinMinWidth) newW=xwinMinWidth;
			if (xwin[wid].minwidth && newW<xwin[wid].minwidth) newW=xwin[wid].minwidth;
			if (xwin[wid].maxwidth && newW>xwin[wid].maxwidth) newW=xwin[wid].maxwidth;
			xwin[wid].xwinMain.style.width=newW;
		}
		if (newH) {
			if (newH<xwinMinHeight) newH=xwinMinHeight;
			if (xwin[wid].minheight && newH<xwin[wid].minheight) newH=xwin[wid].minheight;
			if (xwin[wid].maxheight && newH>xwin[wid].maxheight) newH=xwin[wid].maxheight;
			xwin[wid].xwinMain.style.height=newH;
		}
		
		// actualizar las capas
		xwinUpdate(wid);
		return(false);
	}

}

// se ha soltado el ratón
function xwinMouseUp(e) {
	xwinActiveAction=0;
	xwinMoving=false;
	xwinResizing=false;
	xwinResizeAction=0;
}

// F4 cierra la ventana activa
function xwinOnKeyDown(e) {
	if (!e) e=window.event;
	if (e.keyCode==115) xwinClose(xwinForeground);
}

// actualizar las posiciones y tamaños de una ventana
function xwinUpdate(wid) {
	var xwinMainWidth=parseInt(xwin[wid].xwinMain.style.width);
	var xwinMainHeight=parseInt(xwin[wid].xwinMain.style.height);

	// barra de título
	xwin[wid].xwinCaption.style.width=xwinMainWidth-xwin[wid].xwinButtons.offsetWidth-(isie()?2:0);

	// sombra
	if (!xwin[wid].xwinMaximized) {
		xwin[wid].xwinShadow.style.left=parseInt(xwin[wid].xwinMain.style.left)+xwinShadowSizeLeft;
		xwin[wid].xwinShadow.style.top=parseInt(xwin[wid].xwinMain.style.top)+xwinShadowSizeTop;
		xwin[wid].xwinShadow.style.width=xwinMainWidth;
		xwin[wid].xwinShadow.style.height=xwinMainHeight;
	} else {
		xwin[wid].xwinShadow.style.visibility="hidden";
	}

	// contenido
	if (!xwin[wid].xwinMaximized && !xwin[wid].xwinMinimized) {
		var bodyW=(xwinMainWidth-xwinBorderSize*2);
		var bodyH=(xwinMainHeight-xwin[wid].xwinTitle.offsetHeight-xwinBorderSize*2);
		xwin[wid].xwinBody.style.left  =xwinBorderSize;
		xwin[wid].xwinBody.style.top   =xwinBorderSize;
		xwin[wid].xwinBody.style.width =(bodyW>1?bodyW:1);
		xwin[wid].xwinBody.style.height=(bodyH>1?bodyH:1);
		xwin[wid].xwinShadow.style.visibility="visible";
	} else {
		var bodyW=(xwinMainWidth);
		var bodyH=(xwinMainHeight-xwin[wid].xwinTitle.offsetHeight-xwinBorderSize);
		xwin[wid].xwinBody.style.left  =0;
		xwin[wid].xwinBody.style.top   =xwinBorderSize;
		xwin[wid].xwinBody.style.width =(bodyW>1?bodyW:1);
		xwin[wid].xwinBody.style.height=(bodyH>1?bodyH:1);
		xwin[wid].xwinShadow.style.visibility="hidden";
	}
	if (bodyW<=1 || bodyH<=1) xwin[wid].xwinBody.style.visibility="hidden";
	else xwin[wid].xwinBody.style.visibility="visible";
	if (xwin[wid].disabled) {
		xwin[wid].xwinDisable.style.left  =xwin[wid].xwinBody.style.left;
		xwin[wid].xwinDisable.style.top   =xwin[wid].xwinBody.style.top;
		xwin[wid].xwinDisable.style.width =xwin[wid].xwinBody.style.width;
		xwin[wid].xwinDisable.style.height=xwin[wid].xwinBody.style.height;
		xwin[wid].xwinDisable.style.visibility="visible";
	} else {
		if (xwin[wid].xwinDisable.style.visibility!="hidden") xwin[wid].xwinDisable.style.visibility="hidden";
	}
}

// evento que mueve todas las ventanas si se desplaza la página
function xwinScroll() {

	// nueva posición
	var scrX=ietruebody().scrollLeft;
	var scrY=ietruebody().scrollTop;

	// mover todas las ventanas afectadas
	for (wid=1;wid<=xwinMax;wid++) {
		if (gid('xwin'+wid)) {
			xwin[wid].xwinMain.style.left=parseInt(xwin[wid].xwinMain.style.left)+(scrX-xwinLastScrollX);
			xwin[wid].xwinMain.style.top=parseInt(xwin[wid].xwinMain.style.top)+(scrY-xwinLastScrollY);
			xwinUpdate(wid);
		}
	}

	// actualizar y restaurar variables
	xwinLastScrollX=scrX;
	xwinLastScrollY=scrY;

}

// comprobar cada 1ms en IE si se ha producido un desplazamiento
function xwinIEscrollTimer() {
	if (ietruebody().scrollLeft!=xwinLastScrollX || ietruebody().scrollTop!=xwinLastScrollY) xwinScroll();
	setTimeout("xwinIEscrollTimer()",1);
}

// cerrar una ventana y destruir el objeto asociado
function xwinClose(wid) {
	xwin[wid].xwin.parentNode.removeChild(xwin[wid].xwin);
	xwin[wid]=false;
	xwinIsTitle=false;
	xwinIsMain=false;
}

// definir el HTML del contenedor de la ventana
function xwinSetBody(wid,html) {
	gid('xwin'+wid+'body').innerHTML=html;
}

// minimizar una ventana
function xwinMin(wid) {
	var l,t,w,h;
	var xw=xwin[wid].xwin;
	
	// comprobar si está minimizada o no
	if (!xwin[wid].xwinMinimized) {
		xwin[wid].xwinMinimized=true;
		if (!xwin[wid].xwinMaximized) {
			xwin[wid].oldpos={
				"left":xwin[wid].xwinMain.style.left,
				"top":xwin[wid].xwinMain.style.top,
				"width":xwin[wid].xwinMain.style.width,
				"height":xwin[wid].xwinMain.style.height
				};
		}
	  l=xwin[wid].xwinMain.style.left;
		t=xwin[wid].xwinMain.style.top;
	  w=xwinMinWidth;
	  h=xwin[wid].xwinTitle.offsetHeight+xwinBorderSize;
		if (gid('xwin'+wid+'bmaxi')) gid('xwin'+wid+'bmaxi').src=xwinImagePath+xwinImageRestore;
		if (gid('xwin'+wid+'bmaxa')) gid('xwin'+wid+'bmaxa').title=xwinTRESTORE;
		if (gid('xwin'+wid+'bmina')) gid('xwin'+wid+'bmina').style.display="none";
		eval("xwin["+wid+"].xwinCaption.ondblclick=function(){xwinMin("+wid+");}");
	} else {
		xwin[wid].xwinMinimized=false;
		if (gid('xwin'+wid+'bmina')) gid('xwin'+wid+'bmina').style.display="inline";
		if (!xwin[wid].xwinMaximized) {
			l=xwin[wid].oldpos.left;
			t=xwin[wid].oldpos.top;
			w=xwin[wid].oldpos.width;
			h=xwin[wid].oldpos.height;
			if (gid('xwin'+wid+'bmaxi')) gid('xwin'+wid+'bmaxi').src=xwinImagePath+xwinImageMax;
			if (gid('xwin'+wid+'bmaxa')) gid('xwin'+wid+'bmaxa').title=xwinTMAXIMIZE;
		} else {
			xwin[wid].xwinMaxFromMin=true;
			xwinRestore(wid);
		}
		eval("xwin["+wid+"].xwinCaption.ondblclick=function(){xwinRestore("+wid+");}");
	}
	
	// aplicar valores de posición y tamaño si procede
	if (!xwin[wid].xwinMaxFromMin) {
		xwin[wid].xwinMain.style.left=l;
		xwin[wid].xwinMain.style.top=t;
		xwin[wid].xwinMain.style.width=w;
		xwin[wid].xwinMain.style.height=h;
		xwinUpdate(wid);
	} else {
		xwin[wid].xwinMaxFromMin=false;
	}
}

// maximizar o restaurar el tamaño de una ventana
function xwinRestore(wid) {
	var l,t,w,h;
	var xw=xwin[wid].xwin;
	
	// si está minimizada, tratar por xwinMin
	if (xwin[wid].xwinMinimized) {
		xwinMin(wid);
		return;
	}
	
	// no se puede maximizar ni restaurar, no hay botón
	if (!gid('xwin'+wid+'bmaxi')) return
	
	// comprobar si está maximizada o no
	if (!xwin[wid].xwinMaximized || xwin[wid].xwinMaxFromMin) {
		xwin[wid].xwinMaximized=true;
		if (!xwin[wid].xwinMaxFromMin) {
			xwin[wid].oldpos={
				"left":xwin[wid].xwinMain.style.left,
				"top":xwin[wid].xwinMain.style.top,
				"width":xwin[wid].xwinMain.style.width,
				"height":xwin[wid].xwinMain.style.height
				};
		}
	  var l=ietruebody().scrollLeft; xwinLastScrollX=l;
		var t=ietruebody().scrollTop; xwinLastScrollY=t;
	  var w=(document.all?ietruebody().clientWidth:document.body.clientWidth);
	  var h=(document.all?ietruebody().clientHeight:document.body.clientHeight);
		gid('xwin'+wid+'bmaxi').src=xwinImagePath+xwinImageRestore;
		gid('xwin'+wid+'bmaxa').title=xwinTRESTORE;
	} else {
		xwin[wid].xwinMaximized=false;
		l=xwin[wid].oldpos.left;
		t=xwin[wid].oldpos.top;
		w=xwin[wid].oldpos.width;
		h=xwin[wid].oldpos.height;
		gid('xwin'+wid+'bmaxi').src=xwinImagePath+xwinImageMax;
		gid('xwin'+wid+'bmaxa').title=xwinTMAXIMIZE;
	}
	
	// aplicar valores de posición y tamaño
	xwin[wid].xwinMain.style.left=l;
	xwin[wid].xwinMain.style.top=t;
	xwin[wid].xwinMain.style.width=w;
	xwin[wid].xwinMain.style.height=h;
	xwinUpdate(wid);
}

// poner mezcla alpha a las sombras de las ventanas
function xwinSetAlphaShadow(wid) {
	xwinAlphaShadow=true;
	for (i=(wid?wid:1);i<=(wid?wid:xwinMax);i++) {
		if (xwin[i].xwin) {
			if (isie()) xwin[i].xwinShadow.style.filter="alpha(opacity=50);";
			else xwin[i].xwinShadow.style.opacity=0.5;
		}
	}
}

// quitar mezcla alpha a las sombras de las ventanas
function xwinUnSetAlphaShadow() {
	xwinAlphaShadow=false;
	for (i=1;i<=xwinMax;i++) {
		if (xwin[i].xwin) {
			if (isie()) xwin[i].xwinShadow.style.filter="";
			else xwin[i].xwinShadow.style.opacity=1;
		}
	}
}

// poner sombras a las ventanas a unas distancias definidas por left y top
// si son 0 y 0 respectiamente se quitan las sombras
function xwinSetShadows(left,top) {
	xwinShadowSizeLeft=left;
	xwinShadowSizeTop=top;
	xwinAlphaShadow=false;
	for (i=1;i<=xwinMax;i++) {
		if (xwin[i].xwin) {
			xwinUpdate(i);
			xwin[i].xwinShadow.style.visibility=(xwinShadowSizeLeft||xwinShadowSizeTop?"visible":"hidden");
		}
	}
}

// poner una ventana siempre encima de las otras
function xwinSetOntop(wid) {
	xwin[wid].ontop=true;
	xwinFocus(xwinForeground);
}

// quitar una ventana de estar siempre encima de las otras
function xwinUnSetOntop(wid) {
	xwin[wid].ontop=false;
	xwinFocus(xwinForeground);
}

// habilitar redimensionaiento de una ventana
function xwinResize(wid) {
	xwin[wid].noresize=false;
}

// deshabilitar redimensionaiento de una ventana
function xwinNoResize(wid) {
	xwin[wid].noresize=true;
}

// habilitar el desplazamiento de una ventana
function xwinMobile(wid) {
	xwin[wid].nomobile=false;
}

// deshabilitar el desplazamiento de una ventana
function xwinNoMobile(wid) {
	xwin[wid].nomobile=true;
}

// mover una ventana y cambiar su tamaño si se especificase
// (todos los parámetros son opcionales excepto la ventana)
function xwinMove(wid,left,top,width,height) {
	xwinLeft(wid,left,true);
	xwinTop(wid,top,true);
	xwinWidth(wid,width,true);
	xwinHeight(wid,height,true);
	xwinUpdate(wid);
}

// cambiar el tamaño de una ventana
function xwinGeometry(wid,width,height) {
	xwinWidth(wid,width,true);
	xwinHeight(wid,height,true);
	xwinUpdate(wid);
}

// cambiar la posición horizontal de una ventana
function xwinLeft(wid,left,noupdate) {
	if (left!=undefined) xwin[wid].xwinMain.style.left=left;
	if (!noupdate) xwinUpdate(wid);
}

// cambiar la posición vertical de una ventana
function xwinTop(wid,top,noupdate) {
	if (top!=undefined) xwin[wid].xwinMain.style.top=top;
	if (!noupdate) xwinUpdate(wid);
}

// cambiar el ancho de una ventana
function xwinWidth(wid,width,noupdate) {
	if (width!=undefined) xwin[wid].xwinMain.style.width=width;
	if (!noupdate) xwinUpdate(wid);
}

// cambiar el alto de una ventana
function xwinHeight(wid,height,noupdate) {
	if (height!=undefined) xwin[wid].xwinMain.style.height=height;
	if (!noupdate) xwinUpdate(wid);
}

// deshabilitar una ventana
function xwinEnable(wid) {
	xwin[wid].disabled=false;
	xwinUpdate(wid);
}

// deshabilitar una ventana
function xwinDisable(wid) {
	xwin[wid].disabled=true;
	xwinUpdate(wid);
}

// crear una nueva ventana
function xwinNew(p) {

	// comprobar si hay caché de imágenes, y en caso contrario inicializar
	if (!xwinImageCache) xwinInit();

	// crear nueva ventana y objetos asociados
	for (wid=1;wid<=xwinMax;wid++) {
		if (!gid('xwin'+wid)) break;
	}
	if (wid>xwinMax) xwinMax=wid;
	else {
		// purgar contador si hay ventanas destruidas
		for (i=xwinMax;i>wid;i--) {
			if (gid('xwin'+i)) break;
		}
		xwinMax=i;
	}
	
	// crear un objeto y copiar los parámetros en el objeto (si se especifican)
	xwin[wid]=new Object();
	if (p) xwin[wid]=p;
	
	if (p.noresize) {
		if (p.nomax==undefined) p.nomax=true;
	}

	// contenido de la ventana
	var w="";
	w+="<div id=xwin"+wid+"shadow class=xwinshadow></div>"
		+"<div id=xwin"+wid+"main class=xwinmain>"
			+"<div id=xwin"+wid+"title class=xwintitle onMouseDown='javascript:return(false);'><table><tr>"
				+"<td><div class=xwincaption><div id=xwin"+wid+"caption onDblClick='javascript:if(!xwin["+wid+"].disabled)xwinRestore("+wid+");' title='"+(p.caption?p.caption:"")+"'"+(isie()?" style='text-overflow: ellipsis;'":"")+">"
					+(p.icon==undefined?"&nbsp; ":"<a href='javascript:void(0)' onDblClick='javascript:if(!xwin["+wid+"].disabled)xwinClose("+wid+");'><img src='"+(p.icon!=""?p.icon:xwinImagePath+xwinImageGenIcon)+"' alt='' width=16 height=16 /></a> ")
					+(p.caption?p.caption:"&nbsp;")+"</div></div></td>"
				+"<td id=xwin"+wid+"buttons class=xwinbuttons>"
					+(p.nomin?"":"<a id=xwin"+wid+"bmina href='javascript:if(!xwin["+wid+"].disabled)xwinMin("+wid+");' title='"+xwinTMINIMIZE+"'><img id=xwin"+wid+"bmini src='"+xwinImagePath+xwinImageMin+"' width=16 height=16 alt='_' /></a>")
					+(p.nomax?"":"<a id=xwin"+wid+"bmaxa href='javascript:if(!xwin["+wid+"].disabled)xwinRestore("+wid+");' title='"+xwinTMAXIMIZE+"'><img id=xwin"+wid+"bmaxi src='"+xwinImagePath+xwinImageMax+"' width=16 height=16 alt='[]' /></a>")
					+(p.noclose?"":"<a id=xwin"+wid+"bclosea href='javascript:if(!xwin["+wid+"].disabled)"+(p.onclose?p.onclose:"xwinClose("+wid+");")+"' title='"+xwinTCLOSE+"'><img id=xwin"+wid+"bclosei src='"+xwinImagePath+xwinImageClose+"' width=16 height=16 alt='X' /></a>")
				+"</td>"
			+"</tr></table></div>"
			+"<div class=xwindisable><div id=xwin"+wid+"disable style=\"background-image:url('"+xwinImagePath+xwinImageTrans+"');\"></div></div>"
			+"<div id=xwin"+wid+"body class=xwinbody></div>"
		+"</div>";

	// crear ventana en el documento
	var win=document.createElement("div");
	win.setAttribute("id","xwin"+wid);
	win.setAttribute("class","xwin");
	win.innerHTML=w;
	document.getElementsByTagName("body")[0].appendChild(win);

	// definir las referencias y variables de esta ventana
	xwin[wid].xwin=gid('xwin'+wid);
	xwin[wid].xwinMain=gid('xwin'+wid+'main');
	xwin[wid].xwinShadow=gid('xwin'+wid+'shadow');
	xwin[wid].xwinCaption=gid('xwin'+wid+'caption');
	xwin[wid].xwinTitle=gid('xwin'+wid+'title');
	xwin[wid].xwinBody=gid('xwin'+wid+'body');
	xwin[wid].xwinDisable=gid('xwin'+wid+'disable');
	xwin[wid].xwinButtons=gid('xwin'+wid+'buttons');
	xwin[wid].xwinMinimized=false;
	xwin[wid].xwinMaximized=false;

	// definir eventos de la ventana
	eval("xwin["+wid+"].xwinTitle.onmouseover=function(){xwinIsTitle=true;xwinActive="+wid+";}");
	eval("xwin["+wid+"].xwinTitle.onmouseout=function(){xwinIsTitle=false;xwinActive=0;}");
	eval("xwin["+wid+"].xwinMain.onmouseover=function(){xwinIsMain=true;xwinActive="+wid+";}");
	eval("xwin["+wid+"].xwinMain.onmouseout=function(){xwinIsMain=false;}");
	eval("xwin["+wid+"].xwinMain.onmousedown=function(){if(!xwin["+wid+"].disabled && xwinForeground!="+wid+")xwinFocus("+wid+");}");
	eval("xwin["+wid+"].xwinMain.onmousemove=xwinMouseMoveCheck;");
	eval("xwin["+wid+"].xwinTitle.onmousemove=xwinMouseMoveCheck;");

  var scrX=ietruebody().scrollLeft; xwinLastScrollX=0;
	var scrY=ietruebody().scrollTop; xwinLastScrollY=0;
  var maxW=(document.all?ietruebody().clientWidth:document.body.clientWidth);
  var maxH=(document.all?ietruebody().clientHeight:document.body.clientHeight);

	// tamaño y posición inicial
	xwin[wid].xwinMain.style.width =(p.width ?p.width :xwin[wid].xwinMain.offsetWidth);
	xwin[wid].xwinMain.style.height=(p.height?p.height:xwin[wid].xwinMain.offsetHeight);

	// tamaño y posición iniciales
	xwin[wid].xwinMain.style.left=(p.left?p.left:xwinCreateL=(xwinCreateL+24)%200)+scrX;
	xwin[wid].xwinMain.style.top =(p.top ?p.top :xwinCreateT=(xwinCreateT+24)%200)+scrY;
	if (p.center) {
		if (!p.left) xwin[wid].xwinMain.style.left=((maxW-xwin[wid].xwinMain.offsetWidth)/2+scrX);
		if (!p.top) xwin[wid].xwinMain.style.top =((maxH-xwin[wid].xwinMain.offsetHeight)/2+scrY);
	}
	
	// actualizar tamaños de la ventana
	xwinUpdate(wid);

	// si hay contenido, cambiar
	if (p.body) xwinSetBody(wid,p.body);

	// mostrar ventana y su sombra (si procede)
	if (xwinShadowSizeLeft || xwinShadowSizeTop) {
		xwin[wid].xwinShadow.style.visibility="visible";
		if (xwinAlphaShadow) xwinSetAlphaShadow(wid);
	}
	xwin[wid].xwinMain.style.visibility="visible";

	// traer al frente
	xwinFocus(wid);

	// comprobar si se inicia maximizada
	if (p.maximized) xwinRestore(wid);

	// actualizar todo
	xwinUpdateAll();

	// devolver el identificador de ventana
	return(wid);

}

// limpieza de todas las ventanas y variables
function xwinClean() {
	
	// cerrar todas las ventanas abiertas
	for (i=1;i<=xwinMax;i++) {
		if (xwin[i].xwin) xwinClose(i);
	}
	
	// limpiar variables
	xwin=new Array();
	xwinMax=0;
	xwinCreateL=0;
	xwinCreateT=0;
	xwinZIndex=100;
	xwinImageCache=new Array();

}

// inicialización de las ventanas
// no es necesario llamar a esta función, pero cuanto antes se llame a la misma,
// antes estarán disponibles las imágenes para los botones de las ventanas
function xwinInit() {

	// limpiar variables
	xwinClean();
	
	// precarga de todas las imágenes
	var imageList=Array(xwinImageGenIcon,xwinImageMin,xwinImageMax,xwinImageRestore,xwinImageClose);
	xwinImageCache=new Array();
	for (i=0;i<imageList.length;i++) {
		xwinImageCache[i]=new Image();
		xwinImageCache[i].src=xwinImagePath+imageList[i];
	}

	// activar timer para Internet Explorer que no tiene el evento onscroll
	if (isie()) xwinIEscrollTimer();

	// primera inicialización
	xwinUpdateAll();

}

// inicialización de las variables y eventos
function xwinUpdateAll() {

	// inicializar variables
	xwinIsTitle=false;
	xwinIsMain=false;
	xwinMoving=false;
	xwinResizing=false;
	xwinMaximized=false;
	xwinMoveMinSizeReached=false;

	// declarar los eventos	necesarios
	document.onmouseup=xwinMouseUp;
	document.onmousedown=xwinMouseDown;
	document.onmousemove=xwinMouseMove;
	document.onscroll=xwinScroll;
	document.onkeydown=xwinOnKeyDown;

}