/* UtilLib - Copyright (c) 2007-2018 Vincent Calame - Exemole
 * Logiciel libre donné sous triple licence :
 * 1) selon les termes de la CeCILL V2
 * 2) selon les termes de l’EUPL V.1.1
 * 3) selon les termes de la GNU GPLv3
 * Voir le fichier licences.txt
 */


package net.mapeadores.util.text.lexie;


/**
 *
 * @author Vincent Calame
 */
public final class LexieParser {

    private final LexieParseHandler handler;
    private int wordStart = -1;
    private int bufLength = 0;
    private char[] bufArray;

    private LexieParser(LexieParseHandler handler) {
        this.handler = handler;
    }

    public static void parse(String chaine, LexieParseHandler handler) {
        if (chaine == null) {
            return;
        }
        LexieParser lexieParser = new LexieParser(handler);
        lexieParser.parse(chaine);
    }

    private static boolean isLexieCarac(char carac) {
        if (Character.isLetterOrDigit(carac)) {
            return true;
        }
        switch (Character.getType(carac)) {
            case Character.NON_SPACING_MARK:
            case Character.COMBINING_SPACING_MARK:
            case Character.ENCLOSING_MARK:
                return true;
            default:
                return false;
        }
    }

    private void parse(String chaine) {
        int taille = chaine.length();
        bufArray = new char[taille];
        for (int i = 0; i < taille; i++) {
            char carac = chaine.charAt(i);
            if (Character.isIdeographic(carac)) {
                flushWord();
                wordStart = i;
                bufLength = 1;
                bufArray[0] = carac;
                flushWord();
            } else if (isLexieCarac(carac)) {
                bufArray[bufLength] = carac;
                bufLength++;
                if (wordStart == -1) {
                    wordStart = i;
                }
            } else {
                flushWord();
                handler.checkSpecialChar(carac);
            }
        }
        flushWord();
    }

    private void flushWord() {
        if (wordStart > -1) {
            String word = new String(bufArray, 0, bufLength);
            handler.flushLexie(word, wordStart);
            bufLength = 0;
            wordStart = -1;
        }
    }

}
