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


import java.awt.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.EnumSet;
import java.util.Vector;

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

import static java.awt.RenderingHints.*;

/**
 * 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 updateBackBuffer = true;
    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 ) {
                updateBackBuffer = true;
                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;
        updateBackBuffer = true;
        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 );
        }
        updateBackBuffer = true;
        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;
        updateBackBuffer = true;
        updateFontMetrics = true;
        fc.repaint();
    }

    public void setDrawMethod( int i ) {
        drawMethod = i;
        updateBackBuffer = true;
        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;
        }

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

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

    public void setForce16Columns( boolean b ) {
        force16Cols = b;
        updateBackBuffer = true;
        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),
                          new Integer(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 ) {
        updateBackBuffer = true;
        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;

        /// Offscreen buffer of this canvas
        private BufferedImage backBuffer = null;

        /// LineBreak'ed TextLayout vector
        private Vector 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;
            updateBackBuffer = true;
            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 explictly 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;

            /// Create back buffer when not printing, and its Graphics2D
            /// Then set drawing parameters for that Graphics2D object
            if ( isPrinting )
              g2 = (Graphics2D) g;
            else  {
                backBuffer = (BufferedImage) this.createImage( w, h );
                g2 = backBuffer.createGraphics();
                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 );
                if ( !isPrinting )
                  g.drawImage( backBuffer, 0, 0, this );

                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 );
                      //if ( !isPrinting ) {
                      //    g.setClip( gridLocX, gridLocY, gridWidth + 1, gridHeight + 1 );
                      //    g.drawImage( backBuffer, 0, 0, this );
                            //}

                  }
                }
            }
            else if ( textToUse == USER_TEXT ) {
                g2.drawRect( 0, 0, w - 1, h - 1 );
                if ( !isPrinting )
                  g.drawImage( backBuffer, 0, 0, this );

                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 );
                if ( !isPrinting )
                  g.drawImage( backBuffer, 0, 0, this );

                for ( int i = drawStart; i <= drawEnd; i++ ) {
                    TextLayout oneLine = (TextLayout) 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
                }
            }
                if ( !isPrinting )
                g.drawImage( backBuffer, 0, 0, this );
            g2.dispose();
        }

        /// Component paintComponent function...
        /// Draws/Refreshes canvas according to flag(s) set by other functions
        public void paintComponent( Graphics g ) {
            if ( updateBackBuffer ) {
                Dimension d = this.getSize();
                isPrinting = false;
                try {
                    drawText( g, d.width, d.height );
                }
                catch ( CannotDrawException e ) {
                    f2dt.fireChangeStatus( ERRORS[ e.id ], true );
                    super.paintComponent(g);
                    return;
                }
            }
            else {
              /// Screen refresh
              g.drawImage( backBuffer, 0, 0, this );
            }

            showingError = false;
            updateBackBuffer = 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 backupLineBreakTLs = null;
            if ( textToUse == FILE_TEXT )
              backupLineBreakTLs = (Vector) lineBreakTLs.clone();

            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 {
                ImageIO.write(backBuffer, "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.show();
            /// 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.hide();
                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[])EnumSet.allOf(FMValues.class).toArray(new FMValues[0]);
           }
           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[])EnumSet.allOf(FMValues.class).toArray(new FMValues[0]);
           }
           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[])EnumSet.allOf(AAValues.class).toArray(new AAValues[0]);
           }
           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) {
               Object [] oa = EnumSet.allOf(AAValues.class).toArray(new AAValues[0]);
               valArray = (AAValues[])(EnumSet.allOf(AAValues.class).toArray(new AAValues[0]));
           }
           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;
    }
}
