/*
 * Capsula.java
 *
 *
 *
 *
 */
package com.uvigo.tMaestro.SCOCreator.tool;

import com.uvigo.tMaestro.SCOCreator.tool.properties.Propiedad;
import java.awt.event.MouseEvent;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.xml.parsers.*;
import javax.xml.xpath.*;
import org.w3c.dom.*;
import org.xml.sax.SAXException;

/**
 * Esta clase encapsula cada uno de los beans, proporcion�ndoles a �stos, entre
 * otras cosas, la capacidad de ser seleccionados en el entorno de la herramienta
 * Esta clase es la encargada de hacer la introspecci�n de cada bean.
 * En general es la clase b�sica (unidad m�nima) que respresenta un objeto
 * gr�fico editable en el entorno de la herramienta. Posee toda la informaci�n
 * necesaria relativa al objeto para poder ser personalizado.
 * Ver variables de la clase.
 * @author RA
 * @version 0.5
 */
public class Capsula extends javax.swing.JPanel implements java.awt.event.MouseListener, java.awt.event.MouseMotionListener {

    /**
     * Un Array de objetos de la clase Propiedad.
     * Respresenta las propiedades del Bean que
     * encapsula esta c�psula.
     * @see Propiedad
     */
    private java.util.ArrayList<Propiedad> oPropiedades;
    /**
     * Referencia al bean que se est� encapsulando.
     * En general deber� ser un objeto que herede de java.awt.Component.
     */
    private java.awt.Component oBean;
    /**
     * Algunos componentes no son mostrados tal cual en el entorno.
     * En su lugar se muestra esta etiqueta, por ej, el Media Player
     */
    private javax.swing.JLabel oLabel;
    /**
     * Esta variable indica si el elemento est� activo.
     */
    private boolean bActivo = false;
    /**
     * Un Array con las c�psulas hijas de esta c�psula.
     * Una c�psula hija es un componente que forma
     * parte (visualmente) de la c�psula padre.
     * Es decir una c�psula hija encapsula un bean que es hijo
     * del objeto que encapsula la c�psula padre.
     * Est�n ordenada en el orden de la componente Z
     */
    private java.util.ArrayList<Capsula> oCapsulasHijas;
    /**
     * Referencia a la c�psula padre
     */
    private Capsula oCapsulaPadre;
    /**
     * Guarda la tablas de propiedades de este bean. A diferencia
     * de la variable oPropiedades, esta es utilizada por motivos
     * de presentaci�n al usuario.
     */
    private java.util.ArrayList<javax.swing.table.TableModel> oTablas;
    /**
     * Posicion original del Bean contenido en la coordebada X relativa al
     * elemento padre.
     */
    private int iX;
    /**
     * Posicion original del Bean contenido en la coordebada Y relativa al
     * elemento padre.
     */
    private int iY;
    /**
     * Posici�n original del Bean contenido en la coordenada Z realita al elemento
     * padre
     */
    private int iZ;
    /**
     * Anchura original del Bean contenido.
     */
    private int iWidth;
    /**
     * Altura original del Bean contenido.
     */
    private int iHeight;
    /**
     * Indica  la visibilidad original del Bean contenido
     */
    private boolean bVisible;
    /**
     * X del bean en cada una de las opciones
     */
    private java.util.ArrayList<Integer> oXs;
    /**
     * Y del del bean en cada una de las opciones
     */
    private java.util.ArrayList<Integer> oYs;
    /**
     * Z del del bean en cada una de las opciones
     */
    private java.util.ArrayList<Integer> oZs;
    /**
     * Anchura del bean en cada una de las opciones
     */
    private java.util.ArrayList<Integer> oWidths;
    /**
     * Altura del bean en cada una de las opciones
     */
    private java.util.ArrayList<Integer> oHeights;
    /**
     * Indica si el bean es visible en cada una de las opciones
     */
    private java.util.ArrayList<Boolean> oVisible;
    /**
     * Nombre original del bean en la plantilla
     */
    private String sComponentName;
    /**
     * Indica si el componente encerrado por esta c�psula
     * se puede redimensionar o cambiar su posicion
     * 0 --> no se puede ni dimensionar ni mover
     * 1 --> se puede mover y redimensionar
     * 2 --> solo se puede alterar la componente Z
     */
    private int iSizeMove;
    /**
     * Variable que se utiliza para el movimiento y el dimensionamiento
     * del componente a trav�s del rat�n
     */
    private java.awt.Point punto;
    /**
     * Indica si el redimensionamiento del componente es en la coordenada X, en la Y, en ambas
     * o en ninguna.
     * 0 --> ninnguna
     * 1 --> X
     * 2 --> Y
     * 3 --> X & Y
     */
    private int iSizeType = 0;
    /**
     * Grosor sobre los bordes para que aparezca el rat�n de redimensionado
     */
    public final static int GROSOR = 5;
    public final static int SIZEMOVE = 1;
    public final static int NOTSIZEMOVE = 0;
    public final static int ONLYZ = 2;

    //------------------------------------------------------------------------//
    // METODOS
    //------------------------------------------------------------------------//
    /**
     * Crea una nueva instancia de esta clase. Si el objeto es un panel, la
     * c�psula toma su tama�o y posici�n y a ella se a�ade el panel. La c�psula
     * es presentada en pantalla a�adi�ndola a su c�psula padre.
     * Cada uno de los elementos del panel original es, a su vez, encapsulado
     * en un objeto de esta clase para poder ser tratado por la herramienta.
     * No obstante, a diferencia de los paneles, los componentes no se a�aden a
     * la capsula (ya que visualmente estos ya se encuantran en el entorno
     * a�adidos mediante la adici�n del panel a su correspondiente c�psula)
     * En su lugar, la c�psula (con el mismo tama�o del componente) se a�ade
     * (sin ning�n componente sobre ellas) a la c�psula padre (c�psula del panel
     * al que pertenece el mismo componente) en la misma posici�n en la que se
     * encuentra el componente. Para evitar que el componente sea ocultado,
     * hacemos que las c�psulas de componentes sean transparentes. Esta forma
     * de actuar nos permite evitar el comportamiento no deseado de ciertos
     * componentes en el entorno de edici�n (por ejemplo, si hacemos "click"
     * sobre un HButton el bot�n se hunde, adem�s los HButton se apropian de los
     * eventos del rat�n con lo que no es coherente definir un MouseListener, ya
     * nunca ser�a llamado por la funci�n processMouseEvent definida en HButton).
     * De esta forma cuando el usuario interaccione con los componentes, lo
     * estar� haciendo realmente con las c�psulas de dichos componentes, lo
     * que permitir� comportamientos diferentes a los de ejecuci�n.
     * El resultado de la ejecucu�n de esta funci�n altera la jerarqu�a de contenedores
     * (unos elementos dejan de ser hijos de otros para convertirse en hijos de
     * capsulas que a su vez son hijas de otros componentes). La alteraci�n de
     * esta jerarqu�a no nos afecta en lo que a presentaci�n se refiere (es m�s,
     * es el efecto que buscamos), no obstante nos interesa conocer la jerarqu�a
     * original para generar los ficheros .xml de configuraci�n, para presentarla
     * al usuario, etc. Ello nos obliga a mantener una relaci�n de c�psulas
     * hijas de una c�psula. Existen otros motivos para guardar esta relaci�n, como
     * por ejemplo el visor de jeraqu�as, etc.
     * @param oPadre Referencia de la que ser� la c�psula padre (contenedora)
     * @param oBean El objeto que va a ser "encapsulado" dentro de esta c�psula.
     * @param iOpciones El n�mero de opciones a tener en cuenta.
     * @param iSizeMove Indica la pol�tica de redimensionado y posicionado de la
     * c�psula.
     * @throws java.awt.AWTException Si se produce alg�n error durante el
     * procesado de la plantilla.
     * @throws java.beans.IntrospectionException Si se produce alg�n error
     * durante la introspecci�n de los componentes de la plantilla.
     */
    public Capsula(javax.swing.JPanel oPadre, java.awt.Component oBean, int iOpciones, int iSizeMove, String sNombre) throws java.awt.AWTException, java.beans.IntrospectionException {
        System.out.println("Capsula- oBean: "+oBean.getName());
        this.iSizeMove = iSizeMove;
        if (oPadre instanceof Capsula) {
            oCapsulaPadre = (Capsula) oPadre;
        }
        oTablas = new java.util.ArrayList<javax.swing.table.TableModel>();
        this.oBean = oBean;
        this.iX = oBean.getX();
        this.iY = oBean.getY();
        if (oBean.getParent() != null) this.iZ = oBean.getParent().getComponentZOrder(oBean);
        else this.iZ = -1;
        this.iWidth = oBean.getWidth();
        this.iHeight = oBean.getHeight();
        this.bVisible = oBean.isVisible();
        this.sComponentName = oBean.getName();
        if (sComponentName == null) {
            throw (new java.awt.AWTException("All components must be named"));
        }

        System.out.println("name: " + oBean.getName() + " iSizeMove: " + iSizeMove + " bVisible: " + oBean.isVisible() + " x: " + oBean.getX() + " y: " + oBean.getY() + " w: " + oBean.getWidth() + " h: " + oBean.getHeight() + " z: " + this.iZ + " parent: " + oBean.getParent());

        //Si se trata de un componente que es a su vez contenedor
        if (oBean instanceof com.uvigo.mhp.ui.HPanel) {

            System.out.println("componente que es contenedor");

            java.awt.Container oContenedor = (java.awt.Container) oBean;
            //Todos los paneles excepto el Multipanel deben tener Layout nulo. El multipanel est� autorizado a tener el CardLayout
            if ((oContenedor.getLayout() != null) && (!(oBean instanceof com.uvigo.mhp.ui.HMultiPanel))) {
                throw (new java.awt.AWTException("This method doesn't support containers with layouts"));
            }
            java.awt.Component[] oComponentes = oContenedor.getComponents();
            if (oContenedor.getWidth() == 0) {
                //System.out.println("contenedor sin bounds definidos..");
                int iBordes = MainFrame.oMainFrame.oGetPanel().oGetBordeActivo().iGetGrosor();
                oContenedor.setLocation(oPadre.getX() + iBordes, oPadre.getY() + iBordes);
                oContenedor.setSize(oPadre.getWidth() - 2 * iBordes, oPadre.getHeight() - 2 * iBordes);
            } else {
                this.setBounds(oContenedor.getBounds());
            }
            if (oComponentes.length != 0) {
                oCapsulasHijas = new java.util.ArrayList<Capsula>();

                //Si el contenedor es un multipanel, sus hijos no pueden ni moverse ni redimensionarse
                if (oBean instanceof com.uvigo.mhp.ui.HMultiPanel) {
                    java.awt.Insets oInsets = ((java.awt.Container) oBean).getInsets();
                    int i = 0;
                    //A�adimos el primer elemento del multipanel
                    //Este ser� el elemento visible
                    if (oComponentes[i] instanceof com.uvigo.mhp.ui.HMultiPanel) {
                        throw (new java.awt.AWTException("HMultiPanel can not contain others multipanels"));
                    }
                    oComponentes[i].setSize(oBean.getSize().width - oInsets.left - oInsets.right, oBean.getSize().height - oInsets.top - oInsets.bottom);
                    oComponentes[i].setLocation(oInsets.left, oInsets.top);
                    oComponentes[i].setVisible(true);
                    Capsula oCapsulaHija = new Capsula(this, oComponentes[i], iOpciones, Capsula.ONLYZ, sNombre);
                    oCapsulasHijas.add(oCapsulaHija);
                    //Resto de elementos del multipanel- igual pero no visibles
                    for (i = 1; i < oComponentes.length; i++) {
                        if (oComponentes[i] instanceof com.uvigo.mhp.ui.HMultiPanel) {
                            throw (new java.awt.AWTException("HMultiPanel can not contain others multipanels"));
                        }
                        oComponentes[i].setSize(oBean.getSize().width - oInsets.left - oInsets.right, oBean.getSize().height - oInsets.top - oInsets.bottom);
                        oComponentes[i].setLocation(oInsets.left, oInsets.top);
                        //El resto de los elementos ser�n inicialmente invisibles
                        oComponentes[i].setVisible(false);
                        oCapsulaHija = new Capsula(this, oComponentes[i], iOpciones, Capsula.ONLYZ, sNombre);
                        oCapsulasHijas.add(oCapsulaHija);
                    }


                } //Si no es un multipanel
                else {
                    for (java.awt.Component oComponente : oComponentes) {
                        Capsula oCapsulaHija = new Capsula(this, oComponente, iOpciones, Capsula.SIZEMOVE, sNombre);
                        oCapsulasHijas.add(oCapsulaHija);
                    }
                }
            }
            this.setLayout(null);
            this.setLocation(oContenedor.getLocation());
            this.setSize(oContenedor.getWidth(), oContenedor.getHeight());
            oContenedor.addMouseListener(this);
        } else { // Si se trata de un componente que no es a su vez contenedor (HPanel)

            //System.out.println("componente que NO es contenedor");

            //Primero contemplamos la posibilidad de que el componente sea un HScrollPane.
            //Los HScrollPane s�lo podr�n tener un componente que no sea contenedor (HPanel)
            //Para nosotros el ScrollPanel es un component, no un container
            if (oBean instanceof com.uvigo.mhp.ui.HScrollPane) {
                this.setLayout(null);
                this.setLocation(oBean.getLocation());
                this.setSize(oBean.getWidth(), oBean.getHeight());
                this.setOpaque(false); //Con esta opci�n es visible el componente original
                //Ahora debemos a�adir el elemento encerrado en el ScrollPane como una c�psula hija
                //de esta c�psula. Le damos el tama�o del ScrollPane
                java.awt.Component oComponent = ((com.uvigo.mhp.ui.HScrollPane) oBean).getViewport().getView();
                oComponent.setSize(oBean.getWidth(), oBean.getHeight());
                //if (oComponent instanceof com.uvigo.mhp.ui.HPanel) throw (new java.awt.AWTException("HScrollPane must not contain Containers"));
                oCapsulasHijas = new java.util.ArrayList<Capsula>();
                oCapsulasHijas.add(new Capsula(this, oComponent, iOpciones, Capsula.NOTSIZEMOVE, sNombre));

            } else { //Si no es un HScrollPane
                this.setLayout(null);
                this.setLocation(oBean.getX(), oBean.getY());
                this.setSize(oBean.getWidth(), oBean.getHeight());

                //Como tengo problemas de superposici�n de capas con el mediaplayer
                //opto por no previsualizarlo. Las siguientes l�neas evitan su presentaci�n al usuario
                if (oBean instanceof com.uvigo.mhp.mediaPlayer.MediaPlayer) {
                    java.awt.Dimension oDim = oBean.getSize();
                    java.awt.Point oLocation = oBean.getLocation();
                    //int iZ = oBean.getParent().getComponentZOrder(oBean); //Creo que sobra esta l�nea

                    oLabel = new javax.swing.JLabel("MediaPlayer");
                    oLabel.setHorizontalAlignment(javax.swing.JLabel.CENTER);
                    oLabel.setVerticalAlignment(javax.swing.JLabel.CENTER);
                    oLabel.setSize(oDim);
                    oLabel.setLocation(oLocation);
                    oBean.getParent().add(oLabel, iZ);
                    oBean.getParent().remove(oBean);
                }
            }
        }
        //A�adimos el mouselistener para escuchar eventos del raton
        this.addMouseListener(this);
        //A�adimos el soporte de "dragging"
        punto = new java.awt.Point();
        this.addMouseMotionListener(this);

        this.setOpaque(false);//Con esta opci�n hacemos visible el componente original
        oPadre.add(this);

        //oPadre.remove(oBean);

        Component oComponent = MainFrame.oMainFrame.getSavedComponent(oBean.getName());
        if (oComponent != null) { //Si podemos recuperar los valores del proyecto previo
            oXs = oComponent.oXs;
            oYs = oComponent.oYs;
            oZs = oComponent.oZs;
            oWidths = oComponent.oWidths;
            oHeights = oComponent.oHeights;
            oVisible = oComponent.oVisible;
        /* if (!(oBean instanceof com.uvigo.mhp.Page)) {
        int iOpcion = MainFrame.oMainFrame.iGetOpcion();
        oBean.setLocation(oXs.get(iOpcion),oYs.get(iOpcion));
        if (oBean.getParent()!=null) oBean.getParent().setComponentZOrder(oBean, oZs.get(iOpcion));
        this.setLocation(oXs.get(iOpcion),oYs.get(iOpcion));
        this.setSize(oWidths.get(iOpcion),oHeights.get(iOpcion));
        oBean.setSize(oWidths.get(iOpcion),oHeights.get(iOpcion));
        this.setVisible(oVisible.get(iOpcion));
        oBean.setVisible(oVisible.get(iOpcion));
        }*/
        } else {
            oXs = new java.util.ArrayList<Integer>();
            oYs = new java.util.ArrayList<Integer>();
            oZs = new java.util.ArrayList<Integer>();
            oWidths = new java.util.ArrayList<Integer>();
            oHeights = new java.util.ArrayList<Integer>();
            oVisible = new java.util.ArrayList<Boolean>();


            int i = 0;
            for (i = 0; i < iOpciones; i++) {
                oXs.add(iX);
                oYs.add(iY);
                oZs.add(iZ);
                oWidths.add(iWidth);
                oHeights.add(iHeight);
                oVisible.add(oBean.isVisible());

            }
        }

//        //M - no vamos a considerar proyecto guardado. M- pero s� abrir sco!
//        oXs = new java.util.ArrayList<Integer>();
//        oYs = new java.util.ArrayList<Integer>();
//        oZs = new java.util.ArrayList<Integer>();
//        oWidths = new java.util.ArrayList<Integer>();
//        oHeights = new java.util.ArrayList<Integer>();
//        oVisible = new java.util.ArrayList<Boolean>();
//
//
//        int i = 0;
//        for (i = 0; i < iOpciones; i++) {
//            oXs.add(iX);
//            oYs.add(iY);
//            oZs.add(iZ);
//            oWidths.add(iWidth);
//            oHeights.add(iHeight);
//            oVisible.add(oBean.isVisible());
//
//        }
        vIntrospection(iOpciones, oComponent, sNombre);
       // vIntrospection(iOpciones, null, sNombre);
    }

    /**
     * Esta funci�n realiza la introspecci�n del JavaBean, es decir, averigua
     * el funcionamiento del bean, descubriendo sus propiedades, eventos, etc.
     * @param El n�mero de opciones consideradas en la herramienta
     * @param oComponent Contiene los valores del proyecto previo (null si no hay proyecto previo)
     * @throws java.beans.IntrospectionException Si se produce alg�n error
     * durante la introspecci�n de los componentes de la plantilla.
     */
    private void vIntrospection(int iOpciones, Component oComponent, String sNombre) throws java.beans.IntrospectionException {

        System.out.println("vIntrospection - name: " + this.oBean.getName());

        java.beans.BeanInfo oBeanInfo = java.beans.Introspector.getBeanInfo(this.oBean.getClass());
        java.beans.PropertyDescriptor[] oDescriptoresPropiedades = oBeanInfo.getPropertyDescriptors();

        System.out.println("vIntrospectio - num descriptores de propiedades del bean: " + oDescriptoresPropiedades.length);

        
        oPropiedades = new java.util.ArrayList();
        for (java.beans.PropertyDescriptor oDescriptor : oDescriptoresPropiedades) {
            java.util.ArrayList oValue;
            java.util.ArrayList<java.util.ArrayList<java.io.File>> oPropertyFiles;
            if (oComponent == null) {
                oValue = null;
                oPropertyFiles = null;
            } else { //Si se pueden recuperar los valores previos (del proyecto previo)
                //se los pasamos al contructor de Propiedad
                java.util.ArrayList oProperty = oComponent.oPropertyParameters.get(oDescriptor.getName());
                if (oProperty == null) {
                    oValue = null;
                    oPropertyFiles = null;
                } else {
                    oValue = (java.util.ArrayList) oComponent.oPropertyParameters.get(oDescriptor.getName()).get(0);
                    oPropertyFiles = (java.util.ArrayList<java.util.ArrayList<java.io.File>>) oComponent.oPropertyParameters.get(oDescriptor.getName()).get(1);
                }
            }
            oPropiedades.add(new Propiedad(oDescriptor, oBean, iOpciones, oValue, sNombre, oPropertyFiles));
            
        }
    }

    /**
     * Esta funci�n intenta abrir el fichero .html de ayuda contextual de un elemento.
     * La Ruta de ese fichero se encuentra en la variable de ayuda contextual del MainFrame.
     * Leemos el contenido del fichero a una
     * String y se lo pasamos al m�todo setToolTipText. Vivaaa!! ( En menos de
     * un minuto!!, despues de haber perdido el tiempo dise�ando clases redundantes!!)
     * @param sFile La ruta del fichero realtiva al directorio SCOCreator
     */
    private void loadToolTip(String sFile) {
        /* NOTA: en un maravilloso momento, a uno de los brillantes programadores
         * de Sun se le olvid� comentar en el javadoc
         * que el m�todo setToolTipText(String sText) no s�lo acepta texto plano,
         * sino tambi�n una cadena de texto html.
         * Ni que decir tiene que ante las supuestas (que no ciertas) limitaciones
         * de ni siquiera poder meter un simple salto de l�nea en el ToolTip,
         * este menda se hab�a currado un par de clases personalizando el comportamiento de los JToolTipText
         * de los elementos de capsula, precisamente introduciendo la posibilidad
         * de procesar los ToolTips a partir de documentos .html (no resulta ir�nico??).
         * No obstante, algunos problemas a la hora de depurar estas clases, me llevaron
         * a observar las implementaciones de Sun de BasicToolTipUI (Uno de los
         * ComponentUI que se encarga de renderizar los ToolTips de los JComponent en Swing).
         * Estuve a punto de pegarle un pu�etazo al ordenador al observar en el c�digo
         * la utilizaci�n del BasicHTML (elemento que permite visualizar "texto" html en Swing Components)
         * La verdad es que es para mosquearse que ni siquiera lo mencionen ni en
         * el Javadoc de JComponent ni en la secci�n del Java Tutorial dedicada al
         * ToolTips (How to Use ToolTips). S�lo me queda la duda de si, al menos,
         * tuvieron la decencia de incluir el mencionado detalle en alguno de los ejemplos del tutorial.
         * Ahora entiendo porque el "/n" nunca funcionaba con los ToolTips!!!
         * Lo que viene a continuaci�n son los pasos necesarios para extraer de
         * un fichero .html la ayuda sobre un componente determinado (ver loadToolTip)
         */
        //Obtenemos el fichero de ayuda
        //Programamos dos comportamientos: si la aplicaci�n se ejecuta desde
        //un jar o desde el �rbol de directorios
        try {
            java.io.InputStream oHtmlHelpFile = this.getClass().getResource("/com/uvigo/tMaestro/SCOCreator/" + sFile).openStream();
            java.net.URI oURI = (this.getClass().getResource("")).toURI();

            //Si existe el fichero debemos leerlo y asignar su contenido al ToolTip de esta C�psula
            java.io.BufferedReader oReader = new java.io.BufferedReader(new java.io.InputStreamReader(oHtmlHelpFile));
            StringBuffer sBuffer = new StringBuffer();
            String sLine = oReader.readLine();
            while (sLine != null) {
                sBuffer.append(sLine);
                sLine = oReader.readLine();
            }
            this.setToolTipText(sBuffer.toString());


        } catch (Exception oE) { //Tipicamente saldr� por aqui si oURI est� mal formada (improbable) o si no existe sFile en templates
            oE.printStackTrace();
            return;
        }
    }

    /**
     * Funci�n recursiva que recupera la estructura original de la
     * plantilla eliminando de ella todas las c�psulas.
     * @see vRecuperarEstructuraPlantilla
     * @param oCapsula La c�psula que se desea eliminar de la estructura
     */
    private static void vEliminaCapsula(Capsula oCapsula) {
        java.awt.Container oPadre = oCapsula.getParent();
        oPadre.remove((java.awt.Component) oCapsula);
        if (oCapsula.oBean instanceof com.uvigo.mhp.ui.HPanel) {
            java.awt.Container oContenedor = (java.awt.Container) oCapsula.oBean;
            java.awt.Component[] oComponentes = oContenedor.getComponents();
            for (java.awt.Component oComponente : oComponentes) {
                vEliminaCapsula((Capsula) oComponente);
            }
            oPadre.add(oCapsula.oBean);
            oCapsula.oBean.setLocation(oCapsula.getLocation());
        } else {
            oPadre.add(oCapsula.oBean);
            oCapsula.oBean.setBounds(oCapsula.getBounds());
        }

    }

    /**
     * Devuelve el elemento encapsulado en esta c�psula
     * @return El JavaBean encapsulado
     */
    public java.awt.Component oGetBean() {
        return this.oBean;
    }

    /**
     * Este m�todo es llamado por el elemento capsula que deja
     * de estar activo (seleccionado por el usuario)
     */
    public void vDesactivar() {
        this.bActivo = false;
    }

    
    

       
          ;
    
    /**
     * M�todo llamando por el elemento c�psula que va a pasar a
     * estar activo. Un elemento activo presenta un borde especial
     * para diferenciarlos de los dem�s. Cuando el elemento est� activo
     * es posible actuar sobre �l de manera diferente a si no lo estuviera
     */
    public void vActivar(){
        bActivo=true;

        /* if (oBean instanceof com.uvigo.mhp.ui.HMultiPanel){
        java.awt.Component[] oComps = ((java.awt.Container) oBean).getComponents();
        for (java.awt.Component oC : oComps) System.out.println(oC);
        }*/

        MainFrame.oMainFrame.vSetCapsulaActiva(this);
        //Llamamos al m�todo paint del panel principal, para que pinte los bordes
        //sobre este elemento
        MainFrame.oMainFrame.oGetPanel().repaint();


        //Seleccionamos esta c�psula en el visor de jeraqu�a.
        //Para ello es necesario saber el camino desde la raiz hasta esta c�psula
        boolean bMultipanel = false;
        java.util.ArrayList<Capsula> oPath = new java.util.ArrayList<Capsula>();
        Capsula oNodo = this;
        do {
            oPath.add(oNodo);


            //Si este elemento se encuentra en un "card" de un multipanel debemos hacer visible dicho "card" (en invisibles los dem�s).
            if ((oNodo.oCapsulaPadre != null) && (oNodo.oCapsulaPadre.oGetBean() instanceof com.uvigo.mhp.ui.HMultiPanel)) {
                java.awt.Component[] oComps = oNodo.oCapsulaPadre.getComponents();
                int i = 0;
                for (i = 0; i < oComps.length; i++) {
                    if (!(oComps[i] instanceof com.uvigo.mhp.ui.HMultiPanel)) { //El Multipanel debe ser visible!!
                        //System.out.println(oComps[i]);
                        oComps[i].setVisible(false);
                        Capsula oCapsula = (Capsula) oComps[i];
                        if (oCapsula.getLabel() != null) {
                            oCapsula.getLabel().setVisible(false);
                        } else {
                            oCapsula.oGetBean().setVisible(false);
                        }
                    }
                }
                oNodo.setVisible(true);
                if (oNodo.oLabel != null) {
                    oNodo.oLabel.setVisible(true);
                } else {
                    oNodo.oBean.setVisible(true);
                }
            }


            oNodo = oNodo.oCapsulaPadre;
        } while (oNodo != null);
        //Invertimos el Array.
        java.util.Collections.reverse(oPath);
        MainFrame.oMainFrame.getHSeet().setNode(new javax.swing.tree.TreePath(oPath.toArray()));


    }

    
    

       ; /**
             * Cuando el usuario hace click con el rat�n sobre el elemento.
             * @param evt
             */
             
    

    
    

    public  void mouseClicked(java.awt.event.MouseEvent evt) {





















































































          
          
            
             
               } 
                ;

                /**
                 *
                 * @param evt
                 */
                
                
            
        
    

    
    

    public  void mousePressed(java.awt.event.MouseEvent evt) {
         punto.x 
               
          
            = evt.getX();
        punto.y = evt.getY();
        //System.out.println(evt.getComponent().getClass().toString()+this.oBean.getClass().toString());
        // Si hace click con el bot�n 1
        if (evt.getButton()==java.awt.event.MouseEvent.BUTTON1) {
            Capsula oActivo;
            //Si la nueva c�psula activa no es la actual, desactivamos la actual
            //y activamos este elemento
            if (!(oActivo=MainFrame.oMainFrame.oGetCapsulaActiva()).equals(this)) {
                oActivo.vDesactivar();
                oActivo.setCursor(java.awt.Cursor.getPredefinedCursor(java.awt.Cursor.DEFAULT_CURSOR));
                vActivar();
            }
        }
    };
    
    
    /**
     * M�todo llamado cuando se suelta el bot�n del rat�n.
     */
    public void mouseReleased(java.awt.event.MouseEvent evt){
        
        if (evt.isPopupTrigger()) { //Si el usuario quiere el PopUpMenu
            MainFrame.oMainFrame.popUpRequired(this,this, evt.getX(),evt.getY());
        } else {
            MainFrame.oMainFrame.oGetPanel().setMoving(false);
            MainFrame.oMainFrame.oGetPanel().repaint();
        }
    }

    
    

       ; /**
             *
             * @param evt
             */
             
    

    
    

    public  void mouseEntered(java.awt.event.MouseEvent evt) {
    }

    
    

       ; /**
             *
             * @param evt
             */
             
              
               
               
               
               public void mouseExited(java.awt.event.MouseEvent evt){};
    
    /**
     * M�todo llamado cuando se produce el "dragging" sobre el componente.
     * No permitimos el dragging si el elemento no est� activo.
     */
    public void mouseDragged(MouseEvent e) {
        if (bActivo && iSizeMove==SIZEMOVE) { //Si el elemento se puede desplazar, se desplaza
            java.awt.Point p = this.getLocation();
            int x=this.getX();
            int y=this.getY();
            if (iSizeType==0) {
                boolean bNotMove = false;
                if (p.x + e.getX() - punto.x > 0 && p.x + e.getX() - punto.x < this.getParent().getWidth() - this.getWidth()) {
                    x = p.x + e.getX() - punto.x;
                } else {
                    bNotMove = true;
                }
                if (p.y + e.getY() - punto.y > 0 && p.y + e.getY() - punto.y < this.getParent().getHeight() - this.getHeight()) {
                    y = p.y + e.getY() - punto.y;
                } else {
                    bNotMove = true;
                }
                if (bNotMove) {
                    java.awt.Point oMousePoint = new java.awt.Point(punto.x + p.x, punto.y + p.y);
                    javax.swing.SwingUtilities.convertPointToScreen(oMousePoint, this.getParent());
                    try {
                        new java.awt.Robot().mouseMove(oMousePoint.x, oMousePoint.y);
                    } catch (Exception oE) {
                    }
                }
                MainFrame.oMainFrame.updateComponentLocation(this, x, y);
            } else if (iSizeType < 0) {
                boolean bNotMove = false;
                if (p.x + e.getX() - punto.x > 0 && punto.x - e.getX() + this.getWidth() - GROSOR > 0) {
                    x = p.x + e.getX() - punto.x;
                } else {
                    bNotMove = true;
                }
                if (p.y + e.getY() - punto.y > 0 && punto.y - e.getY() + this.getHeight() - GROSOR > 0) {
                    y = p.y + e.getY() - punto.y;
                } else {
                    bNotMove = true;
                }
                if (bNotMove) {
                    java.awt.Point oMousePoint = new java.awt.Point(punto.x + p.x, punto.y + p.y);
                    javax.swing.SwingUtilities.convertPointToScreen(oMousePoint, this.getParent());
                    try {
                        new java.awt.Robot().mouseMove(oMousePoint.x, oMousePoint.y);
                    } catch (Exception oE) {
                    }
                } else {
                    if (iSizeType == -1) {
                        MainFrame.oMainFrame.updateComponentDimension(this, punto.x - e.getX() + this.getWidth(), this.getHeight());
                        MainFrame.oMainFrame.updateComponentLocation(this, x, this.getY());
                    } else if (iSizeType == -2) {
                        MainFrame.oMainFrame.updateComponentDimension(this, this.getWidth(), punto.y - e.getY() + this.getHeight());
                        MainFrame.oMainFrame.updateComponentLocation(this, this.getX(), y);
                    } else if (iSizeType == -3) {
                        MainFrame.oMainFrame.updateComponentDimension(this, punto.x - e.getX() + this.getWidth(), punto.y - e.getY() + this.getHeight());
                        MainFrame.oMainFrame.updateComponentLocation(this, x, y);
                    }

                }


            } else {
                java.awt.Point oMousePoint = e.getPoint();
                javax.swing.SwingUtilities.convertPointToScreen(oMousePoint, this);
                javax.swing.SwingUtilities.convertPointFromScreen(oMousePoint, this.getParent());
                int iWidth = this.getWidth();
                int iHeight = this.getHeight();
                boolean bNotResize = false;
                if (oMousePoint.x - p.x + GROSOR > 0 && oMousePoint.x + GROSOR < this.getParent().getWidth()) {
                    iWidth = oMousePoint.x - p.x + GROSOR;
                } else {
                    bNotResize = true;
                }
                if (oMousePoint.y - p.y + GROSOR > 0 && oMousePoint.y + GROSOR < this.getParent().getHeight()) {
                    iHeight = oMousePoint.y - p.y + GROSOR;
                } else {
                    bNotResize = true;
                }
                if (bNotResize) {
                    int iPointX = p.x + this.getWidth() - GROSOR;
                    int iPointY = p.y + this.getHeight() - GROSOR;
                    if (iSizeType == 1) {
                        iPointY = e.getY() + p.y;
                    } else if (iSizeType == 2) {
                        iPointX = e.getX() + p.x;
                    }
                    java.awt.Point oPoint = new java.awt.Point(iPointX, iPointY);
                    javax.swing.SwingUtilities.convertPointToScreen(oPoint, this.getParent());
                    try {
                        new java.awt.Robot().mouseMove(oPoint.x, oPoint.y);
                    } catch (Exception oE) {
                    }
                }
                if (iSizeType == 3) {
                    MainFrame.oMainFrame.updateComponentDimension(this, iWidth, iHeight);
                } else if (iSizeType == 1) {
                    MainFrame.oMainFrame.updateComponentDimension(this, iWidth, this.getHeight());
                } else if (iSizeType == 2) {
                    MainFrame.oMainFrame.updateComponentDimension(this, this.getWidth(), iHeight);
                }
            }
            MainFrame.oMainFrame.activateDimensionPanel(iSizeMove);
            MainFrame.oMainFrame.oGetPanel().setMoving(true);
            MainFrame.oMainFrame.oGetPanel().repaint();
        }
    }

    /**
     * Averigua si el rat�n est� en los bordes del componente para cambiar el cursor
     */
    public void mouseMoved(MouseEvent e) {
        if (bActivo && iSizeMove == SIZEMOVE) {
            if (e.getX() < GROSOR) {
                if (e.getY() < GROSOR) {
                    iSizeType = -3;
                    setCursor(java.awt.Cursor.getPredefinedCursor(java.awt.Cursor.NW_RESIZE_CURSOR));
                } else if (e.getY() > this.getHeight() - GROSOR) {
                    //iSizeType=3;
                    setCursor(java.awt.Cursor.getPredefinedCursor(java.awt.Cursor.SW_RESIZE_CURSOR));
                } else {
                    iSizeType = -1;
                    setCursor(java.awt.Cursor.getPredefinedCursor(java.awt.Cursor.W_RESIZE_CURSOR));
                }

            } else if (e.getX() > this.getWidth() - GROSOR) {
                if (e.getY() > this.getHeight() - GROSOR) {
                    iSizeType = 3;
                    setCursor(java.awt.Cursor.getPredefinedCursor(java.awt.Cursor.SE_RESIZE_CURSOR));
                } else if (e.getY() < GROSOR) {
                    //iSizeType=-3;
                    setCursor(java.awt.Cursor.getPredefinedCursor(java.awt.Cursor.NE_RESIZE_CURSOR));
                } else {
                    iSizeType = 1;
                    setCursor(java.awt.Cursor.getPredefinedCursor(java.awt.Cursor.E_RESIZE_CURSOR));
                }
            } else if (e.getY() < GROSOR) {
                iSizeType = -2;
                setCursor(java.awt.Cursor.getPredefinedCursor(java.awt.Cursor.N_RESIZE_CURSOR));
            } else if (e.getY() > this.getHeight() - GROSOR) {
                iSizeType = 2;
                setCursor(java.awt.Cursor.getPredefinedCursor(java.awt.Cursor.S_RESIZE_CURSOR));
            } else {
                iSizeType = 0;
                setCursor(java.awt.Cursor.getPredefinedCursor(java.awt.Cursor.DEFAULT_CURSOR));
            }

        } else if (iSizeType != 0) {
            iSizeType = 0;
            setCursor(java.awt.Cursor.getPredefinedCursor(java.awt.Cursor.DEFAULT_CURSOR));
        }

    }

    /**
     * Esta funci�n realiza la operaci�n inversa al constructor, es decir, recupera la plantilla
     * (con las modificaciones realizadas en el entorno de la herramienta) en su estructura
     * original lista para ser exportada.
     * @see vEliminaCapsula
     * @return La plantilla modificada
     */
    public java.awt.Component oRecuperarEstructuraPlantilla() {
        vEliminaCapsula(this);
        return this.oBean;

    }

    /**
     * Devuelve la tabla de propiedades del bean correspondiente a iOpcion
     * @param iOpcion La Opci�n cuya tabla se desea obtener
     * @return La tabla de propiedades.
     */
    public javax.swing.table.TableModel oGetTabla(int iOpcion) {
        return oTablas.get(iOpcion);
    }

    /**
     * Establece una nueva tabla de propiedades correspondiente a la opcion
     * de �ndice el �ndice de esta nueva tabla en el ArrayList oTablas
     * @param oTabla La nueva tabla de propiedades del bean
     */
    public void addTable(javax.swing.table.TableModel oTabla) {
        oTablas.add(oTabla);
    }

    /**
     * Devuelve el n�mero de tablas establecidas en la c�psula
     * @return El n�mero de tablas
     */
    public int sizeTables() {
        return oTablas.size();
    }

    /**
     * Devuelve las propiedades del bean.
     * @return El array con los properties descriptors del bean
     */
    public java.util.ArrayList oGetPropiedades() {
        return oPropiedades;
    }

    /**
     * Devuelve una referencia a la propiedad de nombre sNombre
     * de esta C�psula
     */
    public Propiedad getProperty(String sName) {
        for (Propiedad oProperty : oPropiedades) {
            if (oProperty.oGetName().equals(sName)) {
                return oProperty;
            }
        }
        return null;
    }

    /**
     * Actualiza las propiedades del bean de esta capsula  a los de la opci�n
     * indicada por iOpcion. Tabi�n los de las c�psulas hijas.
     * Es una funci�n recursiva que va llamando a todas las c�psulas hijas
     * de una c�psula.
     * @param iOpcion El n�mero de la opci�n que va a ser presentada
     */
    public void updateBean(int iOpcion) {
        //Actualizamos las propiedades del Bean encerrado por c�psula
        if (!(oBean instanceof com.uvigo.mhp.Page)) {
            if (oBean.getParent() != null) {
                this.getParent().setComponentZOrder(this, oZs.get(iOpcion));
                if (oLabel != null) {
                    oLabel.getParent().setComponentZOrder(oLabel, oZs.get(iOpcion));
                    if ((oZs.get(iOpcion) == 0) && (oLabel.getParent() instanceof com.uvigo.mhp.ui.HMultiPanel)) {
                        ((java.awt.CardLayout) oLabel.getParent().getLayout()).first(oLabel.getParent());
                    }
                } else {
                    oBean.getParent().setComponentZOrder(oBean, oZs.get(iOpcion));
                    if ((oZs.get(iOpcion) == 0) && (oBean.getParent() instanceof com.uvigo.mhp.ui.HMultiPanel)) {
                        ((java.awt.CardLayout) oBean.getParent().getLayout()).first(oBean.getParent());
                    }
                }


            }
            this.setLocation(oXs.get(iOpcion), oYs.get(iOpcion));
            this.setSize(oWidths.get(iOpcion), oHeights.get(iOpcion));
            this.setVisible(oVisible.get(iOpcion));
            if (oLabel != null) {
                oLabel.setVisible(oVisible.get(iOpcion));
                oLabel.setSize(oWidths.get(iOpcion), oHeights.get(iOpcion));
                oLabel.setLocation(oXs.get(iOpcion), oYs.get(iOpcion));
            } else {
                oBean.setVisible(oVisible.get(iOpcion));
                oBean.setSize(oWidths.get(iOpcion), oHeights.get(iOpcion));
                oBean.setLocation(oXs.get(iOpcion), oYs.get(iOpcion));
            }
        }
        for (Propiedad oProperty : oPropiedades) {
            //System.out.println("------------ "+oProperty.oGetName()+" : "+oProperty.oGetOptionValue(iOpcion));
            oProperty.vWriteValue(iOpcion);
        }
          //System.out.println();
          
        //Ahora las propiedades de las c�psula hijas de �sta.
        if (oCapsulasHijas == null) {
            return;
        }
        for (Capsula oWrapper : oCapsulasHijas) {
            oWrapper.updateBean(iOpcion);
        }
    }

    /**
     * Esta funci�n se utiliza para apuntar las opciones de las propiedades
     * de la capsula en la hastable que se pasa por par�metro. Tambi�n los valores
     * de posici�n y tama�o. Es una funci�n recursiva.
     */
    public void copyOptions(java.util.HashMap<String, Component> oHashMap) {
        Component oComponent = new Component(new java.util.HashMap<String, java.util.ArrayList>(), oXs, oYs, oZs, oWidths, oHeights, oVisible);


        java.util.ArrayList oOptionValues;
        for (Propiedad oProperty : oPropiedades) {

            //Hay ciertas propiedades que interesa que no sean salvadas (por ej las de solo lectura) o las que no son serializables
            if (oProperty.isRedOnly()) {
                continue;
            }
            if (!(oProperty.oGetValue() instanceof java.io.Serializable)) {
                continue;
            }
            java.util.ArrayList oProp = new java.util.ArrayList();
            oProp.add(oProperty.getPropertyOptions());
            oProp.add(oProperty.getPropertyFiles());
            oComponent.oPropertyParameters.put(oProperty.oGetName(), oProp);

        //NOTA: estas l�neas son para prop�sitos de depuraci�n. Deben ser eliminadas.
            /*try {
        java.io.ObjectOutputStream oOOS = new java.io.ObjectOutputStream(new java.io.FileOutputStream("prueba"));
        oOOS.writeObject(oProperty.getPropertyOptions());
        } catch(Exception oE){
        System.out.println(oProperty.oGetName());
        oE.printStackTrace();
        }*/
        }



        oHashMap.put(this.sComponentName, oComponent);
        //Ahora las propiedades de las c�psula hijas de �sta.
        if (oCapsulasHijas == null) {
            return;
        }
        for (Capsula oWrapper : oCapsulasHijas) {
            oWrapper.copyOptions(oHashMap);
        }
    }

    /**
     * A�ade una nueva opci�n a todas las propiedades del bean.
     * Es una funci�n recursiva que va llamando a todas las c�psulas hijas
     * de una c�psula.
     * @param bCurrent True si la nueva opci�n es una copia de la actual o false
     * si es una copia de la opci�n de plantilla original
     */
    public void addOption(boolean bCurrent) {
        //A�adimos m�s opciones a las propiedades de dimensionamiento

        if (!bCurrent) {
            oXs.add(iX);
            oYs.add(iY);
            oZs.add(iZ);
            oWidths.add(iWidth);
            oHeights.add(iHeight);
            oVisible.add(bVisible);
        } else {
            int iOpcion = MainFrame.oMainFrame.iGetOpcion();
            oXs.add(oXs.get(iOpcion));
            oYs.add(oYs.get(iOpcion));
            oZs.add(oZs.get(iOpcion));
            oWidths.add(oWidths.get(iOpcion));
            oHeights.add(oHeights.get(iOpcion));
            oVisible.add(oVisible.get(iOpcion));
        }


        //Actualizamos las propiedades del Bean encerrado por c�psula
        for (Propiedad oProperty : oPropiedades) {
            oProperty.addOption(bCurrent);
        }
        //Ahora las propiedades de las c�psula hijas de �sta.
        if (oCapsulasHijas == null) {
            return;
        }
        for (Capsula oWrapper : oCapsulasHijas) {
            oWrapper.addOption(bCurrent);
        }
    }

    /**
     * Elimina todos los campos correspondientes a la opci�n de indice iIndex
     */
    public void removeOption(int iIndex) {
        oXs.remove(iIndex);
        oYs.remove(iIndex);
        oZs.remove(iIndex);
        oWidths.remove(iIndex);
        oHeights.remove(iIndex);
        oVisible.remove(iIndex);
        oTablas.clear();

        for (Propiedad oProperty : oPropiedades) {
            oProperty.removeOption(iIndex);
        }

        if (oCapsulasHijas == null) {
            return;
        }
        for (Capsula oWrapper : oCapsulasHijas) {
            oWrapper.removeOption(iIndex);
        }

    }

    /**
     * Devuelve el nombre de la clase
     * del objeto que se encapsula
     * (en forma abreviada)
     * @return La clase del Bean que se encapsula.
     */
    public String toString() {
        return (oBean.getName() + "  [" + oBean.getClass().getSimpleName() + "]");
    }

    /**
     * La funci�n devuelve el n�mero de c�psula hijas
     * @return El n�mero de hijos de esta c�psula.
     */
    public int iGetNumHijos() {
        if (oCapsulasHijas == null) {
            return 0;
        } else {
            return oCapsulasHijas.size();
        }
    }

    /**
     * La funci�n devuelve el hijo de �ndice iIndex.
     * @param iIndex El �ndice del hijo en la c�psula
     * @return La c�psula hija de indice proporcionado.
     * @exception IndexOutOfBoundsException Si iIndex est� fuera de rango
     */
    public Capsula oGetHijo(int iIndex) throws IndexOutOfBoundsException {
        return oCapsulasHijas.get(iIndex);
    }

    /**
     * Devuelve el valor de la coordenada X para la opcion iOpcion
     * @param La opci�n
     * @return El valor de la coordenada.
     */
    public int getX(int iOpcion) {
        return oXs.get(iOpcion);
    }

    /**
     * Devuelve el valor de la coordenada Y para la opcion iOpcion
     * @param La opci�n
     * @return El valor de la coordenada.
     */
    public int getY(int iOpcion) {
        return oYs.get(iOpcion);
    }

    /**
     * Devuelve el valor de la coordenada Z para la opcion iOpcion
     * @param La opci�n
     * @return El valor de la coordenada.
     */
    public int getZ(int iOpcion) {
        return oZs.get(iOpcion);
    }

    /**
     * Devuelve el valor de la anchura para la opcion iOpcion
     * @param La opci�n
     * @return El valor de la anchura.
     */
    public int getWidth(int iOpcion) {
        return oWidths.get(iOpcion);
    }

    /**
     * Devuelve el valor de la altura para la opcion iOpcion
     * @param La opci�n
     * @return El valor de la altura.
     */
    public int getHeight(int iOpcion) {
        return oHeights.get(iOpcion);
    }

    /**
     * Dice si el Bean es visible para la opcion iOpcion
     * @param La opci�n
     * @return True si es visible.
     */
    public boolean isVisible(int iOpcion) {
        return oVisible.get(iOpcion);
    }

    /**
     * Devuelve el valor de la coordenada X original
     * @return El valor de la coordenada.
     */
    public int getOriginalX() {
        return iX;
    }

    /**
     * Devuelve el valor de la coordenada Y original
     * @return El valor de la coordenada.
     */
    public int getOriginalY() {
        return iY;
    }

    /**
     * Devuelve el valor de la coordenada Z original
     * @return El valor de la coordenada.
     */
    public int getOriginalZ() {
        return iZ;
    }

    /**
     * Devuelve el valor de la anchura original
     * @return El valor de la anchura.
     */
    public int getOriginalWidth() {
        return iWidth;
    }

    /**
     * Devuelve el valor de la altura original
     * @return El valor de la altura.
     */
    public int getOriginalHeight() {
        return iHeight;
    }

    /**
     * Dice si el Bean era visible originalmente
     * @return True si es visible.
     */
    public boolean isOriginalVisible() {
        return bVisible;
    }

    /**
     * Establece el valor iX para el Bean en la opcion iOpcion
     * @param iX El nuevo valor
     * @param iOpcion La opcion en la que se modificar� el valor
     */
    public void setX(int iOpcion, int iX) {
        oXs.set(iOpcion, iX);
    }

    /**
     * Establece el valor iY para el Bean en la opcion iOpcion
     * @param iY El nuevo valor
     * @param iOpcion La opcion en la que se modificar� el valor
     */
    public void setY(int iOpcion, int iY) {
        oYs.set(iOpcion, iY);
    }

    /**
     * Establece el valor iZ para el Bean en la opcion iOpcion
     * @param iZ El nuevo valor
     * @param iOpcion La opcion en la que se modificar� el valor
     */
    public void setZ(int iOpcion, int iZ) {
        oZs.set(iOpcion, iZ);
    }

    /**
     * Establece la anchura para el Bean en la opcion iOpcion
     * @param iWidth La nueva anchura
     * @param iOpcion La opcion en la que se modificar� el valor
     */
    public void setWidth(int iOpcion, int iWidth) {
        oWidths.set(iOpcion, iWidth);
    }

    /**
     * Establece la altura para el Bean en la opcion iOpcion
     * @param iHeight La nueva altura
     * @param iOpcion La opcion en la que se modificar� el valor
     */
    public void setHeight(int iOpcion, int iHeight) {
        oHeights.set(iOpcion, iHeight);
    }

    /**
     * Establece si el Bean es visible en la opcion iOpcion
     * @param bVisible True si es visible
     * @param iOpcion La opcion en la que se modificar� el valor
     */
    public void setVisible(int iOpcion, boolean bVisible) {
        oVisible.set(iOpcion, bVisible);
    }

    /**
     * Indica si el componente encerrado por la c�psula
     * se puede dimensionar y/o mover
     * @param Un entero indicando si el componente es redimensionable y reposicionable
     */
    public int getSizeMove() {
        return iSizeMove;
    }

    /**
     * Esta funci�n es llamada para establecer la ayudacontextual de componente
     * Esta ayuda est� compuesta por ToolTips. La variable booleana habilita
     * o deshabilita los Tooltips. Es una funci�n recursiva.
     */
    public void setCapsulaHelp(boolean bEnable) {
        if (bEnable) {
            String sRoute = "templates/";
            String sFile = MainFrame.oMainFrame.getTemplateContextHelp(oBean.getName(), "contextFile");
            if (sFile == null) {
                sRoute = "tool/contextHelp/";
                sFile = MainFrame.oMainFrame.getContextHelp(oBean.getClass().getName(), "contextFile");
            }
            if (sFile != null) {
                loadToolTip(sRoute + sFile);
            } else {
                setToolTipText(null);
            }
        } else {
            setToolTipText(null);
        }
        if (oCapsulasHijas == null) {
            return;
        }
        for (Capsula oCapsula : oCapsulasHijas) {
            oCapsula.setCapsulaHelp(bEnable);
        }
    }

    /**
     * A�ade a un array list todas las capsulas de que consta la estructura de oCapsula
     * Es decir todas las c�psula hijas de oCapsula y las hijas de las hijas ...
     * hasta llegar a las hojas. "Aplana" la estructura en �rbol.
     * @param oCapsulas El arrayList en donde a�adirlas
     * @param oCapsula La C�psula de la que tomar la capsulas hijas
     * Como es una funci�n recursiva este par�metro ser� la Capsula Padre
     * NOTA: no a�ade al array a la Capsula Ra�z. Tener en cuenta desde donde se llame
     */
    public static void getCapsulas(java.util.ArrayList<Capsula> oCapsulas, Capsula oCapsula) {
        for (int i = 0; i < oCapsula.iGetNumHijos(); i++) {
            oCapsulas.add(oCapsula.oGetHijo(i));
            if (oCapsula.oGetHijo(i).iGetNumHijos() != 0) {
                getCapsulas(oCapsulas, oCapsula.oGetHijo(i));
            }
        }
    }

    /**
     * Devuelve la c�psula Padre de esta c�psula
     */
    public Capsula getCapsulaParent() {
        return oCapsulaPadre;
    }

    /**
     * Inserta la C�psula oCapsula en iIndex dentro del arrayList de C�psulaHijas
     * @param iIndex El �ndice
     * @param oCapsula La C�psula a insertar
     */
    public void addCapsula(int iIndex, Capsula oCapsula) {
        oCapsulasHijas.add(iIndex, oCapsula);
    }

    /**
     * Elimina oCapsula del array de Capsulas hijas (si est� entre ellas).
     */
    public void removeCapsula(Capsula oCapsula) {
        oCapsulasHijas.remove(oCapsula);
    }

    /**
     * Devuelve la etiqueta asociada a este elemento
     */
    public javax.swing.JLabel getLabel() {
        return oLabel;
    }

    /**
     * Devuelve el �ndice de oCapsula en el Array de oCapsulas hijas de
     * esta c�psula.
     */
    public int getIndexCapsula(Capsula oCapsula) {
        return oCapsulasHijas.indexOf(oCapsula);
    }
}


