/*
 * Copyright (c) 2000, 2021, 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.
 */

/*
 * This source code is provided to illustrate the usage of a given feature
 * or technique and has been deliberately simplified. Additional steps
 * required for a production-quality application, such as security checks,
 * input validation and proper error handling, might not be present in
 * this sample code.
 */



import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsEnvironment;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.Toolkit;
import java.awt.event.AdjustmentEvent;
import java.awt.event.AdjustmentListener;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.font.FontRenderContext;
import java.awt.font.GlyphVector;
import java.awt.font.LineBreakMeasurer;
import java.awt.font.TextLayout;
import java.awt.geom.AffineTransform;
import java.awt.geom.NoninvertibleTransformException;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import java.awt.print.PrinterJob;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.text.AttributedString;
import java.util.Vector;

import javax.imageio.*;
import javax.swing.*;

import static java.awt.RenderingHints.*;
import static java.nio.charset.StandardCharsets.ISO_8859_1;

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

/// This panel is combination of the text drawing area of Font2DTest
/// and the custom controlled scroll bar

public final class FontPanel extends JPanel implements AdjustmentListener {

    /// Drawing Option Constants
    private final String[] STYLES =
      { "plain", "bold", "italic", "bold italic" };

    private final int NONE = 0;
    private final int SCALE = 1;
    private final int SHEAR = 2;
    private final int ROTATE = 3;
    private final String[] TRANSFORMS =
      { "with no transforms", "with scaling", "with Shearing", "with rotation" };

    private final int DRAW_STRING = 0;
    private final int DRAW_CHARS = 1;
    private final int DRAW_BYTES = 2;
    private final int DRAW_GLYPHV = 3;
    private final int TL_DRAW = 4;
    private final int GV_OUTLINE = 5;
    private final int TL_OUTLINE = 6;
    private final String[] METHODS = {
        "drawString", "drawChars", "drawBytes", "drawGlyphVector",
        "TextLayout.draw", "GlyphVector.getOutline", "TextLayout.getOutline" };

    public final int RANGE_TEXT = 0;
    public final int ALL_GLYPHS = 1;
    public final int USER_TEXT = 2;
    public final int FILE_TEXT = 3;
    private final String[] MS_OPENING =
      { " Unicode ", " Glyph Code ", " lines ", " lines " };
    private final String[] MS_CLOSING =
      { "", "", " of User Text ", " of LineBreakMeasurer-reformatted Text " };

    /// General Graphics Variable
    private final JScrollBar verticalBar;
    private final FontCanvas fc;
    private boolean updateFontMetrics = true;
    private boolean updateFont = true;
    private boolean force16Cols = false;
    public boolean showingError = false;
    private int g2Transform = NONE; /// ABP

    /// Printing constants and variables
    public final int ONE_PAGE = 0;
    public final int CUR_RANGE = 1;
    public final int ALL_TEXT = 2;
    private int printMode = ONE_PAGE;
    private PageFormat page = null;
    private PrinterJob printer = null;

    /// Text drawing variables
    private String fontName = "Dialog";
    private float fontSize = 12;
    private int fontStyle = Font.PLAIN;
    private int fontTransform = NONE;
    private Font testFont = null;
    private Object antiAliasType = VALUE_TEXT_ANTIALIAS_DEFAULT;
    private Object fractionalMetricsType = VALUE_FRACTIONALMETRICS_DEFAULT;
    private Object lcdContrast = getDefaultLCDContrast();
    private int drawMethod = DRAW_STRING;
    private int textToUse = RANGE_TEXT;
    private String[] userText = null;
    private String[] fileText = null;
    private int[] drawRange = { 0x0000, 0x007f };
    private String[] fontInfos = new String[2];
    private boolean showGrid = true;

    /// Parent Font2DTest panel
    private final Font2DTest f2dt;
    private final JFrame parent;

    public FontPanel( Font2DTest demo, JFrame f ) {
        f2dt = demo;
        parent = f;

        verticalBar = new JScrollBar ( JScrollBar.VERTICAL );
        fc = new FontCanvas();

        this.setLayout( new BorderLayout() );
        this.add( "Center", fc );
        this.add( "East", verticalBar );

        verticalBar.addAdjustmentListener( this );
        this.addComponentListener( new ComponentAdapter() {
            public void componentResized( ComponentEvent e ) {
                updateFontMetrics = true;
            }
        });

        /// Initialize font and its infos
        testFont = new Font(fontName, fontStyle, (int)fontSize);
        if ((float)((int)fontSize) != fontSize) {
            testFont = testFont.deriveFont(fontSize);
        }
        updateFontInfo();
    }

    public Dimension getPreferredSize() {
        return new Dimension(600, 200);
    }

    /// Functions called by the main programs to set the various parameters

    public void setTransformG2( int transform ) {
        g2Transform = transform;
        updateFontMetrics = true;
        fc.repaint();
    }

    /// convenience fcn to create AffineTransform of appropriate type
    private AffineTransform getAffineTransform( int transform ) {
            /// ABP
            AffineTransform at = new AffineTransform();
            switch ( transform )
            {
            case SCALE:
              at.setToScale( 1.5f, 1.5f ); break;
            case ROTATE:
              at.setToRotation( Math.PI / 6 ); break;
            case SHEAR:
              at.setToShear( 0.4f, 0 ); break;
            case NONE:
              break;
            default:
              //System.err.println( "Illegal G2 Transform Arg: " + transform);
              break;
            }

            return at;
    }

    public void setFontParams(Object obj, float size,
                              int style, int transform) {
        setFontParams( (String)obj, size, style, transform );
    }

    public void setFontParams(String name, float size,
                              int style, int transform) {
        boolean fontModified = false;
        if ( !name.equals( fontName ) || style != fontStyle )
          fontModified = true;

        fontName = name;
        fontSize = size;
        fontStyle = style;
        fontTransform = transform;

        /// Recreate the font as specified
        testFont = new Font(fontName, fontStyle, (int)fontSize);
        if ((float)((int)fontSize) != fontSize) {
            testFont = testFont.deriveFont(fontSize);
        }

        if ( fontTransform != NONE ) {
            AffineTransform at = getAffineTransform( fontTransform );
            testFont = testFont.deriveFont( at );
        }
        updateFontMetrics = true;
        fc.repaint();
        if ( fontModified ) {
            /// Tell main panel to update the font info
            updateFontInfo();
            f2dt.fireUpdateFontInfo();
        }
    }

    public void setRenderingHints( Object aa, Object fm, Object contrast) {
        antiAliasType = ((AAValues)aa).getHint();
        fractionalMetricsType = ((FMValues)fm).getHint();
        lcdContrast = contrast;
        updateFontMetrics = true;
        fc.repaint();
    }

    public void setDrawMethod( int i ) {
        drawMethod = i;
        fc.repaint();
    }

    public void setTextToDraw( int i, int[] range,
                               String[] textSet, String[] fileData ) {
        textToUse = i;

        if ( textToUse == RANGE_TEXT )
          drawRange = range;
        else if ( textToUse == ALL_GLYPHS )
          drawMethod = DRAW_GLYPHV;
        else if ( textToUse == USER_TEXT )
          userText = textSet;
        else if ( textToUse == FILE_TEXT ) {
            fileText = fileData;
            drawMethod = TL_DRAW;
        }

        updateFontMetrics = true;
        fc.repaint();
        updateFontInfo();
    }

    public void setGridDisplay( boolean b ) {
        showGrid = b;
        fc.repaint();
    }

    public void setForce16Columns( boolean b ) {
        force16Cols = b;
        updateFontMetrics = true;
        fc.repaint();
    }

    /// Prints out the text display area
    public void doPrint( int i ) {
        if ( printer == null ) {
            printer = PrinterJob.getPrinterJob();
            page = printer.defaultPage();
        }
        printMode = i;
        printer.setPrintable( fc, page );

        if ( printer.printDialog() ) {
            try {
                printer.print();
            }
            catch ( Exception e ) {
                f2dt.fireChangeStatus( "ERROR: Printing Failed; See Stack Trace", true );
            }
        }
    }

    /// Displays the page setup dialog and updates PageFormat info
    public void doPageSetup() {
        if ( printer == null ) {
            printer = PrinterJob.getPrinterJob();
            page = printer.defaultPage();
        }
        page = printer.pageDialog( page );
    }

    /// Obtains the information about selected font
    private void updateFontInfo() {
        int numGlyphs = 0, numCharsInRange = drawRange[1] - drawRange[0] + 1;
        fontInfos[0] = "Font Face Name: " + testFont.getFontName();
        fontInfos[1] = "Glyphs in This Range: ";

        if ( textToUse == RANGE_TEXT ) {
            for ( int i = drawRange[0]; i < drawRange[1]; i++ )
              if ( testFont.canDisplay( i ))
                numGlyphs++;
            fontInfos[1] = fontInfos[1] + numGlyphs + " / " + numCharsInRange;
        }
        else
          fontInfos[1] = null;
    }

    /// Accessor for the font information
    public String[] getFontInfo() {
        return fontInfos;
    }

    /// Collects the currectly set options and returns them as string
    public String getCurrentOptions() {
        /// Create a new String to store the options
        /// The array will contain all 8 setting (font name, size...) and
        /// character range or user text data used (no file text data)
        int userTextSize = 0;
        String options;

        options = ( fontName + "\n" + fontSize  + "\n" + fontStyle + "\n" +
                    fontTransform + "\n"  + g2Transform + "\n"+
                    textToUse + "\n" + drawMethod + "\n" +
                    AAValues.getHintVal(antiAliasType) + "\n" +
                    FMValues.getHintVal(fractionalMetricsType) + "\n" +
                    lcdContrast + "\n");
        if ( textToUse == USER_TEXT )
          for ( int i = 0; i < userText.length; i++ )
            options += ( userText[i] + "\n" );

        return options;
    }

    /// Reload all options and refreshes the canvas
    public void loadOptions( boolean grid, boolean force16, int start, int end,
                             String name, float size, int style,
                             int transform, int g2transform,
                             int text, int method, int aa, int fm,
                             int contrast, String[] user ) {
        int[] range = { start, end };

        /// Since repaint call has a low priority, these functions will finish
        /// before the actual repainting is done
        setGridDisplay( grid );
        setForce16Columns( force16 );
        // previous call to readTextFile has already set the text to draw
        if (textToUse != FILE_TEXT) {
          setTextToDraw( text, range, user, null );
        }
        setFontParams( name, size, style, transform );
        setTransformG2( g2transform ); // ABP
        setDrawMethod( method );
        setRenderingHints(AAValues.getValue(aa), FMValues.getValue(fm),
                          Integer.valueOf(contrast));
    }

    /// Writes the current screen to PNG file
    public void doSavePNG( String fileName ) {
        fc.writePNG( fileName );
    }

    /// When scrolled using the scroll bar, update the backbuffer
    public void adjustmentValueChanged( AdjustmentEvent e ) {
        fc.repaint();
    }

    public void paintComponent( Graphics g ) {
        // Windows does not repaint correctly, after
        // a zoom. Thus, we need to force the canvas
        // to repaint, but only once. After the first repaint,
        // everything stabilizes. [ABP]
        fc.repaint();
    }

    /// Inner class definition...

    /// Inner panel that holds the actual drawing area and its routines
    private class FontCanvas extends JPanel implements MouseListener, MouseMotionListener, Printable {

        /// Number of characters that will fit across and down this canvas
        private int numCharAcross, numCharDown;

        /// First and last character/line that will be drawn
        /// Limit is the end of range/text where no more draw will be done
        private int drawStart, drawEnd, drawLimit;

        /// FontMetrics variables
        /// Here, gridWidth is equivalent to maxAdvance (slightly bigger though)
        /// and gridHeight is equivalent to lineHeight
        private int maxAscent, maxDescent, gridWidth = 0, gridHeight = 0;

        /// Offset from the top left edge of the canvas where the draw will start
        private int canvasInset_X = 5, canvasInset_Y = 5;

        /// LineBreak'ed TextLayout vector
        private Vector<TextLayout> lineBreakTLs = null;

        /// Whether the current draw command requested is for printing
        private boolean isPrinting = false;

        /// Other printing infos
        private int lastPage, printPageNumber, currentlyShownChar = 0;
        private final int PR_OFFSET = 10;
        private final int PR_TITLE_LINEHEIGHT = 30;

        /// Information about zooming (used with range text draw)
        private final JWindow zoomWindow;
        private BufferedImage zoomImage = null;
        private int mouseOverCharX = -1, mouseOverCharY = -1;
        private int currMouseOverChar = -1, prevZoomChar = -1;
        private float ZOOM = 2.0f;
        private boolean nowZooming = false;
        private boolean firstTime = true;
// ABP

        /// Status bar message backup
        private String backupStatusString = null;

        /// Error constants
        private final String[] ERRORS = {
            "ERROR: drawBytes cannot handle characters beyond 0x00FF. Select different range or draw methods.",
            "ERROR: Cannot fit text with the current font size. Resize the window or use smaller font size.",
            "ERROR: Cannot print with the current font size. Use smaller font size.",
        };

        private final int DRAW_BYTES_ERROR = 0;
        private final int CANT_FIT_DRAW = 1;
        private final int CANT_FIT_PRINT = 2;

        /// Other variables
        private final Cursor blankCursor;

        public FontCanvas() {
            this.addMouseListener( this );
            this.addMouseMotionListener( this );
            this.setForeground( Color.black );
            this.setBackground( Color.white );

            /// Creates an invisble pointer by giving it bogus image
            /// Possibly find a workaround for this...
            Toolkit tk = Toolkit.getDefaultToolkit();
            byte[] bogus = { (byte) 0 };
            blankCursor =
              tk.createCustomCursor( tk.createImage( bogus ), new Point(0, 0), "" );

            zoomWindow = new JWindow( parent ) {
                public void paint( Graphics g ) {
                    g.drawImage( zoomImage, 0, 0, zoomWindow );
                }
            };
            zoomWindow.setCursor( blankCursor );
            zoomWindow.pack();
        }

        public boolean firstTime() { return firstTime; }
        public void refresh() {
            firstTime = false;
            repaint();
        }

        /// Sets the font, hints, according to the set parameters
        private void setParams( Graphics2D g2 ) {
            g2.setFont( testFont );
            g2.setRenderingHint(KEY_TEXT_ANTIALIASING, antiAliasType);
            g2.setRenderingHint(KEY_FRACTIONALMETRICS, fractionalMetricsType);
            g2.setRenderingHint(KEY_TEXT_LCD_CONTRAST, lcdContrast);
            /* I am preserving a somewhat dubious behaviour of this program.
             * Outline text would be drawn anti-aliased by setting the
             * graphics anti-aliasing hint if the text anti-aliasing hint
             * was set. The dubious element here is that people simply
             * using this program may think this is built-in behaviour
             * but its not - at least not when the app explicitly draws
             * outline text.
             * This becomes more dubious in cases such as "GASP" where the
             * size at which text is AA'ed is not something you can easily
             * calculate, so mimicing that behaviour isn't going to be easy.
             * So I precisely preserve the behaviour : this is done only
             * if the AA value is "ON". Its not applied in the other cases.
             */
            if (antiAliasType == VALUE_TEXT_ANTIALIAS_ON &&
                (drawMethod == TL_OUTLINE || drawMethod == GV_OUTLINE)) {
                g2.setRenderingHint(KEY_ANTIALIASING, VALUE_ANTIALIAS_ON);
            } else {
                g2.setRenderingHint(KEY_ANTIALIASING, VALUE_ANTIALIAS_OFF);
            }
        }

        /// Draws the grid (Used for unicode/glyph range drawing)
        private void drawGrid( Graphics2D g2 ) {
            int totalGridWidth = numCharAcross * gridWidth;
            int totalGridHeight = numCharDown * gridHeight;

            g2.setColor( Color.black );
            for ( int i = 0; i < numCharDown + 1; i++ )
              g2.drawLine( canvasInset_X, i * gridHeight + canvasInset_Y,
                           canvasInset_X + totalGridWidth, i * gridHeight + canvasInset_Y );
            for ( int i = 0; i < numCharAcross + 1; i++ )
              g2.drawLine( i * gridWidth + canvasInset_X, canvasInset_Y,
                           i * gridWidth + canvasInset_X, canvasInset_Y + totalGridHeight );
        }

        /// Draws one character at time onto the canvas according to
        /// the method requested (Used for RANGE_TEXT and ALL_GLYPHS)
        public void modeSpecificDrawChar( Graphics2D g2, int charCode,
                                          int baseX, int baseY ) {
            GlyphVector gv;
            int[] oneGlyph = { charCode };
            char[] charArray = Character.toChars( charCode );

            FontRenderContext frc = g2.getFontRenderContext();
            AffineTransform oldTX = g2.getTransform();

            /// Create GlyphVector to measure the exact visual advance
            /// Using that number, adjust the position of the character drawn
            if ( textToUse == ALL_GLYPHS )
              gv = testFont.createGlyphVector( frc, oneGlyph );
            else
              gv = testFont.createGlyphVector( frc, charArray );
            Rectangle2D r2d2 = gv.getPixelBounds(frc, 0, 0);
            int shiftedX = baseX;
            // getPixelBounds returns a result in device space.
            // we need to convert back to user space to be able to
            // calculate the shift as baseX is in user space.
            try {
                 double[] pt = new double[4];
                 pt[0] = r2d2.getX();
                 pt[1] = r2d2.getY();
                 pt[2] = r2d2.getX()+r2d2.getWidth();
                 pt[3] = r2d2.getY()+r2d2.getHeight();
                 oldTX.inverseTransform(pt,0,pt,0,2);
                 shiftedX = baseX - (int) ( pt[2] / 2 + pt[0] );
            } catch (NoninvertibleTransformException e) {
            }

            /// ABP - keep track of old tform, restore it later

            g2.translate( shiftedX, baseY );
            g2.transform( getAffineTransform( g2Transform ) );

            if ( textToUse == ALL_GLYPHS )
              g2.drawGlyphVector( gv, 0f, 0f );
            else {
                if ( testFont.canDisplay( charCode ))
                  g2.setColor( Color.black );
                else {
                  g2.setColor( Color.lightGray );
                }

                switch ( drawMethod ) {
                  case DRAW_STRING:
                    g2.drawString( new String( charArray ), 0, 0 );
                    break;
                  case DRAW_CHARS:
                    g2.drawChars( charArray, 0, 1, 0, 0 );
                    break;
                  case DRAW_BYTES:
                    if ( charCode > 0xff )
                      throw new CannotDrawException( DRAW_BYTES_ERROR );
                    byte[] oneByte = { (byte) charCode };
                    g2.drawBytes( oneByte, 0, 1, 0, 0 );
                    break;
                  case DRAW_GLYPHV:
                    g2.drawGlyphVector( gv, 0f, 0f );
                    break;
                  case TL_DRAW:
                    TextLayout tl = new TextLayout( new String( charArray ), testFont, frc );
                    tl.draw( g2, 0f, 0f );
                    break;
                  case GV_OUTLINE:
                    r2d2 = gv.getVisualBounds();
                    shiftedX = baseX - (int) ( r2d2.getWidth() / 2 + r2d2.getX() );
                    g2.draw( gv.getOutline( 0f, 0f ));
                    break;
                  case TL_OUTLINE:
                    r2d2 = gv.getVisualBounds();
                    shiftedX = baseX - (int) ( r2d2.getWidth() / 2 + r2d2.getX() );
                    TextLayout tlo =
                      new TextLayout( new String( charArray ), testFont,
                                      g2.getFontRenderContext() );
                    g2.draw( tlo.getOutline( null ));
                }
            }

            /// ABP - restore old tform
            g2.setTransform ( oldTX );
        }

        /// Draws one line of text at given position
        private void modeSpecificDrawLine( Graphics2D g2, String line,
                                           int baseX, int baseY ) {
            /// ABP - keep track of old tform, restore it later
            AffineTransform oldTx = null;
            oldTx = g2.getTransform();
            g2.translate( baseX, baseY );
            g2.transform( getAffineTransform( g2Transform ) );

            switch ( drawMethod ) {
              case DRAW_STRING:
                g2.drawString( line, 0, 0 );
                break;
              case DRAW_CHARS:
                g2.drawChars( line.toCharArray(), 0, line.length(), 0, 0 );
                break;
              case DRAW_BYTES:
                try {
                    byte[] lineBytes = line.getBytes(ISO_8859_1);
                    g2.drawBytes( lineBytes, 0, lineBytes.length, 0, 0 );
                }
                catch ( Exception e ) {
                    e.printStackTrace();
                }
                break;
              case DRAW_GLYPHV:
                GlyphVector gv =
                  testFont.createGlyphVector( g2.getFontRenderContext(), line );
                g2.drawGlyphVector( gv, (float) 0, (float) 0 );
                break;
              case TL_DRAW:
                TextLayout tl = new TextLayout( line, testFont,
                                                g2.getFontRenderContext() );
                tl.draw( g2, (float) 0, (float) 0 );
                break;
              case GV_OUTLINE:
                GlyphVector gvo =
                  testFont.createGlyphVector( g2.getFontRenderContext(), line );
                g2.draw( gvo.getOutline( (float) 0, (float) 0 ));
                break;
              case TL_OUTLINE:
                TextLayout tlo =
                  new TextLayout( line, testFont,
                                  g2.getFontRenderContext() );
                AffineTransform at = new AffineTransform();
                g2.draw( tlo.getOutline( at ));
            }

            /// ABP - restore old tform
            g2.setTransform ( oldTx );

        }

        /// Draws one line of text at given position
        private void tlDrawLine( Graphics2D g2, TextLayout tl,
                                           float baseX, float baseY ) {
            /// ABP - keep track of old tform, restore it later
            AffineTransform oldTx = null;
            oldTx = g2.getTransform();
            g2.translate( baseX, baseY );
            g2.transform( getAffineTransform( g2Transform ) );

            tl.draw( g2, (float) 0, (float) 0 );

            /// ABP - restore old tform
            g2.setTransform ( oldTx );

        }


        /// If textToUse is set to range drawing, then convert
        /// int to hex string and prepends 0s to make it length 4
        /// Otherwise line number was fed; simply return number + 1 converted to String
        /// (This is because first line is 1, not 0)
        private String modeSpecificNumStr( int i ) {
            if ( textToUse == USER_TEXT || textToUse == FILE_TEXT )
              return String.valueOf( i + 1 );

            StringBuffer s = new StringBuffer( Integer.toHexString( i ));
            while ( s.length() < 4 )
              s.insert( 0, "0" );
            return s.toString().toUpperCase();
        }

        /// Resets the scrollbar to display correct range of text currently on screen
        /// (This scrollbar is not part of a "ScrollPane". It merely simulates its effect by
        ///  indicating the necessary area to be drawn within the panel.
        ///  By doing this, it prevents creating gigantic panel when large text range,
        ///  i.e. CJK Ideographs, is requested)
        private void resetScrollbar( int oldValue ) {
            int totalNumRows = 1, numCharToDisplay;
            if ( textToUse == RANGE_TEXT || textToUse == ALL_GLYPHS ) {
                if ( textToUse == RANGE_TEXT )
                  numCharToDisplay = drawRange[1] - drawRange[0];
                else /// textToUse == ALL_GLYPHS
                  numCharToDisplay = testFont.getNumGlyphs();

                totalNumRows = numCharToDisplay / numCharAcross;
                if ( numCharToDisplay % numCharAcross != 0 )
                  totalNumRows++;
                if ( oldValue / numCharAcross > totalNumRows )
                  oldValue = 0;

                verticalBar.setValues( oldValue / numCharAcross,
                                       numCharDown, 0, totalNumRows );
            }
            else {
                if ( textToUse == USER_TEXT )
                  totalNumRows = userText.length;
                else /// textToUse == FILE_TEXT;
                  totalNumRows = lineBreakTLs.size();
                verticalBar.setValues( oldValue, numCharDown, 0, totalNumRows );
            }
            if ( totalNumRows <= numCharDown && drawStart == 0) {
              verticalBar.setEnabled( false );
            }
            else {
              verticalBar.setEnabled( true );
            }
        }

        /// Calculates the font's metrics that will be used for draw
        private void calcFontMetrics( Graphics2D g2d, int w, int h ) {
            FontMetrics fm;
            Graphics2D g2 = (Graphics2D)g2d.create();

            /// ABP
            if ( g2Transform != NONE && textToUse != FILE_TEXT ) {
                g2.setFont( g2.getFont().deriveFont( getAffineTransform( g2Transform )) );
                fm = g2.getFontMetrics();
            }
            else {
                fm = g2.getFontMetrics();
            }

            maxAscent = fm.getMaxAscent();
            maxDescent = fm.getMaxDescent();
            if (maxAscent == 0) maxAscent = 10;
            if (maxDescent == 0) maxDescent = 5;
            if ( textToUse == RANGE_TEXT || textToUse == ALL_GLYPHS ) {
                /// Give slight extra room for each character
                maxAscent += 3;
                maxDescent += 3;
                gridWidth = fm.getMaxAdvance() + 6;
                gridHeight = maxAscent + maxDescent;
                if ( force16Cols )
                  numCharAcross = 16;
                else
                  numCharAcross = ( w - 10 ) / gridWidth;
                numCharDown = ( h - 10 ) / gridHeight;

                canvasInset_X = ( w - numCharAcross * gridWidth ) / 2;
                canvasInset_Y = ( h - numCharDown * gridHeight ) / 2;
                if ( numCharDown == 0 || numCharAcross == 0 )
                  throw new CannotDrawException( isPrinting ? CANT_FIT_PRINT : CANT_FIT_DRAW );

                if ( !isPrinting )
                  resetScrollbar( verticalBar.getValue() * numCharAcross );
            }
            else {
                maxDescent += fm.getLeading();
                canvasInset_X = 5;
                canvasInset_Y = 5;
                /// gridWidth and numCharAcross will not be used in this mode...
                gridHeight = maxAscent + maxDescent;
                numCharDown = ( h - canvasInset_Y * 2 ) / gridHeight;

                if ( numCharDown == 0 )
                  throw new CannotDrawException( isPrinting ? CANT_FIT_PRINT : CANT_FIT_DRAW );
                /// If this is text loaded from file, prepares the LineBreak'ed
                /// text layout at this point
                if ( textToUse == FILE_TEXT ) {
                    if ( !isPrinting )
                      f2dt.fireChangeStatus( "LineBreaking Text... Please Wait", false );
                    lineBreakTLs = new Vector<>();
                    for ( int i = 0; i < fileText.length; i++ ) {
                        AttributedString as =
                          new AttributedString( fileText[i], g2.getFont().getAttributes() );

                        LineBreakMeasurer lbm =
                          new LineBreakMeasurer( as.getIterator(), g2.getFontRenderContext() );

                        while ( lbm.getPosition() < fileText[i].length() )
                          lineBreakTLs.add( lbm.nextLayout( (float) w ));

                    }
                }
                if ( !isPrinting )
                  resetScrollbar( verticalBar.getValue() );
            }
        }

        /// Calculates the amount of text that will be displayed on screen
        private void calcTextRange() {
            String displaying = null;

            if ( textToUse == RANGE_TEXT || textToUse == ALL_GLYPHS ) {
                if ( isPrinting )
                  if ( printMode == ONE_PAGE )
                    drawStart = currentlyShownChar;
                  else /// printMode == CUR_RANGE
                    drawStart = numCharAcross * numCharDown * printPageNumber;
                else
                  drawStart = verticalBar.getValue() * numCharAcross;
                if ( textToUse == RANGE_TEXT ) {
                    drawStart += drawRange[0];
                    drawLimit = drawRange[1];
                }
                else
                  drawLimit = testFont.getNumGlyphs();
                drawEnd = drawStart + numCharAcross * numCharDown - 1;

                if ( drawEnd >= drawLimit )
                  drawEnd = drawLimit;
            }
            else {
                if ( isPrinting )
                  if ( printMode == ONE_PAGE )
                    drawStart = currentlyShownChar;
                  else /// printMode == ALL_TEXT
                    drawStart = numCharDown * printPageNumber;
                else {
                    drawStart = verticalBar.getValue();
                }

                drawEnd = drawStart + numCharDown - 1;

                if ( textToUse == USER_TEXT )
                  drawLimit = userText.length - 1;
                else
                  drawLimit = lineBreakTLs.size() - 1;

                if ( drawEnd >= drawLimit )
                  drawEnd = drawLimit;
            }

            // ABP
            if ( drawStart > drawEnd ) {
              drawStart = 0;
              verticalBar.setValue(drawStart);
            }


            /// Change the status bar if not printing...
            if ( !isPrinting ) {
                backupStatusString = ( "Displaying" + MS_OPENING[textToUse] +
                                       modeSpecificNumStr( drawStart ) + " to " +
                                       modeSpecificNumStr( drawEnd ) +
                                       MS_CLOSING[textToUse] );
                f2dt.fireChangeStatus( backupStatusString, false );
            }
        }

        /// Draws text according to the parameters set by Font2DTest GUI
        private void drawText( Graphics g, int w, int h ) {
            Graphics2D g2 = (Graphics2D) g;
            g2.setColor(Color.white);
            g2.fillRect(0, 0, w, h);
            g2.setColor(Color.black);

            /// sets font, RenderingHints.
            setParams( g2 );

            /// If flag is set, recalculate fontMetrics and reset the scrollbar
            if ( updateFontMetrics || isPrinting ) {
                /// NOTE: re-calculates in case G2 transform
                /// is something other than NONE
                calcFontMetrics( g2, w, h );
                updateFontMetrics = false;
            }
            /// Calculate the amount of text that can be drawn...
            calcTextRange();

            /// Draw according to the set "Text to Use" mode
            if ( textToUse == RANGE_TEXT || textToUse == ALL_GLYPHS ) {
                int charToDraw = drawStart;
                if ( showGrid )
                  drawGrid( g2 );

                for ( int i = 0; i < numCharDown && charToDraw <= drawEnd; i++ ) {
                  for ( int j = 0; j < numCharAcross && charToDraw <= drawEnd; j++, charToDraw++ ) {
                      int gridLocX = j * gridWidth + canvasInset_X;
                      int gridLocY = i * gridHeight + canvasInset_Y;

                      modeSpecificDrawChar( g2, charToDraw,
                                            gridLocX + gridWidth / 2,
                                            gridLocY + maxAscent );

                  }
                }
            }
            else if ( textToUse == USER_TEXT ) {
                g2.drawRect( 0, 0, w - 1, h - 1 );
                for ( int i = drawStart; i <= drawEnd; i++ ) {
                    int lineStartX = canvasInset_Y;
                    int lineStartY = ( i - drawStart ) * gridHeight + maxAscent;
                    modeSpecificDrawLine( g2, userText[i], lineStartX, lineStartY );
                }
            }
            else {
                float xPos, yPos = (float) canvasInset_Y;
                g2.drawRect( 0, 0, w - 1, h - 1 );
                for ( int i = drawStart; i <= drawEnd; i++ ) {
                    TextLayout oneLine = lineBreakTLs.elementAt( i );
                    xPos =
                      oneLine.isLeftToRight() ?
                      canvasInset_X : ( (float) w - oneLine.getAdvance() - canvasInset_X );

                    float[] fmData = {0, oneLine.getAscent(), 0, oneLine.getDescent(), 0, oneLine.getLeading()};
                    if (g2Transform != NONE) {
                        AffineTransform at = getAffineTransform(g2Transform);
                        at.transform( fmData, 0, fmData, 0, 3);
                    }
                    //yPos += oneLine.getAscent();
                    yPos += fmData[1]; // ascent
                    //oneLine.draw( g2, xPos, yPos );
                    tlDrawLine( g2, oneLine, xPos, yPos );
                    //yPos += oneLine.getDescent() + oneLine.getLeading();
                    yPos += fmData[3] + fmData[5]; // descent + leading
                }
            }
            g2.dispose();
        }

        /// Component paintComponent function...
        /// Draws/Refreshes canvas according to flag(s) set by other functions
        public void paintComponent( Graphics g ) {
              super.paintComponent(g);

                Dimension d = this.getSize();
                isPrinting = false;
                try {
                    drawText( g, d.width, d.height );
                }
                catch ( CannotDrawException e ) {
                    super.paintComponent(g);
                    f2dt.fireChangeStatus( ERRORS[ e.id ], true );
                    return;
                }

            showingError = false;
        }

        /// Printable interface function
        /// Component print function...
        public int print( Graphics g, PageFormat pf, int pageIndex ) {
            if ( pageIndex == 0 ) {
                /// Reset the last page index to max...
                lastPage = Integer.MAX_VALUE;
                currentlyShownChar = verticalBar.getValue() * numCharAcross;
            }

            if ( printMode == ONE_PAGE ) {
                if ( pageIndex > 0 )
                  return NO_SUCH_PAGE;
            }
            else {
                if ( pageIndex > lastPage )
                  return NO_SUCH_PAGE;
            }

            int pageWidth = (int) pf.getImageableWidth();
            int pageHeight = (int) pf.getImageableHeight();
            /// Back up metrics and other drawing info before printing modifies it
            int backupDrawStart = drawStart, backupDrawEnd = drawEnd;
            int backupNumCharAcross = numCharAcross, backupNumCharDown = numCharDown;
            Vector<TextLayout> backupLineBreakTLs = null;
            if ( textToUse == FILE_TEXT )
              backupLineBreakTLs = new Vector<>(lineBreakTLs);

            printPageNumber = pageIndex;
            isPrinting = true;
            /// Push the actual draw area 60 down to allow info to be printed
            g.translate( (int) pf.getImageableX(), (int) pf.getImageableY() + 60 );
            try {
                drawText( g, pageWidth, pageHeight - 60 );
            }
            catch ( CannotDrawException e ) {
                f2dt.fireChangeStatus( ERRORS[ e.id ], true );
                return NO_SUCH_PAGE;
            }

            /// Draw information about what is being printed
            String hints = ( " with antialias " + antiAliasType + "and" +
                             " fractional metrics " + fractionalMetricsType +
                             " and lcd contrast = " + lcdContrast);
            String infoLine1 = ( "Printing" + MS_OPENING[textToUse] +
                                 modeSpecificNumStr( drawStart ) + " to " +
                                 modeSpecificNumStr( drawEnd ) + MS_CLOSING[textToUse] );
            String infoLine2 = ( "With " + fontName + " " + STYLES[fontStyle] + " at " +
                                 fontSize + " point size " + TRANSFORMS[fontTransform] );
            String infoLine3 = "Using " + METHODS[drawMethod] + hints;
            String infoLine4 = "Page: " + ( pageIndex + 1 );
            g.setFont( new Font( "dialog", Font.PLAIN, 12 ));
            g.setColor( Color.black );
            g.translate( 0, -60 );
            g.drawString( infoLine1, 15, 10 );
            g.drawString( infoLine2, 15, 22 );
            g.drawString( infoLine3, 15, 34 );
            g.drawString( infoLine4, 15, 46 );

            if ( drawEnd == drawLimit )
              /// This indicates that the draw will be completed with this page
              lastPage = pageIndex;

            /// Restore the changed values back...
            /// This is important for JScrollBar settings and LineBreak'ed TLs
            drawStart = backupDrawStart;
            drawEnd = backupDrawEnd;
            numCharAcross = backupNumCharAcross;
            numCharDown = backupNumCharDown;
            if ( textToUse == FILE_TEXT )
              lineBreakTLs = backupLineBreakTLs;
            return PAGE_EXISTS;
        }

        /// Ouputs the current canvas into a given PNG file
        public void writePNG( String fileName ) {
            try {
                int w = this.getSize().width;
                int h = this.getSize().height;
                BufferedImage buffer = (BufferedImage) this.createImage( w, h );
                Graphics2D g2 = buffer.createGraphics();
                g2.setColor(Color.white);
                g2.fillRect(0, 0, w, h);
                g2.setColor(Color.black);
                updateFontMetrics = true;
                drawText(g2, w, h);
                updateFontMetrics = true;
                ImageIO.write(buffer, "png", new java.io.File(fileName));
            }
            catch ( Exception e ) {
                f2dt.fireChangeStatus( "ERROR: Failed to Save PNG image; See stack trace", true );
                e.printStackTrace();
            }
        }

        /// Figures out whether a character at the pointer location is valid
        /// And if so, updates mouse location informations, as well as
        /// the information on the status bar
        private boolean checkMouseLoc( MouseEvent e ) {
            if ( gridWidth != 0 && gridHeight != 0 )
              if ( textToUse == RANGE_TEXT || textToUse == ALL_GLYPHS ) {
                  int charLocX = ( e.getX() - canvasInset_X ) / gridWidth;
                  int charLocY = ( e.getY() - canvasInset_Y ) / gridHeight;

                  /// Check to make sure the mouse click location is within drawn area
                  if ( charLocX >= 0 && charLocY >= 0 &&
                       charLocX < numCharAcross && charLocY < numCharDown ) {
                      int mouseOverChar =
                        charLocX + ( verticalBar.getValue() + charLocY ) * numCharAcross;
                      if ( textToUse == RANGE_TEXT )
                        mouseOverChar += drawRange[0];
                      if ( mouseOverChar > drawEnd )
                        return false;

                      mouseOverCharX = charLocX;
                      mouseOverCharY = charLocY;
                      currMouseOverChar = mouseOverChar;
                      /// Update status bar
                      f2dt.fireChangeStatus( "Pointing to" + MS_OPENING[textToUse] +
                                             modeSpecificNumStr( mouseOverChar ), false );
                      return true;
                  }
              }
            return false;
        }

        /// Shows (updates) the character zoom window
        public void showZoomed() {
            GlyphVector gv;
            Font backup = testFont;
            Point canvasLoc = this.getLocationOnScreen();

            /// Calculate the zoom area's location and size...
            int dialogOffsetX = (int) ( gridWidth * ( ZOOM - 1 ) / 2 );
            int dialogOffsetY = (int) ( gridHeight * ( ZOOM - 1 ) / 2 );
            int zoomAreaX =
              mouseOverCharX * gridWidth + canvasInset_X - dialogOffsetX;
            int zoomAreaY =
              mouseOverCharY * gridHeight + canvasInset_Y - dialogOffsetY;
            int zoomAreaWidth = (int) ( gridWidth * ZOOM );
            int zoomAreaHeight = (int) ( gridHeight * ZOOM );

            /// Position and set size of zoom window as needed
            zoomWindow.setLocation( canvasLoc.x + zoomAreaX, canvasLoc.y + zoomAreaY );
            if ( !nowZooming ) {
                if ( zoomWindow.getWarningString() != null )
                  /// If this is not opened as a "secure" window,
                  /// it has a banner below the zoom dialog which makes it look really BAD
                  /// So enlarge it by a bit
                  zoomWindow.setSize( zoomAreaWidth + 1, zoomAreaHeight + 20 );
                else
                  zoomWindow.setSize( zoomAreaWidth + 1, zoomAreaHeight + 1 );
            }

            /// Prepare zoomed image
            zoomImage =
              (BufferedImage) zoomWindow.createImage( zoomAreaWidth + 1,
                                                      zoomAreaHeight + 1 );
            Graphics2D g2 = (Graphics2D) zoomImage.getGraphics();
            testFont = testFont.deriveFont( fontSize * ZOOM );
            setParams( g2 );
            g2.setColor( Color.white );
            g2.fillRect( 0, 0, zoomAreaWidth, zoomAreaHeight );
            g2.setColor( Color.black );
            g2.drawRect( 0, 0, zoomAreaWidth, zoomAreaHeight );
            modeSpecificDrawChar( g2, currMouseOverChar,
                                  zoomAreaWidth / 2, (int) ( maxAscent * ZOOM ));
            g2.dispose();
            if ( !nowZooming )
              zoomWindow.setVisible(true);
            /// This is sort of redundant... since there is a paint function
            /// inside zoomWindow definition that does the drawImage.
            /// (I should be able to call just repaint() here)
            /// However, for some reason, that paint function fails to respond
            /// from second time and on; So I have to force the paint here...
            zoomWindow.getGraphics().drawImage( zoomImage, 0, 0, this );

            nowZooming = true;
            prevZoomChar = currMouseOverChar;
            testFont = backup;

            // Windows does not repaint correctly, after
            // a zoom. Thus, we need to force the canvas
            // to repaint, but only once. After the first repaint,
            // everything stabilizes. [ABP]
            if ( firstTime() ) {
                refresh();
            }
        }

        /// Listener Functions

        /// MouseListener interface function
        /// Zooms a character when mouse is pressed above it
        public void mousePressed( MouseEvent e ) {
            if ( !showingError) {
                if ( checkMouseLoc( e )) {
                    showZoomed();
                    this.setCursor( blankCursor );
                }
            }
        }

        /// MouseListener interface function
        /// Redraws the area that was drawn over by zoomed character
        public void mouseReleased( MouseEvent e ) {
            if ( textToUse == RANGE_TEXT || textToUse == ALL_GLYPHS ) {
                if ( nowZooming )
                  zoomWindow.setVisible(false);
                nowZooming = false;
            }
            this.setCursor( Cursor.getDefaultCursor() );
        }

        /// MouseListener interface function
        /// Resets the status bar to display range instead of a specific character
        public void mouseExited( MouseEvent e ) {
            if ( !showingError && !nowZooming )
              f2dt.fireChangeStatus( backupStatusString, false );
        }

        /// MouseMotionListener interface function
        /// Adjusts the status bar message when mouse moves over a character
        public void mouseMoved( MouseEvent e ) {
            if ( !showingError ) {
                if ( !checkMouseLoc( e ))
                  f2dt.fireChangeStatus( backupStatusString, false );
            }
        }

        /// MouseMotionListener interface function
        /// Scrolls the zoomed character when mouse is dragged
        public void mouseDragged( MouseEvent e ) {
            if ( !showingError )
              if ( nowZooming ) {
                  if ( checkMouseLoc( e ) && currMouseOverChar != prevZoomChar )
                    showZoomed();
              }
        }

        /// Empty function to comply with interface requirement
        public void mouseClicked( MouseEvent e ) {}
        public void mouseEntered( MouseEvent e ) {}
    }

    private final class CannotDrawException extends RuntimeException {
        /// Error ID
        public final int id;

        public CannotDrawException( int i ) {
            id = i;
        }
    }

    enum FMValues {
       FMDEFAULT ("DEFAULT",  VALUE_FRACTIONALMETRICS_DEFAULT),
       FMOFF     ("OFF",      VALUE_FRACTIONALMETRICS_OFF),
       FMON      ("ON",       VALUE_FRACTIONALMETRICS_ON);

        private String name;
        private Object hint;

        private static FMValues[] valArray;

        FMValues(String s, Object o) {
            name = s;
            hint = o;
        }

        public String toString() {
            return name;
        }

       public Object getHint() {
           return hint;
       }
       public static Object getValue(int ordinal) {
           if (valArray == null) {
               valArray = FMValues.values();
           }
           for (int i=0;i<valArray.length;i++) {
               if (valArray[i].ordinal() == ordinal) {
                   return valArray[i];
               }
           }
           return valArray[0];
       }
       private static FMValues[] getArray() {
           if (valArray == null) {
               valArray = FMValues.values();
           }
           return valArray;
       }

       public static int getHintVal(Object hint) {
           getArray();
           for (int i=0;i<valArray.length;i++) {
               if (valArray[i].getHint() == hint) {
                   return i;
               }
           }
           return 0;
       }
    }

   enum AAValues {
       AADEFAULT ("DEFAULT",  VALUE_TEXT_ANTIALIAS_DEFAULT),
       AAOFF     ("OFF",      VALUE_TEXT_ANTIALIAS_OFF),
       AAON      ("ON",       VALUE_TEXT_ANTIALIAS_ON),
       AAGASP    ("GASP",     VALUE_TEXT_ANTIALIAS_GASP),
       AALCDHRGB ("LCD_HRGB", VALUE_TEXT_ANTIALIAS_LCD_HRGB),
       AALCDHBGR ("LCD_HBGR", VALUE_TEXT_ANTIALIAS_LCD_HBGR),
       AALCDVRGB ("LCD_VRGB", VALUE_TEXT_ANTIALIAS_LCD_VRGB),
       AALCDVBGR ("LCD_VBGR", VALUE_TEXT_ANTIALIAS_LCD_VBGR);

        private String name;
        private Object hint;

        private static AAValues[] valArray;

        AAValues(String s, Object o) {
            name = s;
            hint = o;
        }

        public String toString() {
            return name;
        }

       public Object getHint() {
           return hint;
       }

       public static boolean isLCDMode(Object o) {
           return (o instanceof AAValues &&
                   ((AAValues)o).ordinal() >= AALCDHRGB.ordinal());
       }

       public static Object getValue(int ordinal) {
           if (valArray == null) {
               valArray = AAValues.values();
           }
           for (int i=0;i<valArray.length;i++) {
               if (valArray[i].ordinal() == ordinal) {
                   return valArray[i];
               }
           }
           return valArray[0];
       }

       private static AAValues[] getArray() {
           if (valArray == null) {
               valArray = AAValues.values();
           }
           return valArray;
       }

       public static int getHintVal(Object hint) {
           getArray();
           for (int i=0;i<valArray.length;i++) {
               if (valArray[i].getHint() == hint) {
                   return i;
               }
           }
           return 0;
       }

    }

    private static Integer defaultContrast;
    static Integer getDefaultLCDContrast() {
        if (defaultContrast == null) {
            GraphicsConfiguration gc =
            GraphicsEnvironment.getLocalGraphicsEnvironment().
                getDefaultScreenDevice().getDefaultConfiguration();
        Graphics2D g2d =
            (Graphics2D)(gc.createCompatibleImage(1,1).getGraphics());
        defaultContrast = (Integer)
            g2d.getRenderingHint(RenderingHints.KEY_TEXT_LCD_CONTRAST);
        }
        return defaultContrast;
    }
}
