package com.mindprod.example;

import com.mindprod.common11.FontFactory;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTextArea;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.AffineTransform;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;

/**
 * Demonstrate use of Print using PrinterJob.
 * <p/>
 * composed with IntelliJ IDEA
 *
 * @author Roedy Green, Canadian Mind Products
 * @version 1.0, 2007-07-10
 */
public final class TestPrinterJob extends JFrame implements Printable
    {
    // -------------------------- PUBLIC INSTANCE  METHODS --------------------------
    /**
     * constructor
     *
     * @param title label for title of frame.
     */
    @SuppressWarnings( { "SameParameterValue", "WeakerAccess" } )
    public TestPrinterJob( String title )
        {
        super( title );
        }

    /**
     * Draw this component on a printer, a page at a time.  This component may be so large it could never fit on a
     * screen.
     *
     * @param gr         the context into which the page is drawn, high res for printer.
     * @param pageFormat the paper size and orientation (landscape/portrait) of the page being drawn.
     * @param pageIndex  the zero based index of the page to be drawn.
     * @return Printable.PAGE_EXISTS if the page was rendered successfully or Printable.NO_SUCH_PAGE if pageIndex
     *         specifies a non-existent page. This is how the engine knows when you are done.
     */
    @SuppressWarnings( { "UnnecessaryLocalVariable" } )
    public int print( Graphics gr,
                      PageFormat pageFormat,
                      int pageIndex )
        {
        // Just like Component.paint.
        // In this example we ignore hints such as landscape/portrait in pageFormat
        // If you fail to return NO_SUCH_PAGE, you will get hundreds of pages
        // spewed out of your printer.
        if ( pageIndex > 0 )
            {
            return Printable.NO_SUCH_PAGE;
            }

        // We will be called twice, once with screen transform then
        // again with printer transform.

        // access extended 2D graphics methods.
        final Graphics2D g2 = ( Graphics2D ) gr;

        // save original transform
        final AffineTransform origTransform = g2.getTransform();

        // Pixels here are tiny, used by printer so
        // transform already is scaled to make us draw many more of them.
        final AffineTransform transform = origTransform;

        // apply a border on left and top of equivalent of .5 inch.
        // Our values are scaled into printer pixels.
        transform.translate( 36.0d, 36.0d );

        g2.setTransform( transform );

        // usual Frame.paint()
        paint( gr );
        g2.setTransform( origTransform );
        return Printable.PAGE_EXISTS;
        }

    // -------------------------- OTHER METHODS --------------------------

    /**
     * print the entire frame, including the title bar with the close widget.
     */
    private void printFrame()
        {
        // Get a PrinterJob object to manage this print.
        // Note you can't directly instantiate one since
        // PrinterJob is abstract.
        PrinterJob printerJob = PrinterJob.getPrinterJob();

        // Print this component just the way item would appear on screen.
        // The rendering of item is handled by this component's print method,
        // that works just like paint except item gets passed a printer-style
        // Graphics object instead of a screen-style and draws in higher resolution.

        printerJob.setPrintable( this );

        // pop up a dialog box for the end user to fine tune the options.
        if ( printerJob.printDialog() )
            {
            try
                {
                // render the component onto the printer or print queue.
                printerJob.print();
                }
            catch ( PrinterException e )
                {
                System.err.println( "Error printing: " + e );
                }
            }
        }

    // --------------------------- main() method ---------------------------

    /**
     * standard main method to run the test.
     *
     * @param args not used
     */
    public static void main( String[] args )
        {
        JFrame.setDefaultLookAndFeelDecorated( true );
        final TestPrinterJob jframe = new TestPrinterJob( "TestPrinterJob" );
        final Container contentPane = jframe.getContentPane();
        jframe.setSize( 215, 100 );

        // 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 JTextArea t =
                new JTextArea(
                        "All good men\n"
                        + "should come to the aid of the party." );
        contentPane.add( t, BorderLayout.NORTH );
        final JButton print = new JButton( "Print" );
        print.setBorder( BorderFactory.createRaisedBevelBorder() );
        print.setFocusPainted( false );
        print.setToolTipText( "Print the page" );

        print.setFont( FontFactory.build( "Dialog", Font.BOLD, 15 ) );
        print.addActionListener( new ActionListener()
        {
        /**
         * user clicked save.
         *
         * @param event button push event
         */
        public void actionPerformed( ActionEvent event )
            {
            jframe.printFrame();
            }// end actionPerformed
        } );
        contentPane.add( print, BorderLayout.SOUTH );

        jframe.validate();
        jframe.setVisible( true );
        }
    }