001package Torello.CSS;
002
003import Torello.Java.Additional.ByRef;
004
005import java.util.Vector;
006import java.util.function.Consumer;
007
008@Torello.JavaDoc.JDHeaderBackgroundImg(EmbedTagFileID="CSS_TOK")
009public class Dimension extends Num
010    implements CharSequence, java.io.Serializable, Comparable<CharSequence>
011{
012    /** <EMBED CLASS='external-html' DATA-FILE-ID=SVUID> */
013    protected static final long serialVersionUID = 1;
014
015
016    // ********************************************************************************************
017    // ********************************************************************************************
018    // Public & Final Fields
019    // ********************************************************************************************
020    // ********************************************************************************************
021
022
023    /**
024     * The text / {@code String} that was appended to the end of the number that begin this
025     * {@code Dimension}-Token
026     */
027    public final String dimension;
028
029
030    // ********************************************************************************************
031    // ********************************************************************************************
032    // Private Constructor, API "is" and "if" Methods
033    // ********************************************************************************************
034    // ********************************************************************************************
035
036
037    Dimension(
038            final int[]     css,
039            final int       sPos,
040            final int       ePos,
041            final Num       n,
042            final String    dimension
043        )
044    {
045        super(css, sPos, ePos, n);
046        this.dimension = dimension;
047    }
048
049    @Override 
050    public final boolean isDimension() { return true; }
051
052    @Override
053    public final Dimension ifDimension() { return this; }
054
055
056    // ********************************************************************************************
057    // ********************************************************************************************
058    // User's Constructor: a static "build" method
059    // ********************************************************************************************
060    // ********************************************************************************************
061
062
063    /**
064     * <EMBED CLASS=defs DATA-TOK=Dimension DATA-P=dimensionStr>
065     * <EMBED CLASS='external-html' DATA-FILE-ID=BUILD_DESC>
066     * @param dimensionStr <EMBED CLASS='external-html' DATA-FILE-ID=BUILD_PARAM>
067     * @return <EMBED CLASS='external-html' DATA-FILE-ID=BUILD_RET>
068     * @throws TokenizeException <EMBED CLASS='external-html' DATA-FILE-ID=BUILD_TOK_EX>
069     */
070    public static Dimension build(final String dimensionStr)
071    {
072        CSSToken ret = CSSToken.build(dimensionStr, INPUT_CHECKER, Num::consume);
073
074        if (ret instanceof Dimension) return (Dimension) ret;
075
076        throw new TokenizeException(
077            "Your String could not be converted to a Dimension-Instance.  The Number Parser " +
078            "has returned an instance of class '" + ret.getClass().getSimpleName() + "' instead."
079        );
080    }
081
082    private static final CSSToken.InputChecker INPUT_CHECKER = (int[] css) ->
083    {
084        if (css.length < 2) throw new TokenizeException(Dimension.class);
085
086        if (! Num.is(css, 0)) throw new TokenizeException
087            ("String-text beginning does not constitute a valid CSS Number-Token");
088    };
089
090
091    // ********************************************************************************************
092    // ********************************************************************************************
093    // CONSUME
094    // ********************************************************************************************
095    // ********************************************************************************************
096
097
098    /**
099     * This is a tokenizer method which <B>"consumes"</B> the next Dimension-Token from the
100     * input Code-Point Array.
101     * 
102     * <EMBED CLASS=defs DATA-TOK=Dimension DATA-URL=dimension-token-diagram DATA-OP=Consume>
103     * <EMBED CLASS=external-html DATA-FILE-ID=COPIED_CSS_WG_RR>
104     * <EMBED CLASS=external-html DATA-FILE-ID=COMMENT_SVG>
105     */
106    protected static void consume(
107            final int[]                 css,
108            final ByRef<Integer>        POS,
109            final Consumer<CSSToken>    returnParsedToken,
110            final int                   identifierStartPos,
111            final Num                   num
112        )
113    {
114        /*
115        Please, be merciful, this isn't as fun and as exciting as it looks on first-glance.  These
116        System.out's are for debugging, and to make this parser more clear when running test code.
117        My Test-Code Directory is very, very big and has tests for a lot of things in Java-HTML.
118        It helps TO NO END when debugging code.
119
120        These PrintF's were all written while debugging the Torello.CSS Package
121        All of the "Edge Cases" are difficult to find until you run tests on all of your Edge-Cases
122
123        System.out.println(
124            "Dimension.consume:\n" + 
125            "\tPOS.f:                      " + POS.f + '\n' +
126            "\tcss[POS.f]:                 " + '\'' + ((char) css[POS.f]) + "'\n" +
127            "\tidentifierStartPos:         " + identifierStartPos + '\n' +
128            "\tcss[identifierStartPos]:    " + '\'' + ((char) css[identifierStartPos]) + "'\n" +
129            "\tnum.integerOrNumber:        " + num.integerOrNumber + "\n" +
130            "\tnum.signChar:               " + '\'' + num.signChar + "'\n"  +
131            "\tnum.toString():             " + '"' + num.toString() + "\"\n" +
132            "\tnum.number.toString():      " + '"' + num.number.toString() + "\"\n" +
133            "\tnum.number.intValue():      " + num.number.intValue() + "\n" +
134            "\tnum.number.floatValue():    " + num.number.floatValue()
135        );
136        */
137
138        // Create a <dimension-token> with the same value, type flag, and sign character as
139        // number, and a unit set initially to the empty string.
140        // 
141        // Consume an ident sequence.
142
143        final ByRef<String> identifier = new ByRef<>();
144
145        // Consume an Identifier
146        final int identifierEndPos =
147            Identifier.consumeIdentSequence(css, identifierStartPos, identifier);
148
149        /*
150        System.out.println(
151            "\tidentifier.f:               " + identifier.f + '\n' +
152            "\tidentifierEndPos:           " + identifierEndPos + '\n' +
153            "\tcss[identifierEndPos]:      " + ((identifierEndPos < css.length)
154                ? ((char) css[identifierEndPos])
155                : ((char) 0))
156        );
157        */
158
159        // Set the <dimension-token>’s unit to the returned ident-sequence value
160        // Return the <dimension-token>.
161
162        returnParsedToken.accept(new Dimension(css, POS.f, identifierEndPos, num, identifier.f));
163        POS.f = identifierEndPos;
164    }
165}