/* UtilLib - Copyright (c) 2011-2020 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.format;

import java.util.List;


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

    private FormatUtils() {
    }

    public static boolean getBoolean(FormatDef formatDef, String key) {
        return toBoolean(formatDef.getParameterValue(key));
    }

    public static boolean getBoolean(FormatDef formatDef, String key, boolean defaultValue) {
        return toBoolean(formatDef.getParameterValue(key), defaultValue);
    }

    public static boolean toBoolean(Object value) {
        return toBoolean(value, false);
    }

    public static boolean toBoolean(Object value, boolean defaultValue) {
        if (value == null) {
            return defaultValue;
        }
        try {
            return ((Boolean) value);
        } catch (ClassCastException cce) {
            return defaultValue;
        }
    }

    public static Calcul getCalcul(FormatDef formatDef, String key) {
        return toCalcul(formatDef.getParameterValue(key));
    }

    public static Calcul toCalcul(Object value) {
        if (value == null) {
            return null;
        }
        try {
            return (Calcul) value;
        } catch (ClassCastException cce) {
            return null;
        }
    }

    public static int getInt(FormatDef formatDef, String key) {
        return toInt(formatDef.getParameterValue(key));
    }

    public static int toInt(Object value) {
        if (value == null) {
            return -1;
        }
        try {
            int itg = (Integer) value;
            if (itg < 0) {
                return -1;
            }
            return itg;
        } catch (ClassCastException cce) {
            return -1;
        }
    }

    public static String getString(FormatDef formatDef, String key) {
        return toString(formatDef.getParameterValue(key));
    }

    public static String toString(Object value) {
        if (value == null) {
            return null;
        }
        return value.toString();
    }

    public static char getChar(FormatDef formatDef, String key) {
        return toChar(formatDef.getParameterValue(key));
    }

    public static char toChar(Object value) {
        if (value == null) {
            return ' ';
        }
        try {
            return ((Character) value);
        } catch (ClassCastException cce) {
            return ' ';
        }
    }

    public short getCastType(FormatDef formatDef) {
        if (FormatUtils.getBoolean(formatDef, FormatConstants.JSONARRAY_PARAMKEY)) {
            return FormatConstants.JSON_CAST;
        } else {
            Short castType = (Short) formatDef.getParameterValue(FormatConstants.CAST_PARAMKEY);
            if (castType == null) {
                return FormatConstants.NO_CAST;
            } else {
                return castType;
            }
        }
    }

    public static String getPrefix(FormatDef formatDef) {
        if (FormatUtils.getBoolean(formatDef, FormatConstants.JSONARRAY_PARAMKEY)) {
            return "[";
        } else {
            return getString(formatDef, FormatConstants.PREFIX_PARAMKEY);
        }
    }

    public static String getSuffix(FormatDef formatDef) {
        if (FormatUtils.getBoolean(formatDef, FormatConstants.JSONARRAY_PARAMKEY)) {
            return "]";
        } else {
            return getString(formatDef, FormatConstants.SUFFIX_PARAMKEY);
        }
    }

    public static String getInnerSeparator(FormatDef formatDef, int sourceIndex, String defaultSeparator) {
        String forced = forceSeparator(formatDef);
        if (forced != null) {
            return forced;
        }
        FormatDef.InnerSeparator sep = getInnerSeparatorObject(formatDef, sourceIndex);
        if (sep != null) {
            return sep.getSeparator();
        }
        Object value = formatDef.getParameterValue(FormatConstants.SEPARATOR_PARAMKEY);
        if (value != null) {
            return (String) value;
        }
        return defaultSeparator;
    }

    public static String getSourceSeparator(FormatDef formatDef, int sourceIndex1, int sourceIndex2, String defaultSeparator) {
        String forced = forceSeparator(formatDef);
        if (forced != null) {
            return forced;
        }
        FormatDef.SourceSeparator sep = getSourceSeparatorObject(formatDef, sourceIndex1, sourceIndex2);
        if (sep != null) {
            return sep.getSeparator();
        }
        Object value = formatDef.getParameterValue(FormatConstants.SEPARATOR_PARAMKEY);
        if (value != null) {
            return (String) value;
        }
        return defaultSeparator;
    }

    private static String forceSeparator(FormatDef formatDef) {
        if (FormatUtils.getBoolean(formatDef, FormatConstants.JSONARRAY_PARAMKEY)) {
            return ",";
        } else if (formatDef.getParameterValue(FormatConstants.SUM_PARAMKEY) != null) {
            return ";";
        } else {
            return null;
        }
    }

    private static FormatDef.InnerSeparator getInnerSeparatorObject(FormatDef formatDef, int sourceIndex) {
        List<FormatDef.InnerSeparator> innerSeparatorList = formatDef.getInnerSeparatorList();
        if (innerSeparatorList.isEmpty()) {
            return null;
        }
        for (FormatDef.InnerSeparator innerSeparator : innerSeparatorList) {
            if (innerSeparator.getSourceIndex() == sourceIndex) {
                return innerSeparator;
            }
        }
        return null;
    }


    private static FormatDef.SourceSeparator getSourceSeparatorObject(FormatDef formatDef, int sourceIndex1, int sourceIndex2) {
        List<FormatDef.SourceSeparator> sourceSeparatorList = formatDef.getSourceSeparatorList();
        if (sourceSeparatorList.isEmpty()) {
            return null;
        }
        if (sourceIndex1 > sourceIndex2) {
            int tmp = sourceIndex1;
            sourceIndex1 = sourceIndex2;
            sourceIndex2 = tmp;
        }
        FormatDef.SourceSeparator nearestSourceSeparator = null;
        for (FormatDef.SourceSeparator sourceSeparator : sourceSeparatorList) {
            if (sourceSeparator.getSourceIndex1() == sourceIndex1) {
                int si2 = sourceSeparator.getSourceIndex2();
                if (si2 == sourceIndex2) {
                    return sourceSeparator;
                } else if (si2 > sourceIndex2) {
                    continue;
                } else {
                    if ((nearestSourceSeparator == null) || (nearestSourceSeparator.getSourceIndex2() < si2)) {
                        nearestSourceSeparator = sourceSeparator;
                    }
                }
            }
        }
        if (nearestSourceSeparator != null) {
            return nearestSourceSeparator;
        }
        return null;
    }

    public static short castTypeToShort(String s) {
        switch (s) {
            case FormatConstants.INTEGER_PARAMVALUE:
            case "int":
                return FormatConstants.INTEGER_CAST;
            case FormatConstants.DECIMAL_PARAMVALUE:
            case "double":
            case "float":
                return FormatConstants.DECIMAL_CAST;
            case FormatConstants.DATE_PARAMVALUE:
                return FormatConstants.DATE_CAST;
            case FormatConstants.MONEY_PARAMVALUE:
                return FormatConstants.MONEY_CAST;
            case FormatConstants.PERCENTAGE_PARAMVALUE:
                return FormatConstants.PERCENTAGE_CAST;
            case FormatConstants.JSON_PARAMVALUE:
                return FormatConstants.JSON_CAST;
            default:
                throw new IllegalArgumentException("Unknown cast type : " + s);
        }
    }

    public static String castTypeToString(short castType) {
        switch (castType) {
            case FormatConstants.INTEGER_CAST:
                return FormatConstants.INTEGER_PARAMVALUE;
            case FormatConstants.DECIMAL_CAST:
                return FormatConstants.DECIMAL_PARAMVALUE;
            case FormatConstants.DATE_CAST:
                return FormatConstants.DATE_PARAMVALUE;
            case FormatConstants.MONEY_CAST:
                return FormatConstants.MONEY_PARAMVALUE;
            case FormatConstants.PERCENTAGE_CAST:
                return FormatConstants.PERCENTAGE_PARAMVALUE;
            case FormatConstants.JSON_CAST:
                return FormatConstants.JSON_PARAMVALUE;
            default:
                throw new IllegalArgumentException("Unknown cast type : " + castType);
        }
    }

}
