/*
 * @(#)JPF.java     2.3.4   6 February 2005
 *
 * Copyright 2004
 * College of Computer and Information Science
 * Northeastern University
 * Boston, MA  02115
 *
 * The Java Power Tools software may be used for educational
 * purposes as long as this copyright notice is retained intact
 * at the top of all source files.
 *
 * To discuss possible commercial use of this software, 
 * contact Richard Rasala at Northeastern University, 
 * College of Computer and Information Science,
 * 617-373-2462 or rasala@ccs.neu.edu.
 *
 * The Java Power Tools software has been designed and built
 * in collaboration with Viera Proulx and Jeff Raab.
 *
 * Should this software be modified, the words "Modified from 
 * Original" must be included as a comment below this notice.
 *
 * All publication rights are retained.  This software or its 
 * documentation may not be published in any media either
 * in whole or in part without explicit permission.
 *
 * This software was created with support from Northeastern 
 * University and from NSF grant DUE-9950829.
 * University and from NSF grant DUE-9950829.
 */

package edu.neu.ccs.jpf;

import edu.neu.ccs.console.*;
import edu.neu.ccs.gui.*;
import edu.neu.ccs.util.*;

import java.awt.*;

/**
 * <P>The <I>Java Power Framework</I> class <CODE>JPF</CODE> provides the
 * foundation for creating an automatic Java GUI application with access to:
 *
 * <UL>
 *   <LI> the JPT <CODE>console</CODE> I/O via the interface
 *        {@link edu.neu.ccs.console.ConsoleAware <CODE>ConsoleAware</CODE>}
 *   <LI> a simple graphics window using a
 *        {@link edu.neu.ccs.gui.BufferedPanel <CODE>BufferedPanel</CODE>}.
 * </UL>
 *
 * <P>In this automatic Java GUI application. the action buttons are created
 * automatically from <CODE>public</CODE> methods whose arguments and return
 * type are one of the following types:
 *
 * <UL>
 *   <LI> <CODE>void</CODE>
 *   <LI> <CODE>boolean, char, byte, short, int, long, float, double</CODE>
 *   <LI> <CODE>String, Color, BigInteger, BigDecimal</CODE>
 *   <LI> any type that implements the JPT
 *        {@link edu.neu.ccs.Stringable <CODE>Stringable</CODE>} interface.
 * </UL>
 *
 * <P>The creation of the automatic Java GUI application is accomplished by a
 * combination of Java reflection and the use of the rest of the Java Power
 * Tools.  Since these techniques are encapsulated, the user of the <I>Java
 * Power Framework</I> need not have any knowledge of the JPT.
 *
 * <P>To use the <I>Java Power Framework</I> class <CODE>JPF</CODE>, simply
 * define a class that extends <CODE>JPF</CODE>, directly or indirectly,
 * and execute the default constructor on that new class.
 *
 * <P>For example, if a class named <CODE>Methods</CODE> extends
 * <CODE>JPF</CODE>, directly or indirectly, then all <CODE>public</CODE>
 * methods that satisfy the above constraints and are defined either in the
 * class <CODE>Methods</CODE> itself or in some intermediate class between
 * <CODE>Methods</CODE> and <CODE>JPF</CODE> will give rise to buttons in
 * the automatically generated GUI application.
 *
 * <P>The structure of a typical <CODE>Methods</CODE> class that directly
 * extends <CODE>JPF</CODE> will therefore look as follows:
 *
 * <PRE><CODE>
 *    public class Methods extends JPF {
 *
 *        public static void main(String[] args) { new Methods(); }
 *
 *        // enter here any member or static data declarations as desired
 *
 *        // enter here the public methods to be made into GUI buttons
 *
 *        // enter here any non-public helper methods as desired
 *    }
 * </CODE></PRE>
 * 
 * <P>The <I>Java Power Framework</I> may be used to create GUI buttons in
 * an automatically generated application for any of the following purposes:
 *
 * <UL>
 *   <LI>To write experimental code that will test Java language features.
 *   <LI>To write a systematic suite of tests for one or more separate classes.
 *   <LI>To write small on-the-fly applications using single frames or dialogs. 
 *   <LI>To write methods that will launch one or more separate Java applications
 *       that have been defined in other classes.
 * </UL>
 *
 * <P>To illustrate how to define a method to launch a separate Java application
 * that we will name, for convenience, <CODE>Foo</CODE>, here is the code:
 *
 * <PRE><CODE>
 *        public void LaunchFoo() { Foo.main(null); }
 * </CODE></PRE>
 *
 * Placing this code in the <CODE>Methods</CODE> class will cause a button to be
 * created in the automatic GUI that is labeled "LaunchFoo" and which launches
 * the application <CODE>Foo</CODE> when clicked.
 *
 * <P>The class <CODE>JPF</CODE> itself extends {@link JPFBase <CODE>JPFBase</CODE>}.
 * The class <CODE>JPFBase</CODE> provides a series of methods that may be used to
 * determine if a class possesses a required set of constructors and/or methods.
 * These testing methods are automatically inherited by any class <CODE>Methods</CODE>
 * that extends <CODE>JPF</CODE> and may be used to create unit test suites.
 *
 * @author Viera Proulx
 * @author Jason Jay Rodrigues
 * @author Richard Rasala
 * @author Jeff Raab
 * @version 2.3.4
 * @since 2.2
 */
public class JPF
    extends JPFBase
    implements JPTConstants, ConsoleAware
{
    /** The graphics buffered panel window. */
    public BufferedPanel window = null;
    
    /** The parent Java application. */
    JPFApplication application = null;
    
    /** The frame title. */
    String frameTitle = null;
    
    /////////////////
    // Constructor //
    /////////////////
    
    /**
     * Construct the JPF application using as the given initializer the
     * derived class that uses this constructor.
     */
    public JPF() {
        // create an application object that references this initializer
        application = new JPFApplication(this, frameTitle);
            
        // obtain the graphics window
        window = application.getGraphicsWindow();
    }
    
    
    ////////////////
    // Public API //
    ////////////////
    
    /**
     * Sets the title of the application frame
     * to the given title.
     *
     * @param title title text for the frame
     */
    public void setFrameTitle(String title) {
        frameTitle = title;
        
        if (application != null)
            application.setFrameTitle(title);
    }
    
    
    ////////////////////
    // Static Methods //
    ////////////////////
    
    /**
     * <p>Frame the given object in a JPTFrame
     * and open the frame;
     * return the frame constructed.</p>
     *
     * @param object the object to frame
     * @return the frame constructed
     * @since 2.3.4
     */
    public static JPTFrame frame(Object object) {
        return frame(object, null, CENTER, null);
    }
    
    
    /**
     * <p>Frame the given object in a JPTFrame
     * and open the frame;
     * use the given location which should be either
     * <code>CENTER</code> or one of the standard constants
     * for one of the eight compass directions;
     * return the frame constructed.</p>
     *
     * @param object   the object to frame
     * @param location the constant representing the frame location
     * @return the frame constructed
     * @since 2.3.4
     */
    public static JPTFrame frame(Object object, int location) {
        return frame(object, null, location, null);
    }
    
    
    /**
     * <p>Frame the given object in a JPTFrame
     * and open the frame;
     * use the given title for the frame;
     * return the frame constructed.</p>
     *
     * @param object the object to frame
     * @param title  the title for the frame
     * @return the frame constructed
     * @since 2.3.4
     */
    public static JPTFrame frame(Object object, String title) {
        return frame(object, title, CENTER, null);
    }
    
    
    /**
     * <p>Frame the given object in a JPTFrame
     * and open the frame;
     * use the given title for the frame;
     * use the given location which should be either
     * <code>CENTER</code> or one of the standard constants
     * for one of the eight compass directions;
     * return the frame constructed.</p>
     *
     * @param object   the object to frame
     * @param title    the title for the frame
     * @param location the constant representing the frame location
     * @return the frame constructed
     * @since 2.3.4
     */
    public static JPTFrame frame(Object object, String title, int location) {
        return frame(object, title, location, null);
    }
    
    
    /**
     * <p>Frame the given object in a JPTFrame
     * and open the frame;
     * use the given title for the frame;
     * use the given insets to inset the frame in the screen;
     * return the frame constructed.</p>
     *
     * @param object   the object to frame
     * @param title    the title for the frame
     * @param insets   the screen insets to use to adjust the location
     * @return the frame constructed
     * @since 2.3.4
     */
    public static JPTFrame frame(Object object, String title, Insets insets) {
        return frame(object, title, CENTER, insets);
    }
    
    
    /**
     * <p>Frame the given object in a JPTFrame
     * and open the frame;
     * use the given title for the frame;
     * use the given location which should be either
     * <code>CENTER</code> or one of the standard constants
     * for one of the eight compass directions;
     * use the given insets to inset the frame in the screen;
     * return the frame constructed.</p>
     *
     * @param object   the object to frame
     * @param title    the title for the frame
     * @param location the constant representing the frame location
     * @param insets   the screen insets to use to adjust the location
     * @return the frame constructed
     * @since 2.3.4
     */
    public static JPTFrame frame(Object object, String title, int location, Insets insets) {
        return JPTFrame.frame(object, title, location, insets);
    }
    
    
    /**
     * <p>Place the given object in a modal OK dialog
     * and open the dialog;
     * return the dialog constructed.</p>
     *
     * @param object the object to place in the dialog
     * @return the dialog constructed
     * @since 2.3.4
     */
    public static GeneralDialog OKDialog(Object object) {
        return OKDialog(object, null);
    }
    
    
    /**
     * <p>Place the given object in a modal OK dialog
     * and open the dialog;
     * use the given title for the dialog;
     * return the dialog constructed.</p>
     *
     * @param object the object to place in the dialog
     * @param title  the title for the dialog
     * @return the dialog constructed
     * @since 2.3.4
     */
    public static GeneralDialog OKDialog(Object object, String title) {
        GeneralDialog dialog = GeneralDialog.makeOKDialog(object, title);
        dialog.setVisible(true);
        return dialog;
    }
    
    
    /**
     * <p>Place the given object in a modal OK-Cancel dialog
     * and open the dialog;
     * return the dialog constructed.</p>
     *
     * @param object the object to place in the dialog
     * @return the dialog constructed
     * @since 2.3.4
     */
    public static GeneralDialog OKCancelDialog(Object object) {
        return OKCancelDialog(object, null);
    }
    
    
    /**
     * <p>Place the given object in a modal OK-Cancel dialog
     * and open the dialog;
     * use the given title for the dialog;
     * return the dialog constructed.</p>
     *
     * @param object the object to place in the dialog
     * @param title  the title for the dialog
     * @return the dialog constructed
     * @since 2.3.4
     */
    public static GeneralDialog OKCancelDialog(Object object, String title) {
        GeneralDialog dialog = GeneralDialog.makeOKCancelDialog(object, title);
        dialog.setVisible(true);
        return dialog;
    }
    
    
    /**
     * <p>Place the given object in a modal Yes-No-Cancel dialog
     * and open the dialog;
     * return the dialog constructed.</p>
     *
     * @param object the object to place in the dialog
     * @return the dialog constructed
     * @since 2.3.4
     */
    public static GeneralDialog YesNoCancelDialog(Object object) {
        return YesNoCancelDialog(object, null);
    }
    
    
    /**
     * <p>Place the given object in a modal Yes-No-Cancel dialog
     * and open the dialog;
     * use the given title for the dialog;
     * return the dialog constructed.</p>
     *
     * @param object the object to place in the dialog
     * @param title  the title for the dialog
     * @return the dialog constructed
     * @since 2.3.4
     */
    public static GeneralDialog YesNoCancelDialog(Object object, String title) {
        GeneralDialog dialog = GeneralDialog.makeYesNoCancelDialog(object, title);
        dialog.setVisible(true);
        return dialog;
    }
    
    
    /**
     * <p>Place the given object in a modal general dialog
     * and open the dialog;
     * use the action data to define the dialog buttons;
     * return the dialog constructed.</p>
     *
     * <p>The parameter <code>actionData</code> 
     * is an <code>Object[][]</code> array that specifies 
     * each dialog <code>Action</code> in one of the following ways:</p>
     * 
     * <ul>
     *   <li> A subarray { action }             with an <code>Action</code></li>
     *   <li> A subarray { name }               with an action name</li>
     *   <li> A subarray { name, icon }         with an action name and icon</li>
     *   <li> A subarray { action, option }
     *   <li> A subarray { name, option }
     *   <li> A subarray { name, icon, option }
     * </ul>
     *
     * <p>If the option parameter is specified, it must be one of the following
     * values that will determine what is done to the dialog when the action is
     * finished:</p>
     *
     * <ul><code>
     *   <li> DialogAction.KEEP_OPEN</li>
     *   <li> DialogAction.AUTO_CLOSE</li>
     *   <li> DialogAction.SET_CANCEL</li>
     * </code></ul>
     *
     * <p>If the option parameter is not specified, it is taken to be
     * <code>DialogAction.AUTO_CLOSE</code>.</p>
     *
     * @param object     the object to place in the dialog
     * @param actionData the action data
     * @return the dialog constructed
     * @since 2.3.4
     */
    public static GeneralDialog generalDialog
        (Object object, Object[][] actionData)
    {
        return generalDialog(object, null, actionData, null);
    }
    
    
    /**
     * <p>Place the given object in a modal general dialog
     * and open the dialog;
     * use the action data to define the dialog buttons;
     * use the default action object to define the default button;
     * return the dialog constructed.</p>
     *
     * <p>The parameter <code>actionData</code> 
     * is an <code>Object[][]</code> array that specifies 
     * each dialog <code>Action</code> in one of the following ways:</p>
     * 
     * <ul>
     *   <li> A subarray { action }             with an <code>Action</code></li>
     *   <li> A subarray { name }               with an action name</li>
     *   <li> A subarray { name, icon }         with an action name and icon</li>
     *   <li> A subarray { action, option }
     *   <li> A subarray { name, option }
     *   <li> A subarray { name, icon, option }
     * </ul>
     *
     * <p>If the option parameter is specified, it must be one of the following
     * values that will determine what is done to the dialog when the action is
     * finished:</p>
     *
     * <ul><code>
     *   <li> DialogAction.KEEP_OPEN</li>
     *   <li> DialogAction.AUTO_CLOSE</li>
     *   <li> DialogAction.SET_CANCEL</li>
     * </code></ul>
     *
     * <p>If the option parameter is not specified, it is taken to be
     * <code>DialogAction.AUTO_CLOSE</code>.</p>
     *
     * <p>The <code>Object</code> supplied for the default action must either be
     * an <code>Action</code> or a name that is supplied in the action data.  If
     * the parameter is <code>null</code>, no default action is set.</p>
     * 
     * @param object        the object to place in the dialog
     * @param actionData    the action data
     * @param defaultAction the default action
     * @return the dialog constructed
     * @since 2.3.4
     */
    public static GeneralDialog generalDialog
        (Object object, Object[][] actionData, Object defaultAction)
    {
        return generalDialog(object, null, actionData, defaultAction);
    }
    
    
    /**
     * <p>Place the given object in a modal general dialog
     * and open the dialog;
     * use the given title for the dialog;
     * use the action data to define the dialog buttons;
     * return the dialog constructed.</p>
     *
     * <p>The parameter <code>actionData</code> 
     * is an <code>Object[][]</code> array that specifies 
     * each dialog <code>Action</code> in one of the following ways:</p>
     * 
     * <ul>
     *   <li> A subarray { action }             with an <code>Action</code></li>
     *   <li> A subarray { name }               with an action name</li>
     *   <li> A subarray { name, icon }         with an action name and icon</li>
     *   <li> A subarray { action, option }
     *   <li> A subarray { name, option }
     *   <li> A subarray { name, icon, option }
     * </ul>
     *
     * <p>If the option parameter is specified, it must be one of the following
     * values that will determine what is done to the dialog when the action is
     * finished:</p>
     *
     * <ul><code>
     *   <li> DialogAction.KEEP_OPEN</li>
     *   <li> DialogAction.AUTO_CLOSE</li>
     *   <li> DialogAction.SET_CANCEL</li>
     * </code></ul>
     *
     * <p>If the option parameter is not specified, it is taken to be
     * <code>DialogAction.AUTO_CLOSE</code>.</p>
     *
     * @param object     the object to place in the dialog
     * @param title      the title for the dialog
     * @param actionData the action data
     * @return the dialog constructed
     * @since 2.3.4
     */
    public static GeneralDialog generalDialog
        (Object object, String title, Object[][] actionData)
    {
        return generalDialog(object, title, actionData, null);
    }
    
    
    /**
     * <p>Place the given object in a modal general dialog
     * and open the dialog;
     * use the given title for the dialog;
     * use the action data to define the dialog buttons;
     * use the default action object to define the default button;
     * return the dialog constructed.</p>
     *
     * <p>The parameter <code>actionData</code> 
     * is an <code>Object[][]</code> array that specifies 
     * each dialog <code>Action</code> in one of the following ways:</p>
     * 
     * <ul>
     *   <li> A subarray { action }             with an <code>Action</code></li>
     *   <li> A subarray { name }               with an action name</li>
     *   <li> A subarray { name, icon }         with an action name and icon</li>
     *   <li> A subarray { action, option }
     *   <li> A subarray { name, option }
     *   <li> A subarray { name, icon, option }
     * </ul>
     *
     * <p>If the option parameter is specified, it must be one of the following
     * values that will determine what is done to the dialog when the action is
     * finished:</p>
     *
     * <ul><code>
     *   <li> DialogAction.KEEP_OPEN</li>
     *   <li> DialogAction.AUTO_CLOSE</li>
     *   <li> DialogAction.SET_CANCEL</li>
     * </code></ul>
     *
     * <p>If the option parameter is not specified, it is taken to be
     * <code>DialogAction.AUTO_CLOSE</code>.</p>
     *
     * <p>The <code>Object</code> supplied for the default action must either be
     * an <code>Action</code> or a name that is supplied in the action data.  If
     * the parameter is <code>null</code>, no default action is set.</p>
     * 
     * @param object        the object to place in the dialog
     * @param title         the title for the dialog
     * @param actionData    the action data
     * @param defaultAction the default action
     * @return the dialog constructed
     * @since 2.3.4
     */
    public static GeneralDialog generalDialog
        (Object object, String title, Object[][] actionData, Object defaultAction)
    {
        GeneralDialog dialog = new GeneralDialog(object, title, actionData, defaultAction);
        
        dialog.setVisible(true);
        return dialog;
    }
    
}


