/*
 *******************************************************************************
 * Copyright (C) 2003-2012, Google, International Business Machines Corporation and    *
 * others. All Rights Reserved.                                                *
 *******************************************************************************
*/
package com.ibm.icu.util;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;

/**
 * Provide information about gender in locales based on data in CLDR. Currently supplies gender of lists.
 * @author markdavis
 * @internal
 */
public class GenderInfo {

    private final ListGenderStyle style; // set based on locale

    /**
     * Gender: OTHER means either the information is unavailable, or the person has declined to state MALE or FEMALE. 
     * @internal
     */
    public enum Gender {MALE, FEMALE, OTHER}

    /**
     * Create GenderInfo from a ULocale.
     * @param uLocale desired locale
     * @internal
     */
    public static GenderInfo getInstance(ULocale uLocale) {
        // These can be cached, since they are read-only
        // poor-man's locale lookup, for hardcoded data
        while (true) {
            GenderInfo data = localeToListGender.get(uLocale);
            if (data != null) {
                return data;
            }
            uLocale = uLocale.getFallback();
            if (uLocale == null) {
                return neutral;
            }
        }
    }

    /**
     * Create GenderInfo from a Locale.
     * @param locale desired locale
     * @internal
     */
    public static GenderInfo getInstance(Locale locale) {
        return getInstance(ULocale.forLocale(locale));
    }

    /**
     * Enum only meant for use in CLDR and in testing. Indicates the category for the locale.
     * @internal
     */
    public enum ListGenderStyle {
        /**
         * Always OTHER (if more than one)
         */
        NEUTRAL, 
        /**
         * gender(all male) = male, gender(all female) = female, otherwise gender(list) = other
         */
        MIXED_NEUTRAL, 
        /**
         * gender(all female) = female, otherwise gender(list) = male
         */
        MALE_TAINTS
    }

    /**
     * Reset the data used for mapping locales to styles. Only for use in CLDR and in testing!
     * @param newULocaleToListGender replacement data, copied internally for safety.
     * @internal
     */
    public static void setLocaleMapping(Map<ULocale,GenderInfo> newULocaleToListGender) {
        localeToListGender.clear();
        for (Entry<ULocale, GenderInfo> entry : newULocaleToListGender.entrySet()) {
            localeToListGender.put(entry.getKey(), entry.getValue());
        }
    }

    /**
     * Get the gender of a list, based on locale usage.
     * @param genders a list of genders.
     * @return the gender of the list.
     * @internal
     */
    public Gender getListGender(Gender... genders) {
        return getListGender(Arrays.asList(genders));
    }

    /**
     * Get the gender of a list, based on locale usage.
     * @param genders a list of genders.
     * @return the gender of the list.
     * @internal
     */
    public Gender getListGender(List<Gender> genders) {
        if (genders.size() == 0 || style == ListGenderStyle.NEUTRAL) {
            return Gender.OTHER; // degenerate case
        }
        if (genders.size() == 1) {
            return genders.get(0); // degenerate case
        }
        switch(style) {
        case MIXED_NEUTRAL: // gender(all male) = male, gender(all female) = female, otherwise gender(list) = other
            boolean hasFemale = false;
            boolean hasMale = false;
            for (Gender gender : genders) {
                switch (gender) {
                case FEMALE:
                    if (hasMale) {
                        return Gender.OTHER;
                    }
                    hasFemale = true;
                    break;
                case MALE: 
                    if (hasFemale) {
                        return Gender.OTHER;
                    }
                    hasMale = true;
                    break;
                case OTHER:
                    return Gender.OTHER;
                }
            }
            return hasMale ? Gender.MALE : hasFemale ? Gender.FEMALE : Gender.OTHER;
        case MALE_TAINTS:  // gender(all female) = female, otherwise gender(list) = male
            for (Gender gender : genders) {
                if (gender != Gender.FEMALE) {
                    return Gender.MALE;
                }
            }
            return Gender.FEMALE;
        default:
            return Gender.OTHER; 
        }
    }
    
    /**
     * Only for testing and use with CLDR.
     * @param genderStyle gender style
     * @internal
     */
    public GenderInfo(ListGenderStyle genderStyle) {
        style = genderStyle;
    }
    
    private static GenderInfo neutral = new GenderInfo(ListGenderStyle.NEUTRAL);

    // TODO Get this data from a resource bundle generated from CLDR. 
    // For now, hard coded.

    private static Map<ULocale,GenderInfo> localeToListGender = new HashMap<ULocale,GenderInfo>();
    static {
        GenderInfo taints = new GenderInfo(ListGenderStyle.MALE_TAINTS);
        for (String locale : Arrays.asList("ar", "ca", "cs", "hr", "es", "fr", "he", "hi", "it", "lt", "lv", "mr", "nl", "pl", "pt", "ro", "ru", "sk", "sl", "sr", "uk", "ur", "zh")) {
            localeToListGender.put(new ULocale(locale), taints);
        }
        GenderInfo mixed = new GenderInfo(ListGenderStyle.MIXED_NEUTRAL);
        for (String locale : Arrays.asList("el", "is")) {
            localeToListGender.put(new ULocale(locale), mixed);
        }
    }
}
