/*
 * VentanaPrincipal.java
 *
 * Created on 20 de julio de 2008, 17:16
 */

package sdsimulator.interfaz;
//El generador de código no importa clases porque usa el nombre completo para 
//declarar los objetos.
//
//Imports añadidos por mí
import java.awt.Rectangle;
import javax.swing.*;   
import sdsimulator.runnable.*;

/**
 *
 * @author  Miguel Herreros
 */
public class VentanaPrincipal extends javax.swing.JFrame {
    public VentanaPrincipal(java.awt.Component[] vectorComponentes){
        //Carga el diagrama que viene en forma de vector de componentes
        //Comentar que el splitpane no lo estoy usando como se crea por defecto.
        //He tenido que cambiar orientation a VERTICAL_SPLIT (para que sea un split,
        //vertical, resizeweight a 1.0 (para que el panel de arriba sea el único
        //que crezca verticalmente al maximizar. 
        //Por último he cambiado divider location a un tamaño grande, para que el 
        //panel de arriba sea más grande que el de debajo.
        //Con esto he 'invertido' el funcionamiento por defecto de un JSplitPane
        //Nótese que en el dibujador no se ve el mismo tamaño en los paneles. Lo 
        //importante es que los paneles que contine el jsplit en cada una de sus
        //divisiones queden debidamente cuadrados en el layout (rellenando todo 
        //el espacio disponible). Cualquier resize posterior hace que los conte-
        //nidos del splitpane crezcan con él.
        initComponents();     //Inicializaciones automáticas
        initComponentsMios(); //Mis inicializaciones
        
        //Código específico de este constructor
        try{
            jPanelDiagrama= new JPanelDiagrama(vectorComponentes);
            jScrollPaneDiagrama.setViewportView(jPanelDiagrama);
            ejecutable=new DiagramaEjecutable(jPanelDiagrama.getComponents());
            estadoInterfaz.setInicializada();
        }
        catch (Exception e){
            new VentanaError(this, "Error importing diagram", e);
        }
    }

    /** Creates new form VentanaPrincipal */
    public VentanaPrincipal() {
        initComponents(); 
        initComponentsMios();
    }
    
    /** Esta función, será invocada desde WST, cada vez que entremos en la pesta-
     * ña donde está integrado el simulador.
     */
    public void RefrescarDiagrama(java.awt.Component[] vectorComponentes){
        try{
            jPanelDiagrama= new JPanelDiagrama(vectorComponentes); 
            jScrollPaneDiagrama.setViewportView(jPanelDiagrama);
            ejecutable=new DiagramaEjecutable(jPanelDiagrama.getComponents());
            ejecutable.configurarAsincronos(configuracionAsincronos.getFrecuenciaLlegada(), configuracionAsincronos.getPrioridadAntiguos());
            jTextAreaTraza.setText("");
            estadoInterfaz.setInicializada();
        
    }
    catch (Exception e){
        new VentanaError(this, "Error importing serialized data from file", e);
    }
    }
        
    private void initComponentsMios(){
    //Análogo a initComponents, generado por el editor de interfaces, pero con-
    //tiene el código de los componentes que añadimos manualmente.
        ImageIcon iconoAplicacion = new ImageIcon(getClass().getResource("/sdsimulator/resources/app_ico.png"));
        setIconImage(iconoAplicacion.getImage());
        
        timer = new Timer(jSliderSpeed.getValue()*1000,  
                      new java.awt.event.ActionListener (){ 
                            public void actionPerformed(java.awt.event.ActionEvent e){ 
                                timerActionPerformed(e);
                            } 
                      }
                 );
        jSliderSpeed.setValue(sdsimulator.Main.FRECUENCIA_EJECUCION_DEFECTO);         
        jSliderSpeed.setToolTipText(jSliderSpeed.getValue() + " seconds/step");
        configuracionAsincronos= new VentanaConfigurarAsincronos(this,true); //La
        //creo, pero no la muestro. Así, los controles de la ventana, están cargados 
        //con los valores por defecto.
        estadoInterfaz = new EstadoInterfaz();
    }
    
    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jToolBarBotones = new javax.swing.JToolBar();
        jButtonRun = new javax.swing.JButton();
        jButtonRunStep = new javax.swing.JButton();
        jButtonPause = new javax.swing.JButton();
        jButtonReset = new javax.swing.JButton();
        jLabelStatusBar = new javax.swing.JLabel();
        jSplitPane1 = new javax.swing.JSplitPane();
        jPanelTraza = new javax.swing.JPanel();
        jToolBarTraza = new javax.swing.JToolBar();
        jButtonSaveTraza = new javax.swing.JButton();
        jScrollPaneTraza = new javax.swing.JScrollPane();
        jTextAreaTraza = new javax.swing.JTextArea();
        jScrollPaneDiagrama = new javax.swing.JScrollPane();
        jToolBarSpeed = new javax.swing.JToolBar();
        jLabelSpeed = new javax.swing.JLabel();
        jSliderSpeed = new javax.swing.JSlider();
        jButtonAsynchronous = new javax.swing.JButton();
        jMenuBar1 = new javax.swing.JMenuBar();
        jMenuFile = new javax.swing.JMenu();
        jMenuItemOpen = new javax.swing.JMenuItem();
        jMenuItemSaveTraza = new javax.swing.JMenuItem();
        jMenuItemExit = new javax.swing.JMenuItem();
        jMenuSimulate = new javax.swing.JMenu();
        jMenuItemRun = new javax.swing.JMenuItem();
        jMenuItemRunStep = new javax.swing.JMenuItem();
        jMenuItemPause = new javax.swing.JMenuItem();
        jSeparator1 = new javax.swing.JSeparator();
        jMenuItemRestart = new javax.swing.JMenuItem();
        jMenuHelp = new javax.swing.JMenu();
        jMenuItemHelpContents = new javax.swing.JMenuItem();
        jMenuItemAbout = new javax.swing.JMenuItem();

        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
        java.util.ResourceBundle bundle = java.util.ResourceBundle.getBundle("sdsimulator/resources/application"); // NOI18N
        setTitle(bundle.getString("Application Name")); // NOI18N

        jToolBarBotones.setFloatable(false);
        jToolBarBotones.setRollover(true);

        jButtonRun.setIcon(new javax.swing.ImageIcon(getClass().getResource("/sdsimulator/resources/run.png"))); // NOI18N
        jButtonRun.setToolTipText("Run");
        jButtonRun.setDisabledIcon(new javax.swing.ImageIcon(getClass().getResource("/sdsimulator/resources/dis_run.png"))); // NOI18N
        jButtonRun.setFocusable(false);
        jButtonRun.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        jButtonRun.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        jButtonRun.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonRunActionPerformed(evt);
            }
        });
        jToolBarBotones.add(jButtonRun);

        jButtonRunStep.setIcon(new javax.swing.ImageIcon(getClass().getResource("/sdsimulator/resources/runstep.png"))); // NOI18N
        jButtonRunStep.setToolTipText("Run Step");
        jButtonRunStep.setDisabledIcon(new javax.swing.ImageIcon(getClass().getResource("/sdsimulator/resources/dis_runstep.png"))); // NOI18N
        jButtonRunStep.setFocusable(false);
        jButtonRunStep.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        jButtonRunStep.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        jButtonRunStep.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonRunStepActionPerformed(evt);
            }
        });
        jToolBarBotones.add(jButtonRunStep);

        jButtonPause.setIcon(new javax.swing.ImageIcon(getClass().getResource("/sdsimulator/resources/pause.png"))); // NOI18N
        jButtonPause.setToolTipText("Pause");
        jButtonPause.setDisabledIcon(new javax.swing.ImageIcon(getClass().getResource("/sdsimulator/resources/dis_pause.png"))); // NOI18N
        jButtonPause.setFocusable(false);
        jButtonPause.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        jButtonPause.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        jButtonPause.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonPauseActionPerformed(evt);
            }
        });
        jToolBarBotones.add(jButtonPause);

        jButtonReset.setIcon(new javax.swing.ImageIcon(getClass().getResource("/sdsimulator/resources/restart.png"))); // NOI18N
        jButtonReset.setToolTipText("Restart");
        jButtonReset.setDisabledIcon(new javax.swing.ImageIcon(getClass().getResource("/sdsimulator/resources/dis_restart.png"))); // NOI18N
        jButtonReset.setFocusable(false);
        jButtonReset.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        jButtonReset.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        jButtonReset.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonResetActionPerformed(evt);
            }
        });
        jToolBarBotones.add(jButtonReset);

        jLabelStatusBar.setText("Status");
        jLabelStatusBar.setVerticalAlignment(javax.swing.SwingConstants.TOP);
        jLabelStatusBar.setAlignmentY(0.0F);
        jLabelStatusBar.setOpaque(true);
        jLabelStatusBar.setVerticalTextPosition(javax.swing.SwingConstants.TOP);

        jSplitPane1.setDividerLocation(350);
        jSplitPane1.setOrientation(javax.swing.JSplitPane.VERTICAL_SPLIT);
        jSplitPane1.setResizeWeight(1.0);
        jSplitPane1.setOneTouchExpandable(true);

        jToolBarTraza.setFloatable(false);
        jToolBarTraza.setRollover(true);

        jButtonSaveTraza.setIcon(new javax.swing.ImageIcon(getClass().getResource("/sdsimulator/resources/save.png"))); // NOI18N
        jButtonSaveTraza.setText("Save Trace");
        jButtonSaveTraza.setDisabledIcon(new javax.swing.ImageIcon(getClass().getResource("/sdsimulator/resources/dis_save.png"))); // NOI18N
        jButtonSaveTraza.setFocusable(false);
        jButtonSaveTraza.setHorizontalTextPosition(javax.swing.SwingConstants.RIGHT);
        jButtonSaveTraza.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonSaveTrazaActionPerformed(evt);
            }
        });
        jToolBarTraza.add(jButtonSaveTraza);

        jTextAreaTraza.setColumns(20);
        jTextAreaTraza.setEditable(false);
        jTextAreaTraza.setRows(5);
        jScrollPaneTraza.setViewportView(jTextAreaTraza);

        javax.swing.GroupLayout jPanelTrazaLayout = new javax.swing.GroupLayout(jPanelTraza);
        jPanelTraza.setLayout(jPanelTrazaLayout);
        jPanelTrazaLayout.setHorizontalGroup(
            jPanelTrazaLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jScrollPaneTraza, javax.swing.GroupLayout.DEFAULT_SIZE, 527, Short.MAX_VALUE)
            .addComponent(jToolBarTraza, javax.swing.GroupLayout.DEFAULT_SIZE, 527, Short.MAX_VALUE)
        );
        jPanelTrazaLayout.setVerticalGroup(
            jPanelTrazaLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanelTrazaLayout.createSequentialGroup()
                .addComponent(jToolBarTraza, javax.swing.GroupLayout.PREFERRED_SIZE, 30, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jScrollPaneTraza, javax.swing.GroupLayout.DEFAULT_SIZE, 250, Short.MAX_VALUE))
        );

        jSplitPane1.setBottomComponent(jPanelTraza);
        jSplitPane1.setLeftComponent(jScrollPaneDiagrama);

        jToolBarSpeed.setFloatable(false);
        jToolBarSpeed.setRollover(true);

        jLabelSpeed.setFont(new java.awt.Font("Tahoma", 1, 11));
        jLabelSpeed.setForeground(new java.awt.Color(0, 0, 204));
        jLabelSpeed.setText("Seconds/step");
        jToolBarSpeed.add(jLabelSpeed);

        jSliderSpeed.setMaximum(5);
        jSliderSpeed.setMinimum(1);
        jSliderSpeed.setMinorTickSpacing(1);
        jSliderSpeed.setSnapToTicks(true);
        jSliderSpeed.setValue(2);
        jSliderSpeed.setFocusable(false);
        jSliderSpeed.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseReleased(java.awt.event.MouseEvent evt) {
                jSliderSpeedMouseReleased(evt);
            }
        });
        jToolBarSpeed.add(jSliderSpeed);

        jButtonAsynchronous.setFont(new java.awt.Font("Tahoma", 1, 11));
        jButtonAsynchronous.setForeground(new java.awt.Color(0, 0, 204));
        jButtonAsynchronous.setIcon(new javax.swing.ImageIcon(getClass().getResource("/sdsimulator/resources/cfg_asin.png"))); // NOI18N
        jButtonAsynchronous.setText("Asynchronous...");
        jButtonAsynchronous.setToolTipText("Define the behaviour of asynchronous messages");
        jButtonAsynchronous.setDisabledIcon(new javax.swing.ImageIcon(getClass().getResource("/sdsimulator/resources/dis_cfg_asin.png"))); // NOI18N
        jButtonAsynchronous.setFocusable(false);
        jButtonAsynchronous.setHorizontalTextPosition(javax.swing.SwingConstants.LEFT);
        jButtonAsynchronous.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonAsynchronousActionPerformed(evt);
            }
        });
        jToolBarSpeed.add(jButtonAsynchronous);

        jMenuFile.setText("File");

        jMenuItemOpen.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_O, java.awt.event.InputEvent.CTRL_MASK));
        jMenuItemOpen.setText("Open Diagram");
        jMenuItemOpen.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItemOpenActionPerformed(evt);
            }
        });
        jMenuFile.add(jMenuItemOpen);

        jMenuItemSaveTraza.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_S, java.awt.event.InputEvent.CTRL_MASK));
        jMenuItemSaveTraza.setText("Save Trace");
        jMenuFile.add(jMenuItemSaveTraza);

        jMenuItemExit.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_Q, java.awt.event.InputEvent.CTRL_MASK));
        jMenuItemExit.setText("Exit");
        jMenuItemExit.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItemExitActionPerformed(evt);
            }
        });
        jMenuFile.add(jMenuItemExit);

        jMenuBar1.add(jMenuFile);

        jMenuSimulate.setText("Simulate");

        jMenuItemRun.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_F9, 0));
        jMenuItemRun.setText("Run");
        jMenuSimulate.add(jMenuItemRun);

        jMenuItemRunStep.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_F8, 0));
        jMenuItemRunStep.setText("Run Step");
        jMenuSimulate.add(jMenuItemRunStep);

        jMenuItemPause.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_F5, 0));
        jMenuItemPause.setText("Pause");
        jMenuSimulate.add(jMenuItemPause);
        jMenuSimulate.add(jSeparator1);

        jMenuItemRestart.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_F5, java.awt.event.InputEvent.CTRL_MASK));
        jMenuItemRestart.setText("Restart");
        jMenuSimulate.add(jMenuItemRestart);

        jMenuBar1.add(jMenuSimulate);

        jMenuHelp.setText("Help");

        jMenuItemHelpContents.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_F1, 0));
        jMenuItemHelpContents.setText("Help Contents");
        jMenuItemHelpContents.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItemHelpContentsActionPerformed(evt);
            }
        });
        jMenuHelp.add(jMenuItemHelpContents);

        jMenuItemAbout.setText("About");
        jMenuItemAbout.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItemAboutActionPerformed(evt);
            }
        });
        jMenuHelp.add(jMenuItemAbout);

        jMenuBar1.add(jMenuHelp);

        setJMenuBar(jMenuBar1);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jLabelStatusBar, javax.swing.GroupLayout.DEFAULT_SIZE, 519, Short.MAX_VALUE))
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jToolBarBotones, javax.swing.GroupLayout.DEFAULT_SIZE, 164, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jToolBarSpeed, javax.swing.GroupLayout.PREFERRED_SIZE, 349, javax.swing.GroupLayout.PREFERRED_SIZE))
            .addComponent(jSplitPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 529, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addComponent(jToolBarSpeed, 0, 0, Short.MAX_VALUE)
                    .addComponent(jToolBarBotones, javax.swing.GroupLayout.PREFERRED_SIZE, 30, Short.MAX_VALUE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jSplitPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 576, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jLabelStatusBar, javax.swing.GroupLayout.PREFERRED_SIZE, 18, javax.swing.GroupLayout.PREFERRED_SIZE))
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    
private void jMenuItemAboutActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItemAboutActionPerformed
//Creo un objeto para la ventana About, lo posiciono respecto a la ventana padre
//y lo muesto. El true que le paso al constructor hace la ventana modal con respec-
//to a la invocadora. En este caso, la ventana principal.
    VentanaAcercaDe acercade = new  VentanaAcercaDe(this, true);
    acercade.setLocationRelativeTo(this); 
    acercade.setVisible(true);
}//GEN-LAST:event_jMenuItemAboutActionPerformed


private void jMenuItemExitActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItemExitActionPerformed
    //Cierra la ventana principal del programa. Ponemos dispose porque si se lanza 
    //la ventana del simulador desde la herramienta WST, no queremos que cierre 
    //la herramienta entera al cerrar el simulador.
    setVisible(false);
    dispose();
}//GEN-LAST:event_jMenuItemExitActionPerformed


private void jMenuItemOpenActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItemOpenActionPerformed
    //Sólo hay un bloque catch porque por el momento, la única excepción que se
    //detecta es debida a VentanaAbrirSerializado. Si queremos tratar el resto de
    //excepciones que pudiesen devolver las demás llamadas, pondremos un catch
    //detallando para qué excepción específica se ejecuta (primero las específicas
    //terminando con la más general, que sería la que ahora existe).
    if (estadoInterfaz.getEstado()!=EstadosPosibles.VACIA){
        VentanaConfirmarOpen confirmacion = new VentanaConfirmarOpen(this);
        if (confirmacion.getResultado() == JOptionPane.NO_OPTION)
            return;
    }
        
    try{
        VentanaAbrirSerializado serializado= new VentanaAbrirSerializado(this,"Serialized Diagram","uml");
        if  (serializado.getComponents()!=null){ 
            //Si se pulsó cancel, no se abrió ningún fichero, pero tampoco se ha
            //lanzado ninguna excepción.
                
            jPanelDiagrama= new JPanelDiagrama(serializado.getComponents()); 
            jScrollPaneDiagrama.setViewportView(jPanelDiagrama);
            ejecutable=new DiagramaEjecutable(jPanelDiagrama.getComponents());
            ejecutable.configurarAsincronos(configuracionAsincronos.getFrecuenciaLlegada(), configuracionAsincronos.getPrioridadAntiguos());
            jTextAreaTraza.setText("");
            estadoInterfaz.setInicializada();
        }
    }
    catch (Exception e){
        new VentanaError(this, "Error importing serialized data from file", e);
    }
}//GEN-LAST:event_jMenuItemOpenActionPerformed


private void jButtonRunStepActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonRunStepActionPerformed
    ResultadoEjecucion resultadoPaso=ejecutable.runStep();
    jTextAreaTraza.append(resultadoPaso.traza);
    getContentPane().repaint();
    
    if  (ejecutable.completado()){    
        estadoInterfaz.setFinalizada();
        String texto="There are no more steps to run";
        String titulo="Simulation finished";
        new VentanaInfo(this,texto,titulo);
    }
    else {
        estadoInterfaz.setPausada();
    }
}//GEN-LAST:event_jButtonRunStepActionPerformed


private void jButtonPauseActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonPauseActionPerformed
    timer.stop();
    estadoInterfaz.setPausada();
}//GEN-LAST:event_jButtonPauseActionPerformed


private void jButtonSaveTrazaActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonSaveTrazaActionPerformed
    try{
        new VentanaGuardarTexto(this,jTextAreaTraza);
    }
    catch (Exception e){
        new VentanaError(this,"Error saving trace",e);
    }
}//GEN-LAST:event_jButtonSaveTrazaActionPerformed
                                                                                                            
private void jButtonRunActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonRunActionPerformed
    jButtonRunStepActionPerformed(evt);
    timer.start();
    estadoInterfaz.setEnMarcha();
}//GEN-LAST:event_jButtonRunActionPerformed

private void jSliderSpeedMouseReleased(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jSliderSpeedMouseReleased
    jSliderSpeed.setToolTipText(jSliderSpeed.getValue() + " seconds/step");
    timer.setDelay(jSliderSpeed.getValue() * 1000);
}//GEN-LAST:event_jSliderSpeedMouseReleased

private void jButtonResetActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonResetActionPerformed
    VentanaConfirmarReset confirmacion = new VentanaConfirmarReset(this);
    
    if (confirmacion.getResultado() == JOptionPane.YES_OPTION){
        ejecutable.reset();
        //Me salgo de rango aposta y así se coloca en la mínima posición posible.
        autoscrollDiagrama(-1000000,-1000000);

        ejecutable.configurarAsincronos(configuracionAsincronos.getFrecuenciaLlegada(),configuracionAsincronos.getPrioridadAntiguos());
        
        getContentPane().repaint();
        jTextAreaTraza.setText("");
        estadoInterfaz.setInicializada();
    }
}//GEN-LAST:event_jButtonResetActionPerformed

private void jButtonAsynchronousActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonAsynchronousActionPerformed
//Creo un objeto para la ventana About, lo posiciono respecto a la ventana padre
//y lo muesto. El true que le paso al constructor hace la ventana modal con respec-
//to a la invocadora. En este caso, la ventana principal.
    configuracionAsincronos.setLocationRelativeTo(this); 
    configuracionAsincronos.setVisible(true);
    
    if (configuracionAsincronos.getReturnStatus() == VentanaConfigurarAsincronos.RET_OK)
        ejecutable.configurarAsincronos(configuracionAsincronos.getFrecuenciaLlegada(), configuracionAsincronos.getPrioridadAntiguos());
}//GEN-LAST:event_jButtonAsynchronousActionPerformed

private void jMenuItemHelpContentsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItemHelpContentsActionPerformed
    //Creo un objeto para la ventana Ayuda, lo posiciono respecto a la ventana padre
    //y lo muesto. El true que le paso al constructor hace la ventana modal con respec-
    //to a la invocadora. En este caso, la ventana principal.
    VentanaAyuda ayuda = new  VentanaAyuda(this, true);
    ayuda.setLocationRelativeTo(this); 
    ayuda.setVisible(true);
}//GEN-LAST:event_jMenuItemHelpContentsActionPerformed

private void timerActionPerformed(java.awt.event.ActionEvent e){
    ResultadoEjecucion resultado=ejecutable.runStep();
    jTextAreaTraza.append(resultado.traza);
    getContentPane().repaint();
    autoscrollDiagrama(resultado.x, resultado.y);
    
    if (ejecutable.completado()){
        estadoInterfaz.setFinalizada();
        timer.stop();
        String texto="There are no more steps to run";
        String titulo="Simulation finished";
        new VentanaInfo(this,texto,titulo);
    }
}

//..............................................................................
private void autoscrollDiagrama(int x, int y){    
    if (x==0 && y==0) return; //Cuando una ejecución no requiere autoscroll, pone estos valores.
        
    double xGlobal, yGlobal, nuevaX, nuevaY, ancho, alto;
    
    //Posiciones absolutas (a todo el diagrama, incluso lo que no se ve) del
    //rectágulo que se ve. Dicho de otra manera, porción rectangular del 
    //diagrama que es visible en el scrollpanel
    java.awt.Rectangle rectanguloGlobal  = jScrollPaneDiagrama.getViewport().getViewRect();
    xGlobal = rectanguloGlobal.getX();
    yGlobal = rectanguloGlobal.getY();
    ancho   = rectanguloGlobal.getWidth();
    alto    = rectanguloGlobal.getHeight();
    
    if (!rectanguloGlobal.contains(x, y)){
    //Sólo hacemos scroll si el elemento no aparece en pantalla.
    //La nueva posición es relativa al cuadro que ya se veía.
        nuevaY=y-yGlobal-100; //el 100 es porque quedaba feo irse justo donde estaba el elemento a pintar.
        nuevaX=x-xGlobal-100; //el 100 es porque quedaba feo irse justo donde estaba el elemento a pintar.

        java.awt.Rectangle rectanguloVisible=new Rectangle((int)nuevaX,(int)nuevaY,(int)ancho,(int)alto);
        jScrollPaneDiagrama.getViewport().scrollRectToVisible(rectanguloVisible);
    }
    jScrollPaneDiagrama.repaint();
}
 
//Este código es automático. Lo añade automáticamente el editor para hacer la clase
//ejecutable por sí misma. Viene bien para copiarlo donde queramos lanzar la ventana.
    /**
    * @param args the command line arguments
    */
    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new VentanaPrincipal().setVisible(true);
            }
        });
    }

    // Declaración de variables mías
    private JPanelDiagrama jPanelDiagrama;
    private DiagramaEjecutable ejecutable;
    private Timer timer;
    private VentanaConfigurarAsincronos configuracionAsincronos; //Nos interesa que exista desde el principio,
    //porque así se conservará el contenido de los parámetros de configuración.
    
    //Lleva el control de activación/desactivación de botones y barra de estado.
    private enum EstadosPosibles {VACIA,INICIALIZADA, EN_MARCHA, PAUSADA, FINALIZADA};
    private class EstadoInterfaz{
        EstadosPosibles estado;
        
        String vacia        = "No diagram loaded";
        String inicializada = "Simulation initialized";
        String enMarcha     = "Simulation in course";
        String pausada      = "Simulation paused";
        String finalizada   = "Simulation finished";
  
        public EstadoInterfaz(){
            setVacia();
        }
        
        public EstadosPosibles getEstado(){
            return estado;
        }
        
        public void setVacia(){
            estado=EstadosPosibles.VACIA;
            poner(false,false,false,false,true,false,false,false,vacia);    
        }
        
        public void setInicializada(){
            estado=EstadosPosibles.INICIALIZADA;
            poner(true,false,true,false,true,false,true,true,inicializada);
        }
        
        public void setEnMarcha(){
            estado=EstadosPosibles.EN_MARCHA;
            poner(false,true,false,false,false,false,true,true,enMarcha);
        }
        
        public void setPausada(){
            estado=EstadosPosibles.PAUSADA;
            poner(true,false,true,true,false,true,true,true,pausada);
        }
        
        public void setFinalizada(){
            estado=EstadosPosibles.FINALIZADA;
            poner(false,false,false,true,true,true,true,true,finalizada);
        }
        
        private void poner(boolean run  , boolean pause, boolean runStep, 
                           boolean reset, boolean open , boolean traza  , 
                           boolean speed, boolean asynchronous, String barra){
            
            jButtonRun.setEnabled      (run)    ; jMenuItemRun.setEnabled      (run)    ;  
            jButtonPause.setEnabled    (pause)  ; jMenuItemPause.setEnabled    (pause)  ;
            jButtonRunStep.setEnabled  (runStep); jMenuItemRunStep.setEnabled  (runStep);  
            jButtonReset.setEnabled    (reset)  ; jMenuItemRestart.setEnabled  (reset)  ;
            jMenuItemOpen.setEnabled   (open)   ;
            jButtonSaveTraza.setEnabled(traza)  ; jMenuItemSaveTraza.setEnabled(traza)  ;
            jSliderSpeed.setEnabled    (speed)  ; jButtonAsynchronous.setEnabled(asynchronous);
            jLabelStatusBar.setText    (barra)  ;
        }
    }
    private EstadoInterfaz estadoInterfaz;
    
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton jButtonAsynchronous;
    private javax.swing.JButton jButtonPause;
    private javax.swing.JButton jButtonReset;
    private javax.swing.JButton jButtonRun;
    private javax.swing.JButton jButtonRunStep;
    private javax.swing.JButton jButtonSaveTraza;
    private javax.swing.JLabel jLabelSpeed;
    private javax.swing.JLabel jLabelStatusBar;
    private javax.swing.JMenuBar jMenuBar1;
    private javax.swing.JMenu jMenuFile;
    private javax.swing.JMenu jMenuHelp;
    private javax.swing.JMenuItem jMenuItemAbout;
    private javax.swing.JMenuItem jMenuItemExit;
    private javax.swing.JMenuItem jMenuItemHelpContents;
    private javax.swing.JMenuItem jMenuItemOpen;
    private javax.swing.JMenuItem jMenuItemPause;
    private javax.swing.JMenuItem jMenuItemRestart;
    private javax.swing.JMenuItem jMenuItemRun;
    private javax.swing.JMenuItem jMenuItemRunStep;
    private javax.swing.JMenuItem jMenuItemSaveTraza;
    private javax.swing.JMenu jMenuSimulate;
    private javax.swing.JPanel jPanelTraza;
    private javax.swing.JScrollPane jScrollPaneDiagrama;
    private javax.swing.JScrollPane jScrollPaneTraza;
    private javax.swing.JSeparator jSeparator1;
    private javax.swing.JSlider jSliderSpeed;
    private javax.swing.JSplitPane jSplitPane1;
    private javax.swing.JTextArea jTextAreaTraza;
    private javax.swing.JToolBar jToolBarBotones;
    private javax.swing.JToolBar jToolBarSpeed;
    private javax.swing.JToolBar jToolBarTraza;
    // End of variables declaration//GEN-END:variables

}
