/*
 * Copyright 2010 Google Inc.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.google.gwt.tools.cldr;

import org.unicode.cldr.util.CLDRFile;
import org.unicode.cldr.util.XPathParts;
import org.unicode.cldr.util.CLDRFile.DraftStatus;
import org.unicode.cldr.util.CLDRFile.Factory;

import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;

/**
 * Encapsulates region/language literacy data from CLDR.
 */
public class RegionLanguageData {

  /**
   * Stores the populate literate in a given language.
   */
  public static class LanguagePopulation implements
      Comparable<LanguagePopulation> {
    private final String language;
    private final double literatePopulation;
    private final boolean official;

    public LanguagePopulation(String language, double literatePopulation,
        boolean official) {
      this.language = language;
      this.literatePopulation = literatePopulation;
      this.official = official;
    }

    public int compareTo(LanguagePopulation other) {
      int c = -Double.compare(literatePopulation, other.literatePopulation);
      if (c == 0) {
        c = language.compareTo(other.language);
      }
      return c;
    }

    @Override
    public boolean equals(Object obj) {
      if (this == obj) {
        return true;
      }
      if (obj == null || getClass() != obj.getClass()) {
        return false;
      }
      LanguagePopulation other = (LanguagePopulation) obj;
      return language.equals(other.language)
          && (Double.compare(literatePopulation, other.literatePopulation) == 0);
    }

    public String getLanguage() {
      return language;
    }

    public double getLiteratePopulation() {
      return literatePopulation;
    }

    @Override
    public int hashCode() {
      long temp = Double.doubleToLongBits(literatePopulation);
      return language.hashCode() + 31 * (int) (temp ^ (temp >>> 32));
    }

    public boolean isOfficial() {
      return official;
    }

    @Override
    public String toString() {
      return "[lang=" + language + " pop=" + literatePopulation + "]";
    }
  }

  /**
   * Stores the region populations literate in a given language.
   */
  public static class RegionPopulation implements Comparable<RegionPopulation> {
    private final String region;
    private final double literatePopulation;
    private final boolean official;

    public RegionPopulation(String region, double literatePopulation,
        boolean official) {
      this.region = region;
      this.literatePopulation = literatePopulation;
      this.official = official;
    }

    public int compareTo(RegionPopulation other) {
      int c = -Double.compare(literatePopulation, other.literatePopulation);
      if (c == 0) {
        c = region.compareTo(other.region);
      }
      return c;
    }

    @Override
    public boolean equals(Object obj) {
      if (this == obj) {
        return true;
      }
      if (obj == null || getClass() != obj.getClass()) {
        return false;
      }
      RegionPopulation other = (RegionPopulation) obj;
      return region.equals(other.region)
          && (Double.compare(literatePopulation, other.literatePopulation) == 0);
    }

    public double getLiteratePopulation() {
      return literatePopulation;
    }

    public String getRegion() {
      return region;
    }

    @Override
    public int hashCode() {
      long temp = Double.doubleToLongBits(literatePopulation);
      return region.hashCode() + 31 * (int) (temp ^ (temp >>> 32));
    }

    public boolean isOfficial() {
      return official;
    }

    @Override
    public String toString() {
      return "[region=" + region + " pop=" + literatePopulation + "]";
    }
  }

  private final Factory cldrFactory;

  private Map<String, SortedSet<LanguagePopulation>> regionMap;
  private Map<String, SortedSet<RegionPopulation>> languageMap;

  public RegionLanguageData(Factory cldrFactory) {
    this.cldrFactory = cldrFactory;
  }

  public Set<LanguagePopulation> getLanguages(String region) {
    ensureMaps();
    Set<LanguagePopulation> languageSet = regionMap.get(region);
    if (languageSet == null) {
      languageSet = Collections.emptySet();
    }
    return languageSet;
  }

  public Set<RegionPopulation> getRegions(String language) {
    ensureMaps();
    Set<RegionPopulation> regionSet = languageMap.get(language);
    if (regionSet == null) {
      regionSet = Collections.emptySet();
    }
    return regionSet;
  }

  private void ensureMaps() {
    if (regionMap != null) {
      return;
    }
    regionMap = new HashMap<String, SortedSet<LanguagePopulation>>();
    languageMap = new HashMap<String, SortedSet<RegionPopulation>>();
    CLDRFile supp = cldrFactory.make("supplementalData", true,
        DraftStatus.approved);
    XPathParts parts = new XPathParts();
    Iterator<String> iterator = supp.iterator(
        "//supplementalData/territoryInfo/territory");
    while (iterator.hasNext()) {
      String path = iterator.next();
      parts.set(supp.getFullXPath(path));
      String language = parts.findAttributeValue("languagePopulation", "type");
      if (language == null) {
        continue;
      }
      String territory = parts.findAttributeValue("territory", "type");
      String literacyPercentStr = parts.findAttributeValue("territory",
          "literacyPercent");
      String populationStr = parts.findAttributeValue("territory",
          "population");
      String populationPercentStr = parts.findAttributeValue(
          "languagePopulation", "populationPercent");
      String statusStr = parts.findAttributeValue("languagePopulation",
          "officialStatus");
      double literacyPercent = Double.parseDouble(literacyPercentStr) * .01;
      double population = Double.parseDouble(populationStr);
      double populationPercent = Double.parseDouble(populationPercentStr) * .01;
      double literatePopulation = population * populationPercent
          * literacyPercent;
      boolean official = "official".equals(statusStr);
      SortedSet<RegionPopulation> regPop = languageMap.get(language);
      if (regPop == null) {
        regPop = new TreeSet<RegionPopulation>();
        languageMap.put(language, regPop);
      }
      regPop.add(new RegionPopulation(territory, literatePopulation, official));
      SortedSet<LanguagePopulation> langPop = regionMap.get(territory);
      if (langPop == null) {
        langPop = new TreeSet<LanguagePopulation>();
        regionMap.put(territory, langPop);
      }
      langPop.add(new LanguagePopulation(language, literatePopulation,
          official));
    }
  }
}
