/*
 * PropertiesEditor.java
 *
 */

package com.uvigo.tMaestro.SCOCreator.tool.properties;

import com.uvigo.tMaestro.SCOCreator.tool.*;

/**
 * Esta clase es el JDialog sobre el que se asienta el Editor de propiedades.
 * B�sicamente es un JTabbedPane en el que cada pesta�a supone una opci�n de
 * configuraci�n del elemento seleccionado. Cada opci�n (pesta�a) debe presentar
 * todas las propiedades configurables del elemento. Esto lo hace mediante un
 * JTable de dos columnas. La de la izquierda presenta el nombre de la propiedad
 * y la de la derecha la propiedad, siendo esta editable directamente sobre la
 * JTable, o mediante un editor adecuado (JDialog) al tipo de propiedad.
 * @author  raul
 * @version 0.1
 */
public class PropertiesSheet extends javax.swing.JDialog {
    
    /**
     * Referencia al frame principal.
     */
    private MainFrame oMainFrame;
    
    
    /**
     * Un array con todas las tablas. Una para cada opci�n.
     */
    private java.util.ArrayList<javax.swing.JTable> oTablas;
    
    /**
     * El Render que se encargar� de dibujar la columna de valores de propiedades
     */
    private PropertiesCellRenderer oPropertiesCellRenderer;
    
    /**
     * El Render que se encargar� de dibujar la columna de nombres de propiedades
     */
    private NamePropertiesCellRenderer oNamePropertiesCellRenderer;
    
    /**
     * El editor de las propiedades.
     */
    private PropertiesCellEditor oPropertiesCellEditor;
    
    /**
     * Se pone a true en el proceso de eliminaci�n y adici�n de nuevas opciones
     */
    private boolean bRemove=false;
    
    /**
     * Crea una nueva instancia del editor de propiedades.
     * @parent El Frame padre de este di�logo
     */
    public PropertiesSheet(java.awt.Frame parent,java.util.ArrayList<String> oOpciones) {
        super(parent, false);
       
        oMainFrame=(MainFrame) parent;
        this.addWindowListener(new java.awt.event.WindowAdapter() {
            public void windowClosing(java.awt.event.WindowEvent oEvento){
                JDialogClosing();
            }
        });
        initComponents();
        
        oJTabbedPane.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseReleased(java.awt.event.MouseEvent oEvent) {
                if (oEvent.isPopupTrigger()) { //Si es una solicitud de PopUpMenu
                    mouse(oEvent);
                }
            }
        });
        
        oTablas = new java.util.ArrayList<javax.swing.JTable>();
        
        //Creamos para cada opci�n una pesta�a en el TabbedPane y una JTable
        //para presentar las propiedades de esa opci�n
        /*for (String sOpcion: oOpciones) {
            javax.swing.JScrollPane oJScrollPanel = new javax.swing.JScrollPane();
            javax.swing.JTable oJTable = new javax.swing.JTable();
         
            oJScrollPanel.setViewportView(oJTable);
            oJTabbedPane.addTab(sOpcion, oJScrollPanel);
            oTablas.add(oJTable);
            oJTable.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
        }*/
        
        oPropertiesCellRenderer = new PropertiesCellRenderer();
        oPropertiesCellEditor = new PropertiesCellEditor();
        oNamePropertiesCellRenderer = new NamePropertiesCellRenderer();
        //setVisible(false);
    }
    
    /** 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.
     */
    // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
    private void initComponents() {
        java.awt.GridBagConstraints gridBagConstraints;

        oJPopupMenu1 = new javax.swing.JPopupMenu();
        oJMenuItem1 = new javax.swing.JMenuItem();
        oJMenuItem1.setText(oMainFrame.getMessage("OptionPMenuItem1"));
        oJMenuItem2 = new javax.swing.JMenuItem();
        oJMenuItem2.setText(oMainFrame.getMessage("OptionPMenuItem2"));
        oJLabel1 = new javax.swing.JLabel();
        oJSplitPane1 = new javax.swing.JSplitPane();
        oJTabbedPane = new javax.swing.JTabbedPane();
        jPanel1 = new javax.swing.JPanel();
        oJLabel2 = new javax.swing.JLabel();
        oJScrollPane1 = new javax.swing.JScrollPane();
        oJTextArea1 = new javax.swing.JTextArea();

        oJMenuItem1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                oJMenuItem1ActionPerformed(evt);
            }
        });

        oJPopupMenu1.add(oJMenuItem1);

        oJMenuItem2.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                oJMenuItem2ActionPerformed(evt);
            }
        });

        oJPopupMenu1.add(oJMenuItem2);

        getContentPane().setLayout(new java.awt.GridBagLayout());

        setDefaultCloseOperation(javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE);
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
        gridBagConstraints.weightx = 1.0;
        getContentPane().add(oJLabel1, gridBagConstraints);

        oJSplitPane1.setOrientation(javax.swing.JSplitPane.VERTICAL_SPLIT);
        oJTabbedPane.addChangeListener(new javax.swing.event.ChangeListener() {
            public void stateChanged(javax.swing.event.ChangeEvent evt) {
                oJTabbedPaneStateChanged(evt);
            }
        });

        oJSplitPane1.setLeftComponent(oJTabbedPane);

        jPanel1.setLayout(new java.awt.BorderLayout());

        oJLabel2.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        jPanel1.add(oJLabel2, java.awt.BorderLayout.NORTH);

        oJTextArea1.setEditable(false);
        oJTextArea1.setLineWrap(true);
        oJTextArea1.setWrapStyleWord(true);
        oJScrollPane1.setViewportView(oJTextArea1);

        jPanel1.add(oJScrollPane1, java.awt.BorderLayout.CENTER);

        oJSplitPane1.setRightComponent(jPanel1);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.weighty = 1.0;
        getContentPane().add(oJSplitPane1, gridBagConstraints);

    }// </editor-fold>//GEN-END:initComponents
    
    /**
     * M�todo llamado cuando el usuario pulsa sobre el menu item de borrar
     * opci�n en el popup menu
     */
    private void oJMenuItem2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_oJMenuItem2ActionPerformed
        if (oJTabbedPane.getSelectedIndex()<2) {
            java.awt.Toolkit.getDefaultToolkit().beep();
            MyOptionPane.showMessageDialog(this,oMainFrame.getMessage("Error30"),oMainFrame.getMessage("Title12"),javax.swing.JOptionPane.ERROR_MESSAGE);
            return;
        }
        int iValue=MyOptionPane.showConfirmDialog(this,oMainFrame.getMessage("Question12"),oMainFrame.getMessage("OptionPMenuItem2"),javax.swing.JOptionPane.YES_NO_OPTION, javax.swing.JOptionPane.QUESTION_MESSAGE);
        if (iValue==javax.swing.JOptionPane.NO_OPTION) return;
        oMainFrame.deleteOption(oJTabbedPane.getSelectedIndex());
    }//GEN-LAST:event_oJMenuItem2ActionPerformed
    
    /**
     * M�todo llamado cuando el usuario pulsa sobre el menu item de renombrar
     * opci�n en el popup menu
     */
    private void oJMenuItem1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_oJMenuItem1ActionPerformed
        String sNuevo = MyOptionPane.showInputDialog(oJTabbedPane,oMainFrame.getMessage("Question11")+" "+oJTabbedPane.getTitleAt(oJTabbedPane.getSelectedIndex()),oMainFrame.getMessage("OptionPMenuItem1"),javax.swing.JOptionPane.QUESTION_MESSAGE);
        if (sNuevo==null) return;
        if (oMainFrame.containsOption(sNuevo)) {
            java.awt.Toolkit.getDefaultToolkit().beep();
            MyOptionPane.showMessageDialog(this,oMainFrame.getMessage("Error6"),oMainFrame.getMessage("Title12"),javax.swing.JOptionPane.ERROR_MESSAGE);
            return;
        }
        if (sNuevo.equals("")) {
            java.awt.Toolkit.getDefaultToolkit().beep();
            MyOptionPane.showMessageDialog(this,oMainFrame.getMessage("Error5"),oMainFrame.getMessage("Title12"),javax.swing.JOptionPane.ERROR_MESSAGE);
            return;
        }
        oMainFrame.setOption(oJTabbedPane.getSelectedIndex(), sNuevo,oJTabbedPane.getTitleAt(oJTabbedPane.getSelectedIndex()));
    }//GEN-LAST:event_oJMenuItem1ActionPerformed
    
    /**
     * Esta funci�n es llamada cuando se produce un cambio en el JTabbedPane.
     * Si est� seleccionada la opci�n de mostrar opci�n al cambiarla en el editor de propiedades
     * entoces llamamos al MainFrame para que muestre la opci�n que se ha seleccionado
     * en el JTabbedPane.
     */
    private void oJTabbedPaneStateChanged(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_oJTabbedPaneStateChanged
        
        if (bRemove) return; //Entrar� y saldr� por aqui si se estan estableciendo las nuevas opciones
        //Para porder mostrar un opci�n es necesario que se encuentre cargada una plantilla
        //La plantilla estar� cargada si la funci�n oGetPlantilla devuelve algo distinto de null
        if ((oMainFrame.oGetPlantilla()!=null) && (oMainFrame.isChangeOptionSelected())) oMainFrame.showOption(oJTabbedPane.getSelectedIndex());
    }//GEN-LAST:event_oJTabbedPaneStateChanged
    
    
    /**
     * M�todo llamado cuando el usuario pulsa sobre uno de los tab
     * del oJTabbedPane solicitando un PopUpMenu
     */
    public void mouse(java.awt.event.MouseEvent oEvt) {
        int iOpcion = ((javax.swing.JTabbedPane)oEvt.getSource()).indexAtLocation(oEvt.getX(), oEvt.getY());
        if (iOpcion<0) return;
        oJPopupMenu1.show((java.awt.Component)oEvt.getSource(),oEvt.getX(),oEvt.getY());
    }
    
    
    /**
     * Esta funci�n es llamada cuando el usuario pulse la aspa
     * de cerrar la ventana.
     */
    public void JDialogClosing(){
        oMainFrame.oGetCheckPropertiesSheet().setSelected(false);
        this.setVisible(false);
    }
    
    
    /**
     * Esta funci�n desactiva la hoja de propiedades.
     */
    public void vDesactiva() {
        oJLabel1.setText("");
        //oJTabbedPane.setSelectedIndex(0);
        oJTabbedPane.removeAll();
        oJTabbedPane.setEnabled(false);
        //oTablas.get(0).setVisible(false);
        setContextHelp(null,null);
    }
    
    
    /**
     * Esta funci�n activa la hoja de propiedades
     */
    public void vActiva() {
        if (!oJTabbedPane.isEnabled()) {
            oTablas.get(0).setVisible(true);
            oJTabbedPane.setEnabled(true);
        }
    }
    
    
    /**
     * Esta funci�n permite decirle a la hoja de propiedades c�al de las
     * diferentes p�ginas del oJTabbedPane debe mostrar.
     * @param iPagina El �ndice de la p�gina que debe ser mostrada.
     */
    public void vSeleccionaPagina(int iPagina) {
        if (iPagina!=oJTabbedPane.getSelectedIndex()) {
            oJTabbedPane.setSelectedIndex(iPagina);
        }
    }
    
    
    /**
     * Esta funci�n es llamada para cubrir la tabla con las propiedades del
     * elemento incluido dentro de la c�psula.
     * @param oCapsula Contiene el bean cuyas propiedades se van a exponer en
     * la tabla
     */
    public void vCubreTabla(Capsula oCapsula) {
        oJLabel1.setText(oCapsula.oGetBean().getName());
        int iOpcion=0;
        for (iOpcion=0;iOpcion<oMainFrame.sizeOptions();iOpcion++) {
            if (oCapsula.sizeTables()<=iOpcion) {
                PropertiesTableModel oTableModel = new PropertiesTableModel(oCapsula.oGetPropiedades(),iOpcion);
                oTableModel.addTableModelListener(oTableModel);
                oCapsula.addTable(oTableModel);
                
                
            }
            //Eliminamos los ListSelectionListeners que haya a�adidos a las JTables anteriormente
            javax.swing.event.ListSelectionListener[] oLs = ((javax.swing.DefaultListSelectionModel) oTablas.get(iOpcion).getSelectionModel()).getListSelectionListeners();
            //Comprobamos que el oL es instancia de PorpertiesTableModel, ya que si no nos cargamos todos los LisSelectionListeners
            //inclu�do el por defecto, y de esta forma no se actualizar�a la selecci�n
            for (javax.swing.event.ListSelectionListener oL : oLs) if (oL instanceof PropertiesTableModel) oTablas.get(iOpcion).getSelectionModel().removeListSelectionListener(oL);
            
            
            //A�adimos el ListSelectionListener actual
            //El table model tambi�n escucha las selecciones en la tabla
            oTablas.get(iOpcion).getSelectionModel().addListSelectionListener((PropertiesTableModel) oCapsula.oGetTabla(iOpcion));
            
            oTablas.get(iOpcion).setModel(oCapsula.oGetTabla(iOpcion));
            //Establecemos el Renderer  de propiedades y de nombres de propiedades
            oTablas.get(iOpcion).getColumnModel().getColumn(1).setCellRenderer(oPropertiesCellRenderer);
            oTablas.get(iOpcion).getColumnModel().getColumn(0).setCellRenderer(oNamePropertiesCellRenderer);
            //Establecemos el editor de propiedades
            oTablas.get(iOpcion).getColumnModel().getColumn(1).setCellEditor(oPropertiesCellEditor);
            
        }
    }
    
    /**
     * Cambia la etiqueta del panel de indice Index en el tabbedPane
     * @param iIndex El indice en el panel
     * @param sOption El nuevo nombre;
     */
    public void renameOption(int iIndex,String sOption) {
        oJTabbedPane.setTitleAt(iIndex,sOption);
    }
    
    /**
     * A�ade una nueva opci�n al la hoja de propiedades
     * @param sOption El nuevo nombre
     */
    public void addOption(String sOption) {
        javax.swing.JScrollPane oJScrollPanel = new javax.swing.JScrollPane();
        javax.swing.JTable oJTable = new javax.swing.JTable();
        oJScrollPanel.setViewportView(oJTable);
        oJTabbedPane.addTab(sOption, oJScrollPanel);
        oTablas.add(oJTable);
        oJTable.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
        vCubreTabla(oMainFrame.oGetCapsulaActiva());
    }
    
    /**
     * Elimina la opci�n de indice iIndex de la hoja de propiedades
     * @param iIndex El �ndice de la opci�n a eliminar
     */
    public void removeOption(int iIndex) {
        oTablas.remove(iIndex);
        oJTabbedPane.remove(iIndex);
        vCubreTabla(oMainFrame.oGetCapsulaActiva());
    }
    
    /**
     * Devuelve el �ndice seleccionado en el JTabbedPane
     * @return Un entero representando la opci�n seleccionada
     */
    public int getSelectedOption() {
        return oJTabbedPane.getSelectedIndex();
    }
    
    /**
     * Establece un nuevo conjunto de opciones
     * @param oOpciones El array con los nombres de las nuevas opciones
     */
    public void setOptions(java.util.ArrayList<String> oOpciones) {
        
        bRemove=true;
        oJTabbedPane.removeAll();
        
        oTablas = new java.util.ArrayList<javax.swing.JTable>();
        
        //Creamos para cada opci�n una pesta�a en el TabbedPane y una JTable
        //para presentar las propiedades de esa opci�n
        for (String sOpcion: oOpciones) {
            javax.swing.JScrollPane oJScrollPane = new javax.swing.JScrollPane();
            javax.swing.JTable oJTable = new javax.swing.JTable();
            
            oJScrollPane.setViewportView(oJTable);
            oJTabbedPane.addTab(sOpcion, oJScrollPane);
            oTablas.add(oJTable);
            oJTable.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
        }
        bRemove=false;
    }
    
    /**
     * Establece el valor de la Label que muestra el nombre del bean actualmente seleccionado
     * en el entorno
     * @param sName El nuevo nombre
     */
    public void setLabelCapsula(String sName) {
        oJLabel1.setText(sName);
    }
    
    /**
     * Devuelve el modelo de la tabla del editor de propiedades, correspondiente
     * al bean seleccionado y a la opci�n que muestra el entorno (el MainFrame)
     */
    public PropertiesTableModel getTableModel() {
        return ((PropertiesTableModel) oTablas.get(MainFrame.oMainFrame.iGetOpcion()).getModel());
    }
    
    /**
     * Establece la posici�n del divider del split panel
     */
    public void setDividerLocation(int iPos) {
        oJSplitPane1.setDividerLocation(iPos);
    }
    
    /**
     * Muestra la ayuda contextual correspondiente al elemento y propiedades indicadas
     * @param oBean El elemento
     * @param sProperty La propiedad
     */
    public void setContextHelp(java.awt.Component oBean, String sProperty) {
        if (oBean==null || sProperty ==null) {
            oJLabel2.setText("");
            oJTextArea1.setText("");
            return;
        }
        
        String sHelp=oMainFrame.getTemplateContextHelp(oBean.getName(), sProperty);
        if (sHelp==null) {
            if (oBean instanceof com.uvigo.mhp.Page) sHelp = oMainFrame.getContextHelp("com.uvigo.mhp.Page", sProperty);
            else sHelp=oMainFrame.getContextHelp(oBean.getClass().getName(), sProperty);
        }
        if (sHelp!=null) {
            oJLabel2.setText(sProperty);
            oJTextArea1.setText(sHelp);
            oJTextArea1.setCaretPosition(0); //Para hacer que el Scroll se ponga al principio
            //oJScrollPane1.getViewport().setViewPosition(oJTextArea1.getLocation());
        } else {
            oJLabel2.setText("");
            oJTextArea1.setText("");
        }
    }
    
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JPanel jPanel1;
    private javax.swing.JLabel oJLabel1;
    private javax.swing.JLabel oJLabel2;
    private javax.swing.JMenuItem oJMenuItem1;
    private javax.swing.JMenuItem oJMenuItem2;
    private javax.swing.JPopupMenu oJPopupMenu1;
    private javax.swing.JScrollPane oJScrollPane1;
    private javax.swing.JSplitPane oJSplitPane1;
    private javax.swing.JTabbedPane oJTabbedPane;
    private javax.swing.JTextArea oJTextArea1;
    // End of variables declaration//GEN-END:variables
    
}
