//
// $Id$

package com.threerings.gwt.ui;

import com.google.gwt.event.dom.client.KeyUpEvent;
import com.google.gwt.event.dom.client.KeyUpHandler;
import com.google.gwt.user.client.ui.TextBox;

/**
 * A text box that will only accept numbers.
 */
public class NumberTextBox extends TextBox
{
    public NumberTextBox (boolean allowFloatingPoint)
    {
        this(allowFloatingPoint, 0, 0);
    }

    /**
     * Constructor to set both the visible and maximum lengths to the given value.
     */
    public NumberTextBox (boolean allowFloatingPoint, int length)
    {
        this(allowFloatingPoint, length, length);
    }

    /**
     * @param allowFloatingPoint If true, a single decimal point is part of the allowed character
     * set.  Otherwise, only [0-9]* is accepted.
     */
    public NumberTextBox (final boolean allowFloatingPoint, int maxLength, int visibleLength)
    {
        _allowFloatingPoint = allowFloatingPoint;

        addKeyUpHandler(new KeyUpHandler() {
            public void onKeyUp (KeyUpEvent event) {
                if (event.isShiftKeyDown() ||
                    event.getNativeKeyCode() > '9' || event.getNativeKeyCode() < '0') {
                    String text = getText();
                    boolean foundDecimal = !allowFloatingPoint;
                    for (int ii = 0; ii < text.length(); ii++) {
                        if (text.charAt(ii) > '9' || text.charAt(ii) < '0') {
                            if (text.charAt(ii) == '.' && !foundDecimal) {
                                foundDecimal = true;
                            } else {
                                text = text.substring(0, ii) + text.substring(ii+1);
                                ii--;
                            }
                        }
                    }
                    setText(text);
                }
            }
        });

        if (maxLength != 0) {
            setMaxLength(maxLength);
        }
        if (visibleLength != 0) {
            setVisibleLength(visibleLength);
        }
    }

    /**
     * Sets the numeric contents of this text box. Passing null will clear the box.
     */
    public void setNumber (Number value)
    {
        setText(value == null ? "" : value.toString());
    }

    /**
     * Get the numberic value of this box. Returns 0 if the box is empty.
     */
    public Number getNumber ()
    {
        String valstr = getText().length() == 0 ? "0" : getText();
        return _allowFloatingPoint ? (Number)(new Double(valstr)) : (Number)(new Integer(valstr));
    }

    protected boolean _allowFloatingPoint;
}

@@ -294,275 +294,1256 @@
     
-public NumberTextBox (boolean allowFloatingPoint)%0A    %7B%0A        this(allowFloatingPoint, 0, 0);%0A    %7D%0A%0A    /**%0A     * Constructor to set both the visible and maximum lengths to the given value.%0A     */%0A    public NumberTextBox (boolean allowFloatingPoint, int
+/**%0A     * Creates a text box that only accepts integers and has no max or visible character length.%0A     */%0A    public NumberTextBox newIntBox ()%0A    %7B%0A        return new NumberTextBox(false, 0, 0);%0A    %7D%0A%0A    /**%0A     * Creates a text box that only accepts integers and uses the supplied length as its max and%0A     * visible character length.%0A     */%0A    public NumberTextBox newIntBox (int length)%0A    %7B%0A        return new NumberTextBox(false, length, length);%0A    %7D%0A%0A    /**%0A     * Creates a text box that only accepts integers and has the specified max and visible%0A     * character length.%0A     */%0A    public NumberTextBox newIntBox (int maxLength, int visibleLength)%0A    %7B%0A        return new NumberTextBox(false, maxLength, visibleLength);%0A    %7D%0A%0A    /**%0A     * Creates a text box that accepts floating point numbers and has no max or visible character%0A     * length.%0A     */%0A    public NumberTextBox newFloatBox ()%0A    %7B%0A        return new NumberTextBox(false, 0, 0);%0A    %7D%0A%0A    /**%0A     * Creates a text box that accepts floating point numbers and uses the supplied length as its%0A     * max and visible character length.%0A     */%0A    public NumberTextBox newFloatBox (int length)%0A    %7B%0A        return new NumberTextBox(false, length,
  length)
 %0A   
@@ -1542,57 +1542,295 @@
 gth)
+;
 %0A    
-%7B
+%7D%0A
 %0A    
-    this(allowFloatingPoint, length, l
+/**%0A     * Creates a text box that accepts floating point numbers and has the specified max and visible%0A     * character length.%0A     */%0A    public NumberTextBox newFloatBox (int maxLength, int visibleLength)%0A    %7B%0A        return new NumberTextBox(false, maxLength, visibleL
 engt
@@ -3102,26 +3102,25 @@
  (maxLength 
-!=
+%3E
  0) %7B%0A      
@@ -3190,10 +3190,9 @@
 gth 
-!=
+%3E
  0) 

Use factory methods instead of overloaded constructors.