/* BdfServer - Copyright (c) 2021-2022 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 fr.exemole.bdfserver.tools.exportation.transformation.compilers;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.List;


/**
 *
 * @author Vincent Calame
 */
class PropertiesOdParser {

    private final String content;
    private final List<Object> partList = new ArrayList<Object>();
    private int currentStart = 0;


    PropertiesOdParser(String content) {
        this.content = content;
    }

    private boolean next() {
        int inputTagStartIndex = content.indexOf("<text:text-input", currentStart);
        if (inputTagStartIndex == -1) {
            partList.add(content.substring(currentStart));
            return false;
        }
        String precedingText = content.substring(currentStart, inputTagStartIndex);
        int inputContentStartIndex = content.indexOf(">", inputTagStartIndex) + 1;
        if (content.charAt(inputContentStartIndex - 2) == '/') {
            add(precedingText);
            currentStart = inputContentStartIndex;
            return true;
        }
        int inputContentEndIndex = content.indexOf("</text:text-input>", inputContentStartIndex);
        int newStart = inputContentEndIndex + "</text:text-input>".length();
        PropertyPart propertyPart = PropertyPart.parse(content.substring(inputContentStartIndex, inputContentEndIndex));
        if (replaceParagraph(propertyPart)) {
            int[] newIndices = getNewIndices(precedingText, inputContentEndIndex);
            if (newIndices != null) {
                precedingText = precedingText.substring(0, newIndices[0]);
                newStart = newIndices[1];
            } else {
                precedingText = precedingText + " #ERROR(" + propertyPart.getName() + ")#";
                propertyPart = null;
            }
        }
        add(precedingText);
        add(propertyPart);
        currentStart = newStart;
        return true;
    }

    private void add(String rawText) {
        if (!rawText.isEmpty()) {
            int index = rawText.indexOf("</office:automatic-styles>");
            if (index != -1) {
                partList.add(rawText.substring(0, index));
                partList.add(new InsertPart("automatic-styles"));
                partList.add(rawText.substring(index));
            } else {
                partList.add(rawText);
            }
        }
    }

    private void add(PropertyPart propertyPart) {
        if (propertyPart != null) {
            partList.add(propertyPart);
        }
    }

    private int[] getNewIndices(String precedingText, int followingIndex) {
        int lastParagraphIndex = precedingText.lastIndexOf("<text:p");
        if (lastParagraphIndex == -1) {
            return null;
        }
        char nextChar = precedingText.charAt(lastParagraphIndex + "<text:p".length());
        if ((nextChar != '>') && (!Character.isWhitespace(nextChar))) {
            return null;
        }
        if (precedingText.indexOf("</text:p>", lastParagraphIndex) != -1) {
            return null;
        }
        int end = content.indexOf("</text:p>", followingIndex);
        if (end == - 1) {
            return null;
        }
        end = end + "</text:p>".length();
        int[] result = new int[2];
        result[0] = lastParagraphIndex;
        result[1] = end;
        return result;
    }

    static List<Object> parse(String content) throws ParseException {
        PropertiesOdParser parser = new PropertiesOdParser(content);
        while (true) {
            if (!parser.next()) {
                break;
            }
        }
        return parser.partList;
    }

    private static boolean replaceParagraph(PropertyPart propertyPart) {
        switch (propertyPart.getMode()) {
            case "fragment":
                return true;
            default:
                return false;
        }
    }

}
