/*
 * Copyright (c) 1999, 2007, Oracle and/or its affiliates. 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 Oracle 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 );
        }
    }
}
