/*
 * JNumberField.java
 *
 * iReport  --  Visual designer for generating JasperReports Documents
 *  Copyright (C) 2002-2003  Giulio Toffoli gt@businesslogic.it
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 *  Giulio Toffoli
 *  Via T.Aspetti, 233
 *  35100 Padova ITALY
 *  gt@businesslogic.it
 *
 * Created on 10 febbraio 2003, 0.22
 */

package it.businesslogic.ireport.gui;

import javax.swing.text.*;
import java.text.*;
import java.awt.event.*;
import it.businesslogic.ireport.gui.event.*;

/**
 *
 * @author  Administrator
 */
public class JNumberField extends javax.swing.JTextField implements java.awt.event.FocusListener {
    
    /** Holds value of property decimals. */
    private int decimals=2;    
    
    /** Holds value of property integer. */
    private boolean integer=false;
    
    /** Holds value of property value. */
    private double value = 0.0;
    
    private java.text.NumberFormat numberFormat=null;
    
    /** Holds value of property grouping. */
    private boolean grouping=true;
    
    /** Utility field used by event firing mechanism. */
    private javax.swing.event.EventListenerList listenerList =  null;
    
    /** Creates a new instance of JNumberField */
    public JNumberField() {
        
        super();
        this.addFocusListener(this);
        numberFormat=NumberFormat.getInstance();
        numberFormat.setMaximumFractionDigits(2);
        numberFormat.setMinimumFractionDigits(2);
        numberFormat.setGroupingUsed(true);
        this.setText(numberFormat.format(0));
    }
    
    /** Creates the default implementation of the model
     * to be used at construction if one isn't explicitly
     * given.  An instance of <code>PlainDocument</code> is returned.
     *
     * @return the default model implementation
     *
     */
    protected Document createDefaultModel() {
        //Document retValue;
        
        //retValue = super.createDefaultModel();
        return new NumberDocument();
    }
    
    /** Getter for property decimals.
     * @return Value of property decimals.
     *
     */
    public int getDecimals() {
        return this.decimals;
    }
    
    /** Setter for property decimals.
     * @param decimals New value of property decimals.
     *
     * @throws PropertyVetoException
     *
     */
    public void setDecimals(int decimals) throws java.beans.PropertyVetoException {
        this.decimals = decimals;
        if (!isInteger())
        {
            numberFormat.setMaximumFractionDigits(decimals);
            numberFormat.setMinimumFractionDigits(decimals);
        }
        this.setText( numberFormat.format(getValue()));
    }
    
    /** Getter for property integer.
     * @return Value of property integer.
     *
     */
    public boolean isInteger() {
        return this.integer;
    }
    
    /** Setter for property integer.
     * @param integer New value of property integer.
     *
     * @throws PropertyVetoException
     *
     */
    public void setInteger(boolean integer) throws java.beans.PropertyVetoException { 
        if (integer)
        {
            numberFormat.setMaximumFractionDigits(0);
            numberFormat.setMinimumFractionDigits(0);
        }
        else
        {
            numberFormat.setMaximumFractionDigits(getDecimals());
            numberFormat.setMinimumFractionDigits(getDecimals());
        }
        this.integer = integer;
        this.setText( numberFormat.format(getValue()));
    }
    
    /** Getter for property value.
     * @return Value of property value.
     *
     */
    public double getValue() {
        return this.value;
    }
    
    /** Setter for property value.
     * @param value New value of property value.
     *
     * @throws PropertyVetoException
     *
     */
    public void setValue(double value) throws java.beans.PropertyVetoException {
        this.value = value;
        this.setText( numberFormat.format(getValue()));
    }
    
    public void setValue(int value) throws java.beans.PropertyVetoException {
        setValue((double)value);
    }
    
    
    /** Invoked when a component gains the keyboard focus.
     *
     */
    public void focusGained(FocusEvent e) {
        numberFormat.setGroupingUsed(false);
        setText( numberFormat.format(value));
        numberFormat.setGroupingUsed(this.isGrouping());
    }
    
    /** Invoked when a component loses the keyboard focus.
     *
     */
    public void focusLost(FocusEvent e) {
        try {
            
                double oldValue = value;
                value =  numberFormat.parse(getText()).doubleValue();
                this.fireActionListenerActionPerformed(new java.awt.event.ActionEvent( this, 0, "") );
                
        } catch (ParseException ex){
        System.out.println("Errore");
        ex.printStackTrace();
        }
        setText( numberFormat.format(value)); 
        
    }
    
    /** Getter for property grouping.
     * @return Value of property grouping.
     *
     */
    public boolean isGrouping() {
        return this.grouping;
    }
    
    /** Setter for property grouping.
     * @param grouping New value of property grouping.
     *
     * @throws PropertyVetoException
     *
     */
    public void setGrouping(boolean grouping) throws java.beans.PropertyVetoException {
        this.grouping = grouping;
    }
    
    /** Registers ActionListener to receive events.
     * @param listener The listener to register.
     *
     */
    public synchronized void addActionListener(java.awt.event.ActionListener listener) {
        if (listenerList == null ) {
            listenerList = new javax.swing.event.EventListenerList();
        }
        listenerList.add(java.awt.event.ActionListener.class, listener);
    }
    
    /** Removes ActionListener from the list of listeners.
     * @param listener The listener to remove.
     *
     */
    public synchronized void removeActionListener(java.awt.event.ActionListener listener) {
        listenerList.remove(java.awt.event.ActionListener.class, listener);
    }
    
    /** Notifies all registered listeners about the event.
     *
     * @param event The event to be fired
     *
     */
    private void fireActionListenerActionPerformed(java.awt.event.ActionEvent event) {
        if (listenerList == null) return;
        Object[] listeners = listenerList.getListenerList();
        for (int i = listeners.length-2; i>=0; i-=2) {
            if (listeners[i]==java.awt.event.ActionListener.class) {
                ((java.awt.event.ActionListener)listeners[i+1]).actionPerformed(event);
            }
        }
    }
    
}

