View Javadoc

1   /*
2    * Copyright 2006 Robert Hanson <iamroberthanson AT gmail.com>
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * 
8    *    http://www.apache.org/licenses/LICENSE-2.0
9    * 
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package org.gwtwidgets.client.util;
18  
19  import org.gwtwidgets.client.ui.CalcDisplayListener;
20  import com.google.gwt.user.client.ui.Button;
21  import com.google.gwt.user.client.ui.ClickListener;
22  import com.google.gwt.user.client.ui.Widget;
23  
24  
25  public abstract class CalcEngine
26  {
27      private static final int STATE_KEYING = 1;
28      private static final int STATE_KEYING_DEC = 2;
29      private static final int STATE_POSTOP = 3;
30  
31      public static final int OP_NONE = 0;
32      public static final int OP_PLUS = 1;
33      public static final int OP_MINUS = 2;
34      public static final int OP_EQUALS = 3;
35      public static final int OP_CLEAR = 4;
36      public static final int OP_ERASE = 5;
37      public static final int OP_MULT = 6;
38      public static final int OP_DIV = 7;
39      public static final int OP_DEC = 8;
40      public static final int OP_NEGATE = 9;
41  
42      private int currentState = STATE_POSTOP;
43      private int pendingOp = OP_NONE;
44      private String currentDisplay = "0";
45      private double totalBuffer = 0;
46      private CalcDisplayListener displayListener;
47  
48  
49  
50      protected CalcEngine (CalcDisplayListener cdl)
51      {
52          this.displayListener = cdl;
53          refreshDisplay();
54      }
55  
56      public Button createNumberButton (String styleName, String symbol, int num)
57      {
58          Button b = new Button(symbol);
59          b.setStyleName("calcButton");
60          b.addStyleName(styleName);
61          b.addClickListener(new NumberClickListener(num, this));
62          return b;
63      }
64  
65      public Button createOpButton (String styleName, String symbol, int op)
66      {
67          Button b = new Button(symbol);
68          b.setStyleName("calcButton");
69          b.addStyleName(styleName);
70          b.addClickListener(new OpClickListener(op, this));
71          return b;
72      }
73  
74      public void pressOperator (int op)
75      {
76          switch (op) {
77              case OP_PLUS:
78              case OP_MINUS:
79              case OP_MULT:
80              case OP_DIV:
81                  pendingOp = op;
82                  totalBuffer = Double.parseDouble(currentDisplay);
83                  currentState = STATE_POSTOP;
84                  break;
85              case OP_EQUALS:
86                  totalValue();
87                  break;
88              case OP_ERASE:
89                  currentDisplay = "0";
90                  refreshDisplay();
91                  break;
92              case OP_CLEAR:
93                  currentDisplay = "0";
94                  totalBuffer = 0;
95                  refreshDisplay();
96                  break;
97              case OP_DEC:
98                  if (currentState == STATE_KEYING_DEC) break;
99                  if (currentState == STATE_POSTOP) currentDisplay = "0";
100                 currentDisplay += ".";
101                 currentState = STATE_KEYING_DEC;
102                 refreshDisplay();
103                 break;
104             case OP_NEGATE:
105                 if (currentDisplay.length() > 0 && currentDisplay.startsWith("-")) {
106                     currentDisplay = currentDisplay.substring(1);
107                 }
108                 else {
109                     currentDisplay = "-" + currentDisplay;
110                 }
111                 refreshDisplay();
112                 break;
113         }
114     }
115 
116     private void totalValue ()
117     {
118         switch (pendingOp) {
119             case OP_PLUS:
120                 addValues();
121                 break;
122             case OP_MINUS:
123                 subtractValues();
124                 break;
125             case OP_MULT:
126                 multiplyValues();
127                 break;
128             case OP_DIV:
129                 divideValues();
130                 break;
131         }
132         currentDisplay = Double.toString(totalBuffer);
133         currentState = STATE_POSTOP;
134         pendingOp = OP_NONE;
135         refreshDisplay();
136     }
137 
138     private void divideValues ()
139     {
140         setTotalBuffer(totalBuffer / Double.parseDouble(currentDisplay));
141     }
142 
143     private void multiplyValues ()
144     {
145         setTotalBuffer(totalBuffer * Double.parseDouble(currentDisplay));
146     }
147 
148     private void subtractValues ()
149     {
150         setTotalBuffer(totalBuffer - Double.parseDouble(currentDisplay));
151     }
152 
153     private void setTotalBuffer (double total)
154     {
155         this.totalBuffer = total;
156     }
157 
158     private void addValues ()
159     {
160         setTotalBuffer(totalBuffer + Double.parseDouble(currentDisplay));
161     }
162 
163     public void refreshDisplay ()
164     {
165         displayListener.onDisplayRefresh(currentDisplay);
166     }
167 
168     public void pressDigit (int num)
169     {
170         switch (currentState) {
171             case STATE_POSTOP:
172                 currentDisplay = Integer.toString(num);
173                 currentState = STATE_KEYING;
174                 break;
175             case STATE_KEYING:
176             case STATE_KEYING_DEC:
177                 if (currentDisplay.equals("0")) {
178                     currentDisplay = Integer.toString(num);
179                 }
180                 else {
181                     currentDisplay += Integer.toString(num);
182                 }
183                 break;
184         }
185 
186         refreshDisplay();
187     }
188 
189     public double getTotal ()
190     {
191         return totalBuffer;
192     }
193 
194 
195     private class OpClickListener implements ClickListener
196     {
197         private int op;
198         private CalcEngine calc;
199 
200 
201 
202         public OpClickListener (int op, CalcEngine calc)
203         {
204             this.calc = calc;
205             this.op = op;
206         }
207 
208         public void onClick (Widget sender)
209         {
210             calc.pressOperator(op);
211         }
212     }
213 
214     private class NumberClickListener implements ClickListener
215     {
216         private int num;
217         private CalcEngine calc;
218 
219 
220 
221         public NumberClickListener (int num, CalcEngine calc)
222         {
223             this.calc = calc;
224             this.num = num;
225         }
226 
227         public void onClick (Widget sender)
228         {
229             calc.pressDigit(num);
230         }
231     }
232 }