package metalexer.jflex;

import java.util.Enumeration;
import java.util.Iterator;

public class CharacterGenerator implements Enumeration<Character>, Iterator<Character> {

    private static final char DEFAULT_FIRST_CHAR = '\u0000';

    private char ch;

    public CharacterGenerator() {
        this(DEFAULT_FIRST_CHAR);
    }

    public CharacterGenerator(char ch) {
        this.ch = ch;
    }

    public boolean hasMoreElements() {
        return hasNext();
    }

    public Character nextElement() {
        return next();
    }

    public void remove() {
        //do nothing - there is no underlying collection
    }

    public boolean hasNext() {
        return true;
    }

    public Character next() {
        while(badChar(ch)) {
            //technically this violates the contract of Enumeration and Iterator
            //(since hasNext/hasMoreElements will have returned true) but it's
            //much cheaper than doing it properly and it shouldn't happen in practice
            if(ch == Character.MAX_VALUE) {
                throw new IllegalStateException("No more characters available.");
            }
            ch++;
        }
        return ch++;
    }

    private static boolean badChar(char ch) {
        return !Character.isLetterOrDigit(ch); //TODO-AC: revert to isUnicodeIdentifierPart after debugging
    }
}
