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

import java.awt.Button;
import java.awt.CheckboxMenuItem;
import java.awt.FileDialog;
import java.awt.Font;
import java.awt.Frame;
import java.awt.GraphicsEnvironment;
import java.awt.Label;
import java.awt.Menu;
import java.awt.MenuBar;
import java.awt.MenuItem;
import java.awt.MenuShortcut;
import java.awt.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.text.CharacterIterator;
import java.util.Comparator;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;

import com.ibm.icu.lang.UCharacter;
import com.ibm.icu.text.BreakIterator;
import com.ibm.icu.text.CanonicalIterator;
import com.ibm.icu.text.Normalizer;
import com.ibm.icu.text.ReplaceableString;
import com.ibm.icu.text.Transliterator;
import com.ibm.icu.text.UTF16;
import com.ibm.icu.text.UnicodeSet;
import com.ibm.icu.text.UnicodeSetIterator;

/**
 * A frame that allows the user to experiment with keyboard
 * transliteration.  This class has a main() method so it can be run
 * as an application.  The frame contains an editable text component
 * and uses keyboard transliteration to process keyboard events.
 *
 * <p>Copyright (c) IBM Corporation 1999.  All rights reserved.
 *
 * @author Alan Liu
 */
public class Demo extends Frame {

    /**
     * For serialization
     */
    private static final long serialVersionUID = 1L;
    static final boolean DEBUG = false;
    static final String START_TEXT = "(cut,\u03BA\u03C5\u03C4,\u05D0,\u30AF\u30C8,\u4E80,\u091A\u0941\u0924\u094D)";

    Transliterator translit = null;
    String fontName = "Arial Unicode MS";
    int fontSize = 18;
    
    

    /*
    boolean compound = false;
    Transliterator[] compoundTranslit = new Transliterator[MAX_COMPOUND];
    static final int MAX_COMPOUND = 128;
    int compoundCount = 0;
    */

    TransliteratingTextComponent text = null;

    Menu translitMenu;
    CheckboxMenuItem translitItem;
    CheckboxMenuItem noTranslitItem;

    static final String NO_TRANSLITERATOR = "None";

    public static void main(String[] args) {
        Frame f = new Demo(600, 200);
        f.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                com.ibm.icu.dev.demo.impl.DemoApplet.demoFrameClosed();
//                System.exit(0);
            }
        });
        f.setVisible(true);
        com.ibm.icu.dev.demo.impl.DemoApplet.demoFrameOpened();
    }

    public Demo(int width, int height) {
        super("Transliteration Demo");

        initMenus();

        addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                handleClose();
            }
        });
        
        text = new TransliteratingTextComponent();
        Font font = new Font(fontName, Font.PLAIN, fontSize);
        text.setFont(font);
        text.setSize(width, height);
        text.setVisible(true);
        text.setText(START_TEXT);
        add(text);

        setSize(width, height);
        setTransliterator("Latin-Greek", null);
    }

    private void initMenus() {
        MenuBar mbar;
        Menu menu;
        MenuItem mitem;
        //CheckboxMenuItem citem;
        
        setMenuBar(mbar = new MenuBar());
        mbar.add(menu = new Menu("File"));
        menu.add(mitem = new MenuItem("Quit"));
        mitem.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                handleClose();
            }
        });
/*
        final ItemListener setTransliteratorListener = new ItemListener() {
            public void itemStateChanged(ItemEvent e) {
                CheckboxMenuItem item = (CheckboxMenuItem) e.getSource();
                if (e.getStateChange() == ItemEvent.DESELECTED) {
                    // Don't let the current transliterator be deselected.
                    // Just reselect it.
                    item.setState(true);
                } else if (compound) {
                    // Adding an item to a compound transliterator
                    handleAddToCompound(item.getLabel());
                } else if (item != translitItem) {
                    // Deselect previous choice.  Don't need to call
                    // setState(true) on new choice.
                    translitItem.setState(false);
                    translitItem = item;
                    handleSetTransliterator(item.getLabel());
                }
            }
        };
*/
        /*
        translitMenu.add(translitItem = noTranslitItem =
                         new CheckboxMenuItem(NO_TRANSLITERATOR, true));
        noTranslitItem.addItemListener(new ItemListener() {
            public void itemStateChanged(ItemEvent e) {
                // Can't uncheck None -- any action here sets None to true
                setNoTransliterator();
            }
        });

        translitMenu.addSeparator();
        */

/*
        translitMenu.add(citem = new CheckboxMenuItem("Compound"));
        citem.addItemListener(new ItemListener() {
            public void itemStateChanged(ItemEvent e) {
                CheckboxMenuItem item = (CheckboxMenuItem) e.getSource();
                if (e.getStateChange() == ItemEvent.DESELECTED) {
                    // If compound gets deselected, then select NONE
                    setNoTransliterator();
                } else if (!compound) {
                    // Switching from non-compound to compound
                    translitItem.setState(false);
                    translitItem = item;
                    translit = null;
                    compound = true;
                    compoundCount = 0;
                    for (int i=0; i<MAX_COMPOUND; ++i) {
                        compoundTranslit[i] = null;
                    }
                }
            }
        });
      
        translitMenu.addSeparator();
       */

        /*
        for (Enumeration e=getSystemTransliteratorNames().elements();
             e.hasMoreElements(); ) {
            String s = (String) e.nextElement();
            translitMenu.add(citem = new CheckboxMenuItem(s));
            citem.addItemListener(setTransliteratorListener);
        }
        */
        
        Menu fontMenu = new Menu("Font");
        String[] fonts = GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames();
        for (int i = 0; i < fonts.length; ++i) {
            MenuItem mItem = new MenuItem(fonts[i]);
            mItem.addActionListener(new FontActionListener(fonts[i]));
            fontMenu.add(mItem);
        }
        mbar.add(fontMenu);
        
        Menu sizeMenu = new Menu("Size");
        int[] sizes = {9, 10, 12, 14, 18, 24, 36, 48, 72};
        for (int i = 0; i < sizes.length; ++i) {
            MenuItem mItem = new MenuItem("" + sizes[i]);
            mItem.addActionListener(new SizeActionListener(sizes[i]));
            sizeMenu.add(mItem);
        }
        mbar.add(sizeMenu);
        
        translit = null;
        
        mbar.add(translitMenu = new Menu("Transliterator"));
        
        translitMenu.add(convertSelectionItem = new MenuItem("Transliterate", 
            new MenuShortcut(KeyEvent.VK_K)));
        convertSelectionItem.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                handleBatchTransliterate(translit);
            }
        });
        
        translitMenu.add(swapSelectionItem = new MenuItem("Reverse", 
            new MenuShortcut(KeyEvent.VK_S)));
        swapSelectionItem.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                Transliterator inv;
                try {
                    inv = translit.getInverse();
                } catch (Exception x) {
                    inv = Transliterator.getInstance("null");
                }
                setTransliterator(inv.getID(), null);
            }
        });
        
        translitMenu.add(convertTypingItem = new MenuItem("No Typing Conversion",
            new MenuShortcut(KeyEvent.VK_T)));
        convertTypingItem.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                if (!transliterateTyping) {
                    text.setTransliterator(translit);
                    convertTypingItem.setLabel("No Typing Conversion");
                } else {
                    text.flush();
                    text.setTransliterator(null);
                    convertTypingItem.setLabel("Convert Typing");
                }
                transliterateTyping = !transliterateTyping;
            }
        });
        
        translitMenu.add(historyMenu = new Menu("Recent"));
        
        helpDialog = new InfoDialog(this, "Simple Demo", "Instructions",
           "CTL A, X, C, V have customary meanings.\n"
         + "Arrow keys, delete and backspace work.\n"
         + "To get a character from its control point, type the hex, then hit CTL Q"
        );
        helpDialog.getArea().setEditable(false);
        
       
        Menu helpMenu;
        mbar.add(helpMenu = new Menu("Extras"));
        helpMenu.add(mitem = new MenuItem("Help"));
        mitem.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                helpDialog.show();
            }
        });   
        
        hexDialog = new InfoDialog(this, "Hex Entry", "Use U+..., \\u..., \\x{...}, or &#x...;",
           "\\u00E1"
        );
        Button button = new Button("Insert");
        button.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                String hexValue = hexDialog.getArea().getText();
                text.insertText(fromHex.transliterate(hexValue));
            }
        });
        hexDialog.getBottom().add(button);
        
        helpMenu.add(mitem = new MenuItem("Hex...", 
            new MenuShortcut(KeyEvent.VK_H)));
        mitem.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                hexDialog.show();
            }
        });
        
        // Compound Transliterator
        
        compoundDialog = new InfoDialog(this, "Compound Transliterator", "",
           "[^\\u0000-\\u00FF] hex"
        );
        button = new Button("Set");
        button.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                String compound = "";
                try {
                    compound = compoundDialog.getArea().getText();
                    setTransliterator(compound, null);
                } catch (RuntimeException ex) {
                    compoundDialog.getArea().setText(compound + "\n" + ex.getMessage());
                }
            }
        });
        compoundDialog.getBottom().add(button);
        
        translitMenu.add(mitem = new MenuItem("Multiple...", 
            new MenuShortcut(KeyEvent.VK_M)));
        mitem.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                compoundDialog.show();
            }
        });
        
        // RuleBased Transliterator
        
        rulesDialog = new InfoDialog(this, "Rule-Based Transliterator", "",
           "([A-Z]) > &Hex($1) &Name($1);\r\n" 
            + "&Hex-Any($1) < ('\\' [uU] [a-fA-F0-9]*);\r\n" 
            + "&Name-Any($1) < ('{' [^\\}]* '}');"
        );
        button = new Button("Set");
        button.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                String compound = "";
                try {
                    compound = rulesDialog.getArea().getText();
                    String id = ruleId.getText();
                    setTransliterator(compound, id);
                } catch (RuntimeException ex) {
                    rulesDialog.getArea().setText(compound + "\n#" + ex.getMessage());
                }
            }
        });
        rulesDialog.getBottom().add(button);
        ruleId = new TextField("test1", 20);
        Label temp = new Label(" Name:");
        rulesDialog.getBottom().add(temp);
        rulesDialog.getBottom().add(ruleId);
        
        
        translitMenu.add(mitem = new MenuItem("From Rules...", 
            new MenuShortcut(KeyEvent.VK_R)));
        mitem.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                rulesDialog.show();
            }
        });
        
        
        translitMenu.add(mitem = new MenuItem("From File...", 
            new MenuShortcut(KeyEvent.VK_F)));
        mitem.addActionListener(new FileListener(this, RULE_FILE));
        
        translitMenu.add(mitem = new MenuItem("Test File..."));
        mitem.addActionListener(new FileListener(this, TEST_FILE));
        
        // Flesh out the menu with the installed transliterators
        
        translitMenu.addSeparator();
        
        Iterator sources = add(new TreeSet(), Transliterator.getAvailableSources()).iterator();
        while(sources.hasNext()) {
            String source = (String) sources.next();
            Iterator targets = add(new TreeSet(), Transliterator.getAvailableTargets(source)).iterator();
            Menu targetMenu = new Menu(source);
            while(targets.hasNext()) {
                String target = (String) targets.next();
                Set variantSet = add(new TreeSet(), Transliterator.getAvailableVariants(source, target));
                if (variantSet.size() < 2) {
                    mitem = new MenuItem(target);
                    mitem.addActionListener(new TransliterationListener(source + "-" + target));
                    targetMenu.add(mitem);
                } else {
                    Iterator variants = variantSet.iterator();
                    Menu variantMenu = new Menu(target);
                    while(variants.hasNext()) {
                        String variant = (String) variants.next();
                        String menuName = variant.length() == 0 ? "<default>" : variant;
                        //System.out.println("<" + source + "-" + target + "/" + variant + ">, <" + menuName + ">");
                        mitem = new MenuItem(menuName);
                        mitem.addActionListener(new TransliterationListener(source + "-" + target + "/" + variant));
                        variantMenu.add(mitem);
                    }
                    targetMenu.add(variantMenu);
                }
            }
            translitMenu.add(targetMenu);
        }
        
        
    }
    
    static final int RULE_FILE = 0, TEST_FILE = 1;
    //
    static class FileListener implements ActionListener {
        Demo frame;
        int choice;
        
        FileListener(Demo frame, int choice) {
            this.frame = frame;
            this.choice = choice;
        }
        
        public void actionPerformed(ActionEvent e) {
            String id = frame.translit.getID();
            int slashPos = id.indexOf('/');
            String variant = "";
            if (slashPos >= 0) {
                variant = "_" + id.substring(slashPos+1);
                id = id.substring(0, slashPos);
            }
            
            FileDialog fileDialog = new FileDialog(frame, "Input File");
            fileDialog.setFile("Test_" + id + ".txt");
            fileDialog.show();
            String fileName = fileDialog.getFile();
            String fileDirectory = fileDialog.getDirectory();
            if (fileName != null) {
                try {
                    File f = new File(fileDirectory, fileName);
                    if (choice == RULE_FILE) {
                        
                        // read stuff into buffer
                        
                        StringBuffer buffer = new StringBuffer();
                        FileInputStream fis = new FileInputStream(f);
                        InputStreamReader isr = new InputStreamReader(fis, "UTF8");
                        BufferedReader br = new BufferedReader(isr, 32*1024);
                        while (true) {
                            String line = br.readLine();
                            if (line == null) break;
                            if (line.length() > 0 && line.charAt(0) == '\uFEFF') line = line.substring(1); // strip BOM
                            buffer.append('\n');
                            buffer.append(line);
                        }
                        br.close();
                        
                        // Transform file name into id
                        if (fileName.startsWith("Transliterator_")) {
                            fileName = fileName.substring("Transliterator_".length());
                        }
                        int pos = fileName.indexOf('_');
                        if (pos < 0) {
                            id = fileName;
                        } else {
                            id = fileName.substring(0, pos) + "-";
                            int pos2 = fileName.indexOf('_', pos+1);
                            if (pos2 < 0) {
                                id += fileName.substring(pos+1);
                            } else {
                                id += fileName.substring(pos+1, pos2) + "/" + fileName.substring(pos2 + 1);
                            }
                        }                        
                        pos = id.lastIndexOf('.');
                        if (pos >= 0) id = id.substring(0, pos);
                        
                        // Now set
                        
                        frame.setTransliterator(buffer.toString(), id);
                    } else if (choice == TEST_FILE) {
                        genTestFile(f, frame.translit, variant);
                    }
                } catch (Exception e2) {
                    e2.printStackTrace();
                    System.out.println("Problem opening/reading: " + fileDirectory + ", " + fileName);
                }
            }
            fileDialog.dispose();
        }
    }
    

    boolean transliterateTyping = true;
    Transliterator fromHex = Transliterator.getInstance("Hex-Any");
    InfoDialog helpDialog;
    InfoDialog hexDialog;
    InfoDialog compoundDialog;
    InfoDialog rulesDialog;
    TextField ruleId;
    MenuItem convertSelectionItem = null;
    MenuItem swapSelectionItem = null;
    MenuItem convertTypingItem = null;
    Menu historyMenu;
    Map historyMap = new HashMap();
    Set historySet = new TreeSet(new Comparator() {
            public int compare(Object a, Object b) {
                MenuItem aa = (MenuItem)a;
                MenuItem bb = (MenuItem)b;
                return aa.getLabel().compareTo(bb.getLabel());
            }
        });
        
    // ADD Factory since otherwise getInverse blows out
    static class DummyFactory implements Transliterator.Factory {
        static DummyFactory singleton = new DummyFactory();
        static HashMap m = new HashMap();

        // Since Transliterators are immutable, we don't have to clone on set & get
        static void add(String ID, Transliterator t) {
            m.put(ID, t);
            System.out.println("Registering: " + ID + ", " + t.toRules(true));
            Transliterator.registerFactory(ID, singleton);
        }
        public Transliterator getInstance(String ID) {
            return (Transliterator) m.get(ID);
        }
    }
    
    static void printBreaks(int num, String testSource, BreakIterator brkItr) {
        String result = "";
        int lastPos = 0;
        while (true) {
            int pos = brkItr.next();
            if (pos == BreakIterator.DONE) break;
            result += testSource.substring(lastPos, pos) + "&";
            lastPos = pos;
            System.out.println(pos);
        }
        System.out.println("Test" + num + ": " + result);
    }
    
    static void printIteration(int num, String testSource, CharacterIterator ci) {
        String result = "";
        while (true) {
            char ch = ci.next();
            if (ch == CharacterIterator.DONE) break;
            result += ch + "(" + ci.getIndex() + ")";
        }
        System.out.println("Test" + num + ": " + result);
    }
    
    static void printSources() {
        String[] list = {"Latin-ThaiLogical", "ThaiLogical-Latin", "Thai-ThaiLogical", "ThaiLogical-Thai"};
        UnicodeSet all = new UnicodeSet();
        for (int i = 0; i < list.length; ++i) {
            Transliterator tr = Transliterator.getInstance(list[i]);
            UnicodeSet src = tr.getSourceSet();
            System.out.println(list[i] + ": " + src.toPattern(true));
            all.addAll(src);
        }
        System.out.println("All: " + all.toPattern(true));
        UnicodeSet rem = new UnicodeSet("[[:latin:][:thai:]]");
        System.out.println("missing from [:latin:][:thai:]: " + all.removeAll(rem).toPattern(true));
    }
    
    // 200E;LEFT-TO-RIGHT MARK;Cf;0;L;;;;;N;;;;;

    static Transliterator title = Transliterator.getInstance("title");
    static String hexAndNameRules = "    ([:c:]) > \\u200E &hex/unicode($1) ' ( ) ' &name($1) \\u200E ' ';"
        + "([:mark:]) > \\u200E &hex/unicode($1) ' ( ' \\u200E \u25CC $1 \\u200E ' ) ' &name($1) \\u200E ' ';"
        + "(.) > \\u200E &hex/unicode($1) ' ( ' \\u200E $1 \\u200E ' ) ' &name($1) ' ' \\u200E;";

    static Transliterator hexAndName = Transliterator.createFromRules("any-hexAndName", 
        hexAndNameRules, Transliterator.FORWARD);
    


    //static Transliterator upper = Transliterator.getInstance("upper");
     
    static final byte NONE = 0, TITLEWORD = 1, TITLELINE = 2;
    
    static void genTestFile(File sourceFile, Transliterator translit, String variant) {
        BufferedReader in = null;
        try {
            
            System.out.println("Reading: " + sourceFile.getCanonicalPath());
            in = new BufferedReader(
                new InputStreamReader(
                    new FileInputStream(sourceFile), "UTF-8"));
            String targetFile = sourceFile.getCanonicalPath();
            int dotPos = targetFile.lastIndexOf('.');
            if (dotPos >= 0) targetFile = targetFile.substring(0,dotPos);
            targetFile += variant;
            
            File outFile = new File(targetFile + ".html");
            System.out.println("Writing: " + outFile.getCanonicalPath());
            
            PrintWriter out = new PrintWriter(
                new BufferedWriter(
                    new OutputStreamWriter(
                        new FileOutputStream(outFile), "UTF-8")));
                        
            String direction = "";
            String id = translit.getID();
            if (id.indexOf("Arabic") >= 0 || id.indexOf("Hebrew") >= 0) {
                direction = " direction: rtl;";
            }
            boolean testRoundTrip = true;
            boolean generateSets = true;
            if (id.startsWith("Han-") || id.startsWith("ja-")) {
                testRoundTrip = false;
                generateSets = false;
            }
            out.println("<head><meta http-equiv='Content-Type' content='text/html; charset=utf-8'>");
            out.println("<style><!--");
            out.println("td, th       { vertical-align: top; border: 1px solid black }");
            out.println("td.s       { background-color: #EEEEEE;" + direction + " }");
            out.println("td.r       { background-color: #CCCCCC;" + direction + " }");
            out.println("td.n       { background-color: #FFFFCC; }");
            out.println("td.title       { border: 0px solid black}");
            out.println("span.d       { background-color: #FF6666 }");
            out.println("span.r       { background-color: #66FF66 }");

            out.println("body         { font-family: 'Arial Unicode MS', 'Lucida Sans Unicode', Arial, sans-serif; margin: 5 }");
            out.println("--></style>");
            out.println("<title>" + id + " Transliteration Check</title></head>");
            out.println("<body bgcolor='#FFFFFF'><p>See <a href='Test_Instructions.html'>Test_Instructions.html</a> for details.</p>");
            out.println("<table>");
            
            //out.println("<tr><th width='33%'>Thai</th><th width='33%'>Latin</th><th width='33%'>Thai</th></tr>");
  
            Transliterator tl = translit;
            Transliterator lt = tl.getInverse();
            
            Transliterator ltFilter = tl.getInverse();
            ltFilter.setFilter(new UnicodeSet("[:^Lu:]"));
            Transliterator tlFilter = lt.getInverse();
            tlFilter.setFilter(new UnicodeSet("[:^Lu:]"));
            
            //Transliterator.getInstance("[:^Lu:]" +  lt.getID());
            
            BreakIterator sentenceBreak = BreakIterator.getSentenceInstance();
            
            byte titleSetting = TITLELINE;
            //boolean upperfilter = false;
            boolean first = true;
            while (true) {
                String line = in.readLine();
                if (line == null) break;
                line = line.trim();
                if (line.length() == 0) continue;
                if (line.charAt(0) == '\uFEFF') line = line.substring(1); // remove BOM
                
                if (line.charAt(0) == '#') continue; // comments
                
                if (line.equals("@TITLECASE@")) {
                    titleSetting = TITLEWORD;
                    out.println("<tr><td colspan='2' class='title'><b>Names</b></td></tr>");
                    continue;
                } else if (line.equals("@UPPERFILTER@")) {
                    //upperfilter = true;
                    continue;
                } else if (line.startsWith("@SET")) {
                    UnicodeSet s = new UnicodeSet(line.substring(4).trim());
                    out.println("<tr><td colspan='2' class='title'><b>Characters</b></td></tr>");
                    UnicodeSetIterator it = new UnicodeSetIterator(s);
                    while (it.next()) {
                        addSentenceToTable(out, it.codepoint != UnicodeSetIterator.IS_STRING 
                            ? UTF16.valueOf(it.codepoint)
                            : it.string,
                            NONE, true, testRoundTrip, first, tl, lt);
                    }
                    continue;
                }
                        
                sentenceBreak.setText(line);
                int start = 0;
                while (true) {
                    int end = sentenceBreak.next();
                    if (end == BreakIterator.DONE) break;
                    String coreSentence = line.substring(start, end);
                    //System.out.println("Core: " + hex.transliterate(coreSentence));
                    end = start;
                    
                    int oldPos = 0;
                    while (oldPos < coreSentence.length()) {
                        // hack, because sentence doesn't seem to be working right
                        int pos = coreSentence.indexOf(". ", oldPos);
                        if (pos < 0) pos = coreSentence.length(); else pos = pos+2;
                        int pos2 = coreSentence.indexOf('\u3002', oldPos);
                        if (pos2 < 0) pos2 = coreSentence.length(); else pos2 = pos2 + 1;
                        if (pos > pos2) pos = pos2;
                        String sentence = coreSentence.substring(oldPos, pos).trim();
                        //System.out.println("Sentence: " + hex.transliterate(coreSentence));
                        oldPos = pos;
                        
                        addSentenceToTable(out, sentence,
                            titleSetting, false, testRoundTrip, first, tl, lt);
                        
                        first = false;
                    }
                }
            }
            out.println("</table></body>");
            out.close();
            
            // Now write the source/target sets
            if (generateSets) {
                outFile = new File(targetFile + "_Sets.html");
                System.out.println("Writing: " + outFile.getCanonicalPath());
                
                out = new PrintWriter(
                    new BufferedWriter(
                        new OutputStreamWriter(
                            new FileOutputStream(outFile), "UTF-8")));
                out.println("<head><meta http-equiv='Content-Type' content='text/html; charset=utf-8'>");
                out.println("<style><!--");
                out.println("body         { font-family: 'Arial Unicode MS', 'Lucida Sans Unicode', Arial, sans-serif; margin: 5 }");
                out.println("--></style>");
                out.println("<title>" + id + " Transliteration Sets</title></head>");
                out.println("<body bgcolor='#FFFFFF'>");
                
                int dashPos = id.indexOf('-');
                int slashPos = id.indexOf('/');
                if (slashPos < 0) slashPos = id.length();
                UnicodeSet sourceSuper = null;
                try {
                    String temp = id.substring(0,dashPos);
                    if (temp.equals("ja")) sourceSuper = new UnicodeSet("[[:Han:][:hiragana:][:katakana:]]");
                    else sourceSuper = new UnicodeSet("[[:" + temp + ":][:Mn:][:Me:]]");
                } catch (Exception e) {}
                
                UnicodeSet targetSuper = null;
                try {
                    targetSuper = new UnicodeSet("[[:" + id.substring(dashPos+1, slashPos) + ":][:Mn:][:Me:]]");
                } catch (Exception e) {}
                
                int nfdStyle = CLOSE_CASE | CLOSE_FLATTEN | CLOSE_CANONICAL;
                int nfkdStyle = nfdStyle | CLOSE_COMPATIBILITY;
                out.println("<ul>");
                out.println("<p><b>None</b></p>");
                showSets(out, translit, lt, null, null, 0);
                out.println("<p><b>NFD</b></p>");
                showSets(out, translit, lt, sourceSuper, targetSuper, nfdStyle);
                out.println("<p><b>NFKD</b></p>");
                showSets(out, translit, lt, sourceSuper, targetSuper, nfkdStyle);
                out.println("</ul></body>");
                out.close();
            }
            System.out.println("Done Writing");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (Exception e) {
                    // ignore
                }
            }
        }
    }
    
    static void addSentenceToTable(PrintWriter out, String sentence, 
            byte titleSetting, boolean addName, boolean testRoundTrip, boolean first,
            Transliterator tl, Transliterator lt) {
        if (sentence.length() == 0) return; // skip empty lines
        
        String originalShow = sentence;
        String latin;
        latin = tl.transliterate(saveAscii.transliterate(sentence));

        String latinShow = latin;
        if (titleSetting == TITLEWORD) {
            latinShow = title.transliterate(latin);
        } else if (titleSetting == TITLELINE) {
            latinShow = titlecaseFirstWord(latinShow);
        }
        latinShow = restoreAscii.transliterate(latinShow);
                        
        String reverse;
        reverse = restoreAscii.transliterate(lt.transliterate(latin));
                        
        String NFKDSentence = Normalizer.normalize(sentence, Normalizer.NFKD);
        String NFKDLatin = Normalizer.normalize(latin, Normalizer.NFKD);
        String NFKDReverse = Normalizer.normalize(reverse, Normalizer.NFKD);
        
        if (latinShow.length() == 0) {
            latinShow = "<i>empty</i>";
        } else if (NFKDSentence.equals(NFKDLatin)) {
            latinShow = "<span class='r'>" + latinShow + "</span>";
        }
        String reverseShow = reverse;
        
        if (testRoundTrip && !NFKDReverse.equals(NFKDSentence)) {
            int minLen = reverse.length();
            if (minLen > sentence.length()) minLen = sentence.length();
            int i;
            for (i = 0; i < minLen; ++i) {
                if (reverse.charAt(i) != sentence.charAt(i)) break;
            }
            //originalShow = sentence.substring(0,i) + "<span class='d'>" + sentence.substring(i) + "</span>";
            reverseShow = reverseShow.length() == 0 
                ? "<i>empty</i>" 
                //: reverse.substring(0,i) + "<span class='d'>" + reverse.substring(i) + "</span>";
                : showDifference(sentence, reverse);
            out.println("<tr><td class='s'" + (first ? " width='50%'>" : ">") + originalShow 
                + "</td><td rowSpan='2'>" + latinShow
                + "</td></tr><tr><td class='r'>" + reverseShow
                + "</td></tr>");
        } else {
            out.println("<tr><td class='s'" + (first ? " width='50%'>" : ">") + originalShow 
                + "</td><td>" + latinShow
                + "</td></tr>");
        }
        if (addName) {
            latinShow = hexAndName.transliterate(latin);
            if (latinShow.length() == 0) latinShow = "<i>empty</i>";
            originalShow = hexAndName.transliterate(sentence);
            if (originalShow.length() == 0) originalShow = "<i>empty</i>";

            out.println("<tr><td class='n'>" + originalShow
                + "</td><td class='n'>" + latinShow
                + "</td></tr>");
        }
        out.println("<tr><td></td></tr>");
        
    }

    static String showDifference(String as, String bs) {
        IntDiffer differ = new IntDiffer(300, 3);
        StringBuilder out = new StringBuilder();
        int ia = 0;
        int ib = 0;
        boolean done;
        do {
            done = true;
            if (ia < as.length()) {
                int ca = as.codePointAt(ia);
                ia += Character.charCount(ca);
                differ.addA(ca);
                done = false;
            }
            if (ib < bs.length()) {
                int cb = bs.codePointAt(ib);
                ib += Character.charCount(cb);
                differ.addB(cb);
                done = false;
            }
            differ.checkMatch(done);

            if (differ.getACount() != 0 || differ.getBCount() != 0) {
                out.append("...");
                if (differ.getACount() != 0) {
                    out.append("<span class='r'>");
                    for (int i = 0; i < differ.getACount(); ++i) {
                        out.appendCodePoint(differ.getA(i));
                    }
                    out.append("</span>");
                }
                if (differ.getBCount() != 0) {
                    out.append("<span class='d'>");
                    for (int i = 0; i < differ.getBCount(); ++i) {
                        out.appendCodePoint(differ.getB(i));
                    }
                    out.append("</span>");
                }
                out.append("...");
            }
        } while (!done);
        return out.toString();
    }

    static void showSets(PrintWriter out, Transliterator translit, Transliterator inverse,
      UnicodeSet sourceSuper, UnicodeSet targetSuper, int options) {
        out.println("<li>Source Set:<ul><li>" +         toPattern(closeUnicodeSet(translit.getSourceSet(), options), sourceSuper) + "</li></ul></li>");
        out.println("<li>Reverse Target Set:<ul><li>" + toPattern(closeUnicodeSet(inverse.getTargetSet(),  options), sourceSuper) + "</li></ul></li>");
        out.println("<li>Target Set:<ul><li>" +         toPattern(closeUnicodeSet(translit.getTargetSet(), options), targetSuper) + "</li></ul></li>");
        out.println("<li>Reverse Source Set:<ul><li>" + toPattern(closeUnicodeSet(inverse.getSourceSet(),  options), targetSuper) + "</li></ul></li>");
    }
        
    static final int CLOSE_CASE = 1, CLOSE_FLATTEN = 2, CLOSE_CANONICAL = 4, CLOSE_COMPATIBILITY = 8;
    
    static UnicodeSet closeUnicodeSet(UnicodeSet source, int options) {
        if (options == 0) return source;
        
        UnicodeSetIterator it = new UnicodeSetIterator(source);
        UnicodeSet additions = new UnicodeSet(); // to avoid messing up iterator
        UnicodeSet removals = new UnicodeSet(); // to avoid messing up iterator
        String base;
        int cp;
        
        // Add all case equivalents
        if ((options & CLOSE_CASE) != 0) {
            while (it.next()) {
                cp = it.codepoint;
                if (cp == UnicodeSetIterator.IS_STRING) continue;
                int type = UCharacter.getType(cp);
                if (type == Character.UPPERCASE_LETTER || type == Character.LOWERCASE_LETTER || type == Character.TITLECASE_LETTER) {
                    additions.add(UCharacter.toLowerCase(UTF16.valueOf(cp)));
                    additions.add(UCharacter.toUpperCase(UTF16.valueOf(cp)));
                }
            }
            source.addAll(additions);
        }
       
        // Add the canonical closure of all strings and characters in source
        if ((options & CLOSE_CANONICAL) != 0) {
            it.reset();
            additions.clear();
            CanonicalIterator ci = new CanonicalIterator(".");
            while (it.next()) {
                if (it.codepoint == UnicodeSetIterator.IS_STRING) base = it.string;
                else base = UTF16.valueOf(it.codepoint);
                ci.setSource(base);
                while (true) {
                    String trial = ci.next();
                    if (trial == null) break;
                    if (trial.equals(base)) continue;
                    additions.add(trial);
                }
            }
            source.addAll(additions);
        }

        // flatten strings
        if ((options & CLOSE_FLATTEN) != 0) {
            it.reset();
            additions.clear();
            while (it.next()) {
                if (it.codepoint != UnicodeSetIterator.IS_STRING) continue;
                additions.addAll(it.string);
                removals.add(it.string);
                //System.out.println("flattening '" + hex.transliterate(it.string) + "'");
            }
            source.addAll(additions);
            source.removeAll(removals);
        }
       
        // Now add decompositions of characters in source
        if ((options & CLOSE_COMPATIBILITY) != 0) {
            it.reset(source);
            additions.clear();
            while (it.next()) {
                if (it.codepoint == UnicodeSetIterator.IS_STRING) base = it.string;
                else base = UTF16.valueOf(it.codepoint);
                if (Normalizer.isNormalized(base, Normalizer.NFKD,0)) continue;
                String decomp = Normalizer.normalize(base, Normalizer.NFKD);
                additions.add(decomp);
            }
            source.addAll(additions);
            
            // Now add any other character that decomposes to a character in source
            for (cp = 0; cp < 0x10FFFF; ++cp) {
                if (!UCharacter.isDefined(cp)) continue;
                if (Normalizer.isNormalized(cp, Normalizer.NFKD,0)) continue;
                if (source.contains(cp)) continue;
                
                String decomp = Normalizer.normalize(cp, Normalizer.NFKD);
                if (source.containsAll(decomp)) {
                    // System.out.println("Adding: " + Integer.toString(cp,16) + " " + UCharacter.getName(cp));
                    source.add(cp);
                }
            }
        }
        
        return source;
    }
    
    static String toPattern(UnicodeSet source, UnicodeSet superset) {
        if (superset != null) {
            source.removeAll(superset);
            return "[" + superset.toPattern(true) + " " + source.toPattern(true) + "]";
        }
        return source.toPattern(true);
    }
    
    static BreakIterator bi = BreakIterator.getWordInstance();
    
    static String titlecaseFirstWord(String line) {
        // search for first word with letters. If the first letter is lower, then titlecase it.
        bi.setText(line);
        int start = 0;
        while (true) {
            int end = bi.next();
            if (end == BreakIterator.DONE) break;
            int firstLetterType = getFirstLetterType(line, start, end);
            if (firstLetterType != Character.UNASSIGNED) {
                if (firstLetterType != Character.LOWERCASE_LETTER) break;
                line = line.substring(0, start) 
                    + UCharacter.toTitleCase(line.substring(start, end), bi)
                    + line.substring(end);
                break;
            }
            end = start;
        }
        return line;
    }
    
    static final int LETTER_MASK = 
          (1<<Character.UPPERCASE_LETTER)
        | (1<<Character.LOWERCASE_LETTER)
        | (1<<Character.TITLECASE_LETTER)
        | (1<<Character.MODIFIER_LETTER)
        | (1<<Character.OTHER_LETTER)
        ;
    
    static int getFirstLetterType(String line, int start, int end) {
        int cp;
        for (int i = start; i < end; i += UTF16.getCharCount(cp)) {
            cp = UTF16.charAt(line, i);
            int type = UCharacter.getType(cp);
            if (((1<<type) & LETTER_MASK) != 0) return type;
        }
        return Character.UNASSIGNED;
    }
    
    static void printNames(UnicodeSet s, String targetFile) {
        try {
            File outFile = new File(targetFile);
            System.out.println("Writing: " + outFile.getCanonicalPath());
                
            PrintWriter out = new PrintWriter(
                new BufferedWriter(
                    new OutputStreamWriter(
                        new FileOutputStream(outFile), "UTF-8")));
            UnicodeSet main = new UnicodeSet();
            
            UnicodeSet others = new UnicodeSet();
            UnicodeSetIterator it = new UnicodeSetIterator(s);
            while (it.next()) {
                if (!UCharacter.isDefined(it.codepoint)) continue;
                if (!Normalizer.isNormalized(it.codepoint, Normalizer.NFD,0)) {
                    String decomp = Normalizer.normalize(it.codepoint, Normalizer.NFD);
                    others.addAll(decomp);
                    continue;
                }
                out.println(" " + UTF16.valueOf(it.codepoint) + " <> XXX # " + UCharacter.getName(it.codepoint));
                main.add(it.codepoint);
            }
            
            if (others.size() != 0) {
                out.println("Decomposed characters found above: ");
                others.removeAll(main);
                it.reset(others);
                while (it.next()) {
                    out.println(" " + UTF16.valueOf(it.codepoint) + " <> XXX # " + UCharacter.getName(it.codepoint));
                }
            }
            
            out.close();
            System.out.println("Done Writing");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    static Transliterator hex = Transliterator.getInstance("[^\\u0020-\\u007E] hex");
    static final String saveRules = 
          "A <> \uEA41; B <> \uEA42; C <> \uEA43; D <> \uEA44; E <> \uEA45; F <> \uEA46; G <> \uEA47; H <> \uEA48; I <> \uEA49; "
        + "J <> \uEA4A; K <> \uEA4B; L <> \uEA4C; M <> \uEA4D; N <> \uEA4E; O <> \uEA4F; P <> \uEA50; Q <> \uEA51; R <> \uEA52; "
        + "S <> \uEA53; T <> \uEA54; U <> \uEA55; V <> \uEA56; W <> \uEA57; X <> \uEA58; Y <> \uEA59; Z <> \uEA5A; "
        + "a <> \uEA61; b <> \uEA62; c <> \uEA63; d <> \uEA64; e <> \uEA65; f <> \uEA66; g <> \uEA67; h <> \uEA68; i <> \uEA69; "
        + "j <> \uEA6A; k <> \uEA6B; l <> \uEA6C; m <> \uEA6D; n <> \uEA6E; o <> \uEA6F; p <> \uEA70; q <> \uEA71; r <> \uEA72; "
        + "s <> \uEA73; t <> \uEA74; u <> \uEA75; v <> \uEA76; w <> \uEA77; x <> \uEA78; y <> \uEA79; z <> \uEA7A;";
        
    static Transliterator saveAscii = Transliterator.createFromRules("ascii-saved", saveRules, Transliterator.FORWARD);
    static Transliterator restoreAscii = Transliterator.createFromRules("ascii-saved", saveRules, Transliterator.REVERSE);
    
    static {
        
        if (false) {
        
        for (char i = 'A'; i <= 'z'; ++i) {
            System.out.print(i + " <> " + hex.transliterate(String.valueOf((char)(0xEA00 + i))) + "; ");
        }

        UnicodeSet x = new UnicodeSet("[[:^ccc=0:]&[:^ccc=230:]]");
        x = x.complement();
        x = x.complement();
        System.out.println("Test: " + x.toPattern(true));
        
        Transliterator y = Transliterator.createFromRules("xxx", "$notAbove = [[:^ccc=0:]&[:^ccc=230:]]; u ($notAbove*) \u0308 > XXX | $1; ", Transliterator.FORWARD);
        
        String[] testList = {"u\u0308", "u\u0316\u0308", "u\u0308\u0316", "u\u0301\u0308", "u\u0308\u0301"};
        for (int i = 0; i < testList.length; ++i) {
            String yy = y.transliterate(testList[i]);
            System.out.println(hex.transliterate(testList[i]) + " => " + hex.transliterate(yy));
        }
        
        //printNames(new UnicodeSet("[\u0600-\u06FF]"), "Arabic-Latin.txt");
        
        
        /*  
        BreakTransliterator.register();
        
        BreakTransliterator testTrans = new BreakTransliterator("Any-XXX", null, null, "$");
        String testSource = "The Quick:   Brown fox--jumped.";
        BreakIterator bi = testTrans.getBreakIterator();
        bi.setText(new StringCharacterIterator(testSource));
        printBreaks(0, testSource, bi);
        //bi.setText(UCharacterIterator.getInstance(testSource));
        //printBreaks(1, testSource, bi);
        
        printIteration(2, testSource, new StringCharacterIterator(testSource));
        //printIteration(3, testSource, UCharacterIterator.getInstance(testSource));
        
        
        
        String test = testTrans.transliterate(testSource);
        System.out.println("Test3: " + test);
        DummyFactory.add(testTrans.getID(), testTrans);
        */
        
        // AnyTransliterator.ScriptRunIterator.registerAnyToScript();
        
        AnyTransliterator at = new AnyTransliterator("Greek", null);
        at.transliterate("(cat,\u03b1,\u0915)");
        DummyFactory.add(at.getID(), at);
        
        at = new AnyTransliterator("Devanagari", null);
        at.transliterate("(cat,\u03b1,\u0915)");
        DummyFactory.add(at.getID(), at);
        
        at = new AnyTransliterator("Latin", null);
        at.transliterate("(cat,\u03b1,\u0915)");
        DummyFactory.add(at.getID(), at);
        
        DummyFactory.add("Any-gif", Transliterator.createFromRules("gif", "'\\'u(..)(..) > '<img src=\"http://www.unicode.org/gifs/24/' $1 '/U' $1$2 '.gif\">';", Transliterator.FORWARD));        
        DummyFactory.add("gif-Any", Transliterator.getInstance("Any-Null"));        

        DummyFactory.add("Any-RemoveCurly", Transliterator.createFromRules("RemoveCurly", "[\\{\\}] > ;", Transliterator.FORWARD));        
        DummyFactory.add("RemoveCurly-Any", Transliterator.getInstance("Any-Null"));
        
        System.out.println("Trying &hex");
        Transliterator t = Transliterator.createFromRules("hex2", "(.) > &hex($1);", Transliterator.FORWARD);
        System.out.println("Registering");
        DummyFactory.add("Any-hex2", t);        
        
        System.out.println("Trying &gif");
        t = Transliterator.createFromRules("gif2", "(.) > &any-gif($1);", Transliterator.FORWARD);
        System.out.println("Registering");
        DummyFactory.add("Any-gif2", t);    
        }
    }
    
    
    void setTransliterator(String name, String id) {
        if (DEBUG) System.out.println("Got: " + name);
        if (id == null) {
            translit = Transliterator.getInstance(name);
        } else {
            String reverseId = "";
            int pos = id.indexOf('-');
            if (pos < 0) {
                reverseId = id + "-Any";
                id = "Any-" + id;
            } else {
                int pos2 = id.indexOf("/", pos);
                if (pos2 < 0) {
                    reverseId = id.substring(pos+1) + "-" + id.substring(0,pos);
                } else {
                    reverseId = id.substring(pos+1, pos2) + "-" + id.substring(0,pos) + id.substring(pos2);
                }
            }
            
            
            translit = Transliterator.createFromRules(id, name, Transliterator.FORWARD);
            if (DEBUG) {
                System.out.println("***Forward Rules");
                System.out.println(translit.toRules(true));
                System.out.println("***Source Set");
                System.out.println(translit.getSourceSet().toPattern(true));
            }
                System.out.println("***Target Set");
                UnicodeSet target = translit.getTargetSet();
                System.out.println(target.toPattern(true));
                UnicodeSet rest = new UnicodeSet("[a-z]").removeAll(target);
                System.out.println("***ASCII - Target Set");
                System.out.println(rest.toPattern(true));
                
            DummyFactory.add(id, translit);
            
            Transliterator translit2 = Transliterator.createFromRules(reverseId, name, Transliterator.REVERSE);
            if (DEBUG) {
                System.out.println("***Backward Rules");
                System.out.println(translit2.toRules(true));
            }
            DummyFactory.add(reverseId, translit2);
            
            Transliterator rev = translit.getInverse();
            if (DEBUG) System.out.println("***Inverse Rules");
            if (DEBUG) System.out.println(rev.toRules(true));
            
        }
        text.flush();
        text.setTransliterator(translit);
        convertSelectionItem.setLabel(Transliterator.getDisplayName(translit.getID()));
        
        addHistory(translit);
        
        Transliterator inv;
        try {
            inv = translit.getInverse();
        } catch (Exception ex) {
            inv = null;
        }
        if (inv != null) {
            addHistory(inv);
            swapSelectionItem.setEnabled(true);
        } else {
            swapSelectionItem.setEnabled(false);
        }
        System.out.println("Set transliterator: " + translit.getID()
            + (inv != null ? " and " + inv.getID() : ""));
    }
    
    void addHistory(Transliterator trans) {
        String name = trans.getID();
        MenuItem cmi = (MenuItem) historyMap.get(name);
        if (cmi == null) {
            cmi = new MenuItem(Transliterator.getDisplayName(name));
            cmi.addActionListener(new TransliterationListener(name));
            historyMap.put(name, cmi);
            historySet.add(cmi);
            historyMenu.removeAll();
            Iterator it = historySet.iterator();
            while (it.hasNext()) {
                historyMenu.add((MenuItem)it.next());
            }
        }
    }
    
    class TransliterationListener implements ActionListener, ItemListener {
        String name;
        public TransliterationListener(String name) {
            this.name = name;
        }
        public void actionPerformed(ActionEvent e) {
            setTransliterator(name, null);
        }
        public void itemStateChanged(ItemEvent e) {
            if (e.getStateChange() == ItemEvent.SELECTED) {
                setTransliterator(name, null);
            } else {
                setTransliterator("Any-Null", null);
            }
        }
    }
    
    class FontActionListener implements ActionListener {
        String name;
        public FontActionListener(String name) {
            this.name = name;
        }
        public void actionPerformed(ActionEvent e) {
            if (DEBUG) System.out.println("Font: " + name);
            fontName = name;
            text.setFont(new Font(fontName, Font.PLAIN, fontSize));
        }
    }
    
    class SizeActionListener implements ActionListener {
        int size;
        public SizeActionListener(int size) {
            this.size = size;
        }
        public void actionPerformed(ActionEvent e) {
            if (DEBUG) System.out.println("Size: " + size);
            fontSize = size;
            text.setFont(new Font(fontName, Font.PLAIN, fontSize));
        }
    }
    
    Set add(Set s, Enumeration enumeration) {
        while(enumeration.hasMoreElements()) {
            s.add(enumeration.nextElement());
        }
        return s;
    }

    /**
     * Get a sorted list of the system transliterators.
     */
     /*
    private static Vector getSystemTransliteratorNames() {
        Vector v = new Vector();
        for (Enumeration e=Transliterator.getAvailableIDs();
             e.hasMoreElements(); ) {
            v.addElement(e.nextElement());
        }
        // Insertion sort, O(n^2) acceptable for small n
        for (int i=0; i<(v.size()-1); ++i) {
            String a = (String) v.elementAt(i);
            for (int j=i+1; j<v.size(); ++j) {
                String b = (String) v.elementAt(j);
                if (a.compareTo(b) > 0) {
                    v.setElementAt(b, i);
                    v.setElementAt(a, j);
                    a = b;
                }
            }
        }
        return v;
    }
    */

/*
    private void setNoTransliterator() {
        translitItem = noTranslitItem;
        noTranslitItem.setState(true);
        handleSetTransliterator(noTranslitItem.getLabel());
        compound = false;
        for (int i=0; i<translitMenu.getItemCount(); ++i) {
            MenuItem it = translitMenu.getItem(i);
            if (it != noTranslitItem && it instanceof CheckboxMenuItem) {
                ((CheckboxMenuItem) it).setState(false);
            }
        }
    }
*/
/*
    private void handleAddToCompound(String name) {
        if (compoundCount < MAX_COMPOUND) {
            compoundTranslit[compoundCount] = decodeTranslitItem(name);
            ++compoundCount;
            Transliterator t[] = new Transliterator[compoundCount];
            System.arraycopy(compoundTranslit, 0, t, 0, compoundCount);
            translit = new CompoundTransliterator(t);
            text.setTransliterator(translit);
        }
    }
*/
/*
    private void handleSetTransliterator(String name) {
        translit = decodeTranslitItem(name);
        text.setTransliterator(translit);
    }
    */

    /**
     * Decode a menu item that looks like <translit name>.
     */
     /*
    private static Transliterator decodeTranslitItem(String name) {
        return (name.equals(NO_TRANSLITERATOR))
            ? null : Transliterator.getInstance(name);
    }
    */

    private void handleBatchTransliterate(Transliterator trans) {
        if (trans == null) {
            return;
        }

        int start = text.getSelectionStart();
        int end = text.getSelectionEnd();
        ReplaceableString s =
            new ReplaceableString(text.getText().substring(start, end));

        StringBuffer log = null;
        if (DEBUG) {
            log = new StringBuffer();
            log.append('"' + s.toString() + "\" (start " + start +
                       ", end " + end + ") -> \"");
        }

        trans.transliterate(s);
        String str = s.toString();

        if (DEBUG) {
            log.append(str + "\"");
            System.out.println("Batch " + trans.getID() + ": " + log.toString());
        }

        text.replaceRange(str, start, end);
        text.select(start, start + str.length());
    }

    private void handleClose() {
        helpDialog.dispose();
        dispose();
    }
    
    /*
    class InfoDialog extends Dialog {
        protected Button button;
        protected TextArea area;
        protected Dialog me;
        protected Panel bottom;
        
        public TextArea getArea() {
            return area;
        }
        
        public Panel getBottom() {
            return bottom;
        }
        
        InfoDialog(Frame parent, String title, String label, String message) {
            super(parent, title, false);
            me = this;
            this.setLayout(new BorderLayout());
            if (label.length() != 0) {
                this.add("North", new Label(label));
            }
            
            area = new TextArea(message, 8, 80, TextArea.SCROLLBARS_VERTICAL_ONLY);
            this.add("Center", area);
            
            button = new Button("Hide");
            button.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    me.hide();
                }
            });
            bottom = new Panel();
            bottom.setLayout(new FlowLayout(FlowLayout.CENTER, 0, 0));
            bottom.add(button);
            this.add("South", bottom);
            this.pack();
            addWindowListener(new WindowAdapter() {
                public void windowClosing(WindowEvent e) {
                    me.hide();
                }
            });
        }
    }
    */
}
