/*
 * ComplexPanel.java
 *
 */

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

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

/**
 * Panel para integrar en la ventana ComplexWindow que se utiliza para
 * configurar los parametros de tipo COMPLEX
 * @author  raul
 * @version 0.1
 */
public class ComplexPanel extends javax.swing.JPanel {
    
    /**
     * Referencia al parametro de tipo COMPLEX que se edita mediante este panel
     */
    private Parameter oComplexParameter;
    
    /**
     * Componente grafico utilizado para la eleccion de un valor para los parametros
     * de tipo ENUMERATION
     */
    private javax.swing.JComboBox oCombo;
    
    
    /**
     * Componente grafico utilizado para la eleccion de un valor para los parametros
     * de tipo INTEGER o REAL
     */
    private javax.swing.JSpinner oSpinner;
    
    
    /**
     * Componente grafico utilizado para la eleccion de un valor para los parametros
     * de tipo TEXT
     */
    private javax.swing.JTextField oTextField;
    
    /**
     * Componente grafico utilizado para la eleccion de un valor para los parametros
     * de tipo Complex
     */
    private javax.swing.JButton oButtonComplex;
    
    /**
     * Referencia al Parameter que esta escuchando el ButtonComplex
     */
    private java.awt.event.ActionListener oListenerComplex;
    
    
    final private static int NONE=0;
    final private static int EQUALS=1;
    final private static int ALL=2;
    
    /**
     * Tipo de operadores actualmente activo
     */
    private int iOperatorsType=-1;
   
    
    /**
     * Todos los operadores
     */
    final private static String[] oOperatorsAll={"==","<=",">=","<",">"};
    
    /**
     * Combo con todos los operadores
     */
    final private javax.swing.JComboBox oComboAll = new javax.swing.JComboBox(oOperatorsAll);
    
    /**
     * El Operador equals
     */
    final private static String[] oOperatorsEquals={"=="};
    
    
    /**
     * Combo con el operador equals.
     */
    final private javax.swing.JComboBox oComboEquals = new javax.swing.JComboBox(oOperatorsEquals);
    
    /**
     * Etiqueta para cuando no hay operadores seleccionables
     */
    final private javax.swing.JLabel oLabelComplex = new javax.swing.JLabel(MainFrame.oMainFrame.getMessage("Label24"));

    
    
    /**
     * Crea una instancia de la clase
     * @param sTitle El Titulo del panel
     * @param sParameter El nombre del parametro. Se utiliza para la label del comboBox
     * que permite elegir un ejemplar dentro del parametro complejo.
     * @param oParameter Referencia al parametro
     */
    public ComplexPanel(String sTitle,String sParameter,Parameter oParameter) {
        this.oComplexParameter=oParameter;
        initComponents();
        java.awt.Color oPanelColor = new java.awt.Color(254,254,226);
        this.setBackground(oPanelColor);
        oJPanel2.setBackground(this.getBackground());
        this.setBorder(new javax.swing.border.CompoundBorder(new javax.swing.border.SoftBevelBorder(javax.swing.border.BevelBorder.LOWERED), new javax.swing.border.TitledBorder(sTitle)));
        
        if (sParameter!=null) { //Si es un parametro de Tipo COLLECTION
            oJLabel1.setText(Character.toUpperCase(sParameter.charAt(0))+sParameter.substring(1));
            Parameter oIndexParameter = (Parameter) oParameter.getParameters()[0]; //El primer parametro dentro
            //del parametro COLLECTION es que lo indexa. Lo anadimos al panel
            oJPanel3.add(getComponent(oIndexParameter,true));
            //Anadimos los parametros componentes:(del segundo en adelante)
            for (int i=1;i<oParameter.getParameters().length;i++) oJComboBox2.addItem(((Parameter)oParameter.getParameters()[i]).getName());
            oJComboBox2.setSelectedIndex(0);
        } else { //Si es un parametro de tipo COMPLEX
            oJPanel3.setBackground(oPanelColor);
            //Anadimos los parametros componentes
            for (int i=0;i<oParameter.getParameters().length;i++) oJComboBox2.addItem(((Parameter)oParameter.getParameters()[i]).getName());
            oJComboBox2.setSelectedIndex(0);
        }
        
        
    }
    
    /** 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;

        oJLabel1 = new javax.swing.JLabel();
        oJLabel2 = new javax.swing.JLabel();
        oJLabel2.setText(MainFrame.oMainFrame.getMessage("Label17"));
        oJComboBox2 = new javax.swing.JComboBox();
        oJLabel3 = new javax.swing.JLabel();
        oJLabel3.setText(MainFrame.oMainFrame.getMessage("Label19"));
        oJPanel1 = new javax.swing.JPanel();
        oJLabel4 = new javax.swing.JLabel();
        oJLabel4.setText(MainFrame.oMainFrame.getMessage("Label18"));
        oJPanel2 = new javax.swing.JPanel();
        oJButton1 = new javax.swing.JButton();
        oJButton1.setText(MainFrame.oMainFrame.getMessage("Button3"));
        oJButton2 = new javax.swing.JButton();
        oJButton2.setText(MainFrame.oMainFrame.getMessage("Button6"));
        oJPanel3 = new javax.swing.JPanel();

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

        oJLabel1.setPreferredSize(new java.awt.Dimension(75, 19));
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_END;
        gridBagConstraints.insets = new java.awt.Insets(10, 10, 0, 0);
        add(oJLabel1, gridBagConstraints);

        oJLabel2.setPreferredSize(new java.awt.Dimension(75, 19));
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_END;
        gridBagConstraints.insets = new java.awt.Insets(10, 10, 0, 0);
        add(oJLabel2, gridBagConstraints);

        oJComboBox2.setPreferredSize(new java.awt.Dimension(172, 19));
        oJComboBox2.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                oJComboBox2ActionPerformed(evt);
            }
        });

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(10, 0, 0, 0);
        add(oJComboBox2, gridBagConstraints);

        oJLabel3.setPreferredSize(new java.awt.Dimension(75, 19));
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 3;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_END;
        gridBagConstraints.insets = new java.awt.Insets(10, 10, 0, 0);
        add(oJLabel3, gridBagConstraints);

        oJPanel1.setLayout(new java.awt.GridLayout(1, 0));

        oJPanel1.setPreferredSize(new java.awt.Dimension(175, 19));
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 3;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(10, 0, 0, 0);
        add(oJPanel1, gridBagConstraints);

        oJLabel4.setPreferredSize(new java.awt.Dimension(75, 19));
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 2;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_END;
        gridBagConstraints.insets = new java.awt.Insets(10, 10, 0, 0);
        add(oJLabel4, gridBagConstraints);

        oJPanel2.setLayout(new java.awt.GridLayout(1, 0));

        oJPanel2.setPreferredSize(new java.awt.Dimension(175, 19));
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 2;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(10, 0, 0, 0);
        add(oJPanel2, gridBagConstraints);

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

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 2;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.gridheight = 2;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(0, 10, 0, 10);
        add(oJButton1, gridBagConstraints);

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

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 2;
        gridBagConstraints.gridy = 2;
        gridBagConstraints.gridheight = 2;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(0, 10, 0, 10);
        add(oJButton2, gridBagConstraints);

        oJPanel3.setLayout(new java.awt.GridLayout());

        oJPanel3.setPreferredSize(new java.awt.Dimension(175, 19));
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(10, 0, 0, 0);
        add(oJPanel3, gridBagConstraints);

    }
    // </editor-fold>//GEN-END:initComponents
    
    
    /**
     * Metodo cuando el usuario pulsa sobre el boton de Crear la expresion
     */
    private void oJButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_oJButton1ActionPerformed
        MainFrame.oMainFrame.getAssistant().createComplexExpression(this);
    }//GEN-LAST:event_oJButton1ActionPerformed
    
    /**
     * Metodo llamado cuando el usuario cambia uno de los parametros
     * en el JComboBox
     */
    private void oJComboBox2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_oJComboBox2ActionPerformed
        //Vemos cual es el parametro seleccionado y presentamos el componente
        //adecuado para su configuracion (lo proporciona el ParameterManager)
        oJPanel1.removeAll();
        int i=0;
        if (oComplexParameter.getType()==Parameter.COLLECTION) i=1;
        Parameter oParameterSelected =(Parameter) oComplexParameter.getParameters()[i+oJComboBox2.getSelectedIndex()];
        oJPanel1.add(getComponent(oParameterSelected,false));
        //Seleccionamos el combo con los operadores seleccionables en funcion del tipo de parametro
        switch (oParameterSelected.getType()) {
            case Parameter.ENUMERATION:
            case Parameter.BOOLEAN:
            case Parameter.LANCODE:
            case Parameter.TEXT:
                if (iOperatorsType!=EQUALS) {
                    iOperatorsType=EQUALS;
                    if (!oJButton1.isEnabled()) oJButton1.setEnabled(true);
                    oJPanel2.removeAll();
                    oJPanel2.add(oComboEquals);
                }
                break;
            case Parameter.INTEGER:
            case Parameter.REAL:
                if (iOperatorsType!=ALL) {
                    iOperatorsType=ALL;
                    if (!oJButton1.isEnabled()) oJButton1.setEnabled(true);
                    oJPanel2.removeAll();
                    oJPanel2.add(oComboAll);
                }
                break;
            case Parameter.COLLECTION:
            case Parameter.COMPLEX:
                if (iOperatorsType!=NONE) {
                    iOperatorsType=NONE;
                    oJButton1.setEnabled(false);
                    oJPanel2.removeAll();
                    oJPanel2.add(oLabelComplex);
                    break;
                }
        }
        //Como se han anadido y eliminado elementos a los paneles (siendo visibles) es necesario validarlos
        oJPanel1.validate();
        oJPanel2.validate();
        oJPanel1.repaint();
        oJPanel2.repaint();
    }//GEN-LAST:event_oJComboBox2ActionPerformed
    
    /**
     * Metodo llamado cuando el usuario pulsa sobre el boton cancelar
     * en el panel
     */
    private void oJButton2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_oJButton2ActionPerformed
        MainFrame.oMainFrame.getAssistant().closeLastComplexPanel();
    }//GEN-LAST:event_oJButton2ActionPerformed
    
    
    
    /**
     * Devuelve el componente grafico que permitira al usuario
     * elegir el valor para el parametro oParameter.
     * @param oParameter El parametro
     * @boolean bCreate Si es true crea un elemento nuevo, y no utiliza los de la clase
     * @return El componente para elegir el valor
     */
    private java.awt.Component getComponent(Parameter oParameter,boolean bCreate) {
        
        switch(oParameter.getType()) {
            case Parameter.ENUMERATION:
                if (bCreate) return new javax.swing.JComboBox(new javax.swing.DefaultComboBoxModel(oParameter.getValues()));
                else {
                    if (oCombo==null) oCombo=new javax.swing.JComboBox();
                    oCombo.setModel(new javax.swing.DefaultComboBoxModel(oParameter.getValues()));
                    return oCombo;
                }
            case Parameter.INTEGER:
                int iMin=Integer.MIN_VALUE;
                int iMax=Integer.MAX_VALUE;
                if (oParameter.getMin()!=null) iMin=oParameter.getMin().intValue();
                if (oParameter.getMax()!=null) iMax=oParameter.getMax().intValue();
                if (bCreate) return new javax.swing.JSpinner(new javax.swing.SpinnerNumberModel(0,iMin,iMax, 1));
                else {
                    if (oSpinner==null) oSpinner=new javax.swing.JSpinner();
                    oSpinner.setModel(new javax.swing.SpinnerNumberModel(0,iMin,iMax, 1));
                    return oSpinner;
                }
            case Parameter.REAL:
                double dMin=-(Double.MAX_VALUE);
                double dMax=Double.MAX_VALUE;
                if (oParameter.getMin()!=null) dMin=oParameter.getMin().doubleValue();
                if (oParameter.getMax()!=null) dMax=oParameter.getMax().doubleValue();
                if (bCreate) return new javax.swing.JSpinner(new javax.swing.SpinnerNumberModel(0,dMin,dMax, 0.1));
                else {
                    if (oSpinner==null) oSpinner=new javax.swing.JSpinner();
                    oSpinner.setModel(new javax.swing.SpinnerNumberModel(0,dMin,dMax, 0.1));
                    return oSpinner;
                }
            case Parameter.LANCODE:
                if (bCreate) return new javax.swing.JComboBox(new javax.swing.DefaultComboBoxModel(java.util.Locale.getISOLanguages()));
                else {
                    if (oCombo==null) oCombo=new javax.swing.JComboBox();
                    oCombo.setModel(new javax.swing.DefaultComboBoxModel(java.util.Locale.getISOLanguages()));
                    return oCombo;
                }
            case Parameter.BOOLEAN:
                String[] oBoolean = {"true","false"};
                if (bCreate) return new javax.swing.JComboBox(new javax.swing.DefaultComboBoxModel(oBoolean));
                else {
                    if (oCombo==null) oCombo=new javax.swing.JComboBox();
                    oCombo.setModel(new javax.swing.DefaultComboBoxModel(oBoolean));
                    return oCombo;
                }
            case Parameter.TEXT:
                if (bCreate) return new javax.swing.JTextField();
                else {
                    if (oTextField==null) oTextField=new javax.swing.JTextField();
                    return oTextField;
                }
            case Parameter.COLLECTION:
            case Parameter.COMPLEX:
                if (oButtonComplex==null) {
                    oButtonComplex = new javax.swing.JButton(MainFrame.oMainFrame.getMessage("Menu2"));
                }
                //Si oListenerComplex es null no se realiza ninguna acci�n y el m�todo no lanza ninguna excepci�n
                oButtonComplex.removeActionListener(oListenerComplex);
                oListenerComplex = oParameter;
                oButtonComplex.addActionListener(oListenerComplex);
                return oButtonComplex;
                
        }
        return null;
    }
    
    /**
     * Devuelve el valor que indexa el Parameter asociado al panel.
     * Solo tiene sentido con los parametros de tipo COLLECTION.
     * Con un parametro de tipo COMPLEX devuelve null
     */
    public Object getIndex() {
        if (oComplexParameter.getType()==Parameter.COMPLEX) return null;
        java.awt.Component oComponent = oJPanel3.getComponent(0);
        Object oValue;
        if (oComponent instanceof javax.swing.JComboBox) oValue=((javax.swing.JComboBox)oComponent).getSelectedItem();
        else if (oComponent instanceof javax.swing.JSpinner) oValue = ((javax.swing.JSpinner)oComponent).getValue();
        else oValue=((javax.swing.JTextField)oComponent).getText();
        return oValue;
    }
    
    
    /**
     * Devuelve el indice del operador seleccionado en el comboBox de operadores
     */
    public int getOperator() {
        return ((javax.swing.JComboBox)oJPanel2.getComponent(0)).getSelectedIndex();
    }
    
    /**
     * Devuelve el valor elegido para este parametro complejo
     */
    public Object getValue() {
        java.awt.Component oComponent = oJPanel1.getComponent(0);
        Object oValue;
        if (oComponent instanceof javax.swing.JComboBox) oValue=((javax.swing.JComboBox)oComponent).getSelectedItem();
        else if (oComponent instanceof javax.swing.JSpinner) oValue = ((javax.swing.JSpinner)oComponent).getValue();
        else oValue=((javax.swing.JTextField)oComponent).getText();
        return oValue;
    }
    
    /**
     * Devuelve el parametro complejo que permite configurar este ComplexPanel
     */
    public Parameter getParameter() {
        return oComplexParameter;
    }
    
    
    /**
     * Devuelve el nombre del subparametro seleccionado dentro de este parametro
     */
    public String getSubParameterName() {
        return (String) oJComboBox2.getSelectedItem();
    }
    
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton oJButton1;
    private javax.swing.JButton oJButton2;
    private javax.swing.JComboBox oJComboBox2;
    private javax.swing.JLabel oJLabel1;
    private javax.swing.JLabel oJLabel2;
    private javax.swing.JLabel oJLabel3;
    private javax.swing.JLabel oJLabel4;
    private javax.swing.JPanel oJPanel1;
    private javax.swing.JPanel oJPanel2;
    private javax.swing.JPanel oJPanel3;
    // End of variables declaration//GEN-END:variables
    
}
