/*
 * SheetProperty.java
 *
 * Created on 4 ottobre 2004, 22.08
 */

package it.businesslogic.ireport.gui.sheet;
import com.lowagie.text.Font;
import java.util.*;
import javax.swing.*;
import it.businesslogic.ireport.gui.event.*;
import java.awt.Color;
/**
 *
 * @author  Administrator
 */
public class SheetProperty implements java.awt.event.ActionListener {
    
    public static final int STRING = 0;
    public static final int NUMBER = 1;
    public static final int INTEGER = 6;
    public static final int COMBOBOX = 2;
    public static final int COLOR = 3;
    public static final int BOOLEAN = 4;
    public static final int COMBOBOX_NK = 5; // Combobox number key
    public static final int PASSWORD = 7;
    public static final int CATEGORY_LABEL = 99;
        
    protected String name = "";
    protected String keyName = "";
    protected String group = "";
    protected int type;
    private java.util.Vector tags = null;
    protected Object defaultValue = null;
    protected Object value = null;
    
    private boolean readOnly = false;
    
    private boolean setting = false;
    
    protected JComponent component = null;
    
    private JComponent labelComponent = null;
    
    private boolean showResetButton = true;
    
    private java.awt.Color labelColor = java.awt.Color.BLACK;
    
    private Vector currentSelection = new Vector();
    
    
    
    /**
     * Utility field used by event firing mechanism.
     */
    private javax.swing.event.EventListenerList listenerList =  null;
    
    public SheetProperty(String keyName, String name, int type) {
       this(keyName,name,type,null);
    }
    /** Creates a new instance of SheetProperty */
    public SheetProperty(String keyName, String name, int type, Object defaultValue) {
        this.setName( name );
        this.setKeyName( keyName );
        this.setDefaultValue( defaultValue );
        setType(type);
        tags =  new Vector();
    }
    
    public SheetProperty(String keyName, String name,String groupname, int type, Object defaultValue) {
        this.setName( name );
        this.setKeyName( keyName );
        this.setDefaultValue( defaultValue );
        setType(type);
        tags =  new Vector();
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getType() {
        return type;
    }

    public void setType(int type) {
        this.type = type;
    }

    public java.util.Vector getTags() {
        return tags;
    }

    public void setTags(java.util.Vector tags) {
        this.tags = tags;
    }
    
    public void setTags(Tag[] tags_array) {
         
        this.tags = new Vector();
        
        for (int i=0; i<tags_array.length; ++i)
        {
            tags.add(tags_array[i]);
        }
    }
    
    public JComponent getEditor()
    {
        
        if (component != null) return component;
        
        if (this.getType() == NUMBER)
        {
            component = new it.businesslogic.ireport.gui.JNumberField();
            component.setBorder(null);
            
            ((it.businesslogic.ireport.gui.JNumberField)component).addActionListener( this );
        
        }
        else if (this.getType() == INTEGER)
        {
            component = new it.businesslogic.ireport.gui.JNumberField();
            component.setBorder(null);
            try {
            ((it.businesslogic.ireport.gui.JNumberField)component).setInteger(true);
            } catch (Exception ex){}
            
            ((it.businesslogic.ireport.gui.JNumberField)component).addActionListener( this );
        
        }
        else if (this.getType() == COMBOBOX || this.getType() == COMBOBOX_NK)
        {
            component = new JComboBox(this.getTags());
            component.setBorder(null);
            
            //((JComboBox)component).setEditor(new SimpleComboBoxEditor() );
            
            for (int i=0; i< component.getComponentCount(); ++i)
            {
                try {
                        Object obj = component.getComponent(i);
                        //System.out.println( obj );                    
                        if (obj != null && obj.getClass().getMethod("setBorder", new Class[]{javax.swing.border.Border.class}) != null)
                        {
                            java.lang.reflect.Method mtd = obj.getClass().getMethod("setBorder", new Class[]{javax.swing.border.Border.class});
                            mtd.invoke(obj, new Object[]{null});
                        }
                } catch (Exception ex) { }
            }
            
            ((JComboBox)component).addActionListener( this );            
        }
        else if (this.getType() == BOOLEAN)
        {
            component = new JCheckBox("");
            ((JCheckBox)component).addActionListener( this );
        }
        else if (this.getType() == COLOR)
        {
            component = new ColorSelectorPanel();
            ((ColorSelectorPanel)component).addActionListener( this );
        }
        else if (this.getType() == CATEGORY_LABEL)
        {
            component = new JPanel();
            component.setBackground( java.awt.Color.LIGHT_GRAY);
        }
        else if (this.getType() == PASSWORD)
        {
            component = new JPasswordField();
            component.setBorder(null);
            ((JTextField)component).getDocument().addDocumentListener( new javax.swing.event.DocumentListener() {
            public void changedUpdate(javax.swing.event.DocumentEvent evt) {
                actionPerformed(null);
            }
            public void insertUpdate(javax.swing.event.DocumentEvent evt) {
                actionPerformed(null);
            }
            public void removeUpdate(javax.swing.event.DocumentEvent evt) {
                actionPerformed(null);
            }
        });
        }
        else
        {
            // default (STRING)
            component = new JTextField();
            component.setBorder(null);
            ((JTextField)component).getDocument().addDocumentListener( new javax.swing.event.DocumentListener() {
            public void changedUpdate(javax.swing.event.DocumentEvent evt) {
                actionPerformed(null);
            }
            public void insertUpdate(javax.swing.event.DocumentEvent evt) {
                actionPerformed(null);
            }
            public void removeUpdate(javax.swing.event.DocumentEvent evt) {
                actionPerformed(null);
            }
        });
        }
        
        
        return  component;
        
    }
    
    public Object getEditorValue(JComponent component)
    {
       if (this.getType() == NUMBER)
        {
           return new Double(((it.businesslogic.ireport.gui.JNumberField)component).getValue());
        }
       else if (this.getType() == INTEGER)
        {
            return new Integer( (int)((it.businesslogic.ireport.gui.JNumberField)component).getValue());
        }
        else if (this.getType() == COMBOBOX)
        {
           Object obj = ((JComboBox)component).getSelectedItem();
           if (obj != null)
           {
               if (obj instanceof Tag)
               {
                    return ((Tag)obj).getValue();
               }
               else
               {
                   return obj;
               }
           }
           return null;
        }
       else if (this.getType() == COMBOBOX_NK)
        {
           Object obj = ((JComboBox)component).getSelectedItem();
           if (obj != null)
           {
               return new Integer(((Tag)obj).getValue()+"");
           }
           return null;
        }
        else if (this.getType() == BOOLEAN)
        {
            return  new Boolean(((JCheckBox)component).isSelected());
        }
        else if (this.getType() == BOOLEAN)
        {
            return  new String( ((JPasswordField)component).getPassword() );
        }
        else if (this.getType() == COLOR)
        {
            return ((ColorSelectorPanel)component).getValue();
        }
       
        return ((JTextField)component).getText();
    }
    
    public synchronized void  setEditorValue(JComponent component, Object obj)
    {
        
        String str = ""+obj;
        
        component.setForeground(Color.BLACK );
        
        try {
            
        setSetting(true);
        if (this.getType() == NUMBER)
        {
           if (obj == null) str ="0";
            ((it.businesslogic.ireport.gui.JNumberField)component).setValue(Double.parseDouble(str) );
            
           if (obj == null) ((it.businesslogic.ireport.gui.JNumberField)component).setForeground( Color.LIGHT_GRAY);
           
        }
       else if (this.getType() == INTEGER)
        {
           if (obj == null) str ="0";
            ((it.businesslogic.ireport.gui.JNumberField)component).setValue(Integer.parseInt(str) );
            if (obj == null) ((it.businesslogic.ireport.gui.JNumberField)component).setForeground( Color.LIGHT_GRAY);
        }
        else if (this.getType() == COMBOBOX)
        {
           if (obj == null) { 
                setSetting(false);
                if (getTags().size() > 0 && ((Tag)getTags().elementAt(0)).getValue() == null)
                {
                    ((JComboBox)component).setSelectedIndex(0);
                }
                return;
           }
           boolean found = false;
           for (int i=0; i<getTags().size(); ++i)
           {
                
                Tag t = (Tag)getTags().elementAt(i);
                if (t.getValue() != null && t.getValue().equals(str))
                {
                    found = true;
                    ((JComboBox)component).setSelectedIndex(i);
                    break;
                }
           }
           if (!found && ((JComboBox)component).isEditable())
           {
               ((JComboBox)component).setSelectedItem(obj);
           }
        }
        else if (this.getType() == COMBOBOX_NK)
        {
            if (obj == null) { setSetting(false); 
                if (getTags().size() > 0)
                {
                    ((JComboBox)component).setSelectedIndex(0);
                }
                return;
            }
            for (int i=0; i<getTags().size(); ++i)
            {
                Tag t = (Tag)getTags().elementAt(i);
                if ((t.getValue()+"").equals(str))
                {
                    ((JComboBox)component).setSelectedIndex(i);
                    break;
                }
            }
        }
        else if (this.getType() == BOOLEAN)
        {
            if (obj == null) {  ((JCheckBox)component).setSelected(false); setSetting(false); return;}
            ((JCheckBox)component).setSelected(str.equals("true"));
        }
        else if (this.getType() == COLOR)
        {
            ((ColorSelectorPanel)component).setValue(obj);
        }
        else if (this.getType() == PASSWORD)
        {
            if (obj == null) { ((JPasswordField)component).setText("");  setSetting(false);  return;}
            ((JPasswordField)component).setText(str);
        }
        else
        {
            if (obj == null) { ((JTextField)component).setText(""); setSetting(false); return;}
            ((JTextField)component).setText(str);
        }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        finally {
            setSetting(false);
        }
        
    }

    public String getKeyName() {
        return keyName; 
    }

    public void setKeyName(String keyName) {
        this.keyName = keyName;
    }

    public Object getDefaultValue() {
        return defaultValue;
    }

    public void setDefaultValue(Object defaultValue) {
        this.defaultValue = defaultValue;
    }

    public String getGroup() {
        return group;
    }

    public void setGroup(String group) {
        this.group = group;
    }
    
    public Object getValue() {
        return value;
    }

    public void setValue(Object value) {
        
        this.value = value;
        this.setEditorValue(getEditor(), (value == null) ? getDefaultValue() : value);
        updateLabel();
        
    }
    
    public void updateLabel()
    {
        
        if (this.getType() != CATEGORY_LABEL)
        {
            try {
                if (getLabelComponent() != null)
                {
                    
                    java.awt.Font f = getLabelComponent().getFont();
                    java.awt.Font f2 = new java.awt.Font( f.getName(), (value == null || this.isReadOnly() || !isShowResetButton()) ? 0 : java.awt.Font.BOLD, f.getSize());
                    getLabelComponent().setFont(f2);
                    
                    getLabelComponent().setForeground( getLabelColor());
                    
                    if (this.isReadOnly())
                    {
                        getLabelComponent().setEnabled( false );
                    }
                    else
                    {
                         getLabelComponent().setEnabled( true );
                    }
                    
                    
                    getLabelComponent().updateUI();
                }
            } catch (Exception ex)
            {

            }
        }
    }
    
    public void actionPerformed(java.awt.event.ActionEvent event)
    {
        if (isSetting()) return;
        getEditor().setForeground( Color.BLACK);
        Object new_value = getEditorValue( this.getEditor() );
        if (new_value != null && new_value.equals(value)) return;
                
        Object oldValue = value;
        value = new_value;
        
        if(oldValue == null || new_value == null)
        {
            updateLabel();
        }
        
        fireSheetPropertyValueChangedListenerSheetPropertyValueChanged(
            new SheetPropertyValueChangedEvent(getKeyName(),oldValue,new_value, this));
    }

    /**
     * Registers SheetPropertyValueChangedListener to receive events.
     * @param listener The listener to register.
     */
    public synchronized void addSheetPropertyValueChangedListener(it.businesslogic.ireport.gui.event.SheetPropertyValueChangedListener listener) {

        if (listenerList == null ) {
            listenerList = new javax.swing.event.EventListenerList();
        }
        listenerList.add (it.businesslogic.ireport.gui.event.SheetPropertyValueChangedListener.class, listener);
    }

    /**
     * Removes SheetPropertyValueChangedListener from the list of listeners.
     * @param listener The listener to remove.
     */
    public synchronized void removeSheetPropertyValueChangedListener(it.businesslogic.ireport.gui.event.SheetPropertyValueChangedListener listener) {

        listenerList.remove (it.businesslogic.ireport.gui.event.SheetPropertyValueChangedListener.class, listener);
    }

    /**
     * Notifies all registered listeners about the event.
     * 
     * @param event The event to be fired
     */
    public void fireSheetPropertyValueChangedListenerSheetPropertyValueChanged(it.businesslogic.ireport.gui.event.SheetPropertyValueChangedEvent event) {

        if (listenerList == null) return;
        Object[] listeners = listenerList.getListenerList ();
        for (int i = listeners.length-2; i>=0; i-=2) {
            if (listeners[i]==it.businesslogic.ireport.gui.event.SheetPropertyValueChangedListener.class) {
                ((it.businesslogic.ireport.gui.event.SheetPropertyValueChangedListener)listeners[i+1]).sheetPropertyValueChanged (event);
            }
        }
    }

    public boolean isReadOnly() {
        return readOnly;
    }

    public void setReadOnly(boolean readOnly) {
        this.readOnly = readOnly;
        getEditor().setEnabled(!readOnly);
    }

    public JComponent getLabelComponent() {
        return labelComponent;
    }

    public void setLabelComponent(JComponent labelComponent) {
        this.labelComponent = labelComponent;
    }

    public boolean isSetting() {
        return setting;
    }

    public void setSetting(boolean setting) {
        this.setting = setting;
    }

    public boolean isShowResetButton() {
        return showResetButton;
    }

    public void setShowResetButton(boolean showResetButton) {
        this.showResetButton = showResetButton;
    }

    public java.awt.Color getLabelColor() {
        return labelColor;
    }

    public void setLabelColor(java.awt.Color labelColor) {
        this.labelColor = labelColor;
    }

    public Vector getCurrentSelection() {
        return currentSelection;
    }

    public void setCurrentSelection(Vector currentSelection) {
        this.currentSelection = currentSelection;
    }
    
}
