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

package com.ibm.icu.text;

import com.ibm.icu.impl.Utility;

/**
 * A post-processor for Chinese text.
 */
final class RBNFChinesePostProcessor implements RBNFPostProcessor {
    private NFRuleSet lastRuleSet;
    private boolean longForm;
    private int format;

    private static final String[] rulesetNames = {
        "%traditional", "%simplified", "%accounting", "%time"
    };

    /**
     * Initialization routine for this instance, called once
     * immediately after first construction and never again.  
     */
    public void init(RuleBasedNumberFormat formatter, String rules) {
    }

    /**
     * Work routine.  Post process the output, which was generated by the
     * ruleset with the given name.
     */
    public void process(StringBuffer buf, NFRuleSet ruleSet) {
        // markers depend on what rule set we are using

        if (ruleSet != lastRuleSet) {
            String name = ruleSet.getName();
            for (int i = 0; i < rulesetNames.length; ++i) {
                if (rulesetNames[i].equals(name)) {
                    format = i;
                    longForm = i == 1 || i == 3;
                    break;
                }
            }
        }

        if (longForm) {
            for (int i = Utility.indexOf(buf,"*"); i != -1; i = Utility.indexOf(buf, "*", i)) {
                buf.delete(i, i+1);
            }
            return;
        }

        final String DIAN = "\u9ede"; // decimal point

        final String[][] markers = {
            { "\u842c", "\u5104", "\u5146", "\u3007" }, // marker chars, last char is the 'zero'
            { "\u4e07", "\u4ebf", "\u5146", "\u3007" },
            { "\u842c", "\u5104", "\u5146", "\u96f6" }
            // need markers for time?
        };

        // remove unwanted lings
        // a '0' (ling) with * might be removed
        // mark off 10,000 'chunks', markers are Z, Y, W (zhao, yii, and wan)
        // already, we avoid two lings in the same chunk -- ling without * wins
        // now, just need  to avoid optional lings in adjacent chunks
        // process right to left

        // decision matrix:
        // state, situation
        //     state         none       opt.          req.
        //     -----         ----       ----          ----
        // none to right     none       opt.          req.  
        // opt. to right     none   clear, none  clear right, req.
        // req. to right     none   clear, none       req.

        // mark chunks with '|' for convenience
        {
            String[] m = markers[format];
            for (int i = 0; i < m.length-1; ++i) {
                int n = Utility.indexOf(buf, m[i]);
                if (n != -1) {
                    buf.insert(n+m[i].length(), '|');
                }
            }
        }

        int x = Utility.indexOf(buf, DIAN);
        if (x == -1) {
            x = buf.length();
        }
        int s = 0; // 0 = none to right, 1 = opt. to right, 2 = req. to right
        int n = -1; // previous optional ling
        String ling = markers[format][3];
        while (x >= 0) {
            int m = Utility.lastIndexOf(buf, "|", x);
            int nn = Utility.lastIndexOf(buf, ling, x);
            int ns = 0;
            if (nn > m) {
                ns = (nn > 0 && buf.charAt(nn-1) != '*') ? 2 : 1;
            }
            x = m - 1;

            // actually much simpler, but leave this verbose for now so it's easier to follow
            switch (s*3+ns) {
            case 0: /* none, none */
                s = ns; // redundant
                n = -1;
                break;
            case 1: /* none, opt. */
                s = ns;
                n = nn; // remember optional ling to right
                break;
            case 2: /* none, req. */
                s = ns;
                n = -1;
                break;
            case 3: /* opt., none */
                s = ns;
                n = -1;
                break;
            case 4: /* opt., opt. */
                buf.delete(nn-1, nn+ling.length()); // delete current optional ling
                s = 0;
                n = -1;
                break;
            case 5: /* opt., req. */
                buf.delete(n-1, n+ling.length()); // delete previous optional ling
                s = ns;
                n = -1;
                break;
            case 6: /* req., none */
                s = ns;
                n = -1;
                break;
            case 7: /* req., opt. */
                buf.delete(nn-1, nn+ling.length()); // delete current optional ling
                s = 0;
                n = -1;
                break;
            case 8: /* req., req. */
                s = ns;
                n = -1;
                break;
            default:
                throw new IllegalStateException();
            }
        }

        for (int i = buf.length(); --i >= 0;) {
            char c = buf.charAt(i);
            if (c == '*' || c == '|') {
                buf.delete(i, i+1);
            }
        }
    }
}
