import java.awt.*;
import java.awt.event.*;
import java.applet.*;
import PanelExt;
import CanvasExt;
import SistGravit;

public class SimGravit extends Applet
                       implements ActionListener,
                                  ItemListener,
                                  ComponentListener,
                                  MouseListener,
                                  MouseMotionListener,
                                  Runnable
{
   // Constantes
   // Tamano recomendado de pantalla
   static int TAMX = 550;
   static int TAMY = 500;
   // Tipos de estado
   static final int EST_INICIAL    = 0;
   static final int EST_NUEVO      = 1;
   static final int EST_EDITAR     = 2;
   static final int EST_ZOOM_AMP   = 3;
   static final int EST_ZOOM_RED   = 4;
   static final int EST_EVOLUCION  = 5;
   static final int EST_ITERANDO   = 6;
   // Tipos de sub-estado
   static final int EST_EDIT_POS   = 0;
   static final int EST_EDIT_VEL   = 1;
   static final int EST_EDIT_MAS   = 2;
   static final int EST_EDIT_ESP1  = 3;
   static final int EST_EDIT_ESP2  = 4;
   // Tipos de parametro X
   static final int PAR_INC_TPO  = 0;
   static final int PAR_COE_SIS  = 1;
   static final int PAR_COE_AMOR = 2;
   static final int PAR_OSC_AMPL = 3;
   static final int PAR_OSC_FREC = 4;

   static String[] ayudas = {
     " Elija las caracteristicas de su sistema y pulse [Crear].",
     " Pulse [Crear] para obtener un nuevo sistema.",
     "",
     " Pulse sobre un punto para ampliar la imagen sobre el.",
     " Pulse sobre un punto para reducir la imagen sobre el.",
     " Pulse [Comenzar] o mueva un punto para observar la evolucion del sistema.",
     " Pulse [Parar] para detener la evolucion del sistema.",
   };

   static String[] subayudas = {
     " Arrastre los puntos a la posicion deseada.",
     " Arrastre los vectores velocidad a la posicion deseada.",
     " Pulse para seleccionar un punto y cambie el valor de su masa.",
     " Seleccione el tipo de punto adecuado y pulse sobre los puntos.",
     " Establezca los valores del oscilador y pulse sobre los puntos."
   };

   // Componentes

   CanvasExt lienzo;
   Label etqEstado;
   PanelExt panCon2;
   CardLayout disPanCon2;
   Checkbox chkEvolucion;
   Checkbox chkNuevo;
   Checkbox chkEditar;
   // Nuevo
   Choice lisTipoSis;
   TextField edtDimSis;
   TextField edtIncSis;
   TextField edtAmoSis;
   TextField edtParSis;
   Button btnCrear;
   // Editar
   Panel panCon2bS;
   CardLayout disPanCon2bS;
   Choice lisTipoEdi;
   Button btnZoomAmp;
   Button btnZoomRed;
   Button btnAzarPos;
   Button btnAzarVel;
   TextField edtMasa;
   Button btnAzarMas;
   Choice lisTipoPto;
   Button btnTodos;
   Choice lisTipoOsc;
   TextField edtAmpl;
   TextField edtFrec;
   // Evolucion
   TextField edtIter;
   Label etqParX;
   TextField edtParX;
   Checkbox chkAutoAjuste;
   Checkbox chkAutoZoom;
   Checkbox chkVerPtos;
   Checkbox chkEstela;
   Button btnReiniciar;
   Button btnAnimar;

   // Variables

   volatile int estado = EST_INICIAL;
   volatile int subestado = EST_EDIT_POS;
   volatile int numIter = 5;
   volatile boolean animacion = false;
   volatile boolean autoZoom = false;
   volatile double valParamX = 1.0;
   volatile boolean setParamX = false;
   int numParamX = -1;
   boolean iniciado = false;
   Thread hilo = null;
   SistGravit sistema = new SistGravit();

   public static void main( String[] args )
   {
      Frame ventana = new Frame("Simulacion de un sistema fisico");
      SimGravit applet = new SimGravit();

      ventana.setLayout( new BorderLayout() );
      ventana.add("Center",applet);
      ventana.setSize(TAMX,TAMY);
      ventana.addWindowListener(
        new WindowAdapter( ) {
          public void windowClosing( WindowEvent e ) { System.exit(0); }
        }
      );
      applet.init();
      ventana.show();
   }

   public void init( )
   {
      creaInterfaz();
   }

   public void lineaEstado( )
   {
      if( estado != EST_EDITAR ) {
        etqEstado.setText(ayudas[estado]);
      } else {
        etqEstado.setText(subayudas[subestado]);
      }
   }

   /* *** RESPUESTA A ACCIONES *** */

   public void componentHidden( ComponentEvent e ) { }
   public void componentMoved( ComponentEvent e ) { }
   public void componentShown( ComponentEvent e ) { }
   public void mouseEntered( MouseEvent e ) { }
   public void mouseExited( MouseEvent e ) { }
   public void mouseMoved( MouseEvent e ) { }

   public void actionPerformed( ActionEvent e )
   {
      Object fnt = e.getSource();
      if( fnt == btnCrear )     { crearSistema(); } else
      if( fnt == btnAzarPos )   { azarPosiciones(); } else
      if( fnt == btnAzarVel )   { azarVelocidades(); } else
      if( fnt == btnAzarMas )   { azarMasas(); } else
      if( fnt == btnTodos )     { puntosIguales(); } else
      if( fnt == edtIter )      { cambioNumIteraciones(); } else
      if( fnt == edtParX )      { cambioParametroX(); } else
      if( fnt == edtMasa )      { cambioMasaPunto(); } else
      if( fnt == btnReiniciar ) { reiniciarSistema(); } else
      if( fnt == btnZoomAmp ) {
        cambioEstado((estado==EST_ZOOM_AMP) ? EST_EDITAR : EST_ZOOM_AMP );
      } else
      if( fnt == btnZoomRed ) {
        cambioEstado((estado==EST_ZOOM_RED ) ? EST_EDITAR : EST_ZOOM_RED );
      } else
      if( fnt == btnAnimar ) {
        cambioEstado((estado==EST_ITERANDO) ? EST_EVOLUCION : EST_ITERANDO );
      } 
   }

   public void itemStateChanged( ItemEvent e )
   {
      Object fnt = e.getSource();
      if( e.getStateChange() == ItemEvent.SELECTED ) {
        if( fnt == chkNuevo )     cambioEstado(EST_NUEVO); else
        if( fnt == chkEditar )    cambioEstado(EST_EDITAR); else
        if( fnt == chkEvolucion ) cambioEstado(EST_EVOLUCION);
      }
      if( fnt == lisTipoEdi ) { cambioTipoEdicion(); } else
      if( (fnt == chkAutoAjuste) ||
          (fnt == chkVerPtos) ||
          (fnt == chkEstela) ) { cambioOpcionesDibujo(); } else
      if( fnt == chkAutoZoom ) { autoZoom = chkAutoZoom.getState(); }
   }

   public void componentResized( ComponentEvent e )
   {
     Object fnt = e.getSource();
     if( fnt == lienzo ) { dibujar(); }
   }

   public void mouseClicked( MouseEvent e )
   {
      switch(estado) {
        case EST_EDITAR:
          switch(subestado) {
            case EST_EDIT_MAS: pulsacionEditarMasa( e.getPoint() ); break;
            case EST_EDIT_ESP1: pulsacionTipoPunto( e.getPoint() ); break;
            case EST_EDIT_ESP2: pulsacionOscilador( e.getPoint() ); break;
          }
          break;
        case EST_ZOOM_AMP: zoom(e.getPoint(),true); break;
        case EST_ZOOM_RED: zoom(e.getPoint(),false); break;
      }
   }

   public void mousePressed( MouseEvent e )
   {
      switch(estado) {
        case EST_EDITAR:
          switch(subestado) {
            case EST_EDIT_POS: pulsacionPosicion( e.getPoint() ); break;
            case EST_EDIT_VEL: pulsacionVelocidad( e.getPoint() ); break;
          }
          break;
        case EST_EVOLUCION: pulsacionPosicion( e.getPoint() ); break;
        case EST_ITERANDO: cambioEstado(EST_EVOLUCION); break;
      }
   }

   public void mouseDragged( MouseEvent e )
   {
      switch(estado) {
        case EST_EDITAR:
          switch(subestado) {
            case EST_EDIT_POS: movimientoPosicion( e.getPoint() ); break;
            case EST_EDIT_VEL: movimientoVelocidad( e.getPoint() ); break;
          }
          break;
        case EST_EVOLUCION: movimientoPosicion( e.getPoint() ); break;
      }
   }

   public void mouseReleased( MouseEvent e )
   {
      switch(estado) {
        case EST_EDITAR:
          switch(subestado) {
            case EST_EDIT_POS:
            case EST_EDIT_VEL: finalEdicion(); break;
          }
          break;
        case EST_EVOLUCION:
          if( !sistema.deselecPunto() ) break;
          cambioEstado(EST_ITERANDO);
          break;
      }
   }

   /* *** HILO ALTERNATIVO DE EJECUCION *** */

   public void run( )
   {
      int i;
      sistema.preparaIntegracion();
      do {
        if( autoZoom ) sistema.ajusteInicial();
        for( i = 0; (i < numIter) && animacion ; i++ ) {
          if(setParamX) {
            switch(numParamX) {
              case PAR_INC_TPO:  sistema.setIncTpo(valParamX); break;
              case PAR_COE_SIS:  sistema.setCoefSis(valParamX); break;
              case PAR_COE_AMOR: sistema.setAmortig(valParamX); break;
              case PAR_OSC_AMPL: sistema.setAmplPtoOsc(valParamX); break;
              case PAR_OSC_FREC: sistema.setFrecPtoOsc(valParamX); break;
            }
            setParamX = false;
          }
          sistema.integrar();
        }
        dibujar();
      } while( animacion );
   }

   /* *** PROCESADO DE EVENTOS *** */

   // Procesos asociados a cambios de estado, sobre todo adaptar 
   // la interfaz activando y desactivando componentes.
   protected void cambioEstado( int nuevoEstado )
   {
      estado = nuevoEstado;
      switch(estado) {
        case EST_NUEVO:
          disPanCon2.show(panCon2,"Nuevo");
          chkEvolucion.setEnabled(true);
          chkEditar.setEnabled(true);
          lisTipoSis.setEnabled(true);
          edtDimSis.setEnabled(true);
          edtIncSis.setEnabled(true);
          edtAmoSis.setEnabled(true);
          edtParSis.setEnabled(true);
          btnCrear.setEnabled(true);
          dibujar();
          break;
        case EST_EDITAR:
          disPanCon2.show(panCon2,"Editar");
          chkNuevo.setEnabled(true);
          chkEvolucion.setEnabled(true);
          lisTipoEdi.setEnabled(true);
          btnZoomAmp.setEnabled(true);
          btnZoomRed.setEnabled(true);
          btnZoomAmp.setLabel("Zoom +");
          btnZoomRed.setLabel("Zoom -");
          dibujar();
          break;
        case EST_ZOOM_AMP:
          chkNuevo.setEnabled(false);
          chkEvolucion.setEnabled(false);
          lisTipoEdi.setEnabled(false);
          btnZoomRed.setEnabled(false);
          btnZoomAmp.setLabel("Fin");
          break;
        case EST_ZOOM_RED:
          chkNuevo.setEnabled(false);
          chkEvolucion.setEnabled(false);
          lisTipoEdi.setEnabled(false);
          btnZoomAmp.setEnabled(false);
          btnZoomRed.setLabel("Fin");
          break;
        case EST_EVOLUCION:
          disPanCon2.show(panCon2,"Evolucion");
          chkNuevo.setEnabled(true);
          chkEditar.setEnabled(true);
          btnReiniciar.setEnabled(iniciado);
          btnAnimar.setLabel("Comenzar");
          parar();
          dibujar();
          break;
        case EST_ITERANDO:
          chkNuevo.setEnabled(false);
          chkEditar.setEnabled(false);
          btnReiniciar.setEnabled(false);
          btnAnimar.setLabel("Parar");
          animar();
          break;
      }
      lineaEstado();
   }

   // Pulsacion boton [Crear], panel [Nuevo]
   protected void crearSistema( )
   {
      int fil,col;
      double dt,k,gamma;
      int tipo = lisTipoSis.getSelectedIndex();

      try {
        String lin = edtDimSis.getText();
        int n = lin.indexOf('x');
        if( n == -1 ) throw new Exception("");
        fil = Integer.parseInt( lin.substring(0,n).trim() );
        col = Integer.parseInt( lin.substring(n+1).trim() );

        if( edtIncSis.getText().equals("X") ) {
          dt = compruebaParametroX(PAR_INC_TPO,true);
          edtParX.setText(""+dt);
        } else {
          compruebaParametroX(PAR_INC_TPO,false);
          dt = Double.valueOf( edtIncSis.getText() ).doubleValue();
          if( dt <= 0.0 ) throw new Exception();  
        }

        if( edtParSis.getText().equals("X") ) {
          k = compruebaParametroX(PAR_COE_SIS,true);
          edtParX.setText(""+k);
        } else {
          compruebaParametroX(PAR_COE_SIS,false);
          k = Double.valueOf( edtParSis.getText() ).doubleValue();
          if( k <= 0.0 ) throw new Exception();
        }

        if( edtAmoSis.getText().equals("X") ) {
          gamma = compruebaParametroX(PAR_COE_AMOR,true);
          edtParX.setText(""+gamma);
        } else {
          compruebaParametroX(PAR_COE_AMOR,false);
          gamma = Double.valueOf( edtAmoSis.getText() ).doubleValue();
          if( gamma < 0.0 ) throw new Exception();
        }

        /* -- Creacion del sistema -- */
        sistema.setDimensiones(tipo,fil,col);
        sistema.setIncTpo(dt);
        sistema.setCoefSis(k);
        sistema.setAmortig(gamma);
        sistema.setPropsDibujo(
          chkAutoAjuste.getState(),chkVerPtos.getState(),
          chkEstela.getState() );
        iniciado = false;
        cambioEstado(EST_NUEVO);
      } catch( Exception e ) {
        etqEstado.setText(" Algun parametro es erroneo.");
      }
   }

   protected double compruebaParametroX( int tipo, boolean selec )
                    throws Exception
   {
      if(!selec) {
         if(numParamX == tipo) {
           numParamX = -1;
           etqParX.setText("<No hay parametro>");
           edtParX.setText("--");
         }
         return(0.0);
      }

      if((numParamX != -1) && (numParamX != tipo)) throw new Exception("");
      numParamX = tipo;
      switch(tipo) {
        case PAR_INC_TPO:
          etqParX.setText("Inc. Tpo. (seg):");
          return(0.05);
        case PAR_COE_SIS:
          etqParX.setText("Cte Gravit.:");
          return(1.0);
        case PAR_COE_AMOR:
          etqParX.setText("Coef. Amort.:");
          return(0.0);
        case PAR_OSC_AMPL:
          etqParX.setText("Amplitud:");
          return(0.25);
        case PAR_OSC_FREC:
          etqParX.setText("Frecuencia (Hz):");
          return(1.0);
      }
      return(0.0);
   }

   // Pulsacion boton [Reiniciar], panel [Evolucion]
   protected void reiniciarSistema( )
   {
      sistema.reiniciar();
      dibujar();
   }

   // Pulsacion boton [Azar], panel [Editar], subpanel [Posiciones]
   protected void azarPosiciones( )
   {
      sistema.azarPosiciones();
      dibujar();
   }

   // Pulsacion boton [Azar], panel [Editar], subpanel [Velocidades]
   protected void azarVelocidades( )
   {
      sistema.azarVelocidades();
      dibujar();
   }

   // Pulsacion boton [Azar], panel [Editar], subpanel [Masas]
   protected void azarMasas( )
   {
      sistema.azarMasas();
      dibujar();
   }

   // Pulsacion boton [Todos Igual], panel [Editar], subpanel [Ptos. fijos]
   protected void puntosIguales( )
   {
      int n = lisTipoPto.getSelectedIndex();
      sistema.setTipoTodos(n);
      dibujar();
   }

   // Intro en editor del numero de iteraciones, panel [Evolucion]
   protected void cambioNumIteraciones( )
   {
      try {
        int n = Integer.parseInt( edtIter.getText() );
        if(n < 1) throw new Exception("");
        numIter = n;
        lineaEstado();
      } catch( Exception x ) {
        etqEstado.setText(" Error en el numero de iteraciones.");
      }
   }

   // Intro en editor del parametro X, panel [Evolucion]
   protected void cambioParametroX( )
   {
      if( numParamX == -1 ) return;
      try {
        double v = Double.valueOf( edtParX.getText() ).doubleValue();
        switch(numParamX) {
          case PAR_INC_TPO:
          case PAR_COE_SIS:
          case PAR_OSC_FREC: if(v <= 0.0) throw new Exception(""); break;
          case PAR_COE_AMOR:
          case PAR_OSC_AMPL: if(v < 0.0) throw new Exception(""); break;
        }
        valParamX = v;
        setParamX = true;
        lineaEstado();
      } catch( Exception x ) {
        etqEstado.setText(" Error en el parametro.");
      }
   }

   // Intro en editor de la masa, panel [Editar], subpanel [Masas]
   protected void cambioMasaPunto( )
   {
      try {
        double masa = Double.valueOf( edtMasa.getText() ).doubleValue();
        if(masa <= 0.0) throw new Exception("");
        sistema.setMasaPunto(masa);
        dibujar();
        lineaEstado();
      } catch( Exception x ) {
        etqEstado.setText(" Error en el valor de la masa.");
      }
   }

   // Cambio en lista de tipos de edicion, panel [Editar]
   protected void cambioTipoEdicion( )
   {
      switch( lisTipoEdi.getSelectedIndex() ) {
        case 0:
          disPanCon2bS.show(panCon2bS,"Posiciones");
          subestado = EST_EDIT_POS;
          break;
        case 1:
          disPanCon2bS.show(panCon2bS,"Velocidades");
          subestado = EST_EDIT_VEL;
          break;
        case 2:
          disPanCon2bS.show(panCon2bS,"Masas");
          subestado = EST_EDIT_MAS;
          break;
        case 3:
          disPanCon2bS.show(panCon2bS,"PtosFijos");
          subestado = EST_EDIT_ESP1;
          break;
        case 4:
        case 5:
          disPanCon2bS.show(panCon2bS,"Osciladores");
          subestado = EST_EDIT_ESP2;
          break;
      }
      finalEdicion();
   }

   // Final de cualquier edicion de posicion, movimiento, etc.
   protected void finalEdicion( )
   {
      sistema.deselecPunto();
      lineaEstado();
      dibujar();
   }

   // Cambio en checkbox de opciones de dibujo, panel [Evolucion]
   protected void cambioOpcionesDibujo( )
   {
      sistema.setPropsDibujo( chkAutoAjuste.getState(),chkVerPtos.getState(),
                              chkEstela.getState() );
      chkAutoZoom.setEnabled( chkAutoAjuste.getState() );
      if( estado != EST_ITERANDO ) dibujar();
   }

   // Click de raton en edicion-posicion
   protected void pulsacionPosicion( Point pto )
   {
      sistema.selecPunto(pto);
      dibujar();
   }

   // Movimiento de raton en edicion-posicion
   protected void movimientoPosicion( Point pto )
   {
      sistema.muevePunto(pto,lienzo.imgLx,lienzo.imgLy);
      dibujar();
   }

   // Click de raton en edicion-velocidad
   protected void pulsacionVelocidad( Point pto )
   {
      if( sistema.selecPtoVel(pto) ) {
        etqEstado.setText(sistema.infoVel());
        dibujar();
      }
   }

   // Movimiento de raton en edicion-velocidad
   protected void movimientoVelocidad( Point pto )
   {
      sistema.muevePtoVel(pto,lienzo.imgLx,lienzo.imgLy);
      etqEstado.setText( sistema.infoVel() );
      dibujar();
   }

   // Click de raton en edicion-masa
   protected void pulsacionEditarMasa( Point pto )
   {
      if( sistema.selecPunto(pto) ) {
         edtMasa.setText(""+sistema.getMasaPunto()); 
         dibujar();
      }
   }

   // Click de raton en edicion-puntos fijos
   protected void pulsacionTipoPunto( Point pto )
   {
      int n = lisTipoPto.getSelectedIndex();
      sistema.setTipoPunto(pto,n);
      dibujar();
   }

   // Click de raton en edicion-impulsores o edicion-osciladores
   protected void pulsacionOscilador( Point p )
   {
      try {
        double a,w;

        if( edtAmpl.getText().equals("X") ) {
          a = compruebaParametroX(PAR_OSC_AMPL,true);
          edtParX.setText(""+a);
        } else {
          compruebaParametroX(PAR_OSC_AMPL,false);
          a = Double.valueOf( edtAmpl.getText() ).doubleValue();
          if( a < 0.0 ) throw new Exception();
        }

        if( edtFrec.getText().equals("X") ) {
          w = compruebaParametroX(PAR_OSC_FREC,true);
          edtParX.setText(""+w);
        } else {
          compruebaParametroX(PAR_OSC_FREC,false);
          w = Double.valueOf( edtFrec.getText() ).doubleValue();
          if( w <= 0.0 ) throw new Exception();
        }

        boolean ejex = lisTipoOsc.getSelectedIndex() != 1;
        boolean ejey = lisTipoOsc.getSelectedIndex() != 0;
        boolean impulso = lisTipoEdi.getSelectedIndex() == 4;
        sistema.setPuntoOscilante(p,a,w,ejex,ejey,impulso);
        dibujar();
        lineaEstado();
      } catch( Exception e ) {
        etqEstado.setText(" Algun valor del oscilador es erroneo.");
      }
   }

   // Click de raton en edicion-modo zoom
   protected void zoom( Point pto, boolean ampliar )
   {
      if(ampliar) {
        sistema.ampliar(pto,lienzo.imgLx,lienzo.imgLy);
      } else {
        sistema.reducir(pto,lienzo.imgLx,lienzo.imgLy);
      }
      dibujar();
   }

   // Pulsacion boton [Animar] en panel [Evolucion]
   protected void animar( )
   {
     if( (hilo != null) && hilo.isAlive() ) parar();
     animacion = true;
     iniciado = true;
     hilo = new Thread(this);
     hilo.start();
   }

   // Pulsacion boton [Parar] en panel [Evolucion]
   protected void parar( )
   {
      animacion = false;
      if( hilo != null )
        while( hilo.isAlive() ) Thread.yield();
      hilo = null;
   }

   // Dibujar el sistema (dependiendo de su estado)
   protected void dibujar( )
   {
      lienzo.compruebaImagen();
      Graphics g = lienzo.imagen.getGraphics();
      switch(estado) {
        case EST_EDITAR:
        case EST_ZOOM_AMP:
        case EST_ZOOM_RED:
          switch(subestado) {
            case EST_EDIT_VEL:
              sistema.dibujarVelocidad(g,lienzo.imgLx,lienzo.imgLy);
              break;
            case EST_EDIT_MAS:
              sistema.dibujarMasa(g,lienzo.imgLx,lienzo.imgLy);
              break;
            default:
              sistema.dibujar(g,lienzo.imgLx,lienzo.imgLy);
            break;
          }
          break;
        default:
          sistema.dibujar(g,lienzo.imgLx,lienzo.imgLy);
          break;
      }
      lienzo.dibujar();
   }

   /* *** INTERFAZ DE USUARIO *** */

   protected void creaInterfaz( )
   {
      disPanCon2 = new CardLayout();
      disPanCon2bS = new CardLayout();

      // Creacion de la jerarquia

      PanelExt panCen = new PanelExt( new BorderLayout(), 5 );

      PanelExt panEst = new PanelExt( new BorderLayout(), 3 );

      Panel panCon = new Panel( new BorderLayout() );
         PanelExt panCon1 = new PanelExt( new GridLayout(4,1), 5 );
                  panCon2 = new PanelExt( disPanCon2, 5 );
           Panel panCon2a = new Panel( new BorderLayout() );
             Panel panCon2aN = new Panel( new GridLayout(10,1) );
             Panel panCon2aS = new Panel( new GridLayout(1,1,5,5) );
           panCon2a.add("North",panCon2aN);
           panCon2a.add("South",panCon2aS);

           Panel panCon2b = new Panel( new BorderLayout() );
             Panel panCon2bN = new Panel( new GridLayout(2,1,5,5) );
                   panCon2bS = new Panel( disPanCon2bS );
               Panel panCon2bN1 = new Panel( new GridLayout(1,2,5,5) );
               Panel panCon2bS1 = new Panel( new GridLayout(1,1,5,5) );
               Panel panCon2bS2 = new Panel( new GridLayout(1,1,5,5) );
               Panel panCon2bS3 = new Panel( new GridLayout(3,1,5,5) );
               Panel panCon2bS4 = new Panel( new GridLayout(3,1,5,5) );
               Panel panCon2bS5 = new Panel( new GridLayout(6,1,5,5) );
               Panel panCon2bS1x = new Panel( new BorderLayout() );
               Panel panCon2bS2x = new Panel( new BorderLayout() );
               Panel panCon2bS3x = new Panel( new BorderLayout() );
               Panel panCon2bS4x = new Panel( new BorderLayout() );
               Panel panCon2bS5x = new Panel( new BorderLayout() );
               panCon2bS1x.add("South",panCon2bS1);
               panCon2bS2x.add("South",panCon2bS2);
               panCon2bS3x.add("South",panCon2bS3);
               panCon2bS4x.add("South",panCon2bS4);
               panCon2bS5x.add("South",panCon2bS5);
             panCon2bS.add("Posiciones",  panCon2bS1x);
             panCon2bS.add("Velocidades", panCon2bS2x);
             panCon2bS.add("Masas",       panCon2bS3x);
             panCon2bS.add("PtosFijos",   panCon2bS4x);
             panCon2bS.add("Osciladores", panCon2bS5x);
           panCon2b.add("North",panCon2bN);
           panCon2b.add("South",panCon2bS);

           Panel panCon2c = new Panel( new BorderLayout() );
             Panel panCon2cN = new Panel( new GridLayout(8,1) );
             Panel panCon2cS = new Panel( new GridLayout(2,1,5,5) );
           panCon2c.add("North",panCon2cN);
           panCon2c.add("South",panCon2cS);

         panCon2.add("Nuevo"    , panCon2a);
         panCon2.add("Editar"   , panCon2b);
         panCon2.add("Evolucion", panCon2c);
     
       panCon.add("North",panCon1);
       panCon.add("Center",panCon2);

      setLayout( new BorderLayout() );
      add("Center",panCen);
      add("South",panEst);
      add("West",panCon);

      // Creacion de componentes principales

      lienzo = new CanvasExt();
      etqEstado = new Label(ayudas[estado]);
      CheckboxGroup grupo = new CheckboxGroup();
      chkNuevo = new Checkbox("Nuevo",true,grupo);
      chkEditar = new Checkbox("Editar",false,grupo);
      chkEvolucion = new Checkbox("Evolucion",false,grupo);
      // Nuevo
      lisTipoSis = new Choice();
      edtDimSis = new TextField("10 x 10");
      edtIncSis = new TextField("0.05");
      edtAmoSis = new TextField("0.0");
      edtParSis = new TextField("1.0");
      btnCrear = new Button("Crear");
      // Editar
      lisTipoEdi = new Choice();
      btnZoomAmp = new Button("Zoom +");
      btnZoomRed = new Button("Zoom -");
      btnAzarPos = new Button("Azar");
      btnAzarVel = new Button("Azar");
      edtMasa = new TextField("--");
      btnAzarMas = new Button("Azar");
      lisTipoPto = new Choice();
      btnTodos = new Button("Todos igual");
      lisTipoOsc = new Choice();
      edtAmpl = new TextField("0.25");
      edtFrec = new TextField("1.0");
      // Evolucion
      edtIter = new TextField(""+numIter);
      etqParX = new Label("<No hay parametro>");
      edtParX = new TextField("--");
      chkAutoAjuste = new Checkbox("Auto-ajuste",false);
      chkAutoZoom = new Checkbox("Auto-zoom",false);
      chkVerPtos = new Checkbox("Ver puntos",true);
      chkEstela = new Checkbox("Estela",false);
      btnReiniciar = new Button("Reiniciar");
      btnAnimar = new Button("Comenzar");

      // Creacion de componentes secundarios

      Label etq1 = new Label("Sistema:");
      Label etq2 = new Label("Frec. refresco:");
      Label etq3 = new Label("Distribucion:");
      Label etq4 = new Label("Dimensiones:");
      Label etq5 = new Label("Cte. Gravit.:");
      Label etq6 = new Label("Inc. tpo. (seg):");
      Label etq7 = new Label("Tipo de punto:");
      Label etq8 = new Label("Oscilacion:");
      Label etq9 = new Label("Amplitud:");
      Label etq10 = new Label("Frecuencia (Hz):");
      Label etq11 = new Label("Coef. Amortig.:");
      Label etq12 = new Label("Masa:");

      // Insercion de componentes en contenedores

      panCen.add("Center",lienzo);
      panEst.add("Center",etqEstado);
      panCon1.add(etq1);
      panCon1.add(chkNuevo);
      panCon1.add(chkEditar);
      panCon1.add(chkEvolucion);
      panCon2aN.add(etq3);
      panCon2aN.add(lisTipoSis);
      panCon2aN.add(etq4);
      panCon2aN.add(edtDimSis);
      panCon2aN.add(etq6);
      panCon2aN.add(edtIncSis);
      panCon2aN.add(etq5);
      panCon2aN.add(edtParSis);
      panCon2aN.add(etq11);
      panCon2aN.add(edtAmoSis);
      panCon2aS.add(btnCrear);
      panCon2bN.add(lisTipoEdi);
      panCon2bN.add(panCon2bN1);
      panCon2bN1.add(btnZoomAmp);
      panCon2bN1.add(btnZoomRed);
      panCon2bS1.add(btnAzarPos);
      panCon2bS2.add(btnAzarVel);
      panCon2bS3.add(etq12);
      panCon2bS3.add(edtMasa);
      panCon2bS3.add(btnAzarMas);
      panCon2bS4.add(etq7);
      panCon2bS4.add(lisTipoPto);
      panCon2bS4.add(btnTodos);
      panCon2bS5.add(etq8);
      panCon2bS5.add(lisTipoOsc);
      panCon2bS5.add(etq9);
      panCon2bS5.add(edtAmpl);
      panCon2bS5.add(etq10);
      panCon2bS5.add(edtFrec);
      panCon2cN.add(etq2);
      panCon2cN.add(edtIter);
      panCon2cN.add(etqParX);
      panCon2cN.add(edtParX);
      panCon2cN.add(chkAutoAjuste);
      panCon2cN.add(chkAutoZoom);
      panCon2cN.add(chkVerPtos);
      panCon2cN.add(chkEstela);
      panCon2cS.add(btnReiniciar);
      panCon2cS.add(btnAnimar);

      // Retoques a componentes

      lisTipoSis.addItem("Cuadrado");
      lisTipoSis.addItem("Hexagonal");
      lisTipoSis.addItem("Circular");
      lisTipoEdi.addItem("Posiciones");
      lisTipoEdi.addItem("Velocidades");
      lisTipoEdi.addItem("Masas");
      lisTipoEdi.addItem("Ptos fijos");
      lisTipoEdi.addItem("Impulsores");
      lisTipoEdi.addItem("Osciladores");
      lisTipoPto.addItem("Normal");
      lisTipoPto.addItem("Horizontal");
      lisTipoPto.addItem("Vertical");
      lisTipoPto.addItem("Fijo");
      lisTipoOsc.addItem("Horizontal");
      lisTipoOsc.addItem("Vertical");
      lisTipoOsc.addItem("Circular");
      chkEditar.setEnabled(false);
      chkEvolucion.setEnabled(false);

      // Recogida de eventos

      lienzo.addComponentListener(this);
      lienzo.addMouseListener(this);
      lienzo.addMouseMotionListener(this);
      btnCrear.addActionListener(this);
      btnZoomAmp.addActionListener(this);
      btnZoomRed.addActionListener(this);
      btnAzarPos.addActionListener(this);
      btnAzarVel.addActionListener(this);
      btnAzarMas.addActionListener(this);
      btnTodos.addActionListener(this);
      btnReiniciar.addActionListener(this);
      btnAnimar.addActionListener(this);
      edtIter.addActionListener(this);
      edtMasa.addActionListener(this);
      edtParX.addActionListener(this);
      chkEvolucion.addItemListener(this);
      chkNuevo.addItemListener(this);
      chkEditar.addItemListener(this);
      lisTipoEdi.addItemListener(this);
      chkAutoAjuste.addItemListener(this);
      chkAutoZoom.addItemListener(this);
      chkVerPtos.addItemListener(this);
      chkEstela.addItemListener(this);

      // Poner el fondo adecuado

      panCon2a.setBackground(Color.lightGray);
      panCon2b.setBackground(Color.lightGray);
      panCon2c.setBackground(Color.lightGray);
      etqEstado.setBackground(Color.lightGray);
      chkEvolucion.setBackground(Color.lightGray);
      chkNuevo.setBackground(Color.lightGray);
      chkEditar.setBackground(Color.lightGray);
      etqParX.setBackground(Color.lightGray);
      chkAutoAjuste.setBackground(Color.lightGray);
      chkAutoZoom.setBackground(Color.lightGray);
      chkVerPtos.setBackground(Color.lightGray);
      chkEstela.setBackground(Color.lightGray);
      etq1.setBackground(Color.lightGray);
      etq2.setBackground(Color.lightGray);
      etq3.setBackground(Color.lightGray);
      etq4.setBackground(Color.lightGray);
      etq5.setBackground(Color.lightGray);
      etq6.setBackground(Color.lightGray);
      etq7.setBackground(Color.lightGray);
      etq8.setBackground(Color.lightGray);
      etq9.setBackground(Color.lightGray);
      etq10.setBackground(Color.lightGray);
      etq11.setBackground(Color.lightGray);
      etq12.setBackground(Color.lightGray);
   }
}
