/*
 * [TestPaintComponent.java]
 *
 * Summary: Produces a PNG image, a green rhombus with the letters I/O on it, and exports it as a *.png image.
 *
 * Copyright: (c) 2009-2017 Roedy Green, Canadian Mind Products, http://mindprod.com
 *
 * Licence: This software may be copied and used freely for any purpose but military.
 *          http://mindprod.com/contact/nonmil.html
 *
 * Requires: JDK 1.8+
 *
 * Created with: JetBrains IntelliJ IDEA IDE http://www.jetbrains.com/idea/
 *
 * Version History:
 *  1.0 2007-05-13 initial version
 *  1.1 2011-01-10 add some comments, add drawCenteredString
 */
package com.mindprod.example;

import javax.imageio.ImageIO;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.font.FontRenderContext;
import java.awt.font.LineMetrics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import static java.lang.System.*;

/**
 * Produces a PNG image, a green rhombus with the letters I/O on it, and exports it as a *.png image.
 * <p/>
 * This program is not realistic.
 * It has been greatly simplified for teaching purposes just to show the essential elements.
 * A realistic program would be much more general purpose.
 * See the source code for Masker for a more practical example of png image creation.
 *
 * @author Roedy Green, Canadian Mind Products
 * @version 1.1 2011-01-10 add some comments, add drawCenteredString
 * @since 2007-05-13
 */
public final class TestPaintComponent
    {
    /**
     * Run as a stand-alone application.
     *
     * @param args command line arguments ignored.
     */
    public static void main( String args[] )
        {
        JFrame.setDefaultLookAndFeelDecorated( true );
        final JFrame jframe = new JFrame( "TestPaintCompnent" );
        final Container contentPane = jframe.getContentPane();
        jframe.setSize( 150, 200 );
        // Note that jframe.setBackground is almost useless.
        // You must set the background colour of the contentPane.
        contentPane.setBackground( Color.WHITE );
        contentPane.setForeground( Color.BLUE );
        contentPane.setLayout( new BorderLayout() );
        jframe.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
        final Rhombus rhombus = new Rhombus();
        rhombus.setBackground( Color.YELLOW );
        contentPane.add( rhombus, BorderLayout.NORTH );
        final JButton save = new JButton( "Save" );
        save.setBorder( BorderFactory.createRaisedBevelBorder() );
        save.setFocusPainted( false );
        save.setToolTipText( "Save PNG image as a file." );
        save.setFont( new Font( "Dialog", Font.BOLD, 15 ) );
        save.addActionListener( new ActionListener()
            {
            /**
             * user clicked save.
             * @param event button push event
             */
            public void actionPerformed( ActionEvent event )
                {
                rhombus.saveImage();
                } // end actionPerformed
            } );
        contentPane.add( save, BorderLayout.SOUTH );
        jframe.validate();
        jframe.setVisible( true );
        }
    }

final class Rhombus extends JPanel
    {
    /**
     * Displays a green rhombus with white I/O lettering on it.
     * @author Roedy Green, Canadian Mind Products
     * @version 1.0 2009-01-01 initial version
     */
    /**
     * height of image
     */
    private static final int height = 128;

    /**
     * width of image
     */
    private static final int width = 128;

    private static final Color lightGreen = new Color( 0x30ffaf );

    /* transparent white */
    private static final Color transparent = new Color( 0x00ffffff, true );

    /**
     * Constructor
     */
    Rhombus()
        {
        Dimension d = new Dimension( width, height );
        this.setPreferredSize( d );
        this.setMinimumSize( d );
        this.setMaximumSize( d );
        }

    /**
     * Draw string centered on x,y in both x and y directions
     *
     * @param g2d  the graphics context
     * @param x    location of center of string.
     * @param y    location of center of string.
     * @param text string to display
     */
    private static void drawCenteredString( final Graphics2D g2d, final String text, final int x, final int y )
        {
        final Font font = g2d.getFont();
        int width = g2d.getFontMetrics().stringWidth( text );
        final FontRenderContext fr = g2d.getFontRenderContext();
        final LineMetrics lm = font.getLineMetrics( text, fr );
        final int height = ( int ) ( lm.getAscent() * .76 + .5 )/* compensate for overstating */;
        // x,y is bottom left corner of text
        g2d.drawString( text, x - width / 2, y + height / 2 );
        }

    /**
     * draws the rhombus
     *
     * @param g graphics region where we paint
     */
    public void paintComponent( Graphics g )
        {
        super.paintComponent( g );
        Graphics2D g2d = ( Graphics2D ) g;
        // If you plan to change the clip region or AffineTransform,
        // use Graphics2D g2d = ( Graphics2D ) g.create(); instead
        // to avoid permanently modifying the caller's Graphics2D object.
        g2d.addRenderingHints( new RenderingHints( RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON ) );
        g2d.setBackground( transparent );
        g2d.clearRect( 0, 0, width, height );
        Font font = new Font( "Tiresias PCFont Z", Font.BOLD, 40 );
        g2d.setFont( font );
        String text = "I/O";
        g2d.setColor( lightGreen );
        g2d.fillPolygon( new int[] { 0, 96, 128, 32 }
                /* xs */, new int[] { 32, 32, 96, 96 }
                /* ys */, 4 );
        g2d.setColor( Color.BLUE );
        drawCenteredString( g2d, text, width / 2, height / 2 );
        }

    /**
     * save current image as a png.
     */
    public void saveImage()
        {
        try
            {
            // repaint onto a BufferedImage
            BufferedImage bufferedImage =
                    new BufferedImage( width,
                            height,
                            BufferedImage.TYPE_4BYTE_ABGR_PRE );
            Graphics2D g2d = bufferedImage
                    .createGraphics();
            // redraw using our paintComponent
            paintComponent( g2d );
            File file = new File( "C:/temp", "rhombus.png" );
            // write out the BufferedImage as a PNG
            ImageIO.write( bufferedImage, "png"
                    /* format desired */, file );
            }
        catch ( IOException e )
            {
            err.println( "image not saved." );
            }
        }
    }