/*
 * @(#)ExpressionEvaluationPane.java  2.5.0  31 August 2006
 *
 * Copyright 2006
 * 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.
 */

package edu.neu.ccs.gui;

import edu.neu.ccs.*;

import java.awt.*;
import java.awt.font.*;
import javax.swing.*;

/**
 * <p>Class <code>ExpressionEvaluationPane</code>
 * provides a pane that permits
 * the interactive evaluation of expressions
 * with data types
 * <code>BigInteger</code>,
 * <code>double</code>, and
 * <code>boolean</code>.</p>
 * 
 * @author Richard Rasala
 * @version 2.5.0
 */
public class ExpressionEvaluationPane
    extends BasePane
{
    /**
     * <p>The 2-dimensional array that pairs
     * a string that will appear on a radio button
     * with its corresponding <code>Class</code> object.</p>
     * 
     * <p>The radio button strings are:</p>
     * 
     * <ul>
     *   <li><code>BigInteger</code></li>
     *   <li><code>Double</code></li>
     *   <li><code>Boolean</code></li>
     * </ul>
     * 
     * <p>The corresponding <code>Class</code> objects are:</p>
     * <ul>
     *   <li><code>XBigInteger.class</code></li>
     *   <li><code>XDouble.class</code></li>
     *   <li><code>XBoolean.class</code></li>
     * </ul>
     */
    protected Object[][] typePairs =
        { { "BigInteger", XBigInteger.class },
          { "Double",     XDouble.class     },
          { "Boolean",    XBoolean.class    } };
    
    /**
     * The layout for the 3 radio buttons, namely,
     * 1 row and 3 columns.
     */
    protected TableLayout typeLayout =
        new TableLayout(1, 3, gap, gap, CENTER);
    
    /**
     * The radio button panel that will associate the string
     * labels described above with corresponding objects of
     * type <code>Class</code>.
     * 
     * <p>The radio button strings are:</p>
     * 
     * <ul>
     *   <li><code>BigInteger</code></li>
     *   <li><code>Double</code></li>
     *   <li><code>Boolean</code></li>
     * </ul>
     * 
     * <p>The corresponding <code>Class</code> objects are:</p>
     * <ul>
     *   <li><code>XBigInteger.class</code></li>
     *   <li><code>XDouble.class</code></li>
     *   <li><code>XBoolean.class</code></li>
     * </ul>
     */
    protected StringObjectRadioPanel typePanel =
        new StringObjectRadioPanel
            (typePairs, null, 1, typeLayout);
    
    
    // Set font for the type panel
    {
        typePanel.setFont(labelFont);
    }
    
    
    /** The label for the expression text field. */
    protected Annotation expressionLabel =
        new Annotation("Expression", labelFont);
    
    /** The expression text field. */
    protected TextFieldView expressionTFV =
        new TextFieldView(fieldFont, largeFieldWidth);
    
    /** The array with the expression label and text field. */
    protected Object[] expressionStuff =
        { expressionLabel, expressionTFV };
    
    /** The table with the expression label and text field. */
    protected VTable expressionTable =
        new VTable(expressionStuff, gap, gap, WEST);
    
    
    /** The label for the evaluation text field. */
    protected Annotation evaluationLabel =
        new Annotation("Expression Value", labelFont);
    
    /** The evaluation text field. */
    protected TextFieldView evaluationTFV =
        new TextFieldView(fieldFont, largeFieldWidth);
    
    /** The array with the evaluation label and text field. */
    protected Object[] evaluationStuff =
        { evaluationLabel, evaluationTFV };
    
    /** The table with the evaluation label and text field. */
    protected VTable evaluationTable =
        new VTable(evaluationStuff, gap, gap, WEST);
    
    
    /**
     * <p>The eval action to evaluate an expression.</p>
     * 
     * <p>Utilizes the method <code>evaluate()</code>.</p>
     */
    protected SimpleAction eval =
        new SimpleAction("Evaluate Expression") {
            public void perform() { evaluate(); }
        };
    
    /** The button with the eval action. */
    protected JButton evalButton = new JButton(eval);
    
    
    // Set font for eval button
    // and add eval action as text field listener also
    {
        evalButton.setFont(buttonFont);
        expressionTFV.setAction(eval);
    }
    
    
    /**
     * The array with the expression table, eval button,
     * and evaluation table.
     */
    protected Object[] expStuff =
        { typePanel, expressionTable, evalButton, evaluationTable };
    
    /**
     * The table with the expression table, eval button,
     * and evaluation table.
     */
    protected VTable expTable =
        new VTable(expStuff, gap, gap, CENTER);
    
    
    // Add an empty and a title border to the above table
    {
        expTable.emptyBorder(gap);
        
        expTable.titleBorder(
            " Expression Evaluation Pane ",
            labelFont,
            Color.black);
    }
    
    
    /**
     * The constructor for an expression-evaluation pane.
     */
    public ExpressionEvaluationPane() {
        add(expTable);
    }
    
    
    /**
     * <p>The method to evaluate an expression.</p>
     * 
     * <p>The expression is the text in the expression
     * text field.</p>
     * 
     * <p>The expression value as text is placed into
     * the evaluation text field.</p>
     * 
     * <p>If an error occurs, an error dialog will be
     * displayed.  If evaluation is then cancelled,
     * the word <code>Cancelled</code> is placed into
     * the evaluation text field.</p>
     * 
     * <p>Warning: If the caller sets the contents of
     * the expression text field algorithmically and
     * algorithmically calls this method, then,
     * if an error occurs, an error dialog will be
     * displayed that may be quite puzzing to a user.
     * Hence a direct call of this method should be
     * done with the utmost care if at all.</p>
     */
    public void evaluate() {
        String expression = expressionTFV.getViewState();
        
        try {
            Class type = (Class) typePanel.getSelectedObject();
            expressionTFV.setDataType(type);
            
            Object value = expressionTFV.requestObject();
            
            evaluationTFV.setViewState(value.toString());
        }
        catch (CancelledException ce) {
            expressionTFV.setViewState(expression);
            evaluationTFV.setViewState("Cancelled");
        }
    }
    
    
    /**
     * Set the contents of the expression text field.
     * @param text
     */
    public void setExpression(String text) {
        if (text != null)
            expressionTFV.setViewState(text);
    }
    
    
    /**
     * Returns the current contents of the expression text field.
     */
    public String getExpression() {
        return expressionTFV.getViewState();
    }
    
    
    /**
     * Returns the current contents of the evaluation text field.
     */
    public String getEvaluation() {
        return evaluationTFV.getViewState();
    }
    
    
    /**
     * <p>The main method launches
     * an expession-evaluation pane
     * in its own GUI frame.</p>
     * 
     * <p>Use the call:</p>
     * 
     * <pre>  ExpressionEvaluationPane.main(null)</pre>
     * 
     * @param args ignored and may be <code>null</code>
     */
    public static void main(String[] args) {
        new ExpressionEvaluationPane().frame("Expression Evaluation Pane");
    }
   
}

