// Objeto Menu contenedor de:
//		una colección de opciones, posición del menú, indicador de opción activa,
//		y dos métodos, uno para añadir y otro para inicializar las posiciones.
function Menu() {
	this.aOptions = new Array();
	this.addOption = f_addOption;
	this.initialize = f_initialize;
	this.activeOpt = null;
	this.y = arguments[0];
	this.x = arguments[1];
}
// Añade opciones, recibiendo un objeto opción o los parametros necesarios para crearlo
function f_addOption() {
	if(arguments.length!=1) {
		this.aOptions[this.aOptions.length] = new Option(arguments[0], arguments[1], arguments[2], this);
	} else {
		this.aOptions[this.aOptions.length] = arguments[0];
	}
}
// Llama a todas las opciones del menú solicitado que se recoloquen y muestra sus capas.
function f_initialize() {
	var cont;
	for(cont=0; cont<this.aOptions.length; cont++) {
		this.aOptions[cont].relocate();
		f_shLayer(this.aOptions[cont].name, true);
		if(this.aOptions[cont].child!=null) {
			f_shLayer(this.aOptions[cont].child, true);
		}
	}
}
// Objeto Option detallado en su interior
function Option() {
	this.name = arguments[0];			// Capa con la opcion
	this.child = arguments[1];			// Capa con el menú desplegable
	this.prev = arguments[2];			// Opcion anterior
	this.parent = arguments[3];			// Opcion siguiente (para comunicar despl.)
	this.relocate = f_relocate;			// Metodo que recologa
	if(this.prev!=null) this.prev.next = this;		// Decimos a opc. ant. somos la sig.
	this.x = 0;
	this.y = 0;
	this.height = 0;
	this.childHeight = 0;
	this.click = f_click;
	this.open = f_open;
	this.close = f_close;
	this.slide = f_slide;				// Desplazamiento por apert. de una opcion ant.
	this.active = false;
}
// Metodo que coloca la capa en su sitio. Si se le ha especificado una x manualmente
// la respeta, sino se acoje a la posición del menú. Si es la primera opción se
// acoje a la posición y del menu, sino a la opción anterior mas un margen.
function f_relocate() {
	this.x = (this.x != 0?this.x:this.parent.x);
	this.y = (this.y != 0?this.y:(this.prev!=null?this.prev.y+this.prev.height+7:this.parent.y));
	this.height = f_layerHeight(this.name);
	f_mLayer(this.name, this.y, this.x);
	if(this.child!=null) {
		this.childHeight = f_layerHeight(this.child);
		f_mLayer(this.child, this.y+this.height, this.x+5);
		f_cLayer(this.child, 0);
	}
}
// Función que mueve una capa (sName) a una posición (y o x), para ignorar un
// parametro hay que pasarle null.
function f_mLayer(sName, ypos, xpos) {
	oLayer = (document.all?document.all[sName].style:document.layers[sName]);
	if(ypos!=null) oLayer.top = ypos;
	if(xpos!=null) oLayer.left = xpos;
}
// Función que mide la altura de una capa.
function f_layerHeight(sName) {
	oLayer = (document.all?document.all[sName]:document.layers[sName]);
	return (document.all?oLayer.offsetHeight:oLayer.document.height);
}
// Función que clipa la vertical de una capa.
function f_cLayer(sName, nHeight) {
	if(document.all) {
		document.all[sName].style.clip = "rect(0 183 "+nHeight+" 0)";
	} else {
		document.layers[sName].clip.bottom = nHeight;
	}
}
// Se pulsa una opción
function f_click() {
	if(this.parent.activeOpt!=null) {		// ¿Existe una activa?
		bOpenThis = !this.active;			// Me abriré si estoy cerrada
		this.parent.activeOpt.close();		// Cerramos la que había abierta (que puedo ser yo)
		if(bOpenThis) this.open();			// Reacciono y me cierro si toca.
	} else {
		this.open();						// Me abro incondicionalmente
	}
}
// Setea la opción, abre la capa y produce los desplazamientos
function f_open() {
	this.active = true;
	this.parent.activeOpt = this;
	f_cLayer(this.child, this.childHeight);
	if(this.next!=null) this.next.slide(this.childHeight);
}
// Setea la opción, cierra la capa y produce los desplazamientos
function f_close() {
	this.active = false;
	this.parent.activeOpt = null;
	f_cLayer(this.child, 0);
	if(this.next!=null) this.next.slide(-this.childHeight);
}
// Desplaza una opcion y las opciones sucesivas
function f_slide() {
	f_mLayer(this.name, Math.max(this.y, this.y+arguments[0]));
	if(this.next!=null) this.next.slide(arguments[0]);
}
// Funcion que muestra (true) oculta (false) una capa.
function f_shLayer(sName, bStatus) {
	oLayer = (document.all?document.all[sName].style:document.layers[sName]);
	oLayer.visibility = (bStatus?(document.all?"inherit":"show"):"hidden");
}
