/*
*******************************************************************************
*   Copyright (C) 2010-2011, International Business Machines
*   Corporation and others.  All Rights Reserved.
*******************************************************************************
*   created on: 2010aug21
*   created by: Markus W. Scherer
*/

package com.ibm.icu.dev.demo.messagepattern;

import com.ibm.icu.text.MessagePattern;

/**
 * Demo code for MessagePattern class.
 * Pretty-prints the list of MessagePattern Parts and uses the MiniMessageFormatter
 * with a few patterns.
 * @author Markus Scherer
 * @since 2010-aug-21
 */
public final class MessagePatternDemo {
    private static final String manySpaces="                    ";

    private static final void printParts(MessagePattern msg) {
        String autoQA=msg.autoQuoteApostropheDeep();
        if(!autoQA.equals(msg.getPatternString())) {
            System.out.println("autoQA:   "+autoQA);
        }
        String indent="";
        StringBuilder explanation=new StringBuilder();
        MessagePattern.Part prevPart=null;
        int count=msg.countParts();
        for(int i=0; i<count; ++i) {
            explanation.delete(0, 0x7fffffff);
            MessagePattern.Part part=msg.getPart(i);
            assert prevPart==null || prevPart.getLimit()<=part.getIndex();
            String partString=part.toString();
            MessagePattern.Part.Type type=part.getType();
            if(type==MessagePattern.Part.Type.MSG_START) {
                indent=manySpaces.substring(0, part.getValue()*2);
            }
            if(part.getLength()>0) {
                explanation.append("=\"").append(msg.getSubstring(part)).append('"');
            }
            if(type.hasNumericValue()) {
                explanation.append('=').append(msg.getNumericValue(part));
            }
            System.out.format("%2d: %s%s%s\n", i, indent, partString, explanation);
            if(type==MessagePattern.Part.Type.MSG_LIMIT) {
                int nestingLevel=part.getValue();
                if(nestingLevel>1) {
                    indent=manySpaces.substring(0, (nestingLevel-1)*2);  // outdent
                } else {
                    indent="";
                }
            }
            prevPart=part;
        }
    }

    private static final MessagePattern print(String s) {
        System.out.println("message:  "+s);
        try {
            MessagePattern msg=new MessagePattern(s);
            printParts(msg);
            return msg;
        } catch(Exception e) {
            System.out.println("Exception: "+e.getMessage());
            return null;
        }
    }

    private static final void printFormat(String s, Object... args) {
        MessagePattern msg=print(s);
        if(msg!=null) {
            System.out.println(new MiniMessageFormatter(msg).format(new StringBuilder(), args));
        }
    }

    private static final void printFormatWithNamedArgs(String s, Object... args) {
        MessagePattern msg=print(s);
        if(msg!=null) {
            System.out.println(new MiniMessageFormatter(msg).format(
                new StringBuilder(), MiniMessageFormatter.mapFromNameValuePairs(args)));
        }
    }

    public static void main(String[] argv) {
        print("Hello!");
        print("Hel'lo!");
        print("Hel'{o");
        print("Hel'{'o");
        // double apostrophe inside quoted literal text still encodes a single apostrophe
        printFormat("a'{bc''de'f");
        print("a'{bc''de'f{0,number,g'hi''jk'l#}");
        print("abc{0}def");
        print("abc{ arg }def");
        print("abc{1}def{arg}ghi");
        print("abc{2, number}ghi{3, select, xx {xxx} other {ooo}} xyz");
        print("abc{gender,select,"+
                  "other{His name is {person,XML,<entry name=\"PERSON\">{$PERSON}</entry>}.}}xyz");
        print("abc{num_people, plural, offset:17 few{fff} other {oooo}}xyz");
        print("abc{ num , plural , offset: 2 =1 {1} =-1 {-1} =3.14 {3.14} other {oo} }xyz");
        print("I don't {a,plural,other{w'{'on't #'#'}} and "+
              "{b,select,other{shan't'}'}} '{'''know'''}' and "+
              "{c,choice,0#can't'|'}"+
              "{z,number,#'#'###.00'}'}.");
        print("a_{0,choice,-∞ #-inf|  5≤ five | 99 # ninety'|'nine  }_z");
        print("a_{0,plural,other{num=#'#'=#'#'={1,number,##}!}}_z");
        print("}}}{0}}");  // yes, unmatched '}' are ok in ICU MessageFormat
        printFormat("Hello {0}!", "Alice");
        String msg="++{0, select, female{{1} calls you her friend}"+
                                 "other{{1} calls you '{their}' friend}"+
                                 "male{{1} calls you his friend}}--";
        printFormat(msg, "female", "Alice");
        printFormat(msg, "male", "Bob");
        printFormat(msg, "unknown", "sushifan3");
        msg="_'__{gender, select, female{Her n'ame is {person_name}.}"+
                                "other{His n'ame is {person_name}.}}__'_";
        printFormatWithNamedArgs(msg, "gender", "female", "person_name", "Alice");
        printFormatWithNamedArgs(msg, "gender", "male", "person_name", "Bob");
    }
}
