/*
 *******************************************************************************
 * Copyright (C) 2009-2011, International Business Machines Corporation and    *
 * others. All Rights Reserved.                                                *
 *******************************************************************************
 */
package com.ibm.icu.text;

import java.lang.reflect.Field;
import java.util.Collections;
import java.util.Date;
import java.util.List;

import com.ibm.icu.util.Calendar;
import com.ibm.icu.util.GregorianCalendar;

/**
 * Provides information about currencies that is not specific to a locale.
 * @draft ICU 4.4
 * @provisional This API might change or be removed in a future release.
 */
public class CurrencyMetaInfo {
    private static final CurrencyMetaInfo impl;
    private static final boolean hasData;

    /**
     * Returns the unique instance of the currency meta info.
     * @return the meta info
     * @draft ICU 4.4
     * @provisional This API might change or be removed in a future release.
     */
    public static CurrencyMetaInfo getInstance() {
        return impl;
    }

    /**
     * Returns true if there is data for the currency meta info.
     * @return true if there is actual data
     * @draft ICU 4.4
     * @provisional This API might change or be removed in a future release.
     */
    public static boolean hasData() {
        return hasData;
    }

    /**
     * Subclass constructor.
     * @internal
     * @deprecated This API is ICU internal only.
     */
    protected CurrencyMetaInfo() {
    }

    /**
     * A filter used to select which currency info is returned.
     * @draft ICU 4.4
     * @provisional This API might change or be removed in a future release.
     */
    public static final class CurrencyFilter {
        /**
         * The region to filter on.  If null, accepts any region.
         * @draft ICU 4.4
         * @provisional This API might change or be removed in a future release.
         */
        public final String region;

        /**
         * The currency to filter on.  If null, accepts any currency.
         * @draft ICU 4.4
         * @provisional This API might change or be removed in a future release.
         */
        public final String currency;

        /**
         * The from date to filter on (milliseconds).  Accepts any currency on or after this date.
         * @draft ICU 4.4
         * @provisional This API might change or be removed in a future release.
         */
        public final long from;

        /**
         * The to date to filter on (milliseconds).  Accepts any currency on or before this date.
         * @draft ICU 4.4
         * @provisional This API might change or be removed in a future release.
         */
        public final long to;

        private CurrencyFilter(String region, String currency, long from, long to) {
            this.region = region;
            this.currency = currency;
            this.from = from;
            this.to = to;
        }

        private CurrencyFilter(String region, String currency, Date dateFrom, Date dateTo) {
            this.region = region;
            this.currency = currency;
            this.from = dateFrom == null ? Long.MIN_VALUE : dateFrom.getTime();
            this.to = dateTo == null ? Long.MAX_VALUE : dateTo.getTime();
        }

        private static final CurrencyFilter ALL = new CurrencyFilter(null, null, null, null);

        /**
         * Returns a filter that accepts all currency data.
         * @return a filter
         * @draft ICU 4.4
         * @provisional This API might change or be removed in a future release.
         */
        public static CurrencyFilter all() {
            return ALL;
        }

        /**
         * Returns a filter that accepts all currencies in use as of the current date.
         * @return a filter
         * @see #withDate(Date)
         * @draft ICU 4.4
         * @provisional This API might change or be removed in a future release.
         */
        public static CurrencyFilter now() {
            return ALL.withDate(new Date());
        }

        /**
         * Returns a filter that accepts all currencies ever used in the given region.
         * @param region the region code
         * @return a filter
         * @see #withRegion(String)
         * @draft ICU 4.4
         * @provisional This API might change or be removed in a future release.
         */
        public static CurrencyFilter onRegion(String region) {
            return ALL.withRegion(region);
        }

        /**
         * Returns a filter that accepts the given currency.
         * @param currency the currency code
         * @return a filter
         * @see #withCurrency(String)
         * @draft ICU 4.4
         * @provisional This API might change or be removed in a future release.
         */
        public static CurrencyFilter onCurrency(String currency) {
            return ALL.withCurrency(currency);
        }

        /**
         * Returns a filter that accepts all currencies in use on the given date.
         * @param date the date
         * @return a filter
         * @see #withDate(Date)
         * @draft ICU 4.4
         * @provisional This API might change or be removed in a future release.
         */
        public static CurrencyFilter onDate(Date date) {
            return ALL.withDate(date);
        }

        /**
         * Returns a filter that accepts all currencies that were in use at some point between
         * the given dates, or if dates are equal, currencies in use on that date.
         * @param from date on or after a currency must have been in use
         * @param to date before which a currency must have been in use, or if equal to from,
         * the date on which a currency must have been in use
         * @return a filter
         * @see #withRange(Date, Date)
         * @draft ICU 4.4
         * @provisional This API might change or be removed in a future release.
         */
        public static CurrencyFilter onRange(Date from, Date to) {
            return ALL.withRange(from, to);
        }

        /**
         * Returns a copy of this filter, with the specified region.  Region can be null to
         * indicate no filter on region.
         * @param region the region code
         * @return the filter
         * @see #onRegion(String)
         * @draft ICU 4.4
         * @provisional This API might change or be removed in a future release.
         */
        public CurrencyFilter withRegion(String region) {
            return new CurrencyFilter(region, this.currency, this.from, this.to);
        }

        /**
         * Returns a copy of this filter, with the specified currency.  Currency can be null to
         * indicate no filter on currency.
         * @param currency the currency code
         * @return the filter
         * @see #onCurrency(String)
         * @draft ICU 4.4
         * @provisional This API might change or be removed in a future release.
         */
        public CurrencyFilter withCurrency(String currency) {
            return new CurrencyFilter(this.region, currency, this.from, this.to);
        }

        /**
         * Returns a copy of this filter, with from and to set to the given date.
         * @param date the date on which the currency must have been in use
         * @return the filter
         * @see #onDate(Date)
         * @draft ICU 4.4
         * @provisional This API might change or be removed in a future release.
         */
        public CurrencyFilter withDate(Date date) {
            return new CurrencyFilter(this.region, this.currency, date, date);
        }

        /**
         * Returns a copy of this filter, with from and to set to the given dates.
         * @param from date on or after which the currency must have been in use
         * @param to date before which the currency must have been in use
         * @return the filter
         * @see #onRange(Date, Date)
         * @draft ICU 4.4
         * @provisional This API might change or be removed in a future release.
         */
        public CurrencyFilter withRange(Date from, Date to) {
            return new CurrencyFilter(this.region, this.currency, from, to);
        }

        /**
         * Overrides equals.
         * @draft ICU 4.4
         * @provisional This API might change or be removed in a future release.
         */
        @Override
        public boolean equals(Object rhs) {
            return rhs instanceof CurrencyFilter &&
                equals((CurrencyFilter) rhs);
        }

        /**
         * Type-safe override of {@link #equals(Object)}.
         * @param rhs the currency filter to compare to
         * @return true if the filters are equal
         * @draft ICU 4.4
         * @provisional This API might change or be removed in a future release.
         */
        public boolean equals(CurrencyFilter rhs) {
            return this == rhs || (rhs != null &&
                    equals(this.region, rhs.region) &&
                    equals(this.currency, rhs.currency) &&
                    this.from == rhs.from &&
                    this.to == rhs.to);
        }

        /**
         * Overrides hashCode.
         * @draft ICU 4.4
         * @provisional This API might change or be removed in a future release.
         */
        @Override
        public int hashCode() {
            int hc = 0;
            if (region != null) {
                hc = region.hashCode();
            }
            if (currency != null) {
                hc = hc * 31 + currency.hashCode();
            }
            hc = hc * 31 + (int) from;
            hc = hc * 31 + (int) (from >>> 32);
            hc = hc * 31 + (int) to;
            hc = hc * 31 + (int) (to >>> 32);
            return hc;
        }

        /**
         * Returns a string representing the filter, for debugging.
         * @draft ICU 4.4
         * @provisional This API might change or be removed in a future release.
         */
        @Override
        public String toString() {
            return debugString(this);
        }

        private static boolean equals(String lhs, String rhs) {
            return lhs == rhs || (lhs != null && lhs.equals(rhs));
        }
    }

    /**
     * Represents the raw information about fraction digits and rounding increment.
     * @draft ICU 4.4
     * @provisional This API might change or be removed in a future release.
     */
    public static final class CurrencyDigits {
        /**
         * Number of fraction digits used to display this currency.
         * @draft ICU 4.4
         * @provisional This API might change or be removed in a future release.
         */
        public final byte fractionDigits;
        /**
         * Rounding increment used when displaying this currency.
         * @draft ICU 4.4
         * @provisional This API might change or be removed in a future release.
         */
        public final byte roundingIncrement;

        /**
         * Constructor for CurrencyDigits.
         * @param fractionDigits the fraction digits
         * @param roundingIncrement the rounding increment
         * @draft ICU 4.4
         * @provisional This API might change or be removed in a future release.
         */
        public CurrencyDigits(int fractionDigits, int roundingIncrement) {
            this.fractionDigits = (byte) fractionDigits;
            this.roundingIncrement = (byte) roundingIncrement;
        }

        /**
         * Returns a string representing the currency digits, for debugging.
         * @draft ICU 4.4
         * @provisional This API might change or be removed in a future release.
         */
        @Override
        public String toString() {
            return debugString(this);
        }
    }

    /**
     * Represents a complete currency info record listing the region, currency, from and to dates,
     * and priority.
     * @draft ICU 4.4
     * @provisional This API might change or be removed in a future release.
     */
    public static final class CurrencyInfo {
        /**
         * Region code where currency is used.
         * @draft ICU 4.4
         * @provisional This API might change or be removed in a future release.
         */
        public final String region;

        /**
         * The three-letter ISO currency code.
         * @draft ICU 4.4
         * @provisional This API might change or be removed in a future release.
         */
        public final String code;

        /**
         * Date on which the currency was first officially used in the region.  If there is no
         * date, this is Long.MIN_VALUE;
         * @draft ICU 4.4
         * @provisional This API might change or be removed in a future release.
         */
        public final long from;

        /**
         * Date at which the currency stopped being officially used in the region.  If there is
         * no date, this is Long.MAX_VALUE;
         * @draft ICU 4.4
         * @provisional This API might change or be removed in a future release.
         */
        public final long to;

        /**
         * Preference order of currencies being used at the same time in the region.  Lower
         * values are preferred (generally, this is a transition from an older to a newer
         * currency).  Priorities within a single country are unique.
         * @draft ICU 4.4
         * @provisional This API might change or be removed in a future release.
         */
        public final short priority;

        /**
         * Constructs a currency info.
         * @param region region code
         * @param code currency code
         * @param from start date in milliseconds
         * @param to end date in milliseconds
         * @param priority priority value, 0 is highest priority, increasing values are lower
         * @draft ICU 4.4
         * @provisional This API might change or be removed in a future release.
         */
        public CurrencyInfo(String region, String code, long from, long to, int priority) {
            this.region = region;
            this.code = code;
            this.from = from;
            this.to = to;
            this.priority = (short) priority;
        }

        /**
         * Returns a string useful for debugging.
         * @draft ICU 4.4
         * @provisional This API might change or be removed in a future release.
         */
        @Override
        public String toString() {
            return debugString(this);
        }
    }

///CLOVER:OFF
    /**
     * Returns the list of CurrencyInfos matching the provided filter.  Results
     * are ordered by country code,  then by highest to lowest priority (0 is highest).
     * The returned list is unmodifiable.
     * @param filter the filter to control which currency info to return
     * @return the matching information
     * @draft ICU 4.4
     * @provisional This API might change or be removed in a future release.
     */
    public List<CurrencyInfo> currencyInfo(CurrencyFilter filter) {
        return Collections.emptyList();
    }

    /**
     * Returns the list of currency codes matching the provided filter.
     * Results are ordered as in {@link #currencyInfo(CurrencyFilter)}.
     * The returned list is unmodifiable.
     * @param filter the filter to control which currencies to return.  If filter is null,
     * returns all currencies for which information is available.
     * @return the matching currency codes
     * @draft ICU 4.4
     * @provisional This API might change or be removed in a future release.
     */
    public List<String> currencies(CurrencyFilter filter) {
        return Collections.emptyList();
   }

    /**
     * Returns the list of region codes matching the provided filter.
     * Results are ordered as in {@link #currencyInfo(CurrencyFilter)}.
     * The returned list is unmodifiable.
     * @param filter the filter to control which regions to return.  If filter is null,
     * returns all regions for which information is available.
     * @return the matching region codes
     * @draft ICU 4.4
     * @provisional This API might change or be removed in a future release.
     */
    public List<String> regions(CurrencyFilter filter) {
        return Collections.emptyList();
    }
///CLOVER:ON

    /**
     * Returns the CurrencyDigits for the currency code.
     * @param isoCode the currency code
     * @return the CurrencyDigits
     * @draft ICU 4.4
     * @provisional This API might change or be removed in a future release.
     */
    public CurrencyDigits currencyDigits(String isoCode) {
        return defaultDigits;
    }

    /**
     * @internal
     * @deprecated This API is ICU internal only.
     */
    protected static final CurrencyDigits defaultDigits = new CurrencyDigits(2, 0);

    static {
        CurrencyMetaInfo temp = null;
        boolean tempHasData = false;
        try {
            Class<?> clzz = Class.forName("com.ibm.icu.impl.ICUCurrencyMetaInfo");
            temp = (CurrencyMetaInfo) clzz.newInstance();
            tempHasData = true;
        } catch (Throwable t) {
            temp = new CurrencyMetaInfo();
        }
        impl = temp;
        hasData = tempHasData;
    }

    private static String dateString(long date) {
        if (date == Long.MAX_VALUE || date == Long.MIN_VALUE) {
            return null;
        }
        GregorianCalendar gc = new GregorianCalendar();
        gc.setTimeInMillis(date);
        return "" + gc.get(Calendar.YEAR) + '-' + (gc.get(Calendar.MONTH) + 1) + '-' +
                gc.get(Calendar.DAY_OF_MONTH);
    }

    private static String debugString(Object o) {
        StringBuilder sb = new StringBuilder();
        try {
            for (Field f : o.getClass().getFields()) {
                Object v = f.get(o);
                if (v != null) {
                    String s;
                    if (v instanceof Date) {
                        s = dateString(((Date)v).getTime());
                    } else if (v instanceof Long) {
                        s = dateString(((Long)v).longValue());
                    } else {
                        s = String.valueOf(v);
                    }
                    if (s == null) {
                        continue;
                    }
                    if (sb.length() > 0) {
                        sb.append(",");
                    }
                    sb.append(f.getName())
                        .append("='")
                        .append(s)
                        .append("'");
                }
            }
        } catch (Throwable t) {
        }
        sb.insert(0, o.getClass().getSimpleName() + "(");
        sb.append(")");
        return sb.toString();
    }
}
