1   /*
2    * Copyright 2007-2008 Volker Fritzsch
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  package motej.demos.gui;
17  
18  import java.awt.BorderLayout;
19  import java.awt.Color;
20  import java.awt.Dimension;
21  import java.awt.FlowLayout;
22  import java.awt.Graphics;
23  import java.awt.Graphics2D;
24  import java.awt.event.ActionEvent;
25  import java.awt.event.WindowAdapter;
26  import java.awt.event.WindowEvent;
27  
28  import javax.swing.AbstractAction;
29  import javax.swing.Action;
30  import javax.swing.BorderFactory;
31  import javax.swing.JButton;
32  import javax.swing.JFrame;
33  import javax.swing.JPanel;
34  import javax.swing.SwingUtilities;
35  
36  import motej.CalibrationDataReport;
37  import motej.IrCameraMode;
38  import motej.IrCameraSensitivity;
39  import motej.IrPoint;
40  import motej.Mote;
41  import motej.demos.common.SimpleMoteFinder;
42  import motej.demos.nunchuk.AccelerometerPanel;
43  import motej.event.AccelerometerEvent;
44  import motej.event.AccelerometerListener;
45  import motej.event.CoreButtonEvent;
46  import motej.event.CoreButtonListener;
47  import motej.event.IrCameraEvent;
48  import motej.event.IrCameraListener;
49  import motej.request.ReportModeRequest;
50  
51  /**
52   * 
53   * <p>
54   * @author <a href="mailto:vfritzsch@users.sourceforge.net">Volker Fritzsch</a>
55   */
56  @SuppressWarnings("serial")
57  public class MoteGui {
58  	
59  	private IrPoint p0, p1, p2, p3;
60  	
61  	private AccelerometerPanel accelerometerPanel;
62  	
63  	
64  //	protected class AccelerometerComponent implements GLEventListener {
65  //		
66  //		private GLU glu;
67  //		private GLUT glut;
68  //		
69  //		public void init(GLAutoDrawable drawable) {
70  //			GL gl = drawable.getGL();
71  //			glu = new GLU();
72  //			glut = new GLUT();
73  //			
74  //			gl.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
75  //			gl.glShadeModel(GL.GL_FLAT);
76  //		}
77  //		
78  //		public void display(GLAutoDrawable drawable) {
79  //			GL gl = drawable.getGL();
80  //
81  //			gl.glClear(GL.GL_COLOR_BUFFER_BIT);
82  //		    gl.glColor3f(1.0f, 1.0f, 1.0f);
83  //		    gl.glLoadIdentity(); /* clear the matrix */
84  //		    
85  //		    /* viewing transformation */
86  //		    glu.gluLookAt(-2.5, 5.0, 8.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
87  //		    gl.glScalef(1.0f, 1.0f, 5.0f); /* modeling transformation */
88  //		    gl.glRotated(accx, 1d, 0d, 0d);
89  //		    gl.glRotated(accy, 0d, 1d, 0d);
90  //		    gl.glRotated(accz, 0d, 0d, 1d);
91  //		    glut.glutWireCube(1.0f);
92  //		    gl.glFlush();
93  //		}
94  //
95  //		public void displayChanged(GLAutoDrawable arg0, boolean arg1,
96  //				boolean arg2) {
97  //		}
98  //
99  //		public void reshape(GLAutoDrawable drawable, int x, int y, int w,
100 //				int h) {
101 //			GL gl = drawable.getGL();
102 //
103 //			gl.glMatrixMode(GL.GL_PROJECTION); /* prepare for and then */
104 //		    gl.glLoadIdentity(); /* define the projection */
105 //		    gl.glFrustum(-1.0, 1.0, -1.0, 1.0, 1.5, 20.0); /* transformation */
106 //		    gl.glMatrixMode(GL.GL_MODELVIEW); /* back to modelview matrix */
107 //		    gl.glViewport(0, 0, w, h); /* define the viewport */
108 //		}
109 //		
110 //	}
111 	
112 	protected class IRCompentent extends JPanel {
113 		
114 		public IRCompentent() {
115 			setMinimumSize(new Dimension(1024,768));
116 		}
117 		
118 		@Override
119 		protected void paintComponent(Graphics g) {
120 			super.paintComponent(g);
121 
122 			if (p0 == null)
123 				return;
124 			
125 			Graphics2D g2 = (Graphics2D) g;
126 			Color origColor = g2.getColor();
127 			g2.setColor(Color.BLACK);
128 
129 			System.out.println("Intensity: " + p0.intensity + " min.x: " + p0.min.x + " min.y: " + p0.min.y + " max.x: " + p0.max.x + " max.y: " + p0.max.y);
130 			
131 			g2.fillOval((int) p0.getX(), (int) p0.getY(), p0.getSize() * 5, p0.getSize() * 5);
132 			g2.fillOval((int) p1.getX(), (int) p1.getY(), p1.getSize() * 5, p1.getSize() * 5);
133 			g2.fillOval((int) p2.getX(), (int) p2.getY(), p2.getSize() * 5, p2.getSize() * 5);
134 			g2.fillOval((int) p3.getX(), (int) p3.getY(), p3.getSize() * 5, p3.getSize() * 5);
135 			g2.setColor(origColor);
136 		}
137 		
138 	}
139 	
140 	private MoteGui.IRCompentent ircomp;
141 
142 	private Mote mote;
143 	
144 //	private int accx, accy, accz;
145 
146 	private boolean[] leds = new boolean[] { false, false, false, false };
147 
148 	protected Action findAction = new AbstractAction("Find Motes") {
149 
150 		public void actionPerformed(ActionEvent arg0) {
151 			SimpleMoteFinder simpleMoteFinder = new SimpleMoteFinder();
152 			mote = simpleMoteFinder.findMote();
153 			if (mote != null) {
154 				
155 				while (mote.getStatusInformationReport() == null) {
156 					System.out.println("waiting for status information report");
157 					try {
158 						Thread.sleep(10l);
159 					} catch (InterruptedException e) {
160 						// TODO Auto-generated catch block
161 						e.printStackTrace();
162 					}
163 				}
164 				System.out.println(mote.getStatusInformationReport());
165 				
166 				while (mote.getCalibrationDataReport() == null) {
167 					System.out.println("waiting for calibration data report");
168 					try {
169 						Thread.sleep(10l);
170 					} catch (InterruptedException e) {
171 						// TODO Auto-generated catch block
172 						e.printStackTrace();
173 					}
174 				}
175 				System.out.println(mote.getCalibrationDataReport());
176 				CalibrationDataReport cali = mote.getCalibrationDataReport();
177 				accelerometerPanel.setCalibrationDataX(cali.getZeroX(), cali.getGravityX());
178 				accelerometerPanel.setCalibrationDataY(cali.getZeroY(), cali.getGravityY());
179 				accelerometerPanel.setCalibrationDataZ(cali.getZeroZ(), cali.getGravityZ());
180 				
181 				mote.addAccelerometerListener(new AccelerometerListener<Mote>() {
182 				
183 					public void accelerometerChanged(AccelerometerEvent<Mote> evt) {
184 						accelerometerPanel.accelerometerValueChanged(evt.getX(), evt.getY(), evt.getZ());
185 //						accx = evt.getX();
186 //						accy = evt.getY();
187 //						accz = evt.getZ();
188 ////						glpanel.repaint();
189 					}
190 				
191 				});
192 				
193 				mote.addIrCameraListener(new IrCameraListener() {
194 					
195 					public void irImageChanged(IrCameraEvent evt) {
196 						p0 = evt.getIrPoint(0);
197 						p1 = evt.getIrPoint(1);
198 						p2 = evt.getIrPoint(2);
199 						p3 = evt.getIrPoint(3);
200 						ircomp.repaint();
201 					}
202 				
203 				});
204 				
205 				mote.addCoreButtonListener(new CoreButtonListener() {
206 
207 					public void buttonPressed(final CoreButtonEvent evt) {
208 						SwingUtilities.invokeLater(new Runnable() {
209 
210 							public void run() {
211 								if (evt.isButtonAPressed()) {
212 									feedbackButtonA.setBackground(Color.BLUE);
213 								} else {
214 									feedbackButtonA.setBackground(origColor);
215 								}
216 
217 								if (evt.isButtonBPressed())
218 									feedbackButtonB.setBackground(Color.BLUE);
219 								else
220 									feedbackButtonB.setBackground(origColor);
221 								
222 								if (evt.isButtonHomePressed())
223 									feedbackButtonHome.setBackground(Color.BLUE);
224 								else
225 									feedbackButtonHome.setBackground(origColor);
226 								
227 								if (evt.isButtonMinusPressed())
228 									feedbackButtonMinus.setBackground(Color.BLUE);
229 								else
230 									feedbackButtonMinus.setBackground(origColor);
231 								
232 								if (evt.isButtonOnePressed())
233 									feedbackButtonOne.setBackground(Color.BLUE);
234 								else
235 									feedbackButtonOne.setBackground(origColor);
236 								
237 								if (evt.isButtonPlusPressed())
238 									feedbackButtonPlus.setBackground(Color.BLUE);
239 								else
240 									feedbackButtonPlus.setBackground(origColor);
241 								
242 								if (evt.isButtonTwoPressed())
243 									feedbackButtonTwo.setBackground(Color.BLUE);
244 								else
245 									feedbackButtonTwo.setBackground(origColor);
246 								
247 								if (evt.isDPadDownPressed())
248 									feedbackButtonDPadDown.setBackground(Color.BLUE);
249 								else
250 									feedbackButtonDPadDown.setBackground(origColor);
251 								
252 								if (evt.isDPadLeftPressed())
253 									feedbackButtonDPadLeft.setBackground(Color.BLUE);
254 								else
255 									feedbackButtonDPadLeft.setBackground(origColor);
256 								
257 								if (evt.isDPadRightPressed())
258 									feedbackButtonDPadRight.setBackground(Color.BLUE);
259 								else
260 									feedbackButtonDPadRight.setBackground(origColor);
261 								
262 								if (evt.isDPadUpPressed())
263 									feedbackButtonDPadUp.setBackground(Color.BLUE);
264 								else
265 									feedbackButtonDPadUp.setBackground(origColor);
266 							}
267 
268 						});
269 					}
270 
271 				});
272 			}
273 		}
274 
275 	};
276 	protected Action cameraBasicAction = new AbstractAction("camera (basic / wii level 3)") {
277 		
278 		public void actionPerformed(ActionEvent arg0) {
279 			mote.enableIrCamera(IrCameraMode.BASIC, IrCameraSensitivity.WII_LEVEL_3);
280 		}
281 	
282 	};
283 	
284 
285 	protected Action cameraExtendedAction = new AbstractAction("camera (extended / Wii l3)") {
286 
287 		public void actionPerformed(ActionEvent arg0) {
288 			mote.enableIrCamera(IrCameraMode.EXTENDED, IrCameraSensitivity.WII_LEVEL_3);
289 		}
290 
291 	};
292 	
293 	protected Action cameraFullAction = new AbstractAction("camera (full / Wii l3)") {
294 
295 		public void actionPerformed(ActionEvent arg0) {
296 			mote.enableIrCamera(IrCameraMode.FULL, IrCameraSensitivity.WII_LEVEL_3);
297 		}
298 
299 	};
300 	
301 	protected Action report0x30Action = new AbstractAction("Report: 0x30") {
302 		
303 		public void actionPerformed(ActionEvent arg0) {
304 			mote.setReportMode(ReportModeRequest.DATA_REPORT_0x30);
305 		};
306 		
307 	};
308 	
309 	protected Action report0x31Action = new AbstractAction("Report: 0x31") {
310 		
311 		public void actionPerformed(ActionEvent arg0) {
312 			mote.setReportMode(ReportModeRequest.DATA_REPORT_0x31);
313 		};
314 		
315 	};
316 	
317 	protected Action report0x33Action = new AbstractAction("Report: 0x33") {
318 		
319 		public void actionPerformed(ActionEvent arg0) {
320 			mote.setReportMode(ReportModeRequest.DATA_REPORT_0x33);
321 		};
322 		
323 	};
324 	
325 	protected Action report0x36Action = new AbstractAction("Report: 0x36") {
326 		
327 		public void actionPerformed(ActionEvent arg0) {
328 			mote.setReportMode(ReportModeRequest.DATA_REPORT_0x36);
329 		};
330 		
331 	};
332 
333 	protected Action report0x3eAction = new AbstractAction("Report: 0x3e") {
334 		
335 		public void actionPerformed(ActionEvent arg0) {
336 			mote.setReportMode(ReportModeRequest.DATA_REPORT_0x3e);
337 		};
338 		
339 	};
340 
341 	protected Action setLed1Action = new AbstractAction("LED 1") {
342 
343 		public void actionPerformed(ActionEvent arg0) {
344 			leds[0] = leds[0] ? false : true;
345 			mote.setPlayerLeds(leds);
346 		}
347 
348 	};
349 
350 	protected Action setLed2Action = new AbstractAction("LED 2") {
351 
352 		public void actionPerformed(ActionEvent arg0) {
353 			leds[1] = leds[1] ? false : true;
354 			mote.setPlayerLeds(leds);
355 		}
356 
357 	};
358 
359 	protected Action setLed3Action = new AbstractAction("LED 3") {
360 
361 		public void actionPerformed(ActionEvent arg0) {
362 			leds[2] = leds[2] ? false : true;
363 			mote.setPlayerLeds(leds);
364 		}
365 
366 	};
367 
368 	protected Action setLed4Action = new AbstractAction("LED 4") {
369 
370 		public void actionPerformed(ActionEvent arg0) {
371 			leds[3] = leds[3] ? false : true;
372 			mote.setPlayerLeds(leds);
373 		}
374 
375 	};
376 
377 	protected Action rumbleAction = new AbstractAction("Rumble") {
378 
379 		public void actionPerformed(ActionEvent arg0) {
380 			mote.rumble(1000l);
381 		}
382 
383 	};
384 
385 	private JButton feedbackButtonA;
386 
387 	private JButton feedbackButtonB;
388 
389 	private JButton feedbackButtonHome;
390 
391 	private JButton feedbackButtonPlus;
392 
393 	private JButton feedbackButtonMinus;
394 
395 	private JButton feedbackButtonDPadLeft;
396 
397 	private JButton feedbackButtonDPadRight;
398 
399 	private JButton feedbackButtonDPadUp;
400 
401 	private JButton feedbackButtonDPadDown;
402 
403 	private JButton feedbackButtonOne;
404 
405 	private JButton feedbackButtonTwo;
406 
407 	private Color origColor;
408 
409 //	private GLJPanel glpanel;
410 	
411 	public MoteGui() {
412 		final JFrame frame = new JFrame("MoteGui");
413 		frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
414 		frame.getContentPane().setLayout(new BorderLayout());
415 		
416 		ircomp = new MoteGui.IRCompentent();
417 		ircomp.setBorder(BorderFactory.createLineBorder(Color.BLACK));
418 		ircomp.setPreferredSize(new Dimension(1024, 768));
419 		
420 //		glpanel = new GLJPanel();
421 //		glpanel.addGLEventListener(new MoteGui.AccelerometerComponent());
422 //		glpanel.setPreferredSize(new Dimension(600,600));
423 
424 		JPanel centerPanel = new JPanel(new FlowLayout());
425 		centerPanel.add(ircomp);
426 		
427 		accelerometerPanel = new AccelerometerPanel();
428 		centerPanel.add(accelerometerPanel);
429 //		centerPanel.add(glpanel);
430 		
431 		frame.getContentPane().add(centerPanel, BorderLayout.CENTER);
432 		
433 		JPanel topPanel = new JPanel(new FlowLayout());
434 		frame.getContentPane().add(topPanel, BorderLayout.NORTH);
435 		
436 		JPanel bottomPanel = new JPanel(new FlowLayout());
437 		frame.getContentPane().add(bottomPanel, BorderLayout.SOUTH);
438 
439 		JButton findButton = new JButton("Find motes");
440 		findButton.setAction(findAction);
441 		topPanel.add(findButton);
442 
443 		JButton led1Button = new JButton("LED 1");
444 		led1Button.setAction(setLed1Action);
445 		topPanel.add(led1Button);
446 
447 		JButton led2Button = new JButton("LED 2");
448 		led2Button.setAction(setLed2Action);
449 		topPanel.add(led2Button);
450 
451 		JButton led3Button = new JButton("LED 3");
452 		led3Button.setAction(setLed3Action);
453 		topPanel.add(led3Button);
454 
455 		JButton led4Button = new JButton("LED 4");
456 		led4Button.setAction(setLed4Action);
457 		topPanel.add(led4Button);
458 
459 		JButton rumbleButton = new JButton(rumbleAction);
460 		topPanel.add(rumbleButton);
461 		
462 		JButton cameraBasicButton = new JButton(cameraBasicAction);
463 		topPanel.add(cameraBasicButton);
464 		
465 		JButton cameraExtendedButton = new JButton(cameraExtendedAction);
466 		topPanel.add(cameraExtendedButton);
467 
468 		JButton cameraFullButton = new JButton(cameraFullAction);
469 		topPanel.add(cameraFullButton);
470 
471 		JButton report0x30 = new JButton(report0x30Action);
472 		report0x30.setToolTipText("core buttons");
473 		topPanel.add(report0x30);
474 
475 		JButton report0x31 = new JButton(report0x31Action);
476 		report0x31.setToolTipText("core buttons and accelerometer");
477 		topPanel.add(report0x31);
478 		
479 		JButton report0x33 = new JButton(report0x33Action);
480 		report0x33.setToolTipText("core buttons, accelerometer and IR (extended)");
481 		topPanel.add(report0x33);
482 		
483 		JButton report0x36 = new JButton(report0x36Action);
484 		report0x36.setToolTipText("core buttons, ir (basic) and extension");
485 		topPanel.add(report0x36);
486 		
487 		JButton report0x3e = new JButton(report0x3eAction);
488 		report0x3e.setToolTipText("Interleaved Core Buttons and Accelerometer with 36 IR bytes");
489 		topPanel.add(report0x3e);
490 
491 		feedbackButtonA = new JButton("A");
492 		feedbackButtonA.setEnabled(false);
493 		bottomPanel.add(feedbackButtonA);
494 
495 		feedbackButtonB = new JButton("B");
496 		feedbackButtonB.setEnabled(false);
497 		bottomPanel.add(feedbackButtonB);
498 
499 		feedbackButtonOne = new JButton("One");
500 		feedbackButtonOne.setEnabled(false);
501 		bottomPanel.add(feedbackButtonOne);
502 
503 		feedbackButtonTwo = new JButton("Two");
504 		feedbackButtonTwo.setEnabled(false);
505 		bottomPanel.add(feedbackButtonTwo);
506 
507 		feedbackButtonHome = new JButton("Home");
508 		feedbackButtonHome.setEnabled(false);
509 		bottomPanel.add(feedbackButtonHome);
510 
511 		feedbackButtonDPadLeft = new JButton("DPadLeft");
512 		feedbackButtonDPadLeft.setEnabled(false);
513 		bottomPanel.add(feedbackButtonDPadLeft);
514 
515 		feedbackButtonDPadRight = new JButton("DPadRight");
516 		feedbackButtonDPadRight.setEnabled(false);
517 		bottomPanel.add(feedbackButtonDPadRight);
518 
519 		feedbackButtonDPadUp = new JButton("DPadUp");
520 		feedbackButtonDPadUp.setEnabled(false);
521 		bottomPanel.add(feedbackButtonDPadUp);
522 
523 		feedbackButtonDPadDown = new JButton("DPadDown");
524 		feedbackButtonDPadDown.setEnabled(false);
525 		bottomPanel.add(feedbackButtonDPadDown);
526 
527 		feedbackButtonPlus = new JButton("Plus");
528 		feedbackButtonPlus.setEnabled(false);
529 		bottomPanel.add(feedbackButtonPlus);
530 
531 		feedbackButtonMinus = new JButton("Minus");
532 		feedbackButtonMinus.setEnabled(false);
533 		bottomPanel.add(feedbackButtonMinus);
534 		
535 		frame.addWindowListener(new WindowAdapter() {
536 		
537 			@Override
538 			public void windowClosed(WindowEvent e) {
539 				if (mote != null) {
540 					mote.disconnect();
541 				}
542 			}
543 		
544 		});
545 		
546 		frame.setVisible(true);
547 		frame.pack();
548 
549 		origColor = feedbackButtonA.getBackground();
550 	}
551 
552 	public static void main(String[] args) {
553 		SwingUtilities.invokeLater(new Runnable() {
554 
555 			public void run() {
556 				new MoteGui();
557 			}
558 
559 		});
560 	}
561 }