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

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

import java.util.Locale;

public class Utils {
  public static final Locale localeFromString(String s) {
    String language = s;
    String region = "";
    String variant = "";

    int x = language.indexOf("_");
    if (x != -1) {
      region = language.substring(x+1);
      language = language.substring(0, x);
    }
    x = region.indexOf("_");
    if (x != -1) {
      variant = region.substring(x+1);
      region = region.substring(0, x);
    }
    return new Locale(language, region, variant);
  }
    /*
  public static <T> T[] arraycopy(T[] src) {
    T[] result = (T[])Array.newInstance(src.getClass().getComponentType(), src.length); // can we do this without casting?
    for (int i = 0; i < src.length; ++i) {
      result[i] = src[i];
    }
    return result;
  }
    */

  /**
   * Interesting features of chinese numbers:
   * - Each digit is followed by a unit symbol (10's, 100's, 1000's).
   * - Units repeat in levels of 10,000, there are symbols for each level too (except 1's).
   * - The digit 2 has a special form before the 10 symbol and at the end of the number.
   * - If the first digit in the number is 1 and its unit is 10, the 1 is omitted.
   * - Sequences of 0 digits and their units are replaced by a single 0 and no unit.
   * - If there are two such sequences of 0 digits in a level (1000's and 10's), the 1000's 0 is also omitted.
   * - The 1000's 0 is also omitted in alternating levels, such that it is omitted in the rightmost
   *     level with a 10's 0, or if none, in the rightmost level.
   * - Level symbols are omitted if all of their units are omitted
   */
  public static String chineseNumber(long n, ChineseDigits zh) {
    if (n < 0) {
      n = -n;
    }
    if (n <= 10) {
      if (n == 2) {
        return String.valueOf(zh.liang);
      }
      return String.valueOf(zh.digits[(int)n]);
    }

    // 9223372036854775807
    char[] buf = new char[40]; // as long as we get, and actually we can't get this high, no units past zhao
    char[] digits = String.valueOf(n).toCharArray();

    // first, generate all the digits in place
    // convert runs of zeros into a single zero, but keep places
    // 
    boolean inZero = true; // true if we should zap zeros in this block, resets at start of block
    boolean forcedZero = false; // true if we have a 0 in tens's place
    int x = buf.length;
    for (int i = digits.length, u = -1, l = -1; --i >= 0;) {
      if (u == -1) {
        if (l != -1) {
          buf[--x] = zh.levels[l];
          inZero = true;
          forcedZero = false;
        }
        ++u;
      } else {
        buf[--x] = zh.units[u++];
        if (u == 3) {
          u = -1;
          ++l;
        }
      }
      int d = digits[i] - '0';
      if (d == 0) {
        if (x < buf.length-1 && u != 0) {
          buf[x] = '*';
        }
        if (inZero || forcedZero) {
          buf[--x] = '*';
        } else {
          buf[--x] = zh.digits[0];
          inZero = true;
          forcedZero = u == 1;
        }
      } else {
        inZero = false;
        buf[--x] = zh.digits[d];
      }
    }

    // scanning from right, find first required 'ling'
    // we only care if n > 101,0000 as this is the first case where
    // it might shift.  remove optional lings in alternating blocks.
    if (n > 1000000) {
      boolean last = true;
      int i = buf.length - 3;
      do {
        if (buf[i] == '0') {
          break;
        }
        i -= 8;
        last = !last;
      } while (i > x);

      i = buf.length - 7;
      do {
        if (buf[i] == zh.digits[0] && !last) {
          buf[i] = '*';
        }
        i -= 8;
        last = !last;
      } while (i > x);

      // remove levels for empty blocks
      if (n >= 100000000) {
        i = buf.length - 8;
        do {
          boolean empty = true;
          for (int j = i-1, e = Math.max(x-1, i-8); j > e; --j) {
            if (buf[j] != '*') {
              empty = false;
              break;
            }
          }
          if (empty) {
            if (buf[i+1] != '*' && buf[i+1] != zh.digits[0]) {
              buf[i] = zh.digits[0];
            } else {
              buf[i] = '*';
            }
          }
          i -= 8;
        } while (i > x);
      }          
    }

    // replace er by liang except before or after shi or after ling
    for (int i = x; i < buf.length; ++i) {
      if (buf[i] != zh.digits[2]) continue;
      if (i < buf.length - 1 && buf[i+1] == zh.units[0]) continue;
      if (i > x && (buf[i-1] == zh.units[0] || buf[i-1] == zh.digits[0] || buf[i-1] == '*')) continue;

      buf[i] = zh.liang;
    }
    
    // eliminate leading 1 if following unit is shi
    if (buf[x] == zh.digits[1] && (zh.ko || buf[x+1] == zh.units[0])) {
      ++x;
    }

    // now, compress out the '*'
    int w = x;
    for (int r = x; r < buf.length; ++r) {
      if (buf[r] != '*') {
        buf[w++] = buf[r];
      }
    }
    return new String(buf, x, w-x);
  }

  public static void main(String[] args) {
    for (int i = 0; i < args.length; ++i) {
      String arg = args[i];
      System.out.print(arg);
      System.out.print(" > ");
      long n = Long.parseLong(arg);
      System.out.println(chineseNumber(n, ChineseDigits.DEBUG));
    }
  }

  public static class ChineseDigits {
    final char[] digits;
    final char[] units;
    final char[] levels;
    final char liang;
    final boolean ko;

    ChineseDigits(String digits, String units, String levels, char liang, boolean ko) {
      this.digits = digits.toCharArray();
      this.units = units.toCharArray();
      this.levels = levels.toCharArray();
      this.liang = liang;
      this.ko = ko;
    }

    public static final ChineseDigits DEBUG = 
      new ChineseDigits("0123456789s", "sbq", "WYZ", 'L', false);

    public static final ChineseDigits TRADITIONAL = 
      new ChineseDigits("\u96f6\u4e00\u4e8c\u4e09\u56db\u4e94\u516d\u4e03\u516b\u4e5d\u5341", // to shi
                        "\u5341\u767e\u5343", // shi, bai, qian
                        "\u842c\u5104\u5146", // wan, yi, zhao
                        '\u5169', false); // liang

    public static final ChineseDigits SIMPLIFIED = 
      new ChineseDigits("\u96f6\u4e00\u4e8c\u4e09\u56db\u4e94\u516d\u4e03\u516b\u4e5d\u5341", // to shi
                        "\u5341\u767e\u5343", // shi, bai, qian
                        "\u4e07\u4ebf\u5146", // wan, yi, zhao
                        '\u4e24', false); // liang
    
    // no 1 before first unit no matter what it is
    // not sure if there are 'ling' units
    public static final ChineseDigits KOREAN =
      new ChineseDigits("\uc601\uc77c\uc774\uc0bc\uc0ac\uc624\uc721\uce60\ud314\uad6c\uc2ed", // to ten
                        "\uc2ed\ubc31\ucc9c", // 10, 100, 1000
                        "\ub9cc\uc5b5?", // 10^4, 10^8, 10^12
                        '\uc774', true);
  }
}
