/* UtilLib - Copyright (c) 2010-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.util.table;

import java.time.LocalDate;
import net.mapeadores.util.date.FuzzyDate;
import net.mapeadores.util.format.FormatConstants;
import net.mapeadores.util.money.Amount;
import net.mapeadores.util.primitives.Decimal;


/**
 *
 * @author Vincent Calame
 */
public interface TableWriter {


    /**
     * Commence une nouvelle ligne et retourne son numéro. Les lignes sont
     * numérotées à partir de 1.
     *
     * @return le numéro de la nouvelle ligne
     */
    public int startRow();

    /**
     * Ajoute une cellule avec une valeur entière. Retourne le numéro de la
     * cellule, les cellules étant numérotées à partir de 1.
     *
     * @param lg valeur entière de la cellule
     * @return le numéro de colonne de la cellule
     */
    public int addIntegerCell(Long lg);

    /**
     * joute une cellule avec une valeur décimale. Retourne le numéro de la
     * cellule, les cellules étant numérotées à partir de 1.
     *
     * @param decimal valeur décimale de la cellule
     * @return le numéro de colonne de la cellule
     */
    public int addDecimalCell(Decimal decimal);

    /**
     * Ajoute une cellule avec une chaine de caractères. Retourne le numéro de
     * la cellule, les cellules étant numérotées à partir de 1.
     *
     * @param s valeur de la cellule
     * @return le numéro de colonne de la cellule
     */
    public int addStringCell(String s);

    /**
     * Ajoute une cellule avec date. Retourne le numéro de la cellule, les
     * cellules étant numérotées à partir de 1.
     *
     * @param date date approximative
     * @return le numéro de colonne de la cellule
     */
    public int addDateCell(FuzzyDate date);

    public default int addDateCell(LocalDate localDate) {
        if (localDate == null) {
            return addDateCell((FuzzyDate) null);
        } else {
            return addDateCell(FuzzyDate.fromLocalDate(localDate));
        }
    }

    /**
     * Ajoute une cellule avec un montant monétaire.
     *
     * @param amount montant à rajouter
     * @return le numéro de colonne de la cellule
     */
    public int addMoneyCell(Amount amount);

    /**
     * Ajoute une cellule avec un pourcentage. Retourne le numéro de la cellule,
     * les cellules étant numérotées à partir de 1.
     * <p>
     * La valeur du pourcentage est le nombre correspondant à la division par
     * 100 (12,4% est exprimé sous la forme 0,124)
     *
     * @param decimal valeur du pourcentage
     * @return le numéro de colonne de la cellule
     */
    public int addPercentageCell(Decimal decimal);

    /**
     * Termine la ligne en cours et retourne son numéro. Les lignes sont
     * numérotées à partir de 1.
     *
     * @return le numéro de la ligne terminée
     */
    public int endRow();

    public default int addIntegerCell(int integer) {
        return addIntegerCell(Long.valueOf(integer));
    }

    public default int addNullCell(String castType) {
        switch (castType) {
            case FormatConstants.INTEGER_CAST:
                return addIntegerCell(null);
            case FormatConstants.DECIMAL_CAST:
                return addDecimalCell(null);
            case FormatConstants.DATE_CAST:
                return addDateCell((FuzzyDate) null);
            case FormatConstants.MONEY_CAST:
                return addMoneyCell(null);
            case FormatConstants.PERCENTAGE_CAST:
                return addPercentageCell(null);
            default:
                return addStringCell(null);
        }
    }

    public default int addCell(String castType, Object obj) {
        if (obj == null) {
            return addNullCell(castType);
        } else {
            switch (castType) {
                case FormatConstants.INTEGER_CAST:
                    return addIntegerCell((Long) obj);
                case FormatConstants.DECIMAL_CAST:
                    return addDecimalCell((Decimal) obj);
                case FormatConstants.DATE_CAST:
                    return addDateCell((FuzzyDate) obj);
                case FormatConstants.MONEY_CAST:
                    return addMoneyCell((Amount) obj);
                case FormatConstants.PERCENTAGE_CAST:
                    return addPercentageCell((Decimal) obj);
                default:
                    return addStringCell((String) obj);
            }
        }
    }

}
