/*
 * Copyright 1999-2007 Sun Microsystems, Inc.  All Rights Reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *   - Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *
 *   - Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *
 *   - Neither the name of Sun Microsystems nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */


import java.awt.Color;
import java.awt.Component;
import java.awt.BorderLayout;
import java.awt.CheckboxGroup;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsEnvironment;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.RenderingHints;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.EnumSet;
import java.util.StringTokenizer;
import java.util.BitSet;
import javax.swing.*;
import javax.swing.event.*;

/**
 * Font2DTest.java
 *
 * @author Shinsuke Fukuda
 * @author Ankit Patel [Conversion to Swing - 01/07/30]
 */

/// Main Font2DTest Class

public final class Font2DTest extends JPanel
    implements ActionListener, ItemListener, ChangeListener {

    /// JFrame that will contain Font2DTest
    private final JFrame parent;
    /// FontPanel class that will contain all graphical output
    private final FontPanel fp;
    /// RangeMenu class that contains info about the unicode ranges
    private final RangeMenu rm;

    /// Other menus to set parameters for text drawing
    private final ChoiceV2 fontMenu;
    private final JTextField sizeField;
    private final ChoiceV2 styleMenu;
    private final ChoiceV2 textMenu;
    private int currentTextChoice = 0;
    private final ChoiceV2 transformMenu;
    private final ChoiceV2 transformMenuG2;
    private final ChoiceV2 methodsMenu;
    private final JComboBox antiAliasMenu;
    private final JComboBox fracMetricsMenu;

    private final JSlider contrastSlider;

    /// CheckboxMenuItems
    private CheckboxMenuItemV2 displayGridCBMI;
    private CheckboxMenuItemV2 force16ColsCBMI;
    private CheckboxMenuItemV2 showFontInfoCBMI;

    /// JDialog boxes
    private JDialog userTextDialog;
    private JTextArea userTextArea;
    private JDialog printDialog;
    private JDialog fontInfoDialog;
    private LabelV2 fontInfos[] = new LabelV2[2];
    private JFileChooser filePromptDialog = null;

    private ButtonGroup printCBGroup;
    private JRadioButton printModeCBs[] = new JRadioButton[3];

    /// Status bar
    private final LabelV2 statusBar;

    private int fontStyles [] = {Font.PLAIN, Font.BOLD, Font.ITALIC, Font.BOLD | Font.ITALIC};

    /// Text filename
    private String tFileName;

    // Enabled or disabled status of canDisplay check
    private static boolean canDisplayCheck = true;

    /// Initialize GUI variables and its layouts
    public Font2DTest( JFrame f, boolean isApplet ) {
        parent = f;

        rm = new RangeMenu( this, parent );
        fp = new FontPanel( this, parent );
        statusBar = new LabelV2("");

        fontMenu = new ChoiceV2( this, canDisplayCheck );
        sizeField = new JTextField( "12", 3 );
        sizeField.addActionListener( this );
        styleMenu = new ChoiceV2( this );
        textMenu = new ChoiceV2( ); // listener added later
        transformMenu = new ChoiceV2( this );
        transformMenuG2 = new ChoiceV2( this );
        methodsMenu = new ChoiceV2( this );

        antiAliasMenu =
            new JComboBox(EnumSet.allOf(FontPanel.AAValues.class).toArray());
        antiAliasMenu.addActionListener(this);
        fracMetricsMenu =
            new JComboBox(EnumSet.allOf(FontPanel.FMValues.class).toArray());
        fracMetricsMenu.addActionListener(this);

        contrastSlider = new JSlider(JSlider.HORIZONTAL, 100, 250,
                                 FontPanel.getDefaultLCDContrast().intValue());
        contrastSlider.setEnabled(false);
        contrastSlider.setMajorTickSpacing(20);
        contrastSlider.setMinorTickSpacing(10);
        contrastSlider.setPaintTicks(true);
        contrastSlider.setPaintLabels(true);
        contrastSlider.addChangeListener(this);
        setupPanel();
        setupMenu( isApplet );
        setupDialog( isApplet );

        if(canDisplayCheck) {
            fireRangeChanged();
        }
    }

    /// Set up the main interface panel
    private void setupPanel() {
        GridBagLayout gbl = new GridBagLayout();
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.weightx = 1;
        gbc.insets = new Insets( 2, 0, 2, 2 );
        this.setLayout( gbl );

        addLabeledComponentToGBL( "Font: ", fontMenu, gbl, gbc, this );
        addLabeledComponentToGBL( "Size: ", sizeField, gbl, gbc, this );
        gbc.gridwidth = GridBagConstraints.REMAINDER;
        addLabeledComponentToGBL( "Font Transform:",
                                  transformMenu, gbl, gbc, this );
        gbc.gridwidth = 1;

        addLabeledComponentToGBL( "Range: ", rm, gbl, gbc, this );
        addLabeledComponentToGBL( "Style: ", styleMenu, gbl, gbc, this );
        gbc.gridwidth = GridBagConstraints.REMAINDER;
        addLabeledComponentToGBL( "Graphics Transform: ",
                                  transformMenuG2, gbl, gbc, this );
        gbc.gridwidth = 1;

        gbc.anchor = GridBagConstraints.WEST;
        addLabeledComponentToGBL( "Method: ", methodsMenu, gbl, gbc, this );
        addLabeledComponentToGBL("", null, gbl, gbc, this);
        gbc.anchor = GridBagConstraints.EAST;
        gbc.gridwidth = GridBagConstraints.REMAINDER;
        addLabeledComponentToGBL( "Text to use:", textMenu, gbl, gbc, this );

        gbc.weightx=1;
        gbc.gridwidth = 1;
        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.anchor = GridBagConstraints.WEST;
        addLabeledComponentToGBL("LCD contrast: ",
                                  contrastSlider, gbl, gbc, this);

        gbc.gridwidth = 1;
        gbc.fill = GridBagConstraints.NONE;
        addLabeledComponentToGBL("Antialiasing: ",
                                  antiAliasMenu, gbl, gbc, this);

        gbc.anchor = GridBagConstraints.EAST;
        gbc.gridwidth = GridBagConstraints.REMAINDER;
        addLabeledComponentToGBL("Fractional metrics: ",
                                  fracMetricsMenu, gbl, gbc, this);

        gbc.weightx = 1;
        gbc.weighty = 1;
        gbc.anchor = GridBagConstraints.WEST;
        gbc.insets = new Insets( 2, 0, 0, 2 );
        gbc.fill = GridBagConstraints.BOTH;
        gbl.setConstraints( fp, gbc );
        this.add( fp );

        gbc.weighty = 0;
        gbc.insets = new Insets( 0, 2, 0, 0 );
        gbl.setConstraints( statusBar, gbc );
        this.add( statusBar );
    }

    /// Adds a component to a container with a label to its left in GridBagLayout
    private void addLabeledComponentToGBL( String name,
                                           JComponent c,
                                           GridBagLayout gbl,
                                           GridBagConstraints gbc,
                                           Container target ) {
        LabelV2 l = new LabelV2( name );
        GridBagConstraints gbcLabel = (GridBagConstraints) gbc.clone();
        gbcLabel.insets = new Insets( 2, 2, 2, 0 );
        gbcLabel.gridwidth = 1;
        gbcLabel.weightx = 0;

        if ( c == null )
          c = new JLabel( "" );

        gbl.setConstraints( l, gbcLabel );
        target.add( l );
        gbl.setConstraints( c, gbc );
        target.add( c );
    }

    /// Sets up menu entries
    private void setupMenu( boolean isApplet ) {
        JMenu fileMenu = new JMenu( "File" );
        JMenu optionMenu = new JMenu( "Option" );

        fileMenu.add( new MenuItemV2( "Save Selected Options...", this ));
        fileMenu.add( new MenuItemV2( "Load Options...", this ));
        fileMenu.addSeparator();
        fileMenu.add( new MenuItemV2( "Save as PNG...", this ));
        fileMenu.add( new MenuItemV2( "Load PNG File to Compare...", this ));
        fileMenu.add( new MenuItemV2( "Page Setup...", this ));
        fileMenu.add( new MenuItemV2( "Print...", this ));
        fileMenu.addSeparator();
        if ( !isApplet )
          fileMenu.add( new MenuItemV2( "Exit", this ));
        else
          fileMenu.add( new MenuItemV2( "Close", this ));

        displayGridCBMI = new CheckboxMenuItemV2( "Display Grid", true, this );
        force16ColsCBMI = new CheckboxMenuItemV2( "Force 16 Columns", false, this );
        showFontInfoCBMI = new CheckboxMenuItemV2( "Display Font Info", false, this );
        optionMenu.add( displayGridCBMI );
        optionMenu.add( force16ColsCBMI );
        optionMenu.add( showFontInfoCBMI );

        JMenuBar mb = parent.getJMenuBar();
        if ( mb == null )
          mb = new JMenuBar();
        mb.add( fileMenu );
        mb.add( optionMenu );

        parent.setJMenuBar( mb );

        String fontList[] =
          GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames();

        for ( int i = 0; i < fontList.length; i++ )
          fontMenu.addItem( fontList[i] );
        fontMenu.setSelectedItem( "Dialog" );

        styleMenu.addItem( "Plain" );
        styleMenu.addItem( "Bold" );
        styleMenu.addItem( "Italic" );
        styleMenu.addItem( "Bold Italic" );

        transformMenu.addItem( "None" );
        transformMenu.addItem( "Scale" );
        transformMenu.addItem( "Shear" );
        transformMenu.addItem( "Rotate" );

        transformMenuG2.addItem( "None" );
        transformMenuG2.addItem( "Scale" );
        transformMenuG2.addItem( "Shear" );
        transformMenuG2.addItem( "Rotate" );

        methodsMenu.addItem( "drawString" );
        methodsMenu.addItem( "drawChars" );
        methodsMenu.addItem( "drawBytes" );
        methodsMenu.addItem( "drawGlyphVector" );
        methodsMenu.addItem( "TextLayout.draw" );
        methodsMenu.addItem( "GlyphVector.getOutline + draw" );
        methodsMenu.addItem( "TextLayout.getOutline + draw" );

        textMenu.addItem( "Unicode Range" );
        textMenu.addItem( "All Glyphs" );
        textMenu.addItem( "User Text" );
        textMenu.addItem( "Text File" );
        textMenu.addActionListener ( this ); // listener added later so unneeded events not thrown
    }

    /// Sets up the all dialogs used in Font2DTest...
    private void setupDialog( boolean isApplet ) {
        if (!isApplet)
                filePromptDialog = new JFileChooser( );
        else
                filePromptDialog = null;

        /// Prepare user text dialog...
        userTextDialog = new JDialog( parent, "User Text", false );
        JPanel dialogTopPanel = new JPanel();
        JPanel dialogBottomPanel = new JPanel();
        LabelV2 message1 = new LabelV2( "Enter text below and then press update" );
        LabelV2 message2 = new LabelV2( "(Unicode char can be denoted by \\uXXXX)" );
        LabelV2 message3 = new LabelV2( "(Supplementary chars can be denoted by \\UXXXXXX)" );
        userTextArea = new JTextArea( "Font2DTest!" );
        ButtonV2 bUpdate = new ButtonV2( "Update", this );
        userTextArea.setFont( new Font( "dialog", Font.PLAIN, 12 ));
        dialogTopPanel.setLayout( new GridLayout( 3, 1 ));
        dialogTopPanel.add( message1 );
        dialogTopPanel.add( message2 );
        dialogTopPanel.add( message3 );
        dialogBottomPanel.add( bUpdate );
        //ABP
        JScrollPane userTextAreaSP = new JScrollPane(userTextArea);
        userTextAreaSP.setPreferredSize(new Dimension(300, 100));

        userTextDialog.getContentPane().setLayout( new BorderLayout() );
        userTextDialog.getContentPane().add( "North", dialogTopPanel );
        userTextDialog.getContentPane().add( "Center", userTextAreaSP );
        userTextDialog.getContentPane().add( "South", dialogBottomPanel );
        userTextDialog.pack();
        userTextDialog.addWindowListener( new WindowAdapter() {
            public void windowClosing( WindowEvent e ) {
                userTextDialog.hide();
            }
        });

        /// Prepare printing dialog...
        printCBGroup = new ButtonGroup();
        printModeCBs[ fp.ONE_PAGE ] =
          new JRadioButton( "Print one page from currently displayed character/line",
                         true );
        printModeCBs[ fp.CUR_RANGE ] =
          new JRadioButton( "Print all characters in currently selected range",
                         false );
        printModeCBs[ fp.ALL_TEXT ] =
          new JRadioButton( "Print all lines of text",
                         false );
        LabelV2 l =
          new LabelV2( "Note: Page range in native \"Print\" dialog will not affect the result" );
        JPanel buttonPanel = new JPanel();
        printModeCBs[ fp.ALL_TEXT ].setEnabled( false );
        buttonPanel.add( new ButtonV2( "Print", this ));
        buttonPanel.add( new ButtonV2( "Cancel", this ));

        printDialog = new JDialog( parent, "Print...", true );
        printDialog.setResizable( false );
        printDialog.addWindowListener( new WindowAdapter() {
            public void windowClosing( WindowEvent e ) {
                printDialog.hide();
            }
        });
        printDialog.getContentPane().setLayout( new GridLayout( printModeCBs.length + 2, 1 ));
        printDialog.getContentPane().add( l );
        for ( int i = 0; i < printModeCBs.length; i++ ) {
            printCBGroup.add( printModeCBs[i] );
            printDialog.getContentPane().add( printModeCBs[i] );
        }
        printDialog.getContentPane().add( buttonPanel );
        printDialog.pack();

        /// Prepare font information dialog...
        fontInfoDialog = new JDialog( parent, "Font info", false );
        fontInfoDialog.setResizable( false );
        fontInfoDialog.addWindowListener( new WindowAdapter() {
            public void windowClosing( WindowEvent e ) {
                fontInfoDialog.hide();
                showFontInfoCBMI.setState( false );
            }
        });
        JPanel fontInfoPanel = new JPanel();
        fontInfoPanel.setLayout( new GridLayout( fontInfos.length, 1 ));
        for ( int i = 0; i < fontInfos.length; i++ ) {
            fontInfos[i] = new LabelV2("");
            fontInfoPanel.add( fontInfos[i] );
        }
        fontInfoDialog.getContentPane().add( fontInfoPanel );

        /// Move the location of the dialog...
        userTextDialog.setLocation( 200, 300 );
        fontInfoDialog.setLocation( 0, 400 );
    }

    /// RangeMenu object signals using this function
    /// when Unicode range has been changed and text needs to be redrawn
    public void fireRangeChanged() {
        int range[] = rm.getSelectedRange();
        fp.setTextToDraw( fp.RANGE_TEXT, range, null, null );
        if(canDisplayCheck) {
            setupFontList(range[0], range[1]);
        }
        if ( showFontInfoCBMI.getState() )
          fireUpdateFontInfo();
    }

    /// Changes the message on the status bar
    public void fireChangeStatus( String message, boolean error ) {
        /// If this is not ran as an applet, use own status bar,
        /// Otherwise, use the appletviewer/browser's status bar
        statusBar.setText( message );
        if ( error )
          fp.showingError = true;
        else
          fp.showingError = false;
    }

    /// Updates the information about the selected font
    public void fireUpdateFontInfo() {
        if ( showFontInfoCBMI.getState() ) {
            String infos[] = fp.getFontInfo();
            for ( int i = 0; i < fontInfos.length; i++ )
              fontInfos[i].setText( infos[i] );
            fontInfoDialog.pack();
        }
    }

    private void setupFontList(int rangeStart, int rangeEnd) {

        int listCount = fontMenu.getItemCount();
        int size = 16;

        try {
            size =  Float.valueOf(sizeField.getText()).intValue();
        }
        catch ( Exception e ) {
            System.out.println("Invalid font size in the size textField. Using default value of 16");
        }

        int style = fontStyles[styleMenu.getSelectedIndex()];
        Font f;
        for (int i = 0; i < listCount; i++) {
            String fontName = (String)fontMenu.getItemAt(i);
            f = new Font(fontName, style, size);
            if ((rm.getSelectedIndex() != RangeMenu.SURROGATES_AREA_INDEX) &&
                canDisplayRange(f, rangeStart, rangeEnd)) {
                fontMenu.setBit(i, true);
            }
            else {
                fontMenu.setBit(i, false);
            }
        }

        fontMenu.repaint();
    }

    protected boolean canDisplayRange(Font font, int rangeStart, int rangeEnd) {
        for (int i = rangeStart; i < rangeEnd; i++) {
            if (font.canDisplay(i)) {
                return true;
            }
        }
        return false;
    }

    /// Displays a file load/save dialog and returns the specified file
    private String promptFile( boolean isSave, String initFileName ) {
        int retVal;
        String str;

        /// ABP
        if ( filePromptDialog == null)
                return null;

        if ( isSave ) {
            filePromptDialog.setDialogType( JFileChooser.SAVE_DIALOG );
            filePromptDialog.setDialogTitle( "Save..." );
            str = "Save";


        }
        else {
            filePromptDialog.setDialogType( JFileChooser.OPEN_DIALOG );
            filePromptDialog.setDialogTitle( "Load..." );
            str = "Load";
        }

        if (initFileName != null)
                filePromptDialog.setSelectedFile( new File( initFileName ) );
        retVal = filePromptDialog.showDialog( this, str );

        if ( retVal == JFileChooser.APPROVE_OPTION ) {
                File file = filePromptDialog.getSelectedFile();
                String fileName = file.getAbsolutePath();
                if ( fileName != null ) {
                        return fileName;
                }
        }

        return null;
    }

    /// Converts user text into arrays of String, delimited at newline character
    /// Also replaces any valid escape sequence with appropriate unicode character
    /// Support \\UXXXXXX notation for surrogates
    private String[] parseUserText( String orig ) {
        int length = orig.length();
        StringTokenizer perLine = new StringTokenizer( orig, "\n" );
        String textLines[] = new String[ perLine.countTokens() ];
        int lineNumber = 0;

        while ( perLine.hasMoreElements() ) {
            StringBuffer converted = new StringBuffer();
            String oneLine = perLine.nextToken();
            int lineLength = oneLine.length();
            int prevEscapeEnd = 0;
            int nextEscape = -1;
            do {
                int nextBMPEscape = oneLine.indexOf( "\\u", prevEscapeEnd );
                int nextSupEscape = oneLine.indexOf( "\\U", prevEscapeEnd );
                nextEscape = (nextBMPEscape < 0)
                    ? ((nextSupEscape < 0)
                       ? -1
                       : nextSupEscape)
                    : ((nextSupEscape < 0)
                       ? nextBMPEscape
                       : Math.min(nextBMPEscape, nextSupEscape));

                if ( nextEscape != -1 ) {
                    if ( prevEscapeEnd < nextEscape )
                        converted.append( oneLine.substring( prevEscapeEnd, nextEscape ));

                    prevEscapeEnd = nextEscape + (nextEscape == nextBMPEscape ? 6 : 8);
                    try {
                        String hex = oneLine.substring( nextEscape + 2, prevEscapeEnd );
                        if (nextEscape == nextBMPEscape) {
                            converted.append( (char) Integer.parseInt( hex, 16 ));
                        } else {
                            converted.append( new String( Character.toChars( Integer.parseInt( hex, 16 ))));
                        }
                    }
                    catch ( Exception e ) {
                        int copyLimit = Math.min(lineLength, prevEscapeEnd);
                        converted.append( oneLine.substring( nextEscape, copyLimit ));
                    }
                }
            } while (nextEscape != -1);
            if ( prevEscapeEnd < lineLength )
              converted.append( oneLine.substring( prevEscapeEnd, lineLength ));
            textLines[ lineNumber++ ] = converted.toString();
        }
        return textLines;
    }

    /// Reads the text from specified file, detecting UTF-16 encoding
    /// Then breaks the text into String array, delimited at every line break
    private void readTextFile( String fileName ) {
        try {
            String fileText, textLines[];
            BufferedInputStream bis =
              new BufferedInputStream( new FileInputStream( fileName ));
            int numBytes = bis.available();
            if (numBytes == 0) {
                throw new Exception("Text file " + fileName + " is empty");
            }
            byte byteData[] = new byte[ numBytes ];
            bis.read( byteData, 0, numBytes );
            bis.close();

            /// If byte mark is found, then use UTF-16 encoding to convert bytes...
            if (numBytes >= 2 &&
                (( byteData[0] == (byte) 0xFF && byteData[1] == (byte) 0xFE ) ||
                 ( byteData[0] == (byte) 0xFE && byteData[1] == (byte) 0xFF )))
              fileText = new String( byteData, "UTF-16" );
            /// Otherwise, use system default encoding
            else
              fileText = new String( byteData );

            int length = fileText.length();
            StringTokenizer perLine = new StringTokenizer( fileText, "\n" );
            /// Determine "Return Char" used in this file
            /// This simply finds first occurrence of CR, CR+LF or LF...
            for ( int i = 0; i < length; i++ ) {
                char iTh = fileText.charAt( i );
                if ( iTh == '\r' ) {
                    if ( i < length - 1 && fileText.charAt( i + 1 ) == '\n' )
                      perLine = new StringTokenizer( fileText, "\r\n" );
                    else
                      perLine = new StringTokenizer( fileText, "\r" );
                    break;
                }
                else if ( iTh == '\n' )
                  /// Use the one already created
                  break;
            }
            int lineNumber = 0, numLines = perLine.countTokens();
            textLines = new String[ numLines ];

            while ( perLine.hasMoreElements() ) {
                String oneLine = perLine.nextToken();
                if ( oneLine == null )
                  /// To make LineBreakMeasurer to return a valid TextLayout
                  /// on an empty line, simply feed it a space char...
                  oneLine = " ";
                textLines[ lineNumber++ ] = oneLine;
            }
            fp.setTextToDraw( fp.FILE_TEXT, null, null, textLines );
            rm.setEnabled( false );
            methodsMenu.setEnabled( false );
        }
        catch ( Exception ex ) {
            fireChangeStatus( "ERROR: Failed to Read Text File; See Stack Trace", true );
            ex.printStackTrace();
        }
    }

    /// Returns a String storing current configuration
    private void writeCurrentOptions( String fileName ) {
        try {
            String curOptions = fp.getCurrentOptions();
            BufferedOutputStream bos =
              new BufferedOutputStream( new FileOutputStream( fileName ));
            /// Prepend title and the option that is only obtainable here
            int range[] = rm.getSelectedRange();
            String completeOptions =
              ( "Font2DTest Option File\n" +
                displayGridCBMI.getState() + "\n" +
                force16ColsCBMI.getState() + "\n" +
                showFontInfoCBMI.getState() + "\n" +
                rm.getSelectedItem() + "\n" +
                range[0] + "\n" + range[1] + "\n" + curOptions + tFileName);
            byte toBeWritten[] = completeOptions.getBytes( "UTF-16" );
            bos.write( toBeWritten, 0, toBeWritten.length );
            bos.close();
        }
        catch ( Exception ex ) {
            fireChangeStatus( "ERROR: Failed to Save Options File; See Stack Trace", true );
            ex.printStackTrace();
        }
    }

    /// Updates GUI visibility/status after some parameters have changed
    private void updateGUI() {
        int selectedText = textMenu.getSelectedIndex();

        /// Set the visibility of User Text dialog
        if ( selectedText == fp.USER_TEXT )
          userTextDialog.show();
        else
          userTextDialog.hide();
        /// Change the visibility/status/availability of Print JDialog buttons
        printModeCBs[ fp.ONE_PAGE ].setSelected( true );
        if ( selectedText == fp.FILE_TEXT || selectedText == fp.USER_TEXT ) {
            /// ABP
            /// update methodsMenu to show that TextLayout.draw is being used
            /// when we are in FILE_TEXT mode
            if ( selectedText == fp.FILE_TEXT )
                methodsMenu.setSelectedItem("TextLayout.draw");
            methodsMenu.setEnabled( selectedText == fp.USER_TEXT );
            printModeCBs[ fp.CUR_RANGE ].setEnabled( false );
            printModeCBs[ fp.ALL_TEXT ].setEnabled( true );
        }
        else {
            /// ABP
            /// update methodsMenu to show that drawGlyph is being used
            /// when we are in ALL_GLYPHS mode
            if ( selectedText == fp.ALL_GLYPHS )
                methodsMenu.setSelectedItem("drawGlyphVector");
            methodsMenu.setEnabled( selectedText == fp.RANGE_TEXT );
            printModeCBs[ fp.CUR_RANGE ].setEnabled( true );
            printModeCBs[ fp.ALL_TEXT ].setEnabled( false );
        }
        /// Modify RangeMenu and fontInfo label availabilty
        if ( selectedText == fp.RANGE_TEXT ) {
            fontInfos[1].setVisible( true );
            rm.setEnabled( true );
        }
        else {
            fontInfos[1].setVisible( false );
            rm.setEnabled( false );
        }
    }

    /// Loads saved options and applies them
    private void loadOptions( String fileName ) {
        try {
            BufferedInputStream bis =
              new BufferedInputStream( new FileInputStream( fileName ));
            int numBytes = bis.available();
            byte byteData[] = new byte[ numBytes ];
            bis.read( byteData, 0, numBytes );
            bis.close();
            if ( numBytes < 2 ||
                (byteData[0] != (byte) 0xFE || byteData[1] != (byte) 0xFF) )
              throw new Exception( "Not a Font2DTest options file" );

            String options = new String( byteData, "UTF-16" );
            StringTokenizer perLine = new StringTokenizer( options, "\n" );
            String title = perLine.nextToken();
            if ( !title.equals( "Font2DTest Option File" ))
              throw new Exception( "Not a Font2DTest options file" );

            /// Parse all options
            boolean displayGridOpt = Boolean.parseBoolean( perLine.nextToken() );
            boolean force16ColsOpt = Boolean.parseBoolean( perLine.nextToken() );
            boolean showFontInfoOpt = Boolean.parseBoolean( perLine.nextToken() );
            String rangeNameOpt = perLine.nextToken();
            int rangeStartOpt = Integer.parseInt( perLine.nextToken() );
            int rangeEndOpt = Integer.parseInt( perLine.nextToken() );
            String fontNameOpt = perLine.nextToken();
            float fontSizeOpt = Float.parseFloat( perLine.nextToken() );
            int fontStyleOpt = Integer.parseInt( perLine.nextToken() );
            int fontTransformOpt = Integer.parseInt( perLine.nextToken() );
            int g2TransformOpt = Integer.parseInt( perLine.nextToken() );
            int textToUseOpt = Integer.parseInt( perLine.nextToken() );
            int drawMethodOpt = Integer.parseInt( perLine.nextToken() );
            int antialiasOpt = Integer.parseInt(perLine.nextToken());
            int fractionalOpt = Integer.parseInt(perLine.nextToken());
            int lcdContrast = Integer.parseInt(perLine.nextToken());
            String userTextOpt[] = { "Font2DTest!" };
            String dialogEntry = "Font2DTest!";
            if (textToUseOpt == fp.USER_TEXT )  {
                int numLines = perLine.countTokens(), lineNumber = 0;
                if ( numLines != 0 ) {
                    userTextOpt = new String[ numLines ];
                    dialogEntry = "";
                    for ( ; perLine.hasMoreElements(); lineNumber++ ) {
                        userTextOpt[ lineNumber ] = perLine.nextToken();
                        dialogEntry += userTextOpt[ lineNumber ] + "\n";
                    }
                }
            }

            /// Reset GUIs
            displayGridCBMI.setState( displayGridOpt );
            force16ColsCBMI.setState( force16ColsOpt );
            showFontInfoCBMI.setState( showFontInfoOpt );
            rm.setSelectedRange( rangeNameOpt, rangeStartOpt, rangeEndOpt );
            fontMenu.setSelectedItem( fontNameOpt );
            sizeField.setText( String.valueOf( fontSizeOpt ));
            styleMenu.setSelectedIndex( fontStyleOpt );
            transformMenu.setSelectedIndex( fontTransformOpt );
            transformMenuG2.setSelectedIndex( g2TransformOpt );
            textMenu.setSelectedIndex( textToUseOpt );
            methodsMenu.setSelectedIndex( drawMethodOpt );
            antiAliasMenu.setSelectedIndex( antialiasOpt );
            fracMetricsMenu.setSelectedIndex( fractionalOpt );
            contrastSlider.setValue(lcdContrast);

            userTextArea.setText( dialogEntry );
            updateGUI();

            if ( textToUseOpt == fp.FILE_TEXT ) {
              tFileName = perLine.nextToken();
              readTextFile(tFileName );
            }

            /// Reset option variables and repaint
            fp.loadOptions( displayGridOpt, force16ColsOpt,
                            rangeStartOpt, rangeEndOpt,
                            fontNameOpt, fontSizeOpt,
                            fontStyleOpt, fontTransformOpt, g2TransformOpt,
                            textToUseOpt, drawMethodOpt,
                            antialiasOpt, fractionalOpt,
                            lcdContrast, userTextOpt );
            if ( showFontInfoOpt ) {
                fireUpdateFontInfo();
                fontInfoDialog.show();
            }
            else
              fontInfoDialog.hide();
        }
        catch ( Exception ex ) {
            fireChangeStatus( "ERROR: Failed to Load Options File; See Stack Trace", true );
            ex.printStackTrace();
        }
    }

    /// Loads a previously saved image
    private void loadComparisonPNG( String fileName ) {
        try {
            BufferedImage image =
                javax.imageio.ImageIO.read(new File(fileName));
            JFrame f = new JFrame( "Comparison PNG" );
            ImagePanel ip = new ImagePanel( image );
            f.setResizable( false );
            f.getContentPane().add( ip );
            f.addWindowListener( new WindowAdapter() {
                public void windowClosing( WindowEvent e ) {
                    ( (JFrame) e.getSource() ).dispose();
                }
            });
            f.pack();
            f.show();
        }
        catch ( Exception ex ) {
            fireChangeStatus( "ERROR: Failed to Load PNG File; See Stack Trace", true );
            ex.printStackTrace();
        }
    }

    /// Interface functions...

    /// ActionListener interface function
    /// Responds to JMenuItem, JTextField and JButton actions
    public void actionPerformed( ActionEvent e ) {
        Object source = e.getSource();

        if ( source instanceof JMenuItem ) {
            JMenuItem mi = (JMenuItem) source;
            String itemName = mi.getText();

            if ( itemName.equals( "Save Selected Options..." )) {
                String fileName = promptFile( true, "options.txt" );
                if ( fileName != null )
                  writeCurrentOptions( fileName );
            }
            else if ( itemName.equals( "Load Options..." )) {
                String fileName = promptFile( false, "options.txt" );
                if ( fileName != null )
                  loadOptions( fileName );
            }
            else if ( itemName.equals( "Save as PNG..." )) {
                String fileName = promptFile( true, fontMenu.getSelectedItem() + ".png" );
                if ( fileName != null )
                  fp.doSavePNG( fileName );
            }
            else if ( itemName.equals( "Load PNG File to Compare..." )) {
                String fileName = promptFile( false, null );
                if ( fileName != null )
                  loadComparisonPNG( fileName );
            }
            else if ( itemName.equals( "Page Setup..." ))
              fp.doPageSetup();
            else if ( itemName.equals( "Print..." ))
              printDialog.show();
            else if ( itemName.equals( "Close" ))
              parent.dispose();
            else if ( itemName.equals( "Exit" ))
              System.exit(0);
        }

        else if ( source instanceof JTextField ) {
            JTextField tf = (JTextField) source;
            float sz = 12f;
            try {
                 sz = Float.parseFloat(sizeField.getText());
                 if (sz < 1f || sz > 120f) {
                      sz = 12f;
                      sizeField.setText("12");
                 }
            } catch (Exception se) {
                 sizeField.setText("12");
            }
            if ( tf == sizeField )
              fp.setFontParams( fontMenu.getSelectedItem(),
                                sz,
                                styleMenu.getSelectedIndex(),
                                transformMenu.getSelectedIndex() );
        }

        else if ( source instanceof JButton ) {
            String itemName = ( (JButton) source ).getText();
            /// Print dialog buttons...
            if ( itemName.equals( "Print" )) {
                for ( int i = 0; i < printModeCBs.length; i++ )
                  if ( printModeCBs[i].isSelected() ) {
                      printDialog.hide();
                      fp.doPrint( i );
                  }
            }
            else if ( itemName.equals( "Cancel" ))
              printDialog.hide();
            /// Update button from Usert Text JDialog...
            else if ( itemName.equals( "Update" ))
              fp.setTextToDraw( fp.USER_TEXT, null,
                                parseUserText( userTextArea.getText() ), null );
        }
        else if ( source instanceof JComboBox ) {
            JComboBox c = (JComboBox) source;

            /// RangeMenu handles actions by itself and then calls fireRangeChanged,
            /// so it is not listed or handled here
            if ( c == fontMenu || c == styleMenu || c == transformMenu ) {
                float sz = 12f;
                try {
                    sz = Float.parseFloat(sizeField.getText());
                    if (sz < 1f || sz > 120f) {
                        sz = 12f;
                        sizeField.setText("12");
                    }
                } catch (Exception se) {
                    sizeField.setText("12");
                }
                fp.setFontParams(fontMenu.getSelectedItem(),
                                 sz,
                                 styleMenu.getSelectedIndex(),
                                 transformMenu.getSelectedIndex());
            } else if ( c == methodsMenu )
              fp.setDrawMethod( methodsMenu.getSelectedIndex() );
            else if ( c == textMenu ) {

                if(canDisplayCheck) {
                    fireRangeChanged();
                }

                int selected = textMenu.getSelectedIndex();

                if ( selected == fp.RANGE_TEXT )
                  fp.setTextToDraw( fp.RANGE_TEXT, rm.getSelectedRange(),
                                    null, null );
                else if ( selected == fp.USER_TEXT )
                  fp.setTextToDraw( fp.USER_TEXT, null,
                                    parseUserText( userTextArea.getText() ), null );
                else if ( selected == fp.FILE_TEXT ) {
                    String fileName = promptFile( false, null );
                    if ( fileName != null ) {
                      tFileName = fileName;
                      readTextFile( fileName );
                    } else {
                        /// User cancelled selection; reset to previous choice
                        c.setSelectedIndex( currentTextChoice );
                        return;
                    }
                }
                else if ( selected == fp.ALL_GLYPHS )
                  fp.setTextToDraw( fp.ALL_GLYPHS, null, null, null );

                updateGUI();
                currentTextChoice = selected;
            }
            else if ( c == transformMenuG2 ) {
                fp.setTransformG2( transformMenuG2.getSelectedIndex() );
            }
            else if (c == antiAliasMenu || c == fracMetricsMenu) {
                if (c == antiAliasMenu) {
                    boolean enabled = FontPanel.AAValues.
                        isLCDMode(antiAliasMenu.getSelectedItem());
                        contrastSlider.setEnabled(enabled);
                }
                fp.setRenderingHints(antiAliasMenu.getSelectedItem(),
                                     fracMetricsMenu.getSelectedItem(),
                                     contrastSlider.getValue());
            }
        }
    }

    public void stateChanged(ChangeEvent e) {
         Object source = e.getSource();
         if (source instanceof JSlider) {
             fp.setRenderingHints(antiAliasMenu.getSelectedItem(),
                                  fracMetricsMenu.getSelectedItem(),
                                  contrastSlider.getValue());
         }
    }

    /// ItemListener interface function
    /// Responds to JCheckBoxMenuItem, JComboBox and JCheckBox actions
    public void itemStateChanged( ItemEvent e ) {
        Object source = e.getSource();

        if ( source instanceof JCheckBoxMenuItem ) {
            JCheckBoxMenuItem cbmi = (JCheckBoxMenuItem) source;
            if ( cbmi == displayGridCBMI )
              fp.setGridDisplay( displayGridCBMI.getState() );
            else if ( cbmi == force16ColsCBMI )
              fp.setForce16Columns( force16ColsCBMI.getState() );
            else if ( cbmi == showFontInfoCBMI ) {
                if ( showFontInfoCBMI.getState() ) {
                    fireUpdateFontInfo();
                    fontInfoDialog.show();
                }
                else
                  fontInfoDialog.hide();
            }
        }
    }

    private static void printUsage() {
        String usage = "Usage: java -jar Font2DTest.jar [options]\n" +
            "\nwhere options include:\n" +
            "    -dcdc | -disablecandisplaycheck disable canDisplay check for font\n" +
            "    -?    | -help                   print this help message\n" +
            "\nExample :\n" +
            "     To disable canDisplay check on font for ranges\n" +
            "     java -jar Font2DTest.jar -dcdc";
        System.out.println(usage);
        System.exit(0);
    }

    /// Main function
    public static void main(String argv[]) {

        if(argv.length > 0) {
            if(argv[0].equalsIgnoreCase("-disablecandisplaycheck") ||
               argv[0].equalsIgnoreCase("-dcdc")) {
                canDisplayCheck = false;
            }
            else {
                printUsage();
            }
        }

        UIManager.put("swing.boldMetal", Boolean.FALSE);
        final JFrame f = new JFrame( "Font2DTest" );
        final Font2DTest f2dt = new Font2DTest( f, false );
        f.addWindowListener( new WindowAdapter() {
            public void windowOpening( WindowEvent e ) { f2dt.repaint(); }
            public void windowClosing( WindowEvent e ) { System.exit(0); }
        });

        f.getContentPane().add( f2dt );
        f.pack();
        f.show();
    }

    /// Inner class definitions...

    /// Class to display just an image file
    /// Used to show the comparison PNG image
    private final class ImagePanel extends JPanel {
        private final BufferedImage bi;

        public ImagePanel( BufferedImage image ) {
            bi = image;
        }

        public Dimension getPreferredSize() {
            return new Dimension( bi.getWidth(), bi.getHeight() );
        }

        public void paintComponent( Graphics g ) {
            g.drawImage( bi, 0, 0, this );
        }
    }

    /// Classes made to avoid repetitive calls... (being lazy)
    private final class ButtonV2 extends JButton {
        public ButtonV2( String name, ActionListener al ) {
            super( name );
            this.addActionListener( al );
        }
    }

    private final class ChoiceV2 extends JComboBox {

        private BitSet bitSet = null;

        public ChoiceV2() {;}

        public ChoiceV2( ActionListener al ) {
            super();
            this.addActionListener( al );
        }

        public ChoiceV2( ActionListener al, boolean fontChoice) {
            this(al);
            if(fontChoice) {
                //Register this component in ToolTipManager
                setToolTipText("");
                bitSet = new BitSet();
                setRenderer(new ChoiceV2Renderer(this));
            }
        }

        public String getToolTipText() {
            int index = this.getSelectedIndex();
            String fontName = (String) this.getSelectedItem();
            if(fontName != null &&
               (textMenu.getSelectedIndex() == fp.RANGE_TEXT)) {
                if (getBit(index)) {
                    return "Font \"" + fontName + "\" can display some characters in \"" +
                        rm.getSelectedItem() + "\" range";
                }
                else {
                    return "Font \"" + fontName + "\" cannot display any characters in \"" +
                        rm.getSelectedItem() + "\" range";
                }
            }
            return super.getToolTipText();
        }

        public void setBit(int bitIndex, boolean value) {
            bitSet.set(bitIndex, value);
        }

        public boolean getBit(int bitIndex) {
            return bitSet.get(bitIndex);
        }
    }

    private final class ChoiceV2Renderer extends DefaultListCellRenderer {

        private ImageIcon yesImage, blankImage;
        private ChoiceV2 choice = null;

        public ChoiceV2Renderer(ChoiceV2 choice) {
            BufferedImage yes =
                new BufferedImage(10, 10, BufferedImage.TYPE_INT_ARGB);
            Graphics2D g = yes.createGraphics();
            g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                               RenderingHints.VALUE_ANTIALIAS_ON);
            g.setColor(Color.BLUE);
            g.drawLine(0, 5, 3, 10);
            g.drawLine(1, 5, 4, 10);
            g.drawLine(3, 10, 10, 0);
            g.drawLine(4, 9, 9, 0);
            g.dispose();
            BufferedImage blank =
                new BufferedImage(10, 10, BufferedImage.TYPE_INT_ARGB);
            yesImage = new ImageIcon(yes);
            blankImage = new ImageIcon(blank);
            this.choice = choice;
        }

        public Component getListCellRendererComponent(JList list,
                                                      Object value,
                                                      int index,
                                                      boolean isSelected,
                                                      boolean cellHasFocus) {

            if(textMenu.getSelectedIndex() == fp.RANGE_TEXT) {

                super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);

                //For JComboBox if index is -1, its rendering the selected index.
                if(index == -1) {
                    index = choice.getSelectedIndex();
                }

                if(choice.getBit(index)) {
                    setIcon(yesImage);
                }
                else {
                    setIcon(blankImage);
                }

            } else {
                super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
                setIcon(blankImage);
            }

            return this;
        }
    }

    private final class LabelV2 extends JLabel {
        public LabelV2( String name ) {
            super( name );
        }
    }

    private final class MenuItemV2 extends JMenuItem {
        public MenuItemV2( String name, ActionListener al ) {
            super( name );
            this.addActionListener( al );
        }
    }

    private final class CheckboxMenuItemV2 extends JCheckBoxMenuItem {
        public CheckboxMenuItemV2( String name, boolean b, ItemListener il ) {
            super( name, b );
            this.addItemListener( il );
        }
    }
}
