// ============================================================================
// File:               JDoubleTextField.java
//
// Project:            General.
//
// Purpose:            TextField, which accepts only double values
//
// Author:             Rammi
//
// Copyright Notice:   (c) 2002  Rammi (rammi@caff.de)
//                     This code is in the public domain.
//                     Use at own risk.
//                     No guarantees given.
//
// Latest change:      $Date$
//
// History:	       $Log$
//=============================================================================

package de.caff.gimmicks.swing;

import de.caff.i18n.I18n;

import javax.swing.*;
import javax.swing.event.CaretEvent;
import javax.swing.event.CaretListener;
import java.awt.*;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.text.ParsePosition;

/**
 *  Textfield, which accepts only double values.
 *
 *  @author <a href="mailto:rammi@caff.de">Rammi</a>
 *  @version $Revision$
 */
public class JDoubleTextField
  extends JTextField
{
  /** The default format for doubles. */
  public static final String DEFAULT_FORMAT = "#####0.0#####";

  /** The bgcolor to be set when the input is invalid. */
  private static final Color INVALID_BACKGROUND = new Color(0xff, 0x80, 0x80);

  /** The default bg color. */
  private Color  defaultBG;

  /** Is this field valid? */
  private boolean valid = true;

  /** The current value. */
  private double value;

  /** The format for interpreting input values. */
  private DecimalFormat scanFormat; 

  /**
   *  Initialization.
   *  @param  initValue  initialization value
   *  @param  format parse format, see {@link java.text.DecimalFormat}
   */
  private void init(double initValue, String format)
  {
    this.value = initValue;
    scanFormat = new DecimalFormat(format,
				   new DecimalFormatSymbols(I18n.getDefaultLocale()));

    setText(scanFormat.format(initValue));

    defaultBG = getBackground();

    addCaretListener(new CaretListener() {
      public void caretUpdate(CaretEvent e)
      {
	String text = getText();

	ParsePosition pos = new ParsePosition(0);

        Number number = scanFormat.parse(text, pos);
        if (number != null  &&  pos.getIndex() == text.length()) {
          valid = true;
          value = number.doubleValue();
        }
        else {
          valid = false;
        }

        if (valid) {
	  setBackground(defaultBG);
	}
	else {
	  setBackground(INVALID_BACKGROUND);
	}
      }
    });
  }
  
  /**
   *  Create with value == 0.
   */
  public JDoubleTextField()
  {
    this(0);
  }

  /**
   *  Create with the given value.
   *  @param  value start value
   */
  public JDoubleTextField(double value)
  {
    init(value, DEFAULT_FORMAT);
  }

  /**
   *  Create with the given value, using the given PrintfFormat.
   *  @param  value  start value
   *  @param  format PrintfFormat string
   */
  public JDoubleTextField(double value, String format)
  {
    super();
    if (format == null) {
      format = DEFAULT_FORMAT;
    }
    init(value, format);
  }

  /**
   *  Is this valid?
   *  @return the answer
   */
  public boolean isValid() 
  {
    return valid;
  }

  /**
   *  Get the current value.
   *  @return  value
   */
  public double getValue()
  {
    return isValid() ? value : 0.0;
  }

  /**
   *  Set the value.
   *  @param  value  new value
   */
  public void setValue(double value)
  {
    setText(scanFormat.format(value));
  }

}
