/* UtilLib - Copyright (c) 2007-2014 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.xml;

import java.io.IOException;
import net.mapeadores.util.text.SubstringPosition;
import net.mapeadores.util.text.lexie.LexieDistribution;
import net.mapeadores.util.text.lexie.Occurrence;
import net.mapeadores.util.text.lexie.ParsedLexieSource;
import net.mapeadores.util.text.lexie.TextLexieUnit;
import net.mapeadores.util.xml.AppendableXMLWriter;
import net.mapeadores.util.xml.XMLPart;
import net.mapeadores.util.xml.XMLUtils;
import net.mapeadores.util.xml.XMLWriter;


/**
 *
 * @author Vincent Calame
 */
public class LexieDistributionXMLPart extends XMLPart {

    public LexieDistributionXMLPart(XMLWriter xmlWriter) {
        super(xmlWriter);
    }

    public void appendLexieDistribution(LexieDistribution lexieDistribution) throws IOException {
        openTag("lexie-distribution");
        openTag("lexies");
        int lexieCount = lexieDistribution.getLexieUnitCount();
        for (int i = 0; i < lexieCount; i++) {
            appendLexieUnit(lexieDistribution.getLexieUnit(i));
        }
        closeTag("lexies");
        openTag("sources");
        int count = lexieDistribution.getParserLexieSourceCount();
        for (int i = 0; i < count; i++) {
            appendParsedLexieSource(lexieDistribution.getParsedLexieSourceByIndex(i));
        }
        closeTag("sources");
        closeTag("lexie-distribution");
    }

    public void appendLexieUnit(TextLexieUnit lexieUnit) throws IOException {
        startOpenTag("lexie");
        addAttribute("lexie-id", lexieUnit.getLexieId());
        addAttribute("value", lexieUnit.getCanonicalLexie());
        endOpenTag();
        int occurrenceCount = lexieUnit.getOccurrenceCount();
        for (int i = 0; i < occurrenceCount; i++) {
            Occurrence occurrence = lexieUnit.getOccurrence(i);
            ParsedLexieSource parsedLexieSource = occurrence.getParsedLexieSource();
            startOpenTag("occurrence");
            addAttribute("source-id", parsedLexieSource.getLexieSource().getSourceId());
            addAttribute("position", String.valueOf(occurrence.getOccurrencePosition()));
            closeEmptyTag();
        }
        closeTag("lexie");
    }

    public void appendParsedLexieSource(ParsedLexieSource parsedLexieSource) throws IOException {
        startOpenTag("source");
        addAttribute("source-id", parsedLexieSource.getLexieSource().getSourceId());
        endOpenTag();
        openTag("text");
        appendText(parsedLexieSource);
        closeTag("text", false);
        closeTag("source");
    }

    private void appendText(ParsedLexieSource parsedLexieSource) throws IOException {
        String text = parsedLexieSource.getLexieSource().getSourceText();
        int size = parsedLexieSource.getOccurrenceCount();
        if (size == 0) {
            addText(text);
            return;
        }
        Occurrence currentOccurrence = parsedLexieSource.getOccurrence(0);
        int currentOccurrenceIndex = 0;
        SubstringPosition substringPosition = currentOccurrence.getSubstringPosition();
        int startLexieIndex = substringPosition.getBeginIndex();
        int endLexieIndex = substringPosition.getEndIndex();
        if (startLexieIndex > 0) {
            addText(text.substring(0, startLexieIndex));
        }
        while (true) {
            startOpenTag("lx", false);
            addAttribute("lexie-id", currentOccurrence.getLexieUnit().getLexieId());
            addAttribute("position", String.valueOf(currentOccurrence.getOccurrencePosition()));
            endOpenTag();
            addText(text.substring(startLexieIndex, endLexieIndex + 1));
            closeTag("lx", false);
            currentOccurrenceIndex++;
            if (currentOccurrenceIndex < size) {
                currentOccurrence = parsedLexieSource.getOccurrence(currentOccurrenceIndex);
                substringPosition = currentOccurrence.getSubstringPosition();
                startLexieIndex = substringPosition.getBeginIndex();
                if (startLexieIndex > (endLexieIndex + 1)) {
                    addText(text.substring(endLexieIndex + 1, startLexieIndex));
                }
                endLexieIndex = substringPosition.getEndIndex();
            } else {
                break;
            }
        }
        if (endLexieIndex < (text.length() - 1)) {
            addText(text.substring(endLexieIndex + 1));
        }
    }

    public static String toString(LexieDistribution lexieDistribution, boolean prettyXml, boolean omitXmlDeclaration) {
        StringBuilder buf = new StringBuilder(512);
        AppendableXMLWriter xmlWriter = XMLUtils.toXMLWriter(buf, (prettyXml) ? 0 : -999);
        LexieDistributionXMLPart lexieDistributionXMLPart = new LexieDistributionXMLPart(xmlWriter);
        try {
            if (!omitXmlDeclaration) {
                xmlWriter.appendXMLDeclaration();
            }
            lexieDistributionXMLPart.appendLexieDistribution(lexieDistribution);
        } catch (IOException ioe) {
        }
        return buf.toString();
    }

}
