/* Generated By:JavaCC: Do not edit this line. STLAsciiParser.java */
package org.cybergarage.x3d.parser.threedsystems;

import org.cybergarage.x3d.node.ColorNode;
import org.cybergarage.x3d.node.CoordinateNode;
import org.cybergarage.x3d.node.IndexedFaceSetNode;
import org.cybergarage.x3d.node.NormalNode;
import org.cybergarage.x3d.node.RootNode;
import org.cybergarage.x3d.node.ShapeNode;

public class STLAsciiParser implements STLAsciiParserConstants {

    private RootNode mRootNode;
    private ShapeNode mCurrentShapeNode;

    private boolean mHasFaceColor;
    private float mPrevFaceColor[] = new float[3];
    private int mSolidFaceCount;

    public STLAsciiParser() {
    }

    public void initialize() {
        mRootNode = new RootNode();
        setCurrentShapeNode(null);
        setPrevFaceColor(1.0f, 1.0f, 1.0f);
    }

    public ShapeNode createShapeNode() {
        ShapeNode shape = new ShapeNode();
        IndexedFaceSetNode idxFaceSetNode = new IndexedFaceSetNode();
        shape.addChildNode(idxFaceSetNode);
        idxFaceSetNode.addChildNode(new CoordinateNode());
        idxFaceSetNode.addChildNode(new ColorNode());
        idxFaceSetNode.addChildNode(new NormalNode());
        idxFaceSetNode.setColorPerVertex(false);
        idxFaceSetNode.setNormalPerVertex(true);
        return shape;
    }

    public int getNShapeNodes() {
        return mRootNode.getNChildNodes();
    }

    public ShapeNode getShapeNodes() {
        return mRootNode.getShapeNodes();
    }

    public void addShapeNode(ShapeNode node) {
        mRootNode.addChildNode(node);
    }

    public void setSolidFaceCount(int n) {
        mSolidFaceCount = n;
    }

    public int getSolidFaceCount() {
        return mSolidFaceCount;
    }

    public void setPrevFaceColor(float r, float g, float b) {
        mPrevFaceColor[0] = r;
        mPrevFaceColor[1] = g;
        mPrevFaceColor[2] = b;
    }

    public void getPrevFaceColor(float color[]) {
        color[0] = mPrevFaceColor[0];
        color[1] = mPrevFaceColor[1];
        color[2] = mPrevFaceColor[2];
    }

    public boolean hasFaceColor() {
        return mHasFaceColor;
    }

    public void setFaceColorFlag(boolean flag) {
        mHasFaceColor = flag;
    }

    public void setCurrentShapeNode(ShapeNode node) {
        mCurrentShapeNode = node;
    }

    public ShapeNode getCurrentShapeNode() {
        return mCurrentShapeNode;
    }

    private IndexedFaceSetNode getCurrentIndexedFaceSetNode() {
        return getCurrentShapeNode().getIndexedFaceSetNodes();
    }

    private CoordinateNode getCurrentCoordinateNode() {
        return getCurrentIndexedFaceSetNode().getCoordinateNodes();
    }

    private ColorNode getCurrentColorNode() {
        return getCurrentIndexedFaceSetNode().getColorNodes();
    }

    private NormalNode getCurrentNormalNode() {
        return getCurrentIndexedFaceSetNode().getNormalNodes();
    }

    private void addCoodinate(float x, float y, float z) {
        getCurrentCoordinateNode().addPoint(x, y, z);
    }

    private int getNCoodinates() {
        return getCurrentCoordinateNode().getNPoints();
    }

    private void addColor(float r, float g, float b) {
        getCurrentColorNode().addColor(r, g, b);
    }

    private int getNColors() {
        return getCurrentColorNode().getNColors();
    }

    private void addNormal(float x, float y, float z) {
        getCurrentNormalNode().addVector(x, y, z);
    }

    private int getNNormals() {
        return getCurrentNormalNode().getNVectors();
    }

    private void addCoordIndex(int index) {
        getCurrentIndexedFaceSetNode().addCoordIndex(index);
    }

    public int getNCoordIndices() {
        return getCurrentIndexedFaceSetNode().getNCoordIndices();
    }

    public int getCoordIndex(int n) {
        return getCurrentIndexedFaceSetNode().getCoordIndex(n);
    }

    private void addNormalIndex(int index) {
        getCurrentIndexedFaceSetNode().addNormalIndex(index);
    }

    public int getNNormalIndices() {
        return getCurrentIndexedFaceSetNode().getNNormalIndices();
    }

    public int getNormalIndex(int n) {
        return getCurrentIndexedFaceSetNode().getNormalIndex(n);
    }

    private void addTexCoordIndex(int index) {
        getCurrentIndexedFaceSetNode().addTexCoordIndex(index);
    }

    public int getNTexCoordIndices() {
        return getCurrentIndexedFaceSetNode().getNTexCoordIndices();
    }

    public int getTexCoordIndex(int n) {
        return getCurrentIndexedFaceSetNode().getTexCoordIndex(n);
    }

    // /////////////////////////////////////////////
    // IntegerToken / ValueToken / NameToken
    // /////////////////////////////////////////////
    final public float ValueToken() throws ParseException {
        Token t;
        Integer intObj;
        Float floatObj;
        switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
        case NUMBER:
            t = jj_consume_token(NUMBER);
            intObj = new Integer(t.image);
            {
                if (true)
                    return (float) intObj.intValue();
            }
            // return (float)Integer.parseInt(t.image);

            break;
        case FLOAT_NUMBER:
            t = jj_consume_token(FLOAT_NUMBER);
            floatObj = new Float(t.image);
            {
                if (true)
                    return floatObj.floatValue();
            }
            // return Float.parseFloat(t.image);

            break;
        default:
            jj_la1[0] = jj_gen;
            jj_consume_token(-1);
            throw new ParseException();
        }
        throw new Error("Missing return statement in function");
    }

    final public String NameToken() throws ParseException {
        Token t;
        t = jj_consume_token(NAME);
        {
            if (true)
                return t.image;
        }
        throw new Error("Missing return statement in function");
    }

    // /////////////////////////////////////////////
    // STL Ascii
    // /////////////////////////////////////////////
    final public void STLAscii() throws ParseException {
        label_1: while (true) {
            switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
            case 5:
                ;
                break;
            default:
                jj_la1[1] = jj_gen;
                break label_1;
            }
            Solid();
        }
    }

    // /////////////////////////////////////////////
    // Solid
    // /////////////////////////////////////////////
    final public void SolidBegin() throws ParseException {
        String name;
        jj_consume_token(5);
        name = NameToken();
        ShapeNode shape = createShapeNode();
        shape.setName(name);
        addShapeNode(shape);
        setCurrentShapeNode(shape);
        setSolidFaceCount(0);
    }

    final public void SolidEnd() throws ParseException {
        String name;
        jj_consume_token(6);
        label_2: while (true) {
            switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
            case NAME:
                ;
                break;
            default:
                jj_la1[2] = jj_gen;
                break label_2;
            }
            name = NameToken();
        }

    }

    final public void Solid() throws ParseException {
        SolidBegin();
        label_3: while (true) {
            switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
            case 7:
            case 12:
                ;
                break;
            default:
                jj_la1[3] = jj_gen;
                break label_3;
            }
            switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
            case 12:
                Color();
                break;
            default:
                jj_la1[4] = jj_gen;
                ;
            }
            Face();
        }
        SolidEnd();
    }

    // /////////////////////////////////////////////
    // Face
    // /////////////////////////////////////////////
    final public void Facet() throws ParseException {
        jj_consume_token(7);
        setFaceColorFlag(false);
    }

    final public void EndFacet() throws ParseException {
        int faceCount;
        float color[] = new float[3];
        NormalNode normalNode;
        float vector[] = new float[3];
        jj_consume_token(8);
        faceCount = getSolidFaceCount();

        if (hasFaceColor() == false) {
            getPrevFaceColor(color);
            addColor(color[0], color[1], color[2]);
        }

        int nNormals = getNNormals();
        if (nNormals == 1) {
            normalNode = getCurrentNormalNode();
            normalNode.getVector(0, vector);
            addNormal(vector[0], vector[1], vector[2]);
            addNormal(vector[0], vector[1], vector[2]);
        }

        for (int n = 0; n < 3; n++)
            addCoordIndex((faceCount * 3) + n);
        addCoordIndex(-1);

        setSolidFaceCount(faceCount + 1);
    }

    final public void Face() throws ParseException {
        Facet();
        label_4: while (true) {
            switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) {
            case 14:
                ;
                break;
            default:
                jj_la1[5] = jj_gen;
                break label_4;
            }
            Normal();
        }
        jj_consume_token(9);
        jj_consume_token(10);
        Vertex();
        Vertex();
        Vertex();
        jj_consume_token(11);
        EndFacet();
    }

    // /////////////////////////////////////////////
    // Color
    // /////////////////////////////////////////////
    final public void Color() throws ParseException {
        float r, g, b;
        jj_consume_token(12);
        r = ValueToken();
        g = ValueToken();
        b = ValueToken();
        addColor(r, g, b);
        setFaceColorFlag(true);
        setPrevFaceColor(r, g, b);
    }

    // /////////////////////////////////////////////
    // Vertex
    // /////////////////////////////////////////////
    final public void Vertex() throws ParseException {
        float x, y, z;
        jj_consume_token(13);
        x = ValueToken();
        y = ValueToken();
        z = ValueToken();
        addCoodinate(x, y, z);
    }

    // /////////////////////////////////////////////
    // Normal
    // /////////////////////////////////////////////
    final public void Normal() throws ParseException {
        float x, y, z;
        jj_consume_token(14);
        x = ValueToken();
        y = ValueToken();
        z = ValueToken();
        addNormal(x, y, z);
    }

    final public void Input() throws ParseException {
        STLAscii();
        jj_consume_token(0);
    }

    public STLAsciiParserTokenManager token_source;
    SimpleCharStream jj_input_stream;
    public Token token, jj_nt;
    private int jj_ntk;
    private int jj_gen;
    final private int[] jj_la1 = new int[6];
    final private int[] jj_la1_0 = { 0x28000, 0x20, 0x10000, 0x1080, 0x1000,
            0x4000, };

    public STLAsciiParser(java.io.InputStream stream) {
        jj_input_stream = new SimpleCharStream(stream, 1, 1);
        token_source = new STLAsciiParserTokenManager(jj_input_stream);
        token = new Token();
        jj_ntk = -1;
        jj_gen = 0;
        for (int i = 0; i < 6; i++)
            jj_la1[i] = -1;
    }

    public void ReInit(java.io.InputStream stream) {
        jj_input_stream.ReInit(stream, 1, 1);
        token_source.ReInit(jj_input_stream);
        token = new Token();
        jj_ntk = -1;
        jj_gen = 0;
        for (int i = 0; i < 6; i++)
            jj_la1[i] = -1;
    }

    public STLAsciiParser(java.io.Reader stream) {
        jj_input_stream = new SimpleCharStream(stream, 1, 1);
        token_source = new STLAsciiParserTokenManager(jj_input_stream);
        token = new Token();
        jj_ntk = -1;
        jj_gen = 0;
        for (int i = 0; i < 6; i++)
            jj_la1[i] = -1;
    }

    public void ReInit(java.io.Reader stream) {
        jj_input_stream.ReInit(stream, 1, 1);
        token_source.ReInit(jj_input_stream);
        token = new Token();
        jj_ntk = -1;
        jj_gen = 0;
        for (int i = 0; i < 6; i++)
            jj_la1[i] = -1;
    }

    public STLAsciiParser(STLAsciiParserTokenManager tm) {
        token_source = tm;
        token = new Token();
        jj_ntk = -1;
        jj_gen = 0;
        for (int i = 0; i < 6; i++)
            jj_la1[i] = -1;
    }

    public void ReInit(STLAsciiParserTokenManager tm) {
        token_source = tm;
        token = new Token();
        jj_ntk = -1;
        jj_gen = 0;
        for (int i = 0; i < 6; i++)
            jj_la1[i] = -1;
    }

    final private Token jj_consume_token(int kind) throws ParseException {
        Token oldToken;
        if ((oldToken = token).next != null)
            token = token.next;
        else
            token = token.next = token_source.getNextToken();
        jj_ntk = -1;
        if (token.kind == kind) {
            jj_gen++;
            return token;
        }
        token = oldToken;
        jj_kind = kind;
        throw generateParseException();
    }

    final public Token getNextToken() {
        if (token.next != null)
            token = token.next;
        else
            token = token.next = token_source.getNextToken();
        jj_ntk = -1;
        jj_gen++;
        return token;
    }

    final public Token getToken(int index) {
        Token t = token;
        for (int i = 0; i < index; i++) {
            if (t.next != null)
                t = t.next;
            else
                t = t.next = token_source.getNextToken();
        }
        return t;
    }

    final private int jj_ntk() {
        if ((jj_nt = token.next) == null)
            return (jj_ntk = (token.next = token_source.getNextToken()).kind);
        else
            return (jj_ntk = jj_nt.kind);
    }

    private java.util.Vector jj_expentries = new java.util.Vector();
    private int[] jj_expentry;
    private int jj_kind = -1;

    final public ParseException generateParseException() {
        jj_expentries.removeAllElements();
        boolean[] la1tokens = new boolean[19];
        for (int i = 0; i < 19; i++) {
            la1tokens[i] = false;
        }
        if (jj_kind >= 0) {
            la1tokens[jj_kind] = true;
            jj_kind = -1;
        }
        for (int i = 0; i < 6; i++) {
            if (jj_la1[i] == jj_gen) {
                for (int j = 0; j < 32; j++) {
                    if ((jj_la1_0[i] & (1 << j)) != 0) {
                        la1tokens[j] = true;
                    }
                }
            }
        }
        for (int i = 0; i < 19; i++) {
            if (la1tokens[i]) {
                jj_expentry = new int[1];
                jj_expentry[0] = i;
                jj_expentries.addElement(jj_expentry);
            }
        }
        int[][] exptokseq = new int[jj_expentries.size()][];
        for (int i = 0; i < jj_expentries.size(); i++) {
            exptokseq[i] = (int[]) jj_expentries.elementAt(i);
        }
        return new ParseException(token, exptokseq, tokenImage);
    }

    final public void enable_tracing() {
    }

    final public void disable_tracing() {
    }

}
