/* OdmClicker.java 0.08            UTF-8                  dh:2007-02-12
 *
 * OdmClicker uses a simple single-button window to sequence through a
 * simple ODMJNI demonstration.   This is the test program for testing the
 * 0.52beta association of DMS dialogs with the Java application's display.
 *
 * The early versions provide a regression against the ODMJNI 0.50beta
 * implementation.  There is only one change required to then confirm as
 * part of 0.52beta.  This is that version.
 *
 * This application is adapted from SwingButtons.java, a simple GUI
 * application derived from the Java Tutorial on GUI Development with Swing.
 * It is annotated and refactored to help in understanding of how the GUI
 * interactions are orchestrated.
 */


import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
    /* These are the main Swing and AWT packages that we will use.
       Nothing more will be required except for ODMJNI classes.
       */

public class OdmClicker implements ActionListener
{   /* This is a class that implements the view, the controller, and
       the application/model as a single wad of tin-foil.  It is handy to
       do it this way because it keeps everything in a single source file.
       For more substantial applications, the pieces are broken out for
       separate attention and maintained in separate classes.

       To follow the logic, start with #1 in main and we'll trace through
       how this single class sets up and continues the GUI application.
       */

    private static String theTitle = "OdmClicker 0.08";




        /* APPLICATION INSTANCE DATA
         * *************************
         * This data is held in an instance for the duration of
         * the GUI application.  This is everything that needs to
         * be preserved from one GUI event to the next.
         *
         * The instance is created in createAndLaunchGUI(), step #2.3
         */

    private JFrame myFrame = null;
        /* Carry a reference to the JFrame associated with this
           OdmClicker instance until we don't need it for
           setting up ODMA coordination with the proper window.
           */

    private info.odma.practical100.OdmConnection Odma = null;
        /* The connection that is created and preserved until the
           last operation of the OdmClicker state sequence.
           */

    private info.odma.practical100.OdmWorkingDocument OdmDoc = null;
        /* The document last returned from a chooseDocument operation,
           if we get that far.
           */

    private int numState = 0;
        /* The state of the application.  We will walk through
           the progression of states and perform different
           operations until done.
           */

    final JLabel label
            = new JLabel("0: Waiting for the first click");
        /* This is the label object that us updated to show
           results of application progress.  It is here for access
           from the application.
           */


        /* APPLICATION BEHAVIOR
         * ********************
         * All of the application behavior occurs through the GUI
         * actions reported to the actionPerformed method.  In
         * OdmClicker this is the combined controller and model.
         * The only GUI operation is to click the button and see
         * the next thing that the application reports.
         *
         * The connection of the GUI and this object's ActionListener
         * interface is made in createComponents.
         */


    public void actionPerformed(ActionEvent e)
    {   /* #4: This is the method that operates whenever a GUI action is
               performed.  In this application, that is from the
               button being clicked (or its accelerator key pressed).
               This is essentially the controller with the application
               progression driven off of the different state values.
           */

        switch (numState)
        {   /* Perform different actions based on the state to which
               we have advanced.  This is to work through the stages
               of an OdmConnection usage up to where we see how the
               DMS displays.
               */

            case 0:
                Odma = info.odma.odmjni100.OdmJniBind.application
                            ("OdmNativeTest", myFrame);
                            /* This is the entry that captures the
                               hWnd from the java.awt.Window.
                               */
                label.setText("1: ODMJNI in operation.");
                myFrame = null;
                    /* Not needed beyond creation of OdmConnection */
                numState++;
                return;

            case 1:
                numState++;
                if (!Odma.available())
                     {  label.setText("2: ODMA is not available.");
                        return;
                        }
                numState++;
                label.setText("3: ODMA is available.");
                return;

            case 3:
                numState++;
                if (!Odma.dmsDefaultAvailable())
                     {  label.setText("4: Default DMS unavailable.");
                        return;
                        }
                numState++;
                label.setText("5: Default DMS available.");
                return;

            case 5:
                numState++;
                label.setText("6: Click to launch dialog.");
                return;

            case 6:
                numState = 5;

                if (!(OdmDoc == null))
                     OdmDoc.release();
                OdmDoc = Odma.chooseDocument();
                /* XXX: This is going to block the event queue so
                        I wonder about this and modality.  With modality,
                        it should not be possible to close the window.
                   */
                if (OdmDoc.operationSucceeded())
                     {  label.setText(  "5: "
                                        + OdmDoc.dmsDocName()
                                        + "selected.");
                        return;
                            /* Show the document name so we can verify
                               proper code conversion.
                               */
                        };

                if (OdmDoc.localOperationRequested())
                     {  label.setText("5: Local File requested.");
                        return;
                        }

                numState = 7;

                if (OdmDoc.operationCancelled())
                     {  label.setText("7: Operation Cancelled.");
                        return;
                        }

                label.setText("7: Operation failed.");
                return;

            case 7:
                numState++;
                label.setText("8: No further tests.");
                OdmDoc.release();
                Odma.release();
                Odma = null;
                    /* Clean up here in case the user closes the
                       window.
                       */
                return;

            default:
                label.setText("That's all, folks!!");
                if (Odma == null)
                     return;
                Odma.release();
                Odma = null;

            }


        } /* actionPerformed */


    OdmClicker(JFrame frame)
    {   /* #3: Launch an OdmClicker using the supplied JFrame.  This
               happens in an instance so the frame and the ActionListener
               are tied together appropriately.
           */

        super();

        myFrame = frame;

        myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            /* #3.1 Establish various settings.
               FIXME: It is desirable to do something more active on
                      close.  We'll get around that for now by having
                      explicit release happen in the progression.
               */

        JButton button = new JButton("Click for Next ODMJNI Action");
            /* Create a button with the specified label */
        button.setMnemonic(KeyEvent.VK_I);
            /* We can get it with Alt+I too */
        button.addActionListener(this);
            /* #3.2 The button gets our ActionListener interface
                    implementation for operating on each button click.
               */

        label.setLabelFor(button);
            /* #3.3 Associate the label with the button. This is for
                    access by assistive technologies and has no
                    operational function in the implementation. */


        JPanel pane = new JPanel(new GridLayout(0, 1));
        pane.add(button);
        pane.add(label);
        pane.setBorder(BorderFactory.createEmptyBorder(
                                        30, //top
                                        30, //left
                                        10, //bottom
                                        30) //right
                                        );
            /*  #3.4 Putting the button and label together in a nicely
                     spaced panel.
                */

        frame.getContentPane().add(pane, BorderLayout.CENTER);
        frame.pack();
        frame.setVisible(true);
            /* #3.5 Stitch it all together and initiate display of the
                    frame.

                    The startup process is complete.  All further
                    operations are initiated by frame events reporting to
                    this app instance via the ActiveListener interface.
               */

        } /* OdmClicker */


    private static void createAndLaunchGUI(String title)
    {   /* #2: Create the GUI and Launch the application.
               This static method is invoked from the event-
               dispatching thread (#1.3-1.4), where its operations
               are thread safe.
           */

        try {  UIManager.setLookAndFeel
                    (UIManager.getSystemLookAndFeelClassName());
               }
        catch (Exception e)
            {  System.err.println
                    ("Couldn't get System look and feel for some reason."
                           );
               System.err.println
                    ("Using the default look and feel.");
               e.printStackTrace();
               }
            /* #2.1 Setting the local-system (Windows) look and feel.
                    This operation is unlikely to fail.
               */

        JFrame.setDefaultLookAndFeelDecorated(true);
            /* #2.2 Condition JFrame to always make the decorations
                    called for in the current LookAndFeel.  This will
                    provide the title bar and other features.
               */

        OdmClicker app = new OdmClicker(new JFrame(title));
            /* #2.3 Make an OdmClicker instance that carries the
                    application state.  The GUI is set running in
                    the constructor and that keeps the app around for
                    its listening until the GUI window is closed.
               */


        } /* createAndShowGUI */



    public static void main(String[] args)
    {   /* #1: KICK OFF THE GUI APPLICATION by scheduling a starter
               operation on the Java event loop.
           */


        javax.swing.SwingUtilities.invokeLater
            (  new Runnable() {  public void run()
                                    {  createAndLaunchGUI(theTitle); }
                                 }
               );

            /* Schedule a job for the event-dispatching thread:
               creating and showing this application's GUI.

               #1.1 This is a static main that is performed when the
                    application is initiated.
               #1.2 There is not much to do here.  We will do all of the
                    work on the event loop.
               #1.3 We create an anonymous java.lang.Runnable interface
                    implementation with single run method, and put it on
                    the event loop via invokeLater.  We're done here.
               #1.4 The implemented run method calls the static OdmClicker
                    createAndLaunchGUI method.  This is where the
                    application is actually launched (#2).
               */

        } /* main */

    } /* OdmClicker */


/* 0.08 2007-02-12-17:17 Clean up the termination a little better and
        add code to show the dmsDocName to verify proper code conversions.
   0.07 2007-02-05-16:14 Modify to provide our View to the factory method
        for the ODMJNI application.
   0.06 2007-02-02-17:47 Take the progression of operations through to
        selectDocument.
   0.05 2007-02-02-17:27 Add creation of the Odma OdmConnection as the
        first-click response.
   0.04 2007-02-02-16:15 Refactor to have a structure that keeps particular
        functions together in the launching of the GUI application.
   0.03 2007-02-02-14:17 Customize further to provide the framework needed
        before adding the first ODMA functionality.
   0.02 2007-02-02-13:36 Starting with SwingButtons 0.01 as a base, clone
        to OdmClicker with no other changes (just for regression).
   0.01 2007-01-31-21:52 Switch to Windows Look and Feel and identify the
        version of the application.
   0.00 2007-01-31-21:44 Modify tutorial SwingApplication to begin to match
        the ODMJNI style of layout and organization.  We are going to
        simplify some of this before expanding it to allow for multiple
        actions for a variety of purposes.

   $Header: /ODMdev/info/odma/odmjni100/test/CheckSwing/OdmClicker.java 7     07-02-12 17:31 Orcmid $
   */

/*                       *** end of OdmClicker.java ***               */
