/*
 * DelegateEditor.java
 */

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

/**
 * Esta clase crea un TableCellEditor a partir de un PropertyEditor de un bean
 * Es una clase de "traduccion".
 * @author raul
 * @version 0.1
 */
public class DelegateEditor extends javax.swing.AbstractCellEditor implements javax.swing.table.TableCellEditor{
    
    
    /**
     * Variable que almacena el PropertyEditor
     */
    private java.beans.PropertyEditor oPropEditor;
    
    
    /**
     * Variable que almacena el valor editado
     */
    private Object oValue;
    
    /**
     * El editor que delega en este la responsabilidad
     * de realizar la edicion.
     */
    private PropertiesCellEditor oEditor;
    
    
    /**
     * Componente para mostrar en la Tabla en la edicion
     */
    private java.awt.Component oComponente;
    
    /**
     * Crea una nuevas instancia de la clase
     * @param oEditor El PropertiesCellEditor que delega la edicion de la propiedad.
     * @param oPropEditor El PropertyEditor proporcionado para la edicion de la propiedad del bean.
     */
    public DelegateEditor(PropertiesCellEditor oEditor,java.beans.PropertyEditor oPropEditor) {
        this.oEditor=oEditor;
        this.oPropEditor=oPropEditor;
    }
    
    
    /**
     * Metodo que devuelve el editor para su presentacion en la tabla.
     * Dependiendo de si se proporciona una GUI o no, o del tipo
     * de propiedad se utilizan diferentes estrategias para la edicion.
     */
    public java.awt.Component getTableCellEditorComponent(javax.swing.JTable oTable,Object oValue,boolean isSelected,int iRow,int iColumn) {
        this.oValue=oValue;
        if (oPropEditor.supportsCustomEditor()) { //Si hay una GUI
            java.awt.Component oComponente = oPropEditor.getCustomEditor();
            final javax.swing.JDialog oDialogo= new javax.swing.JDialog();
            //oDialogo.setModal(true);
            oDialogo.setTitle(MainFrame.oMainFrame.getMessage("Title4"));
            oDialogo.addWindowListener(new java.awt.event.WindowAdapter(){
                public void windowClosing(java.awt.event.WindowEvent oEvento){
                    vCerrar();
                }
                
                public void windowDeactivated(java.awt.event.WindowEvent oEvento) {
                    vPerderFoco(oDialogo);
                }
                
            });
            java.awt.Dimension oSize = oComponente.getPreferredSize();
            java.awt.Dimension oScreenSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
            oDialogo.setBounds((oScreenSize.width-oSize.width)/2,(oScreenSize.height-oSize.height)/2,oSize.width,oSize.height+25);
            oDialogo.getContentPane().setLayout(new java.awt.GridLayout());
            oDialogo.getContentPane().add(oComponente);
            oDialogo.setVisible(true);
            return (new javax.swing.JLabel(MainFrame.oMainFrame.getMessage("Label2")));
        } else { // Si no hay una GUI
            //Si la propiedad solo es configurable mediante un conjunto limitado
            //de posibilidades podemos usar un JComboBox
            String[] oOpciones=oPropEditor.getTags();
            if (oOpciones!=null && oOpciones.length!=0) {
                final javax.swing.JComboBox oCombo = new javax.swing.JComboBox(oOpciones);
                oCombo.addActionListener(new java.awt.event.ActionListener(){
                    public void actionPerformed(java.awt.event.ActionEvent oEvento) {
                        vComboSelected(oCombo);
                    }
                });
                oPropEditor.setValue(oValue);
                oCombo.setSelectedItem(oPropEditor.getAsText()); //El elemento seleccionado en el combobox debe ser el actualmente activo
                return oCombo;
            } else { //Si es configurable mediante una cadena de texto
                final javax.swing.JTextField oText = new javax.swing.JTextField();
                oText.addActionListener(new java.awt.event.ActionListener() {
                    public void actionPerformed(java.awt.event.ActionEvent oEvento) {
                        vTextChanged(oText);
                    }
                });
                
                
                if (oValue!=null) oText.setText(oValue.toString()); //Colocamos el texto actual de la propiedad
                return oText;
            }
            
        }
    }
    
    
    /**
     * Devuelve el valor editado.
     * @return El nuevo valor
     */
    public Object getCellEditorValue() {
        return oValue;
    }
    
    
    
    
    /**
     * Si se cierra el editor (GUI) proporcionado por el bean.
     * Hay que avisar al Editor que ha delegado en este
     * que el objeto ha sido ya editado.
     */
    private void vCerrar() {
        //Esta comprobaci�n que parece absurda, es ,no obstante, necesaria,
        //ya que algunos PropertyEditor devuelven null si no se ha modificado
        //el valor actual de la propiedad.
        if (oPropEditor.getValue()!=null) oValue=oPropEditor.getValue();
        oEditor.vEditado();
    }
    
    /**
     * Esta funcion es llamada al perder el foco, descarta los cambios.
     */
    private void vPerderFoco(javax.swing.JDialog oVentana) {
        oVentana.dispose();
        oEditor.vCancel();
    }
    
    /**
     * Esta funcion es llamanda cuando se produce un cambio en el ComboBox
     * que se utiliza para la edicion de las propiedades. La funcion lee
     * el valor actual del ComboBox y lo establece como nuevo valor
     * de la propiedad.
     */
    private void vComboSelected(javax.swing.JComboBox oCombo) {
        oPropEditor.setAsText((String)oCombo.getSelectedItem());
        oValue = oPropEditor.getValue();
        oEditor.vEditado();
    }
    
    /**
     * Esta funcion es llamanda cuando se produce un cambio en el ComboBox
     * que se utiliza para la edicion de las propiedades. La funcion lee
     * el valor actual del ComboBox y lo establece como nuevo valor
     * de la propiedad.
     */
    private void vTextChanged(javax.swing.JTextField oText) {
        try {
            oPropEditor.setAsText(oText.getText());
            oValue = oPropEditor.getValue();
        } catch (IllegalArgumentException oE) {
            oEditor.vCancel();
        }
        oEditor.vEditado();
    }
}
