/* FichothequeLib_Tools  - Copyright (c) 2008-2018 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.format.formatters;

import java.text.ParseException;
import java.util.LinkedHashSet;
import java.util.Locale;
import java.util.Set;
import net.fichotheque.format.FormatSource;
import net.mapeadores.util.instruction.Argument;
import net.mapeadores.util.instruction.Instruction;
import net.mapeadores.util.localisation.Lang;
import net.mapeadores.util.localisation.LangContext;
import net.mapeadores.util.localisation.ListLangContext;
import net.mapeadores.util.localisation.ListLangContextBuilder;
import net.mapeadores.util.localisation.UserLangContext;
import net.mapeadores.util.text.StringUtils;


/**
 *
 * @author Vincent Calame
 */
public class LangParameters {

    private final ListLangContext customLangContext;
    private final String separator;

    private LangParameters(ListLangContext customLangContext, String separator) {
        this.customLangContext = customLangContext;
        this.separator = separator;
    }

    public ListLangContext getCustomLangContext() {
        return customLangContext;
    }

    public String getSeparator() {
        if (separator == null) {
            return ", ";
        }
        return separator;
    }

    public static LangParameters fromInstruction(Instruction instruction, String langKey) {
        ListLangContext customLangContext = null;
        Lang[] langArray = toLangArray(instruction, langKey);
        if (langArray != null) {
            customLangContext = ListLangContextBuilder.build(langArray);
        }
        String separator = null;
        for (Argument argument : instruction) {
            String key = argument.getKey();
            if (key.equals("sep")) {
                separator = argument.getValue();
            }
        }
        return new LangParameters(customLangContext, separator);
    }

    private static Lang[] toLangArray(Instruction instruction, String langKey) {
        Set<Lang> set = new LinkedHashSet<Lang>();
        for (Argument argument : instruction) {
            if (argument.getKey().equals(langKey)) {
                String value = argument.getValue();
                if (value != null) {
                    String[] tokens = StringUtils.getTechnicalTokens(value, true);
                    for (String token : tokens) {
                        addLang(set, token);
                    }
                }
            }
        }
        int size = set.size();
        if (size > 0) {
            return set.toArray(new Lang[size]);
        } else {
            return null;
        }
    }

    private static void addLang(Set<Lang> set, String value) {
        if ((value == null) || (value.length() == 0)) {
            return;
        }
        try {
            Lang lang = Lang.parse(value);
            set.add(lang);
        } catch (ParseException pe) {
        }
    }

    public static Locale[] checkLocaleArray(LangParameters langParameters, FormatSource formatSource) {
        Locale[] result;
        LangContext langContext = langParameters.getCustomLangContext();
        if (langContext == null) {
            langContext = formatSource.getLangContext();
        }
        if (langContext instanceof ListLangContext) {
            ListLangContext listLangContext = (ListLangContext) langContext;
            int langSize = listLangContext.size();
            result = new Locale[langSize];
            for (int i = 0; i < langSize; i++) {
                result[i] = listLangContext.get(i).getFormatLocale();
            }
        } else if (langContext instanceof UserLangContext) {
            result = new Locale[1];
            UserLangContext userLangContext = (UserLangContext) langContext;
            result[0] = userLangContext.getFormatLocale();
        } else {
            result = new Locale[0];
        }
        return result;
    }

    public static Lang[] checkLangArray(LangParameters langParameters, FormatSource formatSource) {
        LangContext langContext = langParameters.getCustomLangContext();
        if (langContext == null) {
            langContext = formatSource.getLangContext();
        }
        Lang[] result;
        if (langContext instanceof ListLangContext) {
            ListLangContext listLangContext = (ListLangContext) langContext;
            int langSize = listLangContext.size();
            result = new Lang[langSize];
            for (int i = 0; i < langSize; i++) {
                result[i] = listLangContext.get(i).getLang();
            }
        } else if (langContext instanceof UserLangContext) {
            result = new Lang[1];
            UserLangContext userLangContext = (UserLangContext) langContext;
            result[0] = userLangContext.getWorkingLang();
        } else {
            result = new Lang[0];
        }
        return result;
    }

}
