// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
/*
 *******************************************************************************
 * Copyright (C) 1996-2010, International Business Machines Corporation and    *
 * others. All Rights Reserved.                                                *
 *******************************************************************************
 */
package com.ibm.icu.dev.demo.rbnf;

import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.CardLayout;
import java.awt.Checkbox;
import java.awt.Choice;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.Panel;
import java.awt.ScrollPane;
import java.awt.TextArea;
import java.awt.TextComponent;
import java.awt.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.TextEvent;
import java.awt.event.TextListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.text.BreakIterator;
import java.text.DecimalFormat;
import java.text.ParsePosition;
import java.util.Locale;

import com.ibm.icu.dev.demo.impl.DemoApplet;
import com.ibm.icu.math.BigDecimal;
import com.ibm.icu.text.RuleBasedNumberFormat;

public class RbnfDemo extends DemoApplet {
    /**
     * For serialization
     */
    private static final long serialVersionUID = -9119861296873763536L;

    /**
     * Puts a copyright in the .class file
     */
//    private static final String copyrightNotice
//        = "Copyright \u00a91997-1998 IBM Corp.  All rights reserved.";

    /*
     * code to run the demo as an application
     */
    public static void main(String[] argv) {
        new RbnfDemo().showDemo();
    }

    @Override
    protected Dimension getDefaultFrameSize(DemoApplet applet, Frame f) {
        return new Dimension(430,270);
    }

    @Override
    protected Frame createDemoFrame(DemoApplet applet) {
        final Frame window = new Frame("Number Spellout Demo");
        window.setSize(800, 600);
        window.setLayout(new BorderLayout());

        Panel mainPanel = new Panel();
        mainPanel.setLayout(new GridLayout(1,2));

        commentaryField = new TextArea("", 0, 0, TextArea.SCROLLBARS_VERTICAL_ONLY);
        commentaryField.setSize(800, 50);
        commentaryField.setText(RbnfSampleRuleSets.sampleRuleSetCommentary[0]);
        commentaryField.setEditable(false);
        commentaryField.setFont(new Font("Helvetica", Font.PLAIN, 14));

        spelloutFormatter = new RuleBasedNumberFormat(RbnfSampleRuleSets.usEnglish, Locale.US);
        spelloutFormatter.setLenientParseMode(lenientParse);
        populateRuleSetMenu();
        numberFormatter = new DecimalFormat("#,##0.##########");
        parsePosition = new ParsePosition(0);
        theNumber = BigDecimal.ZERO;

        numberField = new TextField();
        numberField.setFont(new Font("Serif", Font.PLAIN, 24));
        textField = new DemoTextFieldHolder();
        textField.setFont(new Font("Serif", Font.PLAIN, 24));
        rulesField = new DemoTextFieldHolder();
        rulesField.setFont(new Font("Serif", Font.PLAIN, 14));
        lenientParseButton = new Checkbox("Lenient parse", lenientParse);

        numberField.addTextListener(new TextListener() {
            @Override
            public void textValueChanged(TextEvent e) {
                if (!numberFieldHasFocus)
                    return;

                String fieldText = ((TextComponent)(e.getSource())).getText();
                parsePosition.setIndex(0);
                Number temp = numberFormatter.parse(fieldText, parsePosition);
                if (temp == null || parsePosition.getIndex() == 0) {
                    theNumber = BigDecimal.ZERO;
                    textField.setText("PARSE ERROR");
                }
                else {
                    theNumber = new BigDecimal(temp instanceof Long ? temp.longValue() : temp.doubleValue());
                    textField.setText(spelloutFormatter.format(
                            theNumber.scale() == 0 ? theNumber.longValue() : theNumber.doubleValue(), ruleSetName));
                }
            }
        } );

        numberField.addFocusListener(new FocusAdapter() {
            @Override
            public void focusLost(FocusEvent e) {
                numberFieldHasFocus = false;
                numberField.setText(numberFormatter.format(theNumber));
            }

            @Override
            public void focusGained(FocusEvent e) {
                numberFieldHasFocus = true;
                numberField.selectAll();
            }
        } );

        textField.addKeyListener(new KeyAdapter() {
            @Override
            public void keyTyped(KeyEvent e) {
                if (e.getKeyChar() == '\t') {
                    String fieldText = ((TextComponent)(e.getSource())).getText();
                    parsePosition.setIndex(0);
                    theNumber = new BigDecimal(spelloutFormatter.parse(fieldText, parsePosition)
                                    .doubleValue());
                    if (parsePosition.getIndex() == 0) {
                        theNumber = BigDecimal.ZERO;
                        numberField.setText("PARSE ERROR");
                        textField.selectAll();
                    }
                    else if (parsePosition.getIndex() < fieldText.length()) {
                        textField.select(parsePosition.getIndex(), fieldText.length());
                        numberField.setText(numberFormatter.format(theNumber));
                    }
                    else {
                        textField.selectAll();
                        numberField.setText(numberFormatter.format(theNumber));
                    }
                    e.consume();
                }
            }
        } );

        textField.addFocusListener(new FocusAdapter() {
            @Override
            public void focusLost(FocusEvent e) {
                String fieldText = ((TextComponent)(e.getSource())).getText();
                parsePosition.setIndex(0);
                theNumber = new BigDecimal(spelloutFormatter.parse(fieldText, parsePosition)
                                .doubleValue());
                if (parsePosition.getIndex() == 0)
                    numberField.setText("PARSE ERROR");
                else
                    numberField.setText(numberFormatter.format(theNumber));
                textField.setText(textField.getText()); // textField.repaint() didn't work right
            }

            @Override
            public void focusGained(FocusEvent e) {
                textField.selectAll();
            }
        } );

        rulesField.addKeyListener(new KeyAdapter() {
            @Override
            public void keyTyped(KeyEvent e) {
                if (e.getKeyChar() == '\t') {
                    String fieldText = ((TextComponent)(e.getSource())).getText();
                    if (formatterMenu.getSelectedItem().equals("Custom") || !fieldText.equals(
                                    RbnfSampleRuleSets.sampleRuleSets[formatterMenu.getSelectedIndex()])) {
                        try {
                            RuleBasedNumberFormat temp = new RuleBasedNumberFormat(fieldText);
                            temp.setLenientParseMode(lenientParse);
                            populateRuleSetMenu();
                            spelloutFormatter = temp;
                            customRuleSet = fieldText;
                            formatterMenu.select("Custom");
                            commentaryField.setText(RbnfSampleRuleSets.
                                sampleRuleSetCommentary[RbnfSampleRuleSets.
                                sampleRuleSetCommentary.length - 1]);
                            redisplay();
                        }
                        catch (Exception x) {
                            textField.setText(x.toString());
                        }
                    }
                    e.consume();
                }
            }
        } );

        rulesField.addFocusListener(new FocusAdapter() {
            @Override
            public void focusLost(FocusEvent e) {
                String fieldText = ((TextComponent)(e.getSource())).getText();
                if (formatterMenu.getSelectedItem().equals("Custom") || !fieldText.equals(
                                RbnfSampleRuleSets.sampleRuleSets[formatterMenu.getSelectedIndex()])) {
                    try {
                        RuleBasedNumberFormat temp = new RuleBasedNumberFormat(fieldText);
                        temp.setLenientParseMode(lenientParse);
                        populateRuleSetMenu();
                        spelloutFormatter = temp;
                        customRuleSet = fieldText;
                        formatterMenu.select("Custom");
                        redisplay();
                    }
                    catch (Exception x) {
                        textField.setText(x.toString());
                    }
                }
                rulesField.setText(rulesField.getText()); // rulesField.repaint() didn't work right
            }
        } );

        lenientParseButton.addItemListener(new ItemListener() {
            @Override
            public void itemStateChanged(ItemEvent e) {
                lenientParse = lenientParseButton.getState();
                spelloutFormatter.setLenientParseMode(lenientParse);
            }
        } );

        numberField.setText(numberFormatter.format(theNumber));
        numberField.selectAll();
        textField.setText(spelloutFormatter
                .format(theNumber.scale() == 0 ? theNumber.longValue() : theNumber.doubleValue(), ruleSetName));

        Panel leftPanel = new Panel();
        leftPanel.setLayout(new BorderLayout());
        Panel panel = new Panel();
        panel.setLayout(new BorderLayout());
        Panel panel1 = new Panel();
        panel1.setLayout(new GridLayout(3, 1));
        panel1.add(new Panel());
        panel1.add(numberField, "Center");
        panel1.add(lenientParseButton);
        panel.add(panel1, "Center");
        Panel panel2 = new Panel();
        panel2.setLayout(new GridLayout(3, 3));
        Button button = new Button("+100");
        button.addActionListener( new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                roll(100);
            }
        } );
        panel2.add(button);
        button = new Button("+10");
        button.addActionListener( new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                roll(10);
            }
        } );
        panel2.add(button);
        button = new Button("+1");
        button.addActionListener( new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                roll(1);
            }
        } );
        panel2.add(button);
        button = new Button("<");
        button.addActionListener( new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                theNumber = new BigDecimal(theNumber.toString()).multiply(new BigDecimal("10"));
                redisplay();
            }
        } );
        panel2.add(button);
        panel2.add(new Panel());
        button = new Button(">");
        button.addActionListener( new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                theNumber = new BigDecimal(theNumber.toString()).multiply(new BigDecimal("0.1"));
                redisplay();
            }
        } );
        panel2.add(button);
        button = new Button("-100");
        button.addActionListener( new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                roll(-100);
            }
        } );
        panel2.add(button);
        button = new Button("-10");
        button.addActionListener( new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                roll(-10);
            }
        } );
        panel2.add(button);
        button = new Button("-1");
        button.addActionListener( new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                roll(-1);
            }
        } );
        panel2.add(button);
        panel.add(panel2, "East");
        leftPanel.add(panel, "North");
        leftPanel.add(textField, "Center");

        Panel rightPanel = new Panel();
        rightPanel.setLayout(new BorderLayout());
        formatterMenu = new Choice();
        for (int i = 0; i < RbnfSampleRuleSets.sampleRuleSetNames.length; i++)
            formatterMenu.addItem(RbnfSampleRuleSets.sampleRuleSetNames[i]);
        formatterMenu.addItem("Custom");
        formatterMenu.addItemListener(new ItemListener() {
            @Override
            public void itemStateChanged(ItemEvent e) {
                Choice source = (Choice)(e.getSource());
                int item = source.getSelectedIndex();
                Locale locale = RbnfSampleRuleSets.sampleRuleSetLocales[item];

                commentaryField.setText(RbnfSampleRuleSets.
                                sampleRuleSetCommentary[item]);

                if (locale != null && (locale.getLanguage().equals("iw")
                        || locale.getLanguage().equals("ru") || locale.getLanguage().equals("ja")
                        || locale.getLanguage().equals("el")
                        || locale.getLanguage().equals("zh"))) {
                    textField.togglePanes(false);
                    rulesField.togglePanes(false);
                }
                else {
                    textField.togglePanes(true);
                    rulesField.togglePanes(true);
                }

                makeNewSpelloutFormatter();
                redisplay();
            }
        } );

        ruleSetMenu = new Choice();
        populateRuleSetMenu();

        ruleSetMenu.addItemListener(new ItemListener() {
            @Override
            public void itemStateChanged(ItemEvent e) {
                ruleSetName = ruleSetMenu.getSelectedItem();
                redisplay();
            }
        } );

        Panel menuPanel = new Panel();
        menuPanel.setLayout(new GridLayout(1, 2));
        menuPanel.add(formatterMenu);
        menuPanel.add(ruleSetMenu);
        rightPanel.add(menuPanel, "North");

        rulesField.setText(RbnfSampleRuleSets.sampleRuleSets[formatterMenu.getSelectedIndex()]);
        rightPanel.add(rulesField, "Center");

        mainPanel.add(leftPanel);
        mainPanel.add(rightPanel);

        window.add(mainPanel, "Center");
        window.add(commentaryField, "South");

        window.doLayout();
        window.show();
        final DemoApplet theApplet = applet;
        window.addWindowListener(
                new WindowAdapter() {
                    @Override
                    public void windowClosing(WindowEvent e) {
                        setVisible(false);
                        window.dispose();

                        if (theApplet != null) {
                            theApplet.demoClosed();
                        } else System.exit(0);
                    }
                } );
        return window;
    }

    void roll(int delta) {
        theNumber = theNumber.add(new BigDecimal(delta));
        redisplay();
    }

    void redisplay() {
        numberField.setText(numberFormatter.format(theNumber));
        textField.setText(spelloutFormatter
                .format(theNumber.scale() == 0 ? theNumber.longValue() : theNumber.doubleValue(), ruleSetName));
    }

    void makeNewSpelloutFormatter() {
        int item = formatterMenu.getSelectedIndex();
        String formatterMenuItem = formatterMenu.getSelectedItem();

        if (formatterMenuItem.equals("Custom")) {
            rulesField.setText(customRuleSet);
            spelloutFormatter = new RuleBasedNumberFormat(customRuleSet);
        }
        else {
            rulesField.setText(RbnfSampleRuleSets.sampleRuleSets[item]);

            Locale locale = RbnfSampleRuleSets.sampleRuleSetLocales[item];
            if (locale == null)
                locale = Locale.getDefault();

            spelloutFormatter = new RuleBasedNumberFormat(RbnfSampleRuleSets.
                            sampleRuleSets[item], locale);
        }
        spelloutFormatter.setLenientParseMode(lenientParse);
        populateRuleSetMenu();
    }

    void populateRuleSetMenu() {
        String[] ruleSetNames = spelloutFormatter.getRuleSetNames();

        if (ruleSetMenu != null) {
            ruleSetMenu.removeAll();
            for (int i = 0; i < ruleSetNames.length; i++)
                ruleSetMenu.addItem(ruleSetNames[i]);

            ruleSetName = ruleSetMenu.getSelectedItem();
        }
        else
            ruleSetName = ruleSetNames[0];
    }

//    private Frame demoWindow = null;

    private TextComponent numberField;
    private DemoTextFieldHolder textField;
    private DemoTextFieldHolder rulesField;
    private TextComponent commentaryField;
    private Checkbox lenientParseButton;

    private boolean numberFieldHasFocus = true;

    private RuleBasedNumberFormat spelloutFormatter;
    private DecimalFormat numberFormatter;
    private ParsePosition parsePosition;

    private boolean lenientParse = true;

    private BigDecimal theNumber = BigDecimal.ZERO;
//    private boolean canEdit = true;

    private Choice formatterMenu;
    private Choice ruleSetMenu;
    private String ruleSetName;

    private String customRuleSet = "NO RULES!";
}

class DemoTextField extends Component {
    /**
     * For serialization
     */
    private static final long serialVersionUID = -7947090021239472658L;
    public DemoTextField() {
    }

    public void setText(String text) {
        this.text = text;
        this.repaint();
    }

    public String getText() {
        return text;
    }

    @Override
    public void paint(Graphics g) {
        Font font = getFont();
        FontMetrics fm = g.getFontMetrics();
        g.setFont(font);
        String txt = getText();
        BreakIterator bi = BreakIterator.getLineInstance();
        bi.setText(txt);
        int lineHeight = fm.getHeight();
        int width = getSize().width;
        int penY = fm.getAscent();
        int lineStart = 0;
        int tempLineEnd = bi.first();
        int lineEnd = 0;
        int maxLineEnd = 0;
        totalHeight = 0;

        while (lineStart < txt.length()) {
            maxLineEnd = txt.indexOf('\n', lineStart);
            if (maxLineEnd == -1)
                maxLineEnd = Integer.MAX_VALUE;
            while (tempLineEnd != BreakIterator.DONE && fm.stringWidth(txt.substring(
                            lineStart, tempLineEnd)) < width) {
                lineEnd = tempLineEnd;
                tempLineEnd = bi.next();
            }
            if (lineStart >= lineEnd) {
                if (tempLineEnd == BreakIterator.DONE)
                    lineEnd = txt.length();
                else
                    lineEnd = tempLineEnd;
            }
            if (lineEnd > maxLineEnd)
                lineEnd = maxLineEnd;
            g.drawString(txt.substring(lineStart, lineEnd), 0, penY);
            penY += lineHeight;
            totalHeight += lineHeight;
            lineStart = lineEnd;
            if (lineStart < txt.length() && txt.charAt(lineStart) == '\n')
                ++lineStart;
        }
    }

/*
    public Dimension getPreferredSize() {
        Dimension size = getParent().getSize();
        return new Dimension(size.width, totalHeight);
    }
*/

    private String text;
    private int totalHeight;
}

class DemoTextFieldHolder extends Panel {
    /**
     * For serialization
     */
    private static final long serialVersionUID = 7514498764062569858L;
    public DemoTextFieldHolder() {
        tf1 = new TextArea("", 0, 0, TextArea.SCROLLBARS_VERTICAL_ONLY);
        tf2 = new DemoTextField();
        sp = new ScrollPane();

        setLayout(new CardLayout());

        sp.add(tf2, "TextField1");
        sp.setVisible(false);
        add(tf1, "TestField2");
        add(sp, "ScrollPane");
    }

    @Override
    public void addFocusListener(FocusListener l) {
        tf1.addFocusListener(l);
    }

    @Override
    public void addKeyListener(KeyListener l) {
        tf1.addKeyListener(l);
    }

    public void setText(String text) {
        tf1.setText(text);
        tf2.setText(text);
    }

    public String getText() {
        return tf1.getText();
    }

    public void select(int start, int end) {
        tf1.select(start, end);
    }

    public void selectAll() {
        tf1.selectAll();
    }

    public void togglePanes(boolean canShowRealTextField) {
        if (canShowRealTextField != showingRealTextField) {
            CardLayout layout = (CardLayout)(getLayout());
            layout.next(this);
            showingRealTextField = canShowRealTextField;
        }
    }

    private TextArea tf1 = null;
    private DemoTextField tf2 = null;
    private ScrollPane sp = null;
    private boolean showingRealTextField = true;
}
