summaryrefslogtreecommitdiff
path: root/java/EAC/Source.java
blob: d8b50ee224f013cc8e241a5166e39b42b13c77b8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
/**
 * Title:        Source
 * Description:  An event source for the Event Analysis Configurator
 */
package EAC;
import java.awt.*;

public class Source extends Primitive {

  // Font for text
  protected Font text_font = new EACFont().getFont();

  // triangle dimensions
  protected final int WIDTH = 20;
  protected final int HEIGHT = 35;

  // lower left and lower right corner points
  // inherited anchor attribute holds the top point
  protected Point p2,
                  p3;

  // period at which events will be generated
  protected int period;

  // where the Source was anchored prior to a move
  protected Point old_anchor;

  // where events will be pushed
  protected Connector output[] = new Connector[MAX_OUTPUTS];
  protected int output_count;

  // Is this Source currently selected for dragging?
  protected boolean selected = false;

  // Black-on-white (normal) or white-on-black (reversed)?
  protected boolean reverse_color = false;

  // configuration to which the Source belongs
  Configuration config;

  public Source(EACPanel p, Configuration c) {
    super(p);
    config = c;
    output_count = 0;
    period = 0;
  } /* constructor */

  private void drawTriangle(Graphics g) {
    g.drawLine(anchor.x,anchor.y,p2.x,p2.y);
    g.drawLine(p2.x,p2.y,p3.x,p3.y);
    g.drawLine(p3.x,p3.y,anchor.x,anchor.y);
  } /* drawTriangle */

  public void draw() throws BoundsException {
    int x[] = new int[3],
        y[] = new int[3];

    if (selected)
      selected = false;
    else if (inBounds()) {
      Graphics g = canvas.getGraphics();
      Color bg,
            fg;

      x[0] = anchor.x;
      x[1] = p2.x;
      x[2] = p3.x;

      y[0] = anchor.y;
      y[1] = p2.y;
      y[2] = p3.y;

      if (reverse_color) {
        bg = Color.black;
        fg = Color.white;
      } else {
        bg = Color.white;
        fg = Color.black;
      }

      g.setColor(bg); // for interior
      g.fillPolygon(x,y,3);

      g.setColor(Color.black); // triangle itself is always black
      drawTriangle(g);

      g.setColor(fg); // for text

      // print period
      if (period > 0) {
        g.setFont(text_font);
        g.drawString(java.lang.String.valueOf(period),
                     anchor.x - (3 * java.lang.String.valueOf(period).length()),
                     anchor.y + 28);
      }
    } else
      throw new BoundsException("ERROR: Attempted to place source partially out of bounds");
  } /* draw */

  public void selectedDraw() {
    Graphics g = canvas.getGraphics();
    int x[] = new int[3],
        y[] = new int[3];

    old_anchor = anchor;
    x[0] = anchor.x;
    x[1] = p2.x;
    x[2] = p3.x;

    y[0] = anchor.y;
    y[1] = p2.y;
    y[2] = p3.y;

    //drawTriangle();
    g.setColor(canvas.getBackground());
    g.fillPolygon(x,y,3);

    // this will preclude drawing this Source for one repaint() call
    selected = true;

    super.selectedDraw();
  } /* selectedDraw */

  public void specialDraw() {
    Graphics g = canvas.getGraphics();

    g.setXORMode(canvas.getBackground());
    drawTriangle(g);
  } /* specialDraw */

  public void specialUndraw() {
    Graphics g = canvas.getGraphics();

    g.setColor(canvas.getBackground());
    g.setXORMode(canvas.getForeground());
    drawTriangle(g);
  } /* specialUndraw */

  public void reverseColor() {
    reverse_color = true;
  } /* reverseColor */

  public void normalColor() {
    reverse_color = false;
  } /* normalColor */

  public void reconnect() {
    int i;

    for (i = 0; i < output_count; i++)
      output[i].setAnchor(new Point(output[i].getAnchor().x + anchor.x - old_anchor.x,
                                    output[i].getAnchor().y + anchor.y - old_anchor.y));

    // move label anchor
    label.setAnchor(new Point(label.getAnchor().x + anchor.x - old_anchor.x,
                              label.getAnchor().y + anchor.y - old_anchor.y));
  } /* reconnect */

  public boolean contains(Point p) {
    if ((p.x >= p2.x) &&
        (p.x <= p3.x) &&
        (p.y >= anchor.y) &&
        (p.y <= anchor.y + HEIGHT))
      return true;
    else
      return false;
  } /* contains */

  public Point upperLeft() {
    return new Point(p2.x,anchor.y);
  } /* upperLeft */

  public Point lowerRight() {
    return p3;
  } /* lowerRight */

  public Point upperRight() {
    return new Point(p3.x,anchor.y);
  } /* upperRight */

  public Point lowerLeft() {
    return p2;
  } /* lowerLeft */

  public void setTop(Point p) {
    anchor = p;
    p2 = bottomLeft();
    p3 = bottomRight();
  } /* setTop */

  public Point getTop() {
    return anchor;
  } /* getTop */

  public void setPeriod(int p) throws NumberFormatException {
    if (p > 0) {
      period = p;
      config.eventEnqueue(this,period); // Enqueue first wakeup time
    }
    else
      throw new NumberFormatException();
  } /* setPeriod */

  public int getPeriod() {
    return period;
  } /* getPeriod */

  public void restart() {
    config.eventEnqueue(this,period);
    reverse_color = false;
    selected = false;
  } /* restart */

  public int addOutput(Connector c) throws ConnectionException {
    if (output_count == MAX_OUTPUTS)
      throw new ConnectionException("ERROR: Maximum outputs established for source");
    else
      output[output_count++] = c;

    return output_count;
  } /* addOutput */

  public int addInput(Connector c) throws ConnectionException {
    throw new ConnectionException("ERROR: Attempted to add input to source");
  } /* addInput */

  public Connector getOutput(int i) throws ConnectionException {
    if ((i < 0) || (i >= output_count))
      throw new ConnectionException("ERROR: Bad output index for source");
    else
      return output[i];
  } /* getOutput */

  public Connector getInput(int i) throws ConnectionException {
    throw new ConnectionException("ERROR: Attempted to retrieve input from source");
  } /* getInput */

  public void removeInput(int i) throws ConnectionException {
    throw new ConnectionException("ERROR: Attempted to remove input from source");
  } /* removeInput */

  public void removeOutput(int i) throws ConnectionException {
    if ((i >= 0) && (i < output_count)) {
      output[i] = output[output_count-1];
      --output_count;
    } else
      throw new ConnectionException("ERROR: Bad output index for source");
  } /* removeOutput */

  public int getOutputCount() throws ConnectionException {
    return output_count;
  } /* getOutputCount */

  public int getInputCount() throws ConnectionException {
    throw new ConnectionException("ERROR: Attempted to retrieve input count from source");
  } /* getInputCount */

  public void event(Source s) throws ConnectionException {
    throw new ConnectionException("Internal error: event() called on source");
  } /* event */

  public void wakeup(long t) throws ConnectionException {
    int i;

    //System.out.println("Source wakeup at: " + java.lang.Long.toString(t));
    config.eventEnqueue(this,t + period); // enqueue next wakeup time

    // send an event to all outputs
    for (i = 0; i < output_count; i++)
      output[i].event(this);
  } /* wakeup */

  public boolean inBounds() {
    if (canvas.contains(bottomLeft()) &&
        canvas.contains(bottomRight()) &&
        canvas.contains(anchor))
      return true;
    else
      return false;
  } /* inBounds */

  private Point bottomLeft() {
    return new Point(anchor.x - WIDTH, anchor.y + HEIGHT);
  } /* bottomLeft */

  private Point bottomRight() {
    return new Point(anchor.x + WIDTH, anchor.y + HEIGHT);
  } /* bottomRight */

  public void write(File f) throws java.io.IOException {
    char temp[]; // for reading label
    int i, n;

    f.writeInt(f.SOURCE);
    f.writeInt(anchor.x);
    f.writeInt(anchor.y);
    f.writeInt(period);

    // Write out the associated label
    n = label.getText().length();
    f.writeInt(n); // text length
    temp = new char[n];
    temp = label.getText().toCharArray();

    for (i = 0; i < n; i++)
      f.writeChar(temp[i]);
    f.writeInt(label.getAnchor().x); // label position
    f.writeInt(label.getAnchor().y);
  } /* write */

  public void read(File f) throws java.io.IOException {
    char temp[]; // for reading label
    int i, n;
    int label_x, label_y;

    anchor = new Point();
    anchor.x = f.readInt();
    anchor.y = f.readInt();
    period = f.readInt();
    config.eventEnqueue(this,period); // Enqueue first event
    p2 = bottomLeft();
    p3 = bottomRight();

    // get label info
    n = f.readInt(); // text length
    label = new EACLabel(canvas,n);
    temp = new char[n];
    for (i = 0; i < n; i++)
      temp[i] = f.readChar();
    label.setText(java.lang.String.valueOf(temp));
    label_x = f.readInt();
    label_y = f.readInt();
    label.setAnchor(new Point(label_x,label_y));
    label.setLabelee(this);
    try {
      config.addPrimitive(label);
    } catch (TooManyPrimitivesException tmpe) {
      // have faith :-)
    }
  } /* read */
}