/*
 *******************************************************************************
 * Copyright (C) 1996-2012, 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.impl.Differ;
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";

    //private static final String COPYRIGHT =
    //    "\u00A9 IBM Corporation 1999. All rights reserved.";

    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) {
        Differ differ = new Differ(300, 3);
        StringBuffer out = new StringBuffer();
        int max = as.length();
        if (max < bs.length()) max = bs.length();
        for (int j = 0; j <= max; ++j) {
            if (j < as.length()) differ.addA(as.substring(j, j+1));
            if (j < bs.length()) differ.addB(bs.substring(j, j+1));
            differ.checkMatch(j == max);

            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.append(differ.getA(i));
                    }
                    out.append("</span>");
                }
                if (differ.getBCount() != 0) {
                    out.append("<span class='d'>");
                    for (int i = 0; i < differ.getBCount(); ++i) {
                        out.append(differ.getB(i));
                    }
                    out.append("</span>");
                }
                out.append("...");
            }
        }
        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();
                }
            });
        }
    }
    */
}
