package taberion;

import javax.swing.*;
import javax.swing.text.*;
import javax.swing.event.DocumentListener;

import java.awt.Toolkit;
import java.text.NumberFormat;
import java.text.ParseException;
import java.util.Locale;

    /**
     *  This TextField is added to every Cell as an Editor.
     *  If the user makes any changes in a cell, they are
     *  executed via this special TextField.<br><br>
     *  For a better understanding, read this document:<br>
     *  <a href="http://java.sun.com/docs/books/tutorial/uiswing/components/table.html">How To Use Tables</a>
     *  <br>
     *  <br>
     *  Many code from this project is taken out of Sun-Examples from this page.
     */

public class TVerificationField extends JTextField {


    private NumberFormat integerFormatter;
    private ScanningDocument myScanDoc;

    public TVerificationField(int parseState, int columns) {
        super(columns);
        this.setBorder(null);
        this.setParseState(parseState);
        if (myScanDoc==null){
            myScanDoc = new ScanningDocument(getParseState());
        }
        integerFormatter = NumberFormat.getNumberInstance(Locale.US);
        integerFormatter.setParseIntegerOnly(true);
    }

    protected Document createDefaultModel() {
        myScanDoc = new ScanningDocument();
        return myScanDoc;
    }

    public void setParseState(int pS){
        myScanDoc.setParseState(pS);
    }

    public int getParseState(){
        return myScanDoc.getParseState();
    }

    /**
     *  This internal Class of TVerificationField scans by its insertString method
     *  everything, the user enters into a cell. Every change in a cell is executed via the
     *  insertString method.
     */
    protected class ScanningDocument extends PlainDocument {
    private int parseState = TConsts.PARSE_STRING;

        public ScanningDocument(int parseState){
          super();
          this.parseState=parseState;
          System.out.println("In ScanningDoc");
        }

        public ScanningDocument(){
          super();
        }

        /**
         * Decides what input is accepted, depending on parseState.<br><br>
         * If the parseState is set to "PARSE_STRING", all input is accepted. <br><br>
         * If the parseState is set to "PARSE_BIGINT", this method accepts
         * the minus sign at position 0, and all numbers everywhere, but not
         * ahead a minus sign.<br><br>
         * If the parseState is set to "PARSE_BIGDEC", this method accepts
         * a minus sign at position 0, one point (or one comma, which will be mapped to a point)
         * and any numbers. Point and number are not accepted to be ahead the minus sign.
         * A leading point or a leading minus followed by a point are interpreted as "0." or "-0."
         *
         *@param offs The position on which the string str should be inserted.
         *@param str The String which should be inserted.
         *@param a Is only handed to the super method.
         */
        public void insertString(int offs,
                                 String str,
                                 AttributeSet a)
                throws BadLocationException {

            char[] source = str.toCharArray();
            char[] result = new char[source.length];
            int j = 0;

            /* If a "0" was stated at the beginning, it will be removed..."
             * If a number has to start with a 0 like 0.25 it can also be entered like .25 !!!
             */
            if (this.getLength() == 0 && str.equals("0")) {
              str = "";
              return;
            }

            if (parseState==TConsts.PARSE_STRING){
                  result=source;
                  j=source.length;
            }else if (parseState==TConsts.PARSE_BIGINT){
                if (source.length!=0){
                    if ((source[0]=='-')&&(offs==0)&&(getText(0, this.getLength()).indexOf("-")==-1))
                    {
                        result[j++] = '-';
                    }
                }
                for (int i = 0; i < result.length; i++)
                {

                    if (Character.isDigit(source[i]))
                    {
                        if((getText(0, this.getLength()).indexOf("-")==-1)||(offs!=0))
                        {
                            result[j++] = source[i];
                        }
                    }else
                    {
                        System.err.println("Wrong Char: " + source[i]);
                    }
                }
            }else if (parseState==TConsts.PARSE_BIGDEC){
                if (source.length!=0){
                    if ((source[0]=='-')&&(offs==0)&&(getText(0, this.getLength()).indexOf("-")==-1))
                    {
                        result[j++] = '-';
                    }
                }
                for (int i = 0; i < result.length; i++)
                {
                    if (Character.isDigit(source[i]))
                    {
                        if((getText(0, this.getLength()).indexOf("-")==-1)||(offs!=0))
                        {
                            result[j++] = source[i];
                        }
                    }else if((source[i]=='.'||source[i]==','))
                    {
                        if(getText(0, this.getLength()).indexOf("-")!=-1&&(offs==0))
                        {

                        }else
                        {
                            String temp = getText(0, this.getLength());
                            if((temp.indexOf(".")==-1)||(temp.indexOf(".", temp.indexOf("."))==-1)){
                               result[j++] ='.';
                            }
                        }
                    }else
                    {
                        System.err.println("Wrong Char: " + source[i]);
                    }
                }
            }
            super.insertString(offs, new String(result, 0, j), a);
        }

        public void setParseState(int pS){
            parseState = pS;
        }

        public int getParseState(){
            return parseState;
        }
    }
}