/*
******************************************************************************
* Copyright (C) 2009-2011, International Business Machines Corporation and   *
* others. All Rights Reserved.                                               *
******************************************************************************
*/

package com.ibm.icu.impl.duration.impl;

import java.util.Arrays;

import com.ibm.icu.impl.duration.TimeUnit;
import com.ibm.icu.impl.duration.impl.DataRecord.ECountVariant;
import com.ibm.icu.impl.duration.impl.DataRecord.EDecimalHandling;
import com.ibm.icu.impl.duration.impl.DataRecord.EFractionHandling;
import com.ibm.icu.impl.duration.impl.DataRecord.EGender;
import com.ibm.icu.impl.duration.impl.DataRecord.EHalfPlacement;
import com.ibm.icu.impl.duration.impl.DataRecord.EHalfSupport;
import com.ibm.icu.impl.duration.impl.DataRecord.ENumberSystem;
import com.ibm.icu.impl.duration.impl.DataRecord.EPluralization;
import com.ibm.icu.impl.duration.impl.DataRecord.EUnitVariant;
import com.ibm.icu.impl.duration.impl.DataRecord.EZeroHandling;
import com.ibm.icu.impl.duration.impl.DataRecord.ScopeData;


/**
 * PeriodFormatterData provides locale-specific data used to format
 * relative dates and times, and convenience api to access it.
 *
 * An instance of PeriodFormatterData is usually created by requesting
 * data for a given locale from an PeriodFormatterDataService.
 */
public class PeriodFormatterData {
  final DataRecord dr;
  String localeName;

  // debug
  public static boolean trace = false;

  public PeriodFormatterData(String localeName, DataRecord dr) {
    this.dr = dr;
    this.localeName = localeName;
    if(localeName == null) {
        throw new NullPointerException("localename is null");
    }
//    System.err.println("** localeName is " + localeName);
    if (dr == null) {
//      Thread.dumpStack();
      throw new NullPointerException("data record is null");
    }
  }

  // none - chinese (all forms the same)
  // plural - english, special form for 1
  // dual - special form for 1 and 2
  // paucal - russian, special form for 1, for 2-4 and n > 20 && n % 10 == 2-4
  // rpt_dual_few - slovenian, special form for 1, 2, 3-4 and n as above
  // hebrew, dual plus singular form for years > 11
  // arabic, dual, plus singular form for all terms > 10

  /**
   * Return the pluralization format used by this locale.
   * @return the pluralization format
   */
  public int pluralization() {
    return dr.pl;
  }

  /**
   * Return true if zeros are allowed in the display.
   * @return true if zeros should be allowed
   */
  public boolean allowZero() {
    return dr.allowZero;
  }

  public boolean weeksAloneOnly() {
    return dr.weeksAloneOnly;
  }

  public int useMilliseconds() {
    return dr.useMilliseconds;
  }

  /**
   * Append the appropriate prefix to the string builder, depending on whether and
   * how a limit and direction are to be displayed.
   *
   * @param tl how and whether to display the time limit
   * @param td how and whether to display the time direction
   * @param sb the string builder to which to append the text
   * @return true if a following digit will require a digit prefix
   */
  public boolean appendPrefix(int tl, int td, StringBuffer sb) {
    if (dr.scopeData != null) {
      int ix = tl * 3 + td;
      ScopeData sd = dr.scopeData[ix];
      if (sd != null) {
        String prefix = sd.prefix;
        if (prefix != null) {
          sb.append(prefix);
          return sd.requiresDigitPrefix;
        }
      }
    }
    return false;
  }

  /**
   * Append the appropriate suffix to the string builder, depending on whether and
   * how a limit and direction are to be displayed.
   *
   * @param tl how and whether to display the time limit
   * @param td how and whether to display the time direction
   * @param sb the string builder to which to append the text
   */
  public void appendSuffix(int tl, int td, StringBuffer sb) {
    if (dr.scopeData != null) {
      int ix = tl * 3 + td;
      ScopeData sd = dr.scopeData[ix];
      if (sd != null) {
        String suffix = sd.suffix;
        if (suffix != null) {
          if (trace) {
            System.out.println("appendSuffix '" + suffix + "'");
          }
          sb.append(suffix);
        }
      }
    }
  }

  /**
   * Append the count and unit to the string builder.
   *
   * @param unit the unit to append
   * @param count the count of units, * 1000
   * @param cv the format to use for displaying the count
   * @param uv the format to use for displaying the unit
   * @param useCountSep if false, force no separator between count and unit
   * @param useDigitPrefix if true, use the digit prefix
   * @param multiple true if there are multiple units in this string
   * @param last true if this is the last unit
   * @param wasSkipped true if the unit(s) before this were skipped
   * @param sb the string builder to which to append the text
   * @return true if will require skip marker
   */
  @SuppressWarnings("fallthrough")
  public boolean appendUnit(TimeUnit unit, int count, int cv, 
                            int uv, boolean useCountSep, 
                            boolean useDigitPrefix, boolean multiple, 
                            boolean last, boolean wasSkipped, 
                            StringBuffer sb) {
    int px = unit.ordinal();

    boolean willRequireSkipMarker = false;
    if (dr.requiresSkipMarker != null && dr.requiresSkipMarker[px] && 
        dr.skippedUnitMarker != null) {
      if (!wasSkipped && last) {
        sb.append(dr.skippedUnitMarker);
      }
      willRequireSkipMarker = true;
    }

    if (uv != EUnitVariant.PLURALIZED) {
      boolean useMedium = uv == EUnitVariant.MEDIUM; 
      String[] names = useMedium ? dr.mediumNames : dr.shortNames;
      if (names == null || names[px] == null) {
        names = useMedium ? dr.shortNames : dr.mediumNames;
      }
      if (names != null && names[px] != null) {
        appendCount(unit, false, false, count, cv, useCountSep, 
                    names[px], last, sb); // omit suffix, ok?
        return false; // omit skip marker
      }
    }

    // check cv
    if (cv == ECountVariant.HALF_FRACTION && dr.halfSupport != null) {
      switch (dr.halfSupport[px]) {
        case EHalfSupport.YES: break;
        case EHalfSupport.ONE_PLUS:
          if (count > 1000) {
            break;
          }
          // else fall through to decimal
        case EHalfSupport.NO: {
          count = (count / 500) * 500;  // round to 1/2
          cv = ECountVariant.DECIMAL1; 
        } break;
      }
    }
          
    String name = null;
    int form = computeForm(unit, count, cv, multiple && last);
    if (form == FORM_SINGULAR_SPELLED) {
      if (dr.singularNames == null) {
        form = FORM_SINGULAR;
        name = dr.pluralNames[px][form];
      } else {
        name = dr.singularNames[px];
      }
    } else if (form == FORM_SINGULAR_NO_OMIT) {
      name = dr.pluralNames[px][FORM_SINGULAR];
    } else if (form == FORM_HALF_SPELLED) {
      name = dr.halfNames[px];
    } else { 
      try {
        name = dr.pluralNames[px][form];
      } catch (NullPointerException e) {
        System.out.println("Null Pointer in PeriodFormatterData["+localeName+"].au px: " + px + " form: " + form + " pn: " + Arrays.toString(dr.pluralNames));
        throw e;
      }
    }
    if (name == null) {
      form = FORM_PLURAL;
      name = dr.pluralNames[px][form];
    }

    boolean omitCount =
      (form == FORM_SINGULAR_SPELLED || form == FORM_HALF_SPELLED) ||
      (dr.omitSingularCount && form == FORM_SINGULAR) ||
      (dr.omitDualCount && form == FORM_DUAL);

    int suffixIndex = appendCount(unit, omitCount, useDigitPrefix, count, cv, 
                                  useCountSep, name, last, sb);
    if (last && suffixIndex >= 0) {
      String suffix = null;
      if (dr.rqdSuffixes != null && suffixIndex < dr.rqdSuffixes.length) {
        suffix = dr.rqdSuffixes[suffixIndex];
      }
      if (suffix == null && dr.optSuffixes != null && 
          suffixIndex < dr.optSuffixes.length) {
        suffix = dr.optSuffixes[suffixIndex];
      }
      if (suffix != null) {
        sb.append(suffix);
      }
    }
    return willRequireSkipMarker;
  }

  /**
   * Append a count to the string builder.
   *
   * @param unit the unit
   * @param count the count
   * @param cv the format to use for displaying the count
   * @param useSep whether to use the count separator, if available
   * @param name the term name
   * @param last true if this is the last unit to be formatted
   * @param sb the string builder to which to append the text
   * @return index to use if might have required or optional suffix, or -1 if none required
   */
  public int appendCount(TimeUnit unit, boolean omitCount, 
                         boolean useDigitPrefix, 
                         int count, int cv, boolean useSep, 
                         String name, boolean last, StringBuffer sb) {
    if (cv == ECountVariant.HALF_FRACTION && dr.halves == null) {
      cv = ECountVariant.INTEGER;
    }

    if (!omitCount && useDigitPrefix && dr.digitPrefix != null) {
      sb.append(dr.digitPrefix);
    }

    int index = unit.ordinal();
    switch (cv) {
      case ECountVariant.INTEGER: {
        if (!omitCount) {
          appendInteger(count/1000, 1, 10, sb);
        }
      } break;

      case ECountVariant.INTEGER_CUSTOM: {
        int val = count / 1000;
        // only custom names we have for now
        if (unit == TimeUnit.MINUTE && 
            (dr.fiveMinutes != null || dr.fifteenMinutes != null)) {
          if (val != 0 && val % 5 == 0) {
            if (dr.fifteenMinutes != null && (val == 15 || val == 45)) {
              val = val == 15 ? 1 : 3;
              if (!omitCount) appendInteger(val, 1, 10, sb);
              name = dr.fifteenMinutes;
              index = 8; // hack
              break;
            }
            if (dr.fiveMinutes != null) {
              val = val / 5;
              if (!omitCount) appendInteger(val, 1, 10, sb);
              name = dr.fiveMinutes;
              index = 9; // hack
              break;
            }
          }
        }
        if (!omitCount) appendInteger(val, 1, 10, sb);
      } break;

      case ECountVariant.HALF_FRACTION: {
        // 0, 1/2, 1, 1-1/2...
        int v = count / 500;
        if (v != 1) {
          if (!omitCount) appendCountValue(count, 1, 0, sb);
        }
        if ((v & 0x1) == 1) {
          // hack, using half name
          if (v == 1 && dr.halfNames != null && dr.halfNames[index] != null) {
            sb.append(name);
            return last ? index : -1;
          }

          int solox = v == 1 ? 0 : 1;
          if (dr.genders != null && dr.halves.length > 2) {
            if (dr.genders[index] == EGender.F) {
              solox += 2;
            }
          }
          int hp = dr.halfPlacements == null 
              ? EHalfPlacement.PREFIX
              : dr.halfPlacements[solox & 0x1];
          String half = dr.halves[solox];
          String measure = dr.measures == null ? null : dr.measures[index];
          switch (hp) {
            case EHalfPlacement.PREFIX:
              sb.append(half);
              break;
            case EHalfPlacement.AFTER_FIRST: {
              if (measure != null) {
                sb.append(measure);
                sb.append(half);
                if (useSep && !omitCount) {
                  sb.append(dr.countSep);
                } 
                sb.append(name);
              } else { // ignore sep completely
                sb.append(name);
                sb.append(half);
                return last ? index : -1; // might use suffix
              }
            } return -1; // exit early
            case EHalfPlacement.LAST: {
              if (measure != null) {
                sb.append(measure);
              }
              if (useSep && !omitCount) {
                sb.append(dr.countSep);
              }
              sb.append(name);
              sb.append(half);
            } return last ? index : -1; // might use suffix
          }
        }
      } break;
      default: {
        int decimals = 1;
        switch (cv) {
          case ECountVariant.DECIMAL2: decimals = 2; break;
          case ECountVariant.DECIMAL3: decimals = 3; break;
          default: break;
        }
        if (!omitCount) appendCountValue(count, 1, decimals, sb);
      } break;
    }
    if (!omitCount && useSep) {
      sb.append(dr.countSep);
    }
    if (!omitCount && dr.measures != null && index < dr.measures.length) {
      String measure = dr.measures[index];
      if (measure != null) {
        sb.append(measure);
      }
    }
    sb.append(name);
    return last ? index : -1;
  }

  /**
   * Append a count value to the builder.
   *
   * @param count the count
   * @param integralDigits the number of integer digits to display
   * @param decimalDigits the number of decimal digits to display, <= 3
   * @param sb the string builder to which to append the text
   */
  public void appendCountValue(int count, int integralDigits, 
                               int decimalDigits, StringBuffer sb) {
    int ival = count / 1000;
    if (decimalDigits == 0) {
      appendInteger(ival, integralDigits, 10, sb);
      return;
    }

    if (dr.requiresDigitSeparator && sb.length() > 0) {
      sb.append(' ');
    }
    appendDigits(ival, integralDigits, 10, sb);
    int dval = count % 1000;
    if (decimalDigits == 1) {
      dval /= 100;
    } else if (decimalDigits == 2) {
      dval /= 10;
    }
    sb.append(dr.decimalSep);
    appendDigits(dval, decimalDigits, decimalDigits, sb);
    if (dr.requiresDigitSeparator) {
      sb.append(' ');
    }
  }

  public void appendInteger(int num, int mindigits, int maxdigits, 
                            StringBuffer sb) {
    if (dr.numberNames != null && num < dr.numberNames.length) {
      String name = dr.numberNames[num];
      if (name != null) {
        sb.append(name);
        return;
      }
    }

    if (dr.requiresDigitSeparator && sb.length() > 0) {
      sb.append(' ');
    }
    switch (dr.numberSystem) {
      case ENumberSystem.DEFAULT: appendDigits(num, mindigits, maxdigits, sb); break;
      case ENumberSystem.CHINESE_TRADITIONAL: sb.append(
          Utils.chineseNumber(num, Utils.ChineseDigits.TRADITIONAL)); break;
      case ENumberSystem.CHINESE_SIMPLIFIED: sb.append(
          Utils.chineseNumber(num, Utils.ChineseDigits.SIMPLIFIED)); break;
      case ENumberSystem.KOREAN: sb.append(
          Utils.chineseNumber(num, Utils.ChineseDigits.KOREAN)); break;
    }
    if (dr.requiresDigitSeparator) {
      sb.append(' ');
    }
  }

  /**
   * Append digits to the string builder, using this.zero for '0' etc.
   *
   * @param num the integer to append
   * @param mindigits the minimum number of digits to append
   * @param maxdigits the maximum number of digits to append
   * @param sb the string builder to which to append the text
   */
  public void appendDigits(long num, int mindigits, int maxdigits,  
                           StringBuffer sb) {
    char[] buf = new char[maxdigits];
    int ix = maxdigits;
    while (ix > 0 && num > 0) {
      buf[--ix] = (char)(dr.zero + (num % 10));
      num /= 10;
    }
    for (int e = maxdigits - mindigits; ix > e;) {
      buf[--ix] = dr.zero;
    }
    sb.append(buf, ix, maxdigits - ix);
  }

  /**
   * Append a marker for skipped units internal to a string.
   * @param sb the string builder to which to append the text
   */
  public void appendSkippedUnit(StringBuffer sb) {
    if (dr.skippedUnitMarker != null) {
      sb.append(dr.skippedUnitMarker);
    }
  }

  /**
   * Append the appropriate separator between units
   *
   * @param unit the unit to which to append the separator
   * @param afterFirst true if this is the first unit formatted
   * @param beforeLast true if this is the next-to-last unit to be formatted
   * @param sb the string builder to which to append the text
   * @return true if a prefix will be required before a following unit
   */
  public boolean appendUnitSeparator(TimeUnit unit, boolean longSep, 
                                     boolean afterFirst, boolean beforeLast, 
                                     StringBuffer sb) {
    // long seps
    // false, false "...b', '...d"
    // false, true  "...', and 'c"
    // true, false - "a', '...c"
    // true, true - "a' and 'b"
    if ((longSep && dr.unitSep != null) || dr.shortUnitSep != null) {
      if (longSep && dr.unitSep != null) {
        int ix = (afterFirst ? 2 : 0) + (beforeLast ? 1 : 0);
        sb.append(dr.unitSep[ix]);
        return dr.unitSepRequiresDP != null && dr.unitSepRequiresDP[ix];
      }
      sb.append(dr.shortUnitSep); // todo: investigate whether DP is required
    }
    return false;
  }

  private static final int 
    FORM_PLURAL = 0,
    FORM_SINGULAR = 1,
    FORM_DUAL = 2,
    FORM_PAUCAL = 3,
    FORM_SINGULAR_SPELLED = 4, // following are not in the pluralization list
    FORM_SINGULAR_NO_OMIT = 5, // a hack
    FORM_HALF_SPELLED = 6;

  private int computeForm(TimeUnit unit, int count, int cv, 
                          boolean lastOfMultiple) {
    // first check if a particular form is forced by the countvariant.  if
    // SO, just return that.  otherwise convert the count to an integer
    // and use pluralization rules to determine which form to use.
    // careful, can't assume any forms but plural exist.

    if (trace) {
      System.err.println("pfd.cf unit: " + unit + " count: " + count + " cv: " + cv + " dr.pl: " + dr.pl);
      Thread.dumpStack();
    }
    if (dr.pl == EPluralization.NONE) {
      return FORM_PLURAL;
    }
    // otherwise, assume we have at least a singular and plural form

    int val = count/1000;

    switch (cv) {
      case ECountVariant.INTEGER: 
      case ECountVariant.INTEGER_CUSTOM: {
        // do more analysis based on floor of count
      } break;
      case ECountVariant.HALF_FRACTION: {
        switch (dr.fractionHandling) {
          case EFractionHandling.FPLURAL:
            return FORM_PLURAL;

          case EFractionHandling.FSINGULAR_PLURAL_ANDAHALF:
          case EFractionHandling.FSINGULAR_PLURAL: {
            // if half-floor is 1/2, use singular
            // else if half-floor is not integral, use plural
            // else do more analysis
            int v = count / 500;
            if (v == 1) {
              if (dr.halfNames != null && dr.halfNames[unit.ordinal()] != null) {
                return FORM_HALF_SPELLED;
              }
              return FORM_SINGULAR_NO_OMIT;
            }
            if ((v & 0x1) == 1) {
              if (dr.pl == EPluralization.ARABIC && v > 21) { // hack
                return FORM_SINGULAR_NO_OMIT;
              }
              if (v == 3 && dr.pl == EPluralization.PLURAL &&
                  dr.fractionHandling != EFractionHandling.FSINGULAR_PLURAL_ANDAHALF) {
                return FORM_PLURAL;
              }
            }
            
            // it will display like an integer, so do more analysis
          } break;

          case EFractionHandling.FPAUCAL: {
            int v = count / 500;
            if (v == 1 || v == 3) {
              return FORM_PAUCAL;
            }
            // else use integral form
          } break;

          default:
            throw new IllegalStateException();
        }
      } break;
      default: { // for all decimals
        switch (dr.decimalHandling) {
          case EDecimalHandling.DPLURAL: break;
          case EDecimalHandling.DSINGULAR: return FORM_SINGULAR_NO_OMIT;
          case EDecimalHandling.DSINGULAR_SUBONE:
            if (count < 1000) {
              return FORM_SINGULAR_NO_OMIT;
            }
            break;
          case EDecimalHandling.DPAUCAL:
            if (dr.pl == EPluralization.PAUCAL) {
              return FORM_PAUCAL;
            }
            break;
          default:
            break;
        }
        return FORM_PLURAL;
      }
    }

    // select among pluralization forms
    if (trace && count == 0) {
      System.err.println("EZeroHandling = " + dr.zeroHandling);
    }
    if (count == 0 && dr.zeroHandling == EZeroHandling.ZSINGULAR) {
      return FORM_SINGULAR_SPELLED;
    }

    int form = FORM_PLURAL;
    switch(dr.pl) {
      case EPluralization.NONE: break; // never get here
      case EPluralization.PLURAL: {
        if (val == 1) { 
          form = FORM_SINGULAR_SPELLED; // defaults to form_singular if no spelled forms
        } 
      } break;
      case EPluralization.DUAL: {
        if (val == 2) {
          form = FORM_DUAL; 
        } else if (val == 1) {
          form = FORM_SINGULAR; 
        } 
      } break;
      case EPluralization.PAUCAL: {
        int v = val;
        v = v % 100;
        if (v > 20) {
          v = v % 10;
        }
        if (v == 1) {
          form = FORM_SINGULAR;
        } else if (v > 1 && v < 5) {
          form = FORM_PAUCAL;
        }
      } break;
        /*
      case EPluralization.RPT_DUAL_FEW: {
        int v = val;
        if (v > 20) {
          v = v % 10;
        }
        if (v == 1) {
          form = FORM_SINGULAR;
        } else if (v == 2) {
          form = FORM_DUAL;
        } else if (v > 2 && v < 5) {
          form = FORM_PAUCAL;
        }
      } break;
        */
      case EPluralization.HEBREW: {
        if (val == 2) {
          form = FORM_DUAL;
        } else if (val == 1) {
          if (lastOfMultiple) {
            form = FORM_SINGULAR_SPELLED;
          } else {
            form = FORM_SINGULAR;
          } 
        } else if (unit == TimeUnit.YEAR && val > 11) {
          form = FORM_SINGULAR_NO_OMIT;
        }
      } break;
      case EPluralization.ARABIC: {
        if (val == 2) {
          form = FORM_DUAL;
        } else if (val == 1) {
          form = FORM_SINGULAR;
        } else if (val > 10) {
          form = FORM_SINGULAR_NO_OMIT;
        }
      } break;
      default: 
        System.err.println("dr.pl is " + dr.pl);
        throw new IllegalStateException();
    }

    return form;
  }
}
