package cnp.ew.spin;

import cnp.ew.util.*;
import java.util.*;
import java.io.*;

public class CpFormattedStringModel extends CpDefaultObservable
{

    Vector fields;

    static final int STATE_INNUMBER=0;
    static final int STATE_INLITERAL=1;
    static final int STATE_START=2;
    static final int EOF=-1;

    public CpFormattedStringModel(String format)
    {
        parseFormatString(format);
    }

    void parseFormatString(String format)
    {
        fields = new Vector(4);
        int currentState = STATE_START;
        int startIndex=0;
        int curChar;

        for (int i=0; i <= format.length(); i++) {
            if (i == format.length()) {
                curChar = EOF;
            } else {
                curChar = format.charAt(i);
            }
            switch (currentState) {
            case STATE_START:
                switch(curChar) {
                case '#':
                    currentState = STATE_INNUMBER;
                    break;
                default:
                    currentState = STATE_INLITERAL;
                    break;
                }
                break;
            case STATE_INLITERAL:
                switch (curChar) {
                case '#':
                case EOF:
                    fields.addElement(new CpLiteralFormatField(format.substring(startIndex, i)));
                    startIndex = i;
                    currentState = STATE_INNUMBER;
                    break;
                default:
                    break;
                }
                break;
            case STATE_INNUMBER:
                switch (curChar) {
                case '#':
                    break;
                default:
                    fields.addElement(new CpNumericFormatField(format.substring(startIndex, i)));
                    startIndex = i;
                    currentState = STATE_INLITERAL;
                    break;
                }
                break;
            }
        }
    }

    public void setString(String text)
    {
        Enumeration e = fields.elements();
        StringBufferInputStream stream = new StringBufferInputStream(text);

        while (e.hasMoreElements()) {
            ((CpFormatField)e.nextElement()).readValueFrom(stream);
        }
        notifyObservers();
    }

    public String getString()
    {
        Enumeration e = fields.elements();
        ByteArrayOutputStream byteStream = new ByteArrayOutputStream(20);
        PrintStream stream = new PrintStream(byteStream);

        while (e.hasMoreElements()) {
            ((CpFormatField)e.nextElement()).writeValueTo(stream);
        }

        return byteStream.toString();
    }

    public String getFormattedString()
    {
        Enumeration e = fields.elements();
        ByteArrayOutputStream byteStream = new ByteArrayOutputStream(20);
        PrintStream stream = new PrintStream(byteStream);

        while (e.hasMoreElements()) {
            ((CpFormatField)e.nextElement()).writeFormattedValueTo(stream);
        }

        return byteStream.toString();
    }


    public void setFieldValue(int index, String text)
    {
        boolean notify = !getFieldValue(index).equals(text);
        ((CpFormatField)fields.elementAt(index)).setValue(text);

        if (notify) {
            notifyObservers();
        }
    }

    public String getFieldValue(int index)
    {
        return ((CpFormatField)fields.elementAt(index)).getValue();
    }

    public Vector createSpinFields()
    {
        Vector spinVector = new Vector(fields.size());
        for (int i = 0; i < fields.size(); i++) {
            spinVector.addElement(((CpFormatField)fields.elementAt(i)).createSpinField(i));
        }
        return spinVector;
    }
}



