/* UtilLib - Copyright (c) 2018-2019 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.money;

import java.text.ParseException;
import java.util.AbstractList;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.Set;
import net.mapeadores.util.text.StringUtils;


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

    public final static Currencies EMPTY_CURRENCIES = new EmptyCurrencies();

    private CurrenciesUtils() {

    }

    public static Currencies toCleanCurrencies(String s) {
        ExtendedCurrency[] array = toCleanCurrencyArray(s);
        return new ArrayCurrencies(array);
    }

    public static ExtendedCurrency[] toCleanCurrencyArray(String s) {
        String[] tokens = StringUtils.getTechnicalTokens(s, true);
        Set<ExtendedCurrency> currencySet = new LinkedHashSet<ExtendedCurrency>();
        for (String token : tokens) {
            try {
                ExtendedCurrency lang = ExtendedCurrency.parse(token);
                currencySet.add(lang);
            } catch (ParseException mce) {
            }
        }
        return currencySet.toArray(new ExtendedCurrency[currencySet.size()]);
    }

    public static boolean areEquals(Currencies currencies, Collection<ExtendedCurrency> collection) {
        int length = collection.size();
        if (length != currencies.size()) {
            return false;
        }
        if (length == 0) {
            return true;
        }
        int p = 0;
        for (ExtendedCurrency currency : collection) {
            if (!currency.equals(currencies.get(p))) {
                return false;
            }
            p++;
        }
        return true;
    }

    public static Currencies fromCollection(Collection<ExtendedCurrency> collection) {
        ExtendedCurrency[] array = collection.toArray(new ExtendedCurrency[collection.size()]);
        return new ArrayCurrencies(array);
    }

    public static Currencies wrap(ExtendedCurrency... currencies) {
        if ((currencies == null) || (currencies.length == 0)) {
            return EMPTY_CURRENCIES;
        }
        return new ArrayCurrencies(currencies);
    }


    private static class EmptyCurrencies extends AbstractList<ExtendedCurrency> implements Currencies {

        private EmptyCurrencies() {
        }

        @Override
        public int size() {
            return 0;
        }

        @Override
        public ExtendedCurrency get(int i) {
            throw new IndexOutOfBoundsException("currencyCount = 0");
        }

    }


    private static class SingletonCurrencies extends AbstractList<ExtendedCurrency> implements Currencies {

        private final ExtendedCurrency currency;

        private SingletonCurrencies(ExtendedCurrency currency) {
            this.currency = currency;
        }

        @Override
        public int size() {
            return 1;
        }

        @Override
        public ExtendedCurrency get(int i) {
            if (i != 0) {
                throw new IndexOutOfBoundsException("currencyCount = 1");
            }
            return currency;
        }

    }


    private static class ArrayCurrencies extends AbstractList<ExtendedCurrency> implements Currencies {

        private final ExtendedCurrency[] array;

        private ArrayCurrencies(ExtendedCurrency[] array) {
            this.array = array;
        }

        @Override
        public int size() {
            return array.length;
        }

        @Override
        public ExtendedCurrency get(int i) {
            return array[i];
        }

    }

}
