////////////////////////////////////////////////////////////////////////////////
//																			  //
// AUTHOR:      Tevfik Metin Sezgin	                        				  //
//				Massachusetts Institute of Technology						  //
//				Department of Electrical Engineering and Computer Science	  //
//				Artificial Intelligence Laboratory							  //
//																			  //
// E-MAIL:		mtsezgin@ai.mit.edu, mtsezgin@mit.edu						  //
//																			  //
// COPYRIGHT:   Tevfik Metin Sezgin                    						  //
//              All rights reserved. This code can not be copied, modified,   //
//              or distributed in whole or partially without the written 	  //
//				permission of the author. Also see the COPYRIGHT file.		  //
//																			  //
////////////////////////////////////////////////////////////////////////////////

/**
  *
  * See the end of the file for the log of changes.
  *
  * $Author: mtsezgin $
  * $Date: 2000/06/08 03:11:46 $
  * $Revision: 1.4 $
  * $Headers$
  * $Id: ControlModule.java,v 1.4 2000/06/08 03:11:46 mtsezgin Exp $
  * $Name:  $
  * $Locker:  $
  * $Source: /mit/mtsezgin/CVS/Repository/REC/ControlModule.java,v $
  *
  **/


import java.awt.Button;
import java.awt.Choice;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Frame;
import java.awt.GridLayout;
import java.awt.Label;
import java.awt.List;
import java.awt.Menu;
import java.awt.MenuBar;
import java.awt.MenuItem;
import java.awt.Image;
import java.awt.Panel;
import java.awt.TextField;
import java.awt.Toolkit;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;

/**
  *
  * This class is used for controlling and changing the parameters
  * in the main application.
  *
  **/

class      ControlModule
extends    Frame
implements ActionListener,
		   ItemListener
{
    private TabletDataProcessor tablet;
    
    private Menu      file;
    private MenuBar   menubar;
    private MenuItem  quit_menu;

    private TextField speed_average_scale;
    private TextField dd_dt_average_scale;
    private TextField circle_bias;
    private TextField window_width;
    private TextField test_line_scale;
    private TextField orientation_angle;
    private TextField direction_window_width;
    private TextField zoom;
	private Button    simple_tangents_method;
	private Button    swodr_method;
	private Button    rotational_odr_method;
	private Button    convolve_d;
	private Button    convolve_dd_dt;
	
    private Choice    direction_fit_method;

    private List polygon_fit_list;
    
    /**
    *
    * The constructor.
    *
    **/
    public ControlModule( TabletDataProcessor tablet )
    {
        super( "Controls" );
        this.tablet = tablet;

        menubar     = new MenuBar();
        file        = new Menu( "File" );
        quit_menu   = new MenuItem( "Quit" );
        
        
        speed_average_scale = 
            new TextField( "" + 
                tablet.speed_average_scale );
        dd_dt_average_scale = 
            new TextField( "" + 
                tablet.dd_dt_average_scale );
        test_line_scale   = 
            new TextField( "" + 
                tablet.test_line_scale );
        circle_bias       = 
            new TextField( "" + 
                tablet.circle_bias );
        window_width      = 
            new TextField( "" + 
                GeometryUtil.radian2degree( tablet.window_width ) );
        orientation_angle = 
            new TextField( "" + 
                GeometryUtil.radian2degree( tablet.orientation_angle ) );
        direction_window_width = 
            new TextField( "" + 
                tablet.direction_window_width );
        zoom = new TextField( "1.0" );
        
		simple_tangents_method = new Button( "Tangents"        );
		swodr_method           = new Button( "SOWDR   "        );
		rotational_odr_method  = new Button( "RODR    "        );
		convolve_d             = new Button( "Convolve d"      );
		convolve_dd_dt         = new Button( "Convolve dd_dt " );

		direction_fit_method = new Choice();

		direction_fit_method.addItem( 
			LinearFit.fitMethodToString(
				LinearFit.SIMPLE_TANGENTS_METHOD ) );

		direction_fit_method.addItem( 
			LinearFit.fitMethodToString(
				LinearFit.SWODR_METHOD ) );

		direction_fit_method.addItem( 
			LinearFit.fitMethodToString(
				LinearFit.ROTATION_METHOD ) );
				
		direction_fit_method.select( Tablet.fit_method );
		
		polygon_fit_list = new List( 5 );
		
        setLayout( new GridLayout( 2, 1 ) );

		
		Panel button_panel = new Panel();
		button_panel.setLayout( new GridLayout( 1, 3 ) );
		button_panel.add( simple_tangents_method  );
		button_panel.add( swodr_method			  );
		button_panel.add( rotational_odr_method   );

		Panel text_field_panel = new Panel();
        setLayout( new GridLayout( 1, 2 ) );

		text_field_panel.setLayout( new GridLayout( 0, 2 ) );
        text_field_panel.add( new Label("v Average scale  ") );
        text_field_panel.add( speed_average_scale            );
        text_field_panel.add( new Label("dd_dt avrg. scale") );
        text_field_panel.add( dd_dt_average_scale            );
        text_field_panel.add( new Label("Test Line Scale  ") );
        text_field_panel.add( test_line_scale                );
        text_field_panel.add( new Label("Window Width     ") );
        text_field_panel.add( window_width                   );
        text_field_panel.add( new Label("Circle LSQE bias ") );
        text_field_panel.add( circle_bias                    );
        text_field_panel.add( new Label("Orientation Angle") );
        text_field_panel.add( orientation_angle              );
        text_field_panel.add( new Label("DSW Width")         );
        text_field_panel.add( direction_window_width         );
        text_field_panel.add( new Label("Zooming factor")    );
        text_field_panel.add( zoom                           );
        text_field_panel.add( new Label("Fit method")        );
        text_field_panel.add( direction_fit_method           );
        text_field_panel.add( new Label("Fit method")        );
        text_field_panel.add( button_panel                   );
        text_field_panel.add( convolve_d                     );
        text_field_panel.add( convolve_dd_dt                 );
        
		
		
		

        add( polygon_fit_list );
        add( text_field_panel );
        
        file.add( quit_menu );
        menubar.add( file );
        setMenuBar( menubar );
        file.add( quit_menu );
        
		direction_fit_method.addItemListener( this ) ;
		polygon_fit_list.addActionListener( this );
        quit_menu.addActionListener( this );
        speed_average_scale.addActionListener( this );
        dd_dt_average_scale.addActionListener( this );
        circle_bias.addActionListener( this );
        window_width.addActionListener( this );
        test_line_scale.addActionListener( this );
        orientation_angle.addActionListener( this );
        direction_window_width.addActionListener( this );
        zoom.addActionListener( this );
		swodr_method.addActionListener( this );
		convolve_d.addActionListener( this );
		convolve_dd_dt.addActionListener( this );
		rotational_odr_method.addActionListener( this );
        simple_tangents_method.addActionListener( this );
		
        pack();
        validate();
    }
    

    /**
    *
    * Handle key stroke events
    *
    **/
    public void
    keyPressed( KeyEvent k )
    {
    }
     
    /**
    *
    * Handle key stroke events
    *
    **/
    public void
    keyReleased( KeyEvent k )
    {    
    }
     
	 
    /**
    *
    * Handle key stroke events
    *
    **/
    public void
    keyTyped( KeyEvent k )
    {
        char key = k.getKeyChar();
        
        if ( key == 'q' ) {
            System.exit( 0 );
            return;
        }
    }

     
    /**
    *
    * Handle key stroke events
    *
    **/
    public void
    itemStateChanged( ItemEvent e )
    {
		Object source = e.getSource();
		
		if ( source == direction_fit_method ) {
			((Tablet)tablet).setFitMehod( 
				direction_fit_method.getSelectedIndex() );
		}
    }

     
    /**
    *
    * Handle action events
    *
    **/
    public void
    actionPerformed( ActionEvent e ) 
    {
        String command = e.getActionCommand();
        Object source  = e.getSource();

        if ( source == simple_tangents_method ) {
			((Tablet)tablet).setFitMehod( 
				LinearFit.SIMPLE_TANGENTS_METHOD );
			return;
        }             
		
        if ( source == swodr_method ) {
			((Tablet)tablet).setFitMehod( 
				LinearFit.SWODR_METHOD );
			return;
        }             
		
        if ( source == rotational_odr_method ) {
			((Tablet)tablet).setFitMehod( 
				LinearFit.ROTATION_METHOD );
			return;
        }             
			
        if ( source == convolve_d ) {
			((Tablet)tablet).convolveDirection();
			return;
        }             
			
        if ( source == convolve_dd_dt ) {
			((Tablet)tablet).convolveChangeInDirection();
			return;
        }             
			
        if ( source == polygon_fit_list ) {
			tablet.paint( Tablet.debug_graphics );
			Blackboard.hybrid_fits[polygon_fit_list.getSelectedIndex()].paint(
				Tablet.debug_graphics );
			return;
		}

        if ( ( source == speed_average_scale    ) || 
             ( source == dd_dt_average_scale    ) ||
             ( source == circle_bias            ) ||
             ( source == window_width           ) ||
             ( source == test_line_scale        ) ||
             ( source == orientation_angle      ) ||
             ( source == direction_window_width ) ||
             ( source == zoom                   ) ) {

            double angle = GeometryUtil.degree2radian( 
                    Double.valueOf( command ).doubleValue() );

            double value = Double.valueOf( command ).doubleValue();

            if ( source == speed_average_scale ) {
                tablet.speed_average_scale = value;
            }
            
            if ( source == dd_dt_average_scale ) {
                tablet.dd_dt_average_scale = value;
            }
            
            if ( source == test_line_scale ) {
                tablet.test_line_scale = value;
            }
            
            if ( source == circle_bias ) {
                tablet.circle_bias = value;
            }
            
            if ( source == window_width ) {
                tablet.window_width = angle;
            }
            
            if ( source == orientation_angle ) {
                tablet.orientation_angle = angle;
            }             
			
            if ( source == direction_window_width ) {
				System.out.println( "direction_window_width = " + command );
                tablet.direction_window_width = (int)value;
            }
			
            if ( source == zoom ) {
				System.out.println( "zooming with factor = " + value );
                ((Tablet)tablet).zoom( value );
            }
        }

        System.out.println( command );

        if ( command == "Quit" ) {
            System.exit( 0 );
        }
    }


    /**
    *
    * Add the hybrid fits to the list
    *
    **/
    public void
    setHybridFitList( Fit fits[] )
    {
		polygon_fit_list.removeAll();
		for ( int i=0; i<fits.length; i++ ) {
			polygon_fit_list.add( fits[i] + "" );
		}
    }
}

/**
  *
  * $Log: ControlModule.java,v $
  * Revision 1.4  2000/06/08 03:11:46  mtsezgin
  * *** empty log message ***
  *
  * Revision 1.3  2000/06/03 01:52:31  mtsezgin
  * *** empty log message ***
  *
  * Revision 1.2  2000/06/02 21:11:14  mtsezgin
  * *** empty log message ***
  *
  * Revision 1.1  2000/05/26 20:39:25  mtsezgin
  *
  * This GUI lets the user play with the paramaters used by the
  * recognition algorithms.
  *
  * Revision 1.2  2000/05/24 01:53:22  mtsezgin
  *
  * The polygon angle normalization works reliably.
  *
  * Revision 1.1  2000/05/21 23:13:15  mtsezgin
  *
  * This module is used for plotting and investigating certain statistical
  * features.
  *
  *
  *
  **/
