/* FichothequeLib_Tools - Copyright (c) 2012-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.fichotheque.tools.exportation.table;

import java.util.Collection;
import java.util.List;
import net.fichotheque.Fichotheque;
import net.fichotheque.Subset;
import net.fichotheque.SubsetItem;
import net.fichotheque.croisement.Croisements;
import net.fichotheque.exportation.table.Cell;
import net.fichotheque.exportation.table.CellConverter;
import net.fichotheque.exportation.table.ColDef;
import net.fichotheque.exportation.table.CroisementTable;
import net.fichotheque.exportation.table.CroisementTableWriter;
import net.fichotheque.exportation.table.SubsetTable;
import net.fichotheque.exportation.table.SumResult;
import net.mapeadores.util.money.Amount;
import net.mapeadores.util.table.TableWriter;


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

    private TableExportEngine() {
    }

    public static void exportSubset(SubsetTable subsetTable, TableWriter tableWriter, CellConverter cellConverter, Collection<SubsetItem> subsetItems) {
        if (subsetItems == null) {
            subsetItems = subsetTable.getSubset().getSubsetItemList();
        }
        for (SubsetItem subsetItem : subsetItems) {
            Cell[] cellArray = cellConverter.toCellArray(subsetItem);
            if (cellArray != null) {
                tableWriter.startRow();
                for (Cell cell : cellArray) {
                    cell.write(tableWriter);
                }
                tableWriter.endRow();
            }
        }
    }

    public static void exportCroisement(CroisementTable croisementTable, CroisementTableWriter croisementTableWriter) {
        Subset subset = croisementTable.getSubset1();
        Subset otherSubset = croisementTable.getSubset2();
        Fichotheque fichotheque = subset.getFichotheque();
        for (SubsetItem subsetItem : subset.getSubsetItemList()) {
            Croisements croisements = fichotheque.getCroisements(subsetItem, otherSubset);
            for (Croisements.Entry entry : croisements.getEntryList()) {
                SubsetItem otherItem = entry.getSubsetItem();
                croisementTableWriter.startRow();
                croisementTableWriter.addIntegerCell(subsetItem.getId());
                croisementTableWriter.addIntegerCell(otherItem.getId());
                croisementTableWriter.endRow();
            }
        }
    }

    public static int writeSumRows(TableWriter tableWriter, SumResult sumResult, int startRowNumber, NamedRangeHandler namedRangeHandler) {
        if (!sumResult.hasColumnSum()) {
            return 0;
        }
        int rowCount = 0;
        List<SumResult.Entry> entryList = sumResult.getEntryList();
        int colCount = entryList.size();
        short[] castTypeArray = new short[colCount];
        SumResult.ColumnSum[] columnSumArray = new SumResult.ColumnSum[colCount];
        tableWriter.startRow();
        rowCount++;
        for (int i = 0; i < colCount; i++) {
            SumResult.Entry entry = entryList.get(i);
            ColDef colDef = entry.getColDef();
            short castType = colDef.getCastType();
            tableWriter.addNullCell(castType);
            castTypeArray[i] = castType;
            columnSumArray[i] = entry.getColumnSum();
        }
        tableWriter.endRow();
        startRowNumber++;
        int moneyMaxCount = 0;
        tableWriter.startRow();
        rowCount++;
        for (int i = 0; i < colCount; i++) {
            SumResult.Entry entry = entryList.get(i);
            ColDef colDef = entry.getColDef();
            SumResult.ColumnSum columnSum = entry.getColumnSum();
            short castType = castTypeArray[i];
            if (columnSum == null) {
                tableWriter.addNullCell(castType);
            } else {
                if (columnSum instanceof SumResult.IntegerColumnSum) {
                    tableWriter.addIntegerCell(((SumResult.IntegerColumnSum) columnSum).getResult());
                    namedRangeHandler.addColumnSum(startRowNumber, i, colDef);
                } else if (columnSum instanceof SumResult.DecimalColumnSum) {
                    tableWriter.addDecimalCell(((SumResult.DecimalColumnSum) columnSum).getResult());
                    namedRangeHandler.addColumnSum(startRowNumber, i, colDef);
                } else if (columnSum instanceof SumResult.PercentageColumnSum) {
                    tableWriter.addPercentageCell(((SumResult.PercentageColumnSum) columnSum).getResult());
                    namedRangeHandler.addColumnSum(startRowNumber, i, colDef);
                } else if (columnSum instanceof SumResult.MoneyColumnSum) {
                    SumResult.MoneyColumnSum moneyColumnSum = (SumResult.MoneyColumnSum) columnSum;
                    int count = moneyColumnSum.getResultCount();
                    moneyMaxCount = Math.max(count, moneyMaxCount);
                    Amount amount = moneyColumnSum.getResult(0);
                    tableWriter.addMoneyCell(amount);
                    if (count == 1) {
                        namedRangeHandler.addColumnSum(startRowNumber, i, colDef);
                    }
                } else {
                    tableWriter.addNullCell(castType);
                }
            }
        }
        tableWriter.endRow();
        if (moneyMaxCount > 1) {
            tableWriter.startRow();
            rowCount++;
            for (int j = 1; j < moneyMaxCount; j++) {
                for (int i = 0; i < colCount; i++) {
                    SumResult.ColumnSum columnSum = columnSumArray[i];
                    short castType = castTypeArray[i];
                    if ((columnSum != null) && (columnSum instanceof SumResult.MoneyColumnSum)) {
                        SumResult.MoneyColumnSum moneyColumnSum = (SumResult.MoneyColumnSum) columnSum;
                        int count = moneyColumnSum.getResultCount();
                        if (j < count) {
                            Amount result = moneyColumnSum.getResult(j);
                            tableWriter.addMoneyCell(result);
                        } else {
                            tableWriter.addMoneyCell(null);
                        }
                    } else {
                        tableWriter.addNullCell(castType);
                    }
                }
            }
            tableWriter.endRow();
        }
        return rowCount;
    }

}
