1
2
3
4
5
6
7
8
9
10
11
12
13
14
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 }