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

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

import com.ibm.icu.impl.duration.TimeUnit;

import com.ibm.icu.impl.duration.impl.DataRecord.*;


/**
 * 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
   * @param return true if will require skip marker
   */
  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: " + 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 = (int)(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 = (int)(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;
  }
}
