/*
 * @(#)CMPAboutJBox.java
 *
 * Summary: A Swing About box that truly tells you about he program, not just the author's name.
 *
 * Copyright: (c) 2008-2010 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.3+
 *
 * Created with: IntelliJ IDEA IDE.
 *
 * Version History:
 *  1.3 2008-11-12 - add JDK version to About box
 */
package com.mindprod.common13;

import com.mindprod.common11.Build;
import com.mindprod.common11.FontFactory;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

/**
 * A Swing About box that truly tells you about he program, not just the author's name.
 * <p/>
 *
 * @author Roedy Green, Canadian Mind Products
 * @version 1.3 2008-11-12 - add JDK version to About box
 * @noinspection FieldCanBeLocal
 * @see "com.mindprod.common11.CMPAboutBox"
 * @since 2008
 */
public final class CMPAboutJBox extends JDialog
    {
    // ------------------------------ CONSTANTS ------------------------------

    /**
     * true if want debugging output
     */
    private static final boolean DEBUGGING = false;

    /**
     * height of the about box not counting frame
     */
    private static final int HEIGHT = 400;

    /**
     * width of the about box not counting frame
     */
    private static final int WIDTH = 490;

    private static final Color BLACK = Color.black;

    private static final Color DARK_GREEN = new Color( 0x008000 );

    private static final Color LABEL_FOREGROUND = new Color( 0x0000b0 );

    /**
     * for titles
     */
    private static final Color TITLE_FOREGROUND = new Color( 0xdc143c );

    private static final Color WHITE = Color.white;

    /**
     * for for titles and About buttons
     */
    private static final Font TITLE_FONT = FontFactory.build( "Dialog", Font.BOLD, 16 );

    // ------------------------------ FIELDS ------------------------------

    /**
     * trigger dismiss of about box
     */
    private JButton dismissButton;

    /**
     * first line of CMP mailing address
     */
    private JLabel showAddr1;

    /**
     * second line of CMP mailing address
     */
    private JLabel showAddr2;

    /**
     * program author
     */
    private JLabel showAuthor;

    /**
     * Canadian Mind Products
     */
    private JLabel showCMP;

    /**
     * copyright
     */
    private JLabel showCopyright;

    /**
     * download url
     */
    private JLabel showDownloadURL;

    /**
     * contact email
     */
    private JLabel showMailTo;

    /**
     * min JDK version required
     */
    private JLabel showMinJdkVersion;

    /**
     * cmp phone
     */
    private JLabel showPhone;

    /**
     * program name and version
     */
    private JLabel showProgramVersionBuild;

    /**
     * first line of purpose
     */
    private JLabel showPurpose1;

    /**
     * second line of purpose
     */
    private JLabel showPurpose2;

    /**
     * date released yyyy-mm-dd
     */
    private JLabel showReleaseDate;

    /**
     * JDK version running now
     */
    private JLabel showRunningJdkVersion;

    /**
     * freeware, shareware etc.
     */
    private JLabel showStatus;

    /**
     * name of VM
     */

    private JLabel showVmName;
    // -------------------------- PUBLIC INSTANCE  METHODS --------------------------

    /**
     * Create an about box, no parent
     *
     * @param progname           Program name
     * @param version            Program version e.g. "1.3"
     * @param purpose1           what is this program for? line-1
     * @param purpose2           what is this program for? line-2. may be null, or "".
     * @param status             e.g. "unregistered shareware", "freeware", "commercial", "company confidential"
     * @param released           Date released e.g. "1999-12-31"
     * @param firstCopyrightYear e.g. 1996
     * @param author             program's author
     * @param masterSite         anchor on products page e.g. CONVERTER -- where to find most up to date ZIP
     * @param minJdkVersion      e.g. 1.1 (minimum JDK version required)
     *
     * @noinspection UnusedDeclaration
     */
    public CMPAboutJBox( final String progname,
                         final String version,
                         final String purpose1,
                         final String purpose2,
                         final String status,
                         final String released,
                         final int firstCopyrightYear,
                         final String author,
                         final String masterSite,
                         final String minJdkVersion )
        {
        // dummy frame won't be properly disposed
        this( new JFrame( progname + " " + version + " build " + Build.BUILD_NUMBER ),
                progname,
                version,
                purpose1,
                purpose2,
                status,
                released,
                firstCopyrightYear,
                author,
                masterSite,
                minJdkVersion );
        }

    /**
     * Create an about box
     *
     * @param parent             frame for this about box.
     * @param progname           Program name
     * @param version            Program version e.g. "1.3"
     * @param purpose1           what is this program for? line-1
     * @param purpose2           what is this program for? line-2. may be null, or "".
     * @param status             e.g. "unregistered shareware", "freeware", "commercial", "company confidential"
     * @param released           Date released e.g. "1999-12-31"
     * @param firstCopyrightYear e.g. 1996
     * @param author             program's author
     * @param masterSite         anchor on products page e.g. CONVERTER -- where to find most up to date ZIP
     * @param minJkdVersion      e.g. 1.1 (minimum JDK version required)
     */
    public CMPAboutJBox( final Frame parent,
                         final String progname,
                         final String version,
                         final String purpose1,
                         final String purpose2,
                         final String status,
                         final String released,
                         final int firstCopyrightYear,
                         final String author,
                         final String masterSite,
                         final String minJkdVersion )
        {
        super( parent,
                progname + " " + version + " build " + Build.BUILD_NUMBER,
                false
        );
        guts( progname,
                version,
                purpose1,
                purpose2,
                status,
                released,
                firstCopyrightYear,
                author,
                masterSite,
                minJkdVersion );
        }

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

    /**
     * Shutdown the about box
     */
    private void dismiss()
        {
        this.dispose();
        }// end dismiss

    /**
     * Create an about box
     *
     * @param progname           Program name
     * @param version            Program version e.g. "1.3"
     * @param purpose1           what is this program for? line-1
     * @param purpose2           what is this program for? line-2. may be null, or "".
     * @param status             e.g. "unregistered shareware", "freeware", "commercial", "company confidential"
     * @param released           Date released e.g. "1999-12-31"
     * @param firstCopyrightYear e.g. 1996
     * @param author             who wrote the program.
     * @param masterSite         anchor on products page e.g. CONVERTER -- where to find most up to date ZIP
     * @param minJdkVersion      e.g. 1.1 (minimum JDK version required)
     */
    private void guts( final String progname,
                       final String version,
                       final String purpose1,
                       final String purpose2,
                       final String status,
                       final String released,
                       final int firstCopyrightYear,
                       final String author,
                       final String masterSite,
                       final String minJdkVersion )
        {
        // leave room for warning this frame belongs to Java applet.
        setSize( WIDTH + 22, WIDTH + 32 );
        setLocation( 0, 0 );
        Container contentPane = this.getContentPane();
        contentPane.setBackground( WHITE );

        showProgramVersionBuild =
                new JLabel( progname + " " + version + " build " + Build.BUILD_NUMBER,
                        JLabel.CENTER );
        showProgramVersionBuild.setFont( TITLE_FONT );
        showProgramVersionBuild.setForeground( TITLE_FOREGROUND );
        showProgramVersionBuild.setBackground( WHITE );

        showPurpose1 = new JLabel( purpose1, JLabel.CENTER );
        showPurpose1.setFont( FontFactory.build( "Dialog", Font.ITALIC, 12 ) );
        showPurpose1.setForeground( BLACK );
        showPurpose1.setBackground( WHITE );

        if ( purpose2 != null && purpose2.length() > 0 )
            {
            showPurpose2 = new JLabel( purpose2, JLabel.CENTER );
            showPurpose2.setFont( FontFactory.build( "Dialog", Font.ITALIC, 12 ) );
            showPurpose2.setForeground( BLACK );
            showPurpose2.setBackground( WHITE );
            }

        showStatus = new JLabel( status, JLabel.CENTER );
        showStatus.setFont( FontFactory.build( "Dialog", Font.BOLD, 12 ) );
        showStatus.setForeground( LABEL_FOREGROUND );
        showStatus.setBackground( WHITE );

        showReleaseDate = new JLabel( "released: " + released, JLabel.CENTER );
        showReleaseDate.setFont( FontFactory.build( "Dialog", Font.PLAIN, 11 ) );
        showReleaseDate.setForeground( LABEL_FOREGROUND );
        showReleaseDate.setBackground( WHITE );

        final String copyright;
        if ( firstCopyrightYear == Build.THIS_COPYRIGHT_YEAR )
            {
            copyright = Integer.toString( Build.THIS_COPYRIGHT_YEAR );
            }
        else
            {
            copyright = firstCopyrightYear + "-" + Build.THIS_COPYRIGHT_YEAR;
            }
        showCopyright = new JLabel( "copyright " + copyright, JLabel.LEFT );
        showCopyright.setFont( FontFactory.build( "Dialog", Font.ITALIC, 11 ) );
        showCopyright.setForeground( DARK_GREEN );
        showCopyright.setBackground( WHITE );

        showAuthor = new JLabel( author, JLabel.LEFT );
        showAuthor.setFont( FontFactory.build( "Dialog", Font.BOLD + Font.ITALIC, 11 ) );
        showAuthor.setForeground( DARK_GREEN );
        showAuthor.setBackground( WHITE );

        showCMP = new JLabel( "Canadian Mind Products", JLabel.LEFT );
        showCMP.setFont( FontFactory.build( "Dialog", Font.BOLD + Font.ITALIC, 11 ) );
        showCMP.setForeground( DARK_GREEN );
        showCMP.setBackground( WHITE );

        showAddr1 = new JLabel( "#101 - 2536 Wark Street", JLabel.LEFT );
        showAddr1.setFont( FontFactory.build( "Dialog", Font.ITALIC, 11 ) );
        showAddr1.setForeground( DARK_GREEN );
        showAddr1.setBackground( WHITE );

        showAddr2 = new JLabel( "Victoria, BC Canada V8T 4G8", JLabel.LEFT );
        showAddr2.setFont( FontFactory.build( "Dialog", Font.ITALIC, 11 ) );
        showAddr2.setForeground( DARK_GREEN );
        showAddr2.setBackground( WHITE );

        showMinJdkVersion = new JLabel( "requires: Java " + minJdkVersion + "+", JLabel.RIGHT );
        showMinJdkVersion.setFont( FontFactory.build( "Dialog", Font.ITALIC, 11 ) );
        showMinJdkVersion.setForeground( DARK_GREEN );
        showMinJdkVersion.setBackground( WHITE );

        // running Java 1.06_16
        showRunningJdkVersion = new JLabel( "running: Java " + System.getProperty( "java.version", "unknown" ), JLabel.RIGHT );
        showRunningJdkVersion.setFont( FontFactory.build( "Dialog", Font.ITALIC, 11 ) );
        showRunningJdkVersion.setForeground( DARK_GREEN );
        showRunningJdkVersion.setBackground( WHITE );

        //  Java HotSpot(TM) 64-Bit Server VM  or Excelsior JET
        showVmName = new JLabel( System.getProperty( "java.vm.name", "unknown" ), JLabel.RIGHT );
        showVmName.setFont( FontFactory.build( "Dialog", Font.ITALIC, 11 ) );
        showVmName.setForeground( DARK_GREEN );
        showVmName.setBackground( WHITE );

        showPhone = new JLabel( "phone: (250) 361-9093", JLabel.RIGHT );
        showPhone.setFont( FontFactory.build( "Dialog", Font.ITALIC, 11 ) );
        showPhone.setForeground( DARK_GREEN );
        showPhone.setBackground( WHITE );

        showMailTo = new JLabel( "roedyg@mindprod.com", JLabel.LEFT );
        showMailTo.setFont( FontFactory.build( "Dialog", Font.ITALIC, 11 ) );
        showMailTo.setForeground( DARK_GREEN );
        showMailTo.setBackground( WHITE );

        showDownloadURL = new JLabel( "http://mindprod.com/products.html#" + masterSite, JLabel.RIGHT );
        showDownloadURL.setFont( FontFactory.build( "Dialog", Font.ITALIC, 10 ) );
        showDownloadURL.setForeground( DARK_GREEN );
        showDownloadURL.setBackground( WHITE );

        dismissButton = new JEButton( "Dismiss" );
        dismissButton.requestFocus();
        dismissButton.setToolTipText( "Dismiss About dialog" );

        // add components:
        layoutComponents( contentPane );

        // hook up About box listeners

        this.addWindowListener( new WindowAdapter()
        {
        /**
         * Handle request to close about box
         *
         * @param e event giving details of closing.
         */
        public void windowClosing( WindowEvent e )
            {
            dismiss();
            }// end WindowClosing
        }// end anonymous class
        );// end addWindowListener line

        dismissButton.addActionListener( new ActionListener()
        {
        /**
         * close down the About box when user clicks Dismiss
         */
        public void actionPerformed( ActionEvent e )
            {
            Object object = e.getSource();
            if ( object == dismissButton )
                {
                dismiss();
                }// end if
            }// end actionPerformed
        }// end anonymous class
        );// end addActionListener line

        this.validate();
        this.setVisible( true );
        }// end constructor

    /**
     * layout the components
     */
    private void layoutComponents( final Container contentPane )
        {
        // basic layout
        // 0 1
        // 0 ---------------progname version--------------------------------- 0
        //
        // 1 ---------------------purpose1------------------------------------ 1
        // 2 ---------------------purpose2------------------------------------ 2
        //
        // 3 ---------------------status-------------------------------------- 3
        // 4 --------------released: xxxxxxxxx-------------------------------- 4
        //
        // 5 copyright (c) 2009-2010     ----requires:JDK 1.1+-----------------5
        // 6 Roedy Green                 --- running Java 1.06_16------------- 6
        // 7 Canadian Mind Products 7    ---- Java HotSpot(TM) 64-Bit Server   7
        // 8 #101 - 2536 Wark Street ------------------------------------------8
        // 9 Victoria, BC Canada V8T 4G8 ----phone:(250) 361-9093--------------9
        // 10 roedyg@mindprod.com------- --- http://mindprod.com/products1#COR 10
        //
        // 11 (Dismiss) 11
        // 0 1

        contentPane.setLayout( new GridBagLayout() );

        // x y w h wtx wty anchor fill T L B R padx pady

        contentPane.add( showProgramVersionBuild,
                new GridBagConstraints( 0,
                        0,
                        2,
                        1,
                        0.0,
                        0.0,
                        GridBagConstraints.CENTER,
                        GridBagConstraints.NONE,
                        new Insets( 10, 10, 0, 10 ),
                        0,
                        0 ) );

        contentPane.add( showPurpose1,
                new GridBagConstraints( 0,
                        1,
                        2,
                        1,
                        0.0,
                        0.0,
                        GridBagConstraints.CENTER,
                        GridBagConstraints.NONE,

                        new Insets( 5, 10, 0, 10 ),
                        0,
                        0 ) );

        if ( showPurpose2 != null )
            {
            contentPane.add( showPurpose2,
                    new GridBagConstraints( 0,
                            2,
                            2,
                            1,
                            0.0,
                            0.0,
                            GridBagConstraints.CENTER,
                            GridBagConstraints.NONE,
                            new Insets( 1, 10, 0, 10 ),
                            0,
                            0 ) );
            }

        contentPane.add( showStatus,
                new GridBagConstraints( 0,
                        3,
                        2,
                        1,
                        0.0,
                        0.0,
                        GridBagConstraints.CENTER,
                        GridBagConstraints.NONE,
                        new Insets( 3, 10, 0, 10 ),
                        0,
                        0 ) );

        contentPane.add( showReleaseDate,
                new GridBagConstraints( 0,
                        4,
                        2,
                        1,
                        0.0,
                        0.0,
                        GridBagConstraints.CENTER,
                        GridBagConstraints.NONE,
                        new Insets( 2, 10, 0, 10 ),
                        0,
                        0 ) );

        contentPane.add( showCopyright,
                new GridBagConstraints( 0,
                        5,
                        1,
                        1,
                        0.0,
                        0.0,
                        GridBagConstraints.WEST,
                        GridBagConstraints.NONE,
                        new Insets( 3, 10, 0, 3 ),
                        0,
                        0 ) );

        contentPane.add( showAuthor,
                new GridBagConstraints( 0,
                        6,
                        1,
                        1,
                        0.0,
                        0.0,
                        GridBagConstraints.WEST,
                        GridBagConstraints.NONE,
                        new Insets( 3, 10, 0, 3 ),
                        0,
                        0 ) );

        contentPane.add( showCMP,
                new GridBagConstraints( 0,
                        7,
                        1,
                        1,
                        0.0,
                        0.0,
                        GridBagConstraints.WEST,
                        GridBagConstraints.NONE,
                        new Insets( 3, 10, 0, 3 ),
                        0,
                        0 ) );

        contentPane.add( showAddr1,
                new GridBagConstraints( 0,
                        8,
                        1,
                        1,
                        0.0,
                        0.0,
                        GridBagConstraints.WEST,
                        GridBagConstraints.NONE,
                        new Insets( 3, 10, 0, 3 ),
                        0,
                        0 ) );

        contentPane.add( showAddr2,
                new GridBagConstraints( 0,
                        9,
                        1,
                        1,
                        0.0,
                        0.0,
                        GridBagConstraints.WEST,
                        GridBagConstraints.NONE,
                        new Insets( 3, 10, 0, 3 ),
                        0,
                        0 ) );
        contentPane.add( showMailTo,
                new GridBagConstraints( 0,
                        10,
                        1,
                        1,
                        0.0,
                        0.0,
                        GridBagConstraints.WEST,
                        GridBagConstraints.NONE,
                        new Insets( 3, 10, 0, 3 ),
                        0,
                        0 ) );

        contentPane.add( dismissButton,
                new GridBagConstraints( 0,
                        11,
                        2,
                        1,
                        0.0,
                        0.0,
                        GridBagConstraints.CENTER,
                        GridBagConstraints.NONE,
                        new Insets( 10, 10, 10, 10 ),
                        0,
                        0 ) );

        // second column
        contentPane.add( showMinJdkVersion,
                new GridBagConstraints( 1,
                        5,
                        1,
                        1,
                        0.0,
                        0.0,
                        GridBagConstraints.EAST,
                        GridBagConstraints.NONE,
                        new Insets( 3, 3, 0, 10 ),
                        0,
                        0 ) );
        contentPane.add( showRunningJdkVersion,
                new GridBagConstraints( 1,
                        6,
                        1,
                        1,
                        0.0,
                        0.0,
                        GridBagConstraints.EAST,
                        GridBagConstraints.NONE,
                        new Insets( 3, 3, 0, 10 ),
                        0,
                        0 ) );

        contentPane.add( showVmName,
                new GridBagConstraints( 1,
                        7,
                        1,
                        1,
                        0.0,
                        0.0,
                        GridBagConstraints.EAST,
                        GridBagConstraints.NONE,
                        new Insets( 3, 3, 0, 10 ),
                        0,
                        0 ) );

        contentPane.add( showPhone,
                new GridBagConstraints( 1,
                        9,
                        1,
                        1,
                        0.0,
                        0.0,
                        GridBagConstraints.EAST,
                        GridBagConstraints.NONE,
                        new Insets( 3, 3, 0, 10 ),
                        0,
                        0 ) );

        contentPane.add( showDownloadURL,
                new GridBagConstraints( 1,
                        10,
                        1,
                        1,
                        0.0,
                        0.0,
                        GridBagConstraints.EAST,
                        GridBagConstraints.NONE,
                        new Insets( 3, 3, 0, 10 ),
                        0,
                        0 ) );
        }

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

    /**
     * sample test driver
     *
     * @param args not used
     */
    public static void main( String[] args )
        {
        if ( DEBUGGING )
            {
            final JFrame frame = new JFrame( "About box test" );
            frame.setSize( WIDTH, HEIGHT + 26 );

            JMenuBar mb = new JMenuBar();
            frame.setJMenuBar( mb );

            JMenu help = new JMenu( "Help", /* tearoff */false );
            help.getAccessibleContext().setAccessibleDescription( "Help" );

            mb.add( help );

            help.add( new JMenuItem( "keyboard" ) );
            help.add( new JMenuItem( "command line" ) );

            JMenuItem about = new JMenuItem( "About" );
            about.setActionCommand( "About" );
            help.add( about );

            about.addActionListener( new ActionListener()
            {
            /**
             * Handle Menu Selection Request
             *
             * @param e event giving details of selection
             */
            public void actionPerformed( ActionEvent e )
                {
                new CMPAboutJBox( frame,
                        "Sample Amanuensis",
                        "1.0",
                        "Teaches you how to interconvert the 16 basic Java types,",
                        "e.g. String to int, Long to double.",
                        "freeware",
                        "2000-01-01",
                        1996 /* first copyrighted */,
                        "Roedy Green",
                        "SAMPLE",
                        "1.5" );
                }// end ActionListener
            }// end anonymous class
            );// end addActionListener line

            frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
            frame.validate();
            frame.setVisible( true );
            }// end if
        }// end main
    }
