001    /*
002     * Calculator State and Behavior
003     *
004     * Developed for "Rethinking CS101", a project of Lynn Andrea Stein's AP Group.
005     * For more information, see <a href="http://www.ai.mit.edu/projects/cs101/">the
006     * CS101 homepage</a> or email <las@ai.mit.edu>.
007     *
008     * Copyright (C) 1999 Massachusetts Institute of Technology.
009     * Please do not redistribute without obtaining permission.
010     */
011    package calculator;
012    import cs101.util.Coerce;
013    import cs101.io.Console;
014    
015    /**
016     * This class provides the main functionality for a basic four-function 
017     * calculator.   Adapted from the earlier ButtonHandler<p>
018     *
019     * <P>Copyright (c) 1999 Massachusetts Institute of Technology
020     *
021     * @author  Todd C. Parnell, tparnell@ai.mit.edu
022     * @author  Emil Sit, sit@mit.edu
023     * @author  Lynn Andrea Stein, las@ai.mit.edu
024     * @version $Id: CalculatorState.java,v 1.2 2003/03/28 17:25:06 gus Exp $
025     *
026     * @see Calculator
027     */
028    
029    public class CalculatorState extends Object
030    {
031      /**
032       * The GUI for which this CalculatorState is providing behavior.
033       */
034      private Calculator gui;
035    
036      protected boolean seenDecimal, readyForNewNumber;
037      protected double previousNumber;
038      protected int operation;
039      
040      protected CalculatorState ( Calculator gui )
041      {
042          super();
043          this.gui = gui;
044          this.resetCalc();
045      }
046      
047      public String toString() 
048      {
049          return "CalculatorState:  currentNumber is " + this.readScreen() + ",\n" +
050                 "                  seenDecimal is " + this.seenDecimal + ",\n" +
051                 "                  operation is " + this.operation + ",\n" +
052                 "                  previousNumber is " + this.previousNumber + ",\n" +
053                 "                  readyForNewNumber is " + this.readyForNewNumber ;
054      }
055    
056      protected void handleNumKey( int num ) 
057      {
058          if ( this.readyForNewNumber ) 
059          {
060              this.clearScreen();
061              this.seenDecimal = false;
062              this.readyForNewNumber = false;
063          }
064          this.writeScreen( this.readScreen() + String.valueOf(num) );
065      }
066    
067      protected void handleDecimal () 
068      {
069          if ( this.readyForNewNumber ) 
070          {
071              this.handleNumKey( 0 );
072          }
073          if ( this.seenDecimal ) 
074          {
075              this.seenDecimal = false;
076              this.writeScreen( this.readScreen() + ".");
077          }
078      }
079            
080      protected void handleOperation( int op ) 
081      {
082          this.handleEquals();
083          this.operation = op;
084          this.previousNumber = Coerce.stringToDouble( this.readScreen() );
085      }
086    
087      protected void handleEquals () 
088      {
089          double answer = this.doOperation ( Coerce.stringToDouble( this.readScreen() ) );      
090    
091          this.writeScreen( answer );
092          
093          this.seenDecimal = true;
094              this.operation = Calculator.NO_OP;
095          this.readyForNewNumber = true;
096      }
097    
098      protected double doOperation ( double currentNumber ) {
099        switch ( this.operation ) 
100        {
101          case Calculator.OP_MUL:
102                return ( this.previousNumber * currentNumber );
103          case Calculator.OP_DIV:
104                return ( this.previousNumber / currentNumber );
105          case Calculator.OP_SUB:
106                return ( this.previousNumber - currentNumber );
107          case Calculator.OP_ADD:
108                return ( this.previousNumber + currentNumber );
109          case Calculator.NO_OP:
110               // fall through....
111          default:
112                return ( currentNumber );
113        }
114      }
115    
116      protected void resetDecimal () 
117      {
118        this.seenDecimal = false;
119      }
120    
121      protected void clearScreen() 
122      {
123        this.writeScreen( "" );
124      }
125      
126      protected String readScreen()
127      {
128            return this.gui.getText();
129      }
130      
131      protected void writeScreen( String s )
132      {
133          this.gui.setText( s );
134      }
135      
136      protected void writeScreen( double d )
137      {
138          this.writeScreen( String.valueOf( d ) );
139      }
140    
141      protected void writeScreen( int i )
142      {
143          this.writeScreen( String.valueOf( i ) );
144      }
145    
146      protected void resetCalc() {
147        this.clearScreen();
148        this.writeScreen( 0.0 );
149        this.previousNumber = 0.0;
150        this.seenDecimal = true;
151        this.readyForNewNumber = true;
152        this.operation = Calculator.NO_OP;
153      }
154    
155    }
156    
157    
158    /* Comments:
159     *
160     * History:
161     *     $Log: CalculatorState.java,v $
162     *     Revision 1.2  2003/03/28 17:25:06  gus
163     *     changed method name in Coerce
164     *
165     *     Revision 1.1.1.1  2002/06/05 21:56:34  root
166     *     CS101 comes to Olin finally.
167     *
168     *     Revision 1.1  1999/10/08 15:09:24  las
169     *     This pset replaces the old Calculator pset.  However, not everything
170     *     has been transferred.  At the moment, it's just java, doc, and index.
171     *     The rest are still in the repository under Calculator-Old.
172     *
173     */
174