/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
 * This file is part of CMUcamGUI, a java program that helps     *
 * interface with the CMUcam Vision Board.                       *
 * Contact cmucam@cs.cmu.edu, or see                             *
 * http://www.cs.cmu.edu/~cmucam for more information.           *
 *                                                               *
 * Copyright 2001 Anthony Rowe                                   *
 *                                                               *
 * This program is free software; you can redistribute it and/or *
 * modify it under the terms of the GNU General Public License   *
 * as published by the Free Software Foundation - version 2.     *
 *                                                               *
 * This program is distributed in the hope that it will be       *
 * useful, but WITHOUT ANY WARRANTY; without even the implied    *
 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR       *
 * PURPOSE.  See the GNU General Public License in file COPYING  *
 * for more details.                                             *
 *                                                               *
 * You should have received a copy of the GNU General Public     *
 * License along with this program; if not, write to the Free    *
 * Software Foundation, Inc., 59 Temple Place - Suite 330,       *
 * Boston, MA 02111, USA.                                        *
\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

import java.awt.*;
import java.lang.*;
import java.awt.event.*;
import java.util.EventListener;
import java.io.*;
/*
  This object controls the way the GUI looks and handles the 
  menu events etc.  This is also where the serial config box
  can be found.
*/
public class mainWindow implements ActionListener, ItemListener
{
    
    volatile int commandVal;
    Button sendstring_b;
    TextField rawCommand_f;
    Thread updateThread;
    CameraImage cImage;
    aboutWindow myAbout;
mainWindow()
{
commandVal=0;
commWindow cWindow = new commWindow();  // Serial Config Window
while(cWindow.ready()==0);
myAbout = new aboutWindow();
Frame main_f = new Frame("CMUcamGUI");
cImage = new CameraImage(160,144,cWindow.getPort()); // Set serial port
rawCommand_f=new TextField("gv");
sendstring_b = new Button("Send String");
sendstring_b.addActionListener(this);

// Make menus and such
Panel myPanel = new Panel();
MenuBar menuBar = new MenuBar();
Menu file_m = new Menu("File");
file_m.add(makeMenuItem("About"));
file_m.add(makeMenuItem("Quit"));
Menu commands_m = new Menu("Commands",true);
commands_m.add(makeMenuItem("Update Channels"));
commands_m.add(makeMenuItem("Idle/Stop"));
commands_m.add(makeMenuItem("Flush Serial Buff"));
commands_m.add(makeMenuItem("Reset Camera"));
commands_m.add(makeMenuItem("-----------------"));
commands_m.add(makeMenuItem("Dump Frame"));
commands_m.add(makeMenuItem("Track Color"));
commands_m.add(makeMenuItem("Track Window"));
commands_m.add(makeMenuItem("Get Mean"));
commands_m.add(makeMenuItem("Set Window"));
commands_m.add(makeMenuItem("Set Camera Regs"));
Menu mode_m = new Menu("Mode",true);
mode_m.add(makeCheckMenuItem("Line Dump Mode",0));
mode_m.add(makeCheckMenuItem("Middle Mass",1));

Menu tool_m = new Menu("Panels",true);
tool_m.add(makeCheckMenuItem("Color Picker",1));
tool_m.add(makeCheckMenuItem("Color Track",1));
tool_m.add(makeCheckMenuItem("Mean Window",1));
tool_m.add(makeCheckMenuItem("Channels",1));
tool_m.add(makeCheckMenuItem("Camera Registers",1));
tool_m.add(makeCheckMenuItem("Text Output",1));
tool_m.add(makeCheckMenuItem("Set Window",1));

menuBar.add(file_m);
menuBar.add(commands_m);
menuBar.add(mode_m);
menuBar.add(tool_m);
main_f.setMenuBar(menuBar);
main_f.setSize(230,250);
main_f.add("Center",cImage);
myPanel.setLayout( new BorderLayout());

myPanel.add( "Center",rawCommand_f);
myPanel.add( "East", sendstring_b);
main_f.add("South",myPanel);
//main_f.add( "South",pause_b);
//main_f.add( "South",rawCommand_f);
//main_f.add( "South",sendstring_b);


main_f.show();
updateThread=new Thread(new Runnable() { 
	public void run() {grabFrame();}
	});
updateThread.start();
cImage.writeText("Searching for camera...");
// At startup, reset the camera and look for an ack
boolean conf;
conf=cImage.sendCommand("rs\r");
clear();
if(!conf)  // Try one more time if it failed
    {
	cImage.sendCommand("rs\r");
	clear();
    }
commandVal=0; 
}

    /*
      This gets polled from a thread to help manage the camera 
      getting confusing commands. Once a menu is selected, in
      turn a commandVal is set.  When this function gets polled,
      the new cammandVal can then be sent to the CameraImage class
      where the program handles the camera's output etc.
    */
private void grabFrame()
{
    int tempVal=-1,cnt;
while(true)
	{
	
	try{
	    switch(commandVal)
		{
		case 1: //Dump Frame
     		    tempVal=cImage.dumpFrame();
		    break;
		case 2: // Track Color
		    tempVal=cImage.trackColor(0);
		    break;
		case 3:
		    commandVal=0;
		    cnt=0;
		    while(!cImage.idle());
		    break;
		case 4:
		    commandVal=0;
		    cImage.sendCommand(rawCommand_f.getText()+'\r');
		    break;
		case 5: // Track Window
		    tempVal=cImage.trackColor(1);
		    break;
		case 6: // Track Color
		    tempVal=cImage.getMean(0);
		    break; 
		case 7: // Set Window
		    commandVal=0;
		    tempVal=cImage.sw();
		    break;
		case 8: //Set Camera Regs
		    commandVal=0;
		    cImage.setCamera();
		    break;
		    
		default:
		}
	    if(tempVal==0){ commandVal=0; clear(); tempVal=-1; }
	   Thread.sleep(1);
           }
        catch(InterruptedException e) {}
	}

}

/*
  This is where the menus do clean up and set the commandVal value.
*/
public void actionPerformed(ActionEvent e)
{
     String command = e.getActionCommand();
     if( command.equals("Quit"))
	System.exit(0);
     if( command.equals("Dump Frame"))
	 { 
	     clear();
 	     commandVal=1;
	 } 
     if( command.equals("About"))
	 { 
	     myAbout.show();
	 } 
     if( command.equals("Update Channels"))
	 { 
	     cImage.splitChannels();
	 }
     if( command.equals("Track Color"))
	 {
	     clear();
	     commandVal=2;
	 }
     if( command.equals("Track Window"))
	 {
	     clear();
	     commandVal=5;
	 }   
     if( command.equals("Set Window"))
	 {
	     clear();
	     commandVal=7;
	 }  
     if( command.equals("Set Camera Regs"))
	 {
	     clear();
	     commandVal=8;
	 } 
     if( command.equals("Get Mean"))
	 {
	     clear();
	     commandVal=6;
	 }
     if( command.equals("Idle/Stop"))
	 {
	     commandVal=3;
	 }
     if( command.equals("Flush Serial Buff"))
	 {
	     commandVal=0;
	     cImage.flushBuf();
	 }
 if( command.equals("Reset Camera"))
	 { 
	     boolean conf;
	     conf=cImage.sendCommand("rs\r");
	     clear();
	     if(!conf) 
		 {
		     cImage.sendCommand("rs\r");
		     clear();
		 }
	     commandVal=0; 
	 }
    if( command.equals("Send String"))
	{
	    commandVal=0;
	    while(!cImage.idle());
	    commandVal=4;
	   
	}
     
   

}

private void clear()
{
    int cnt;
    commandVal=0;
   
    for(cnt=0; cnt<100; cnt++ )
	{
	    try{ 
		Thread.sleep(500); 
	    } catch(Exception blah){}
	    if(cImage.idle()) break;
	}
    if(cnt==99) System.out.println("<clear> time out" );
   cImage.flushBuf();
}

/*
  This is for check box menus
*/
public void itemStateChanged(ItemEvent e)
{
     String item = e.getItem().toString();
     int action = e.getStateChange();
     if( item.equals("Color Picker"))
	 {
	     if(action==2)cImage.picker_f.hide();
	     else cImage.picker_f.show();    
	 }

 if( item.equals("Color Track"))
	 {
	     if(action==2)cImage.hideTrack();
	     else cImage.showTrack();    
	 } 
 if( item.equals("Mean Window"))
	 {
	     if(action==2)cImage.hideMean();
	     else cImage.showMean();    
	 } 
if( item.equals("Channels"))
	 {
	     if(action==2)cImage.channel_f.hide();
	     else cImage.channel_f.show();    
	 }
if( item.equals("Middle Mass"))
	{ 
	    clear();
	    if(cImage.mm==0)
		{
		    cImage.sendCommand("mm 1\r");
		    cImage.mm=1;
		}
	    else
		{
		    cImage.sendCommand("mm 0\r");
		    cImage.mm=0;
		}
	}

if( item.equals("Line Dump Mode"))
	{ 
	    clear();
	    if(cImage.lm==0)
		{
		    cImage.sendCommand("lm 1\r");
		    cImage.lm=1;
		}
	    else
		{
		    cImage.sendCommand("lm 0\r");
		    cImage.lm=0;
		}
	}
}

private MenuItem makeMenuItem( String name )
{
     MenuItem m = new MenuItem(name);
     m.addActionListener(this);
     return m;

}

private CheckboxMenuItem makeCheckMenuItem( String name,int val )
{
     CheckboxMenuItem m = new CheckboxMenuItem(name);
     if(val==1) 
	 m.setState(true);
     else
	 m.setState(false);
     m.addItemListener(this);
     return m;

}
}


    
