/* OdLib_Io - Copyright (c) 2020-2025 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.opendocument.io.odtable;

import java.io.IOException;
import java.time.LocalDate;
import java.util.List;
import net.mapeadores.opendocument.elements.OdLog;
import net.mapeadores.opendocument.io.OdXML;
import net.mapeadores.util.money.Amount;
import net.mapeadores.util.date.FuzzyDate;
import net.mapeadores.util.xml.XMLPart;
import net.mapeadores.util.xml.XMLWriter;


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

    private final StyleManager styleManager;

    public OdsXMLPart(XMLWriter xmlWriter, StyleManager styleManager) {
        super(xmlWriter);
        this.styleManager = styleManager;
    }

    public StyleManager getStyleManager() {
        return styleManager;
    }

    public OdsXMLPart rowStart() throws IOException {
        OdXML.openTableRow(this);
        return this;
    }

    public OdsXMLPart rowEnd() throws IOException {
        OdXML.closeTableRow(this);
        return this;
    }

    public OdsXMLPart currencyCell(Amount amount) throws IOException {
        OdXML.addCurrencyTableCell(this, amount, null, 1);
        return this;
    }

    public OdsXMLPart currencyCell(Amount amount, String cellStyleName) throws IOException {
        OdXML.addCurrencyTableCell(this, amount, cellStyleName, 1);
        return this;
    }

    public OdsXMLPart currencyCell(Amount amount, String cellStyleName, int colSpan) throws IOException {
        OdXML.addCurrencyTableCell(this, amount, cellStyleName, colSpan);
        return this;
    }

    public OdsXMLPart dateCell(FuzzyDate date) throws IOException {
        return dateCell(date, null, 1);
    }

    public OdsXMLPart dateCell(FuzzyDate date, String cellStyleName) throws IOException {
        return dateCell(date, cellStyleName, 1);
    }

    public OdsXMLPart dateCell(FuzzyDate date, String cellStyleName, int colSpan) throws IOException {
        OdXML.addDateTableCell(this, date.toISOString(), cellStyleName, colSpan);
        return this;
    }

    public OdsXMLPart dateCell(LocalDate date, String cellStyleName, int colSpan) throws IOException {
        OdXML.addDateTableCell(this, date.toString(), cellStyleName, colSpan);
        return this;
    }

    public OdsXMLPart emptyCell() throws IOException {
        OdXML.addEmptyTableCell(this);
        return this;
    }

    public OdsXMLPart emptyCells(int count) throws IOException {
        for (int i = 0; i < count; i++) {
            OdXML.addEmptyTableCell(this);
        }
        return this;
    }

    public OdsXMLPart numberCell(int value) throws IOException {
        OdXML.addNumberTableCell(this, String.valueOf(value), null, 1);
        return this;
    }

    public OdsXMLPart numberCell(String numberValue) throws IOException {
        OdXML.addNumberTableCell(this, numberValue, null, 1);
        return this;
    }

    public OdsXMLPart numberCell(String numberValue, String cellStyleName) throws IOException {
        OdXML.addNumberTableCell(this, numberValue, cellStyleName, 1);
        return this;
    }

    public OdsXMLPart numberCell(String numberValue, String cellStyleName, int colSpan) throws IOException {
        OdXML.addNumberTableCell(this, numberValue, cellStyleName, colSpan);
        return this;
    }

    public OdsXMLPart numberCell(String numberValue, String cellStyleName, int colSpan, String annotation) throws IOException {
        OdXML.addNumberTableCell(this, numberValue, cellStyleName, colSpan, annotation);
        return this;
    }

    public OdsXMLPart percentageCell(String numberValue) throws IOException {
        OdXML.addPercentageTableCell(this, numberValue, null, 1);
        return this;
    }

    public OdsXMLPart percentageCell(String numberValue, String cellStyleName) throws IOException {
        OdXML.addPercentageTableCell(this, numberValue, cellStyleName, 1);
        return this;
    }

    public OdsXMLPart percentageCell(String numberValue, String cellStyleName, int colSpan) throws IOException {
        OdXML.addPercentageTableCell(this, numberValue, cellStyleName, colSpan);
        return this;
    }

    public OdsXMLPart stringCell(String value) throws IOException {
        OdXML.addStringTableCell(this, value, null, 1);
        return this;
    }

    public OdsXMLPart stringCell(String value, String cellStyleName) throws IOException {
        OdXML.addStringTableCell(this, value, cellStyleName, 1);
        return this;
    }

    public OdsXMLPart stringCell(String value, String cellStyleName, int colSpan) throws IOException {
        OdXML.addStringTableCell(this, value, cellStyleName, colSpan);
        return this;
    }

    public OdsXMLPart stringCell(String value, String cellStyleName, int colSpan, String annotation) throws IOException {
        OdXML.addStringTableCell(this, value, cellStyleName, colSpan, annotation);
        return this;
    }

    public OdsXMLPart tableStart(String name) throws IOException {
        OdXML.openTable(this, name);
        List<OdColumn> list = styleManager.getOdColumnList(name);
        if (list != null) {
            for (OdColumn odColumn : list) {
                OdXML.addTableColumn(this, odColumn.getStyleName(), 1, odColumn.getDefaultCellStyle().getName());
            }
        }
        return this;
    }

    public OdsXMLPart tableEnd() throws IOException {
        OdXML.closeTable(this);
        return this;
    }

    public void insertErrorLogTable(OdLog odLog, String logTableName) throws IOException {
        if (odLog == null) {
            return;
        }
        if ((odLog.hasFatalError()) || (odLog.hasErrorOrWarning())) {
            tableStart(logTableName);
            OdLog.LogItem fatalErrorLogItem = odLog.getFatalErrorLogItem();
            if (fatalErrorLogItem != null) {
                this
                        .rowStart()
                        .stringCell("Fatal error")
                        .rowEnd()
                        .rowStart()
                        .stringCell(fatalErrorLogItem.getURI())
                        .stringCell(fatalErrorLogItem.getMessage())
                        .rowEnd()
                        .rowStart()
                        .emptyCell()
                        .rowEnd();
            }
            for (OdLog.LogItem logItem : odLog.getLogItemArray()) {
                this
                        .rowStart()
                        .stringCell(logItem.getURI())
                        .stringCell(logItem.getMessage())
                        .rowEnd();
            }
            tableEnd();
        }
    }

}
