

import java.awt.event.*;
import javax.swing.*;
import com.genlogic.*;

//////////////////////////////////////////////////////////////////////////
public class GlgAvionicsDemo extends GlgJBean implements ActionListener
{
   //////////////////////////////////////////////////////////////////////////
   // The main demo class
   //////////////////////////////////////////////////////////////////////////
   static final long serialVersionUID = 0;

   static final int NUM_VALUES = 15;
   boolean
     IsReady = false,
     AutoUpdate = true;
   GlgAnimationValue animation_array[] = new GlgAnimationValue[ NUM_VALUES ];
   static boolean AntiAliasing = true;

   Timer timer = null;

   //////////////////////////////////////////////////////////////////////////
   public GlgAvionicsDemo()
   {
      super();
      SetDResource( "$config/GlgAntiAliasing", AntiAliasing ? 1. : 0. );
   }

   //////////////////////////////////////////////////////////////////////////
   // Starts updates
   //////////////////////////////////////////////////////////////////////////
   public void ReadyCallback()
   {
      if( GetJavaLog() )
        PrintToJavaConsole( "Debug: Ready\n" );

      super.ReadyCallback();

      InitializeArrays();
      
      if( timer == null )
      {
         timer = new Timer( 50, this );
         timer.setRepeats( true );
         timer.start();
      }

      IsReady = true;      
   }

   //////////////////////////////////////////////////////////////////////////
   // For use as a stand-alone java demo
   //////////////////////////////////////////////////////////////////////////
   public static void main( final String arg[] )
   {
      SwingUtilities.
        invokeLater( new Runnable(){ public void run() { Main( arg ); } } );
   }

   //////////////////////////////////////////////////////////////////////////
   public static void Main( final String arg[] )
   {
      class DemoQuit extends WindowAdapter
      {
         public void windowClosing( WindowEvent e ) { System.exit( 0 ); }
      } 

      JFrame frame = new JFrame();

      frame.setResizable( true );
      frame.setSize( 750, 600 );
      frame.setLocation( 20, 20 );

      GlgAvionicsDemo avionics = new GlgAvionicsDemo();
      frame.getContentPane().add( avionics );

      frame.addWindowListener( new DemoQuit() );
      frame.setVisible( true );

      // Setting the viewport triggers the ReadyCallback which starts
        // updates.
      avionics.SetViewport( GlgObject.LoadWidget( "avionics.glg",
                                                 GlgObject.FILE ) );
   }

   //////////////////////////////////////////////////////////////////////////
   public void UpdateAvionics()
   { 
      if( !IsReady )
        return;

      if( AutoUpdate )
      {
         // Update all animation_values
         for( int i=0; i < NUM_VALUES; ++i )
           if( animation_array[ i ] != null )
             animation_array[ i ].Iterate();

         Update();   // Show changes
      }
   }

   //////////////////////////////////////////////////////////////////////////
   public void Start()
   {
      AutoUpdate = true;
      if( timer != null )
        timer.start();
   }

   //////////////////////////////////////////////////////////////////////////
   public void Stop()
   {
      AutoUpdate = false;
      if( timer != null )
        timer.stop();
   }

   //////////////////////////////////////////////////////////////////////////
   public void ToggleAntiAliasing()
   {
      AntiAliasing = !AntiAliasing;
      SetDResource( "$config/GlgAntiAliasing", AntiAliasing ? 1. : 0. );

      // Restart with new AntiAliasing setting
      stop();
      start();
   }

   //////////////////////////////////////////////////////////////////////////
   void InitializeArrays()
   {
      int k = 5;   // Speed factor

      // Initilize simulation controlling parameters
      animation_array[ 0 ] =
        new GlgAnimationValue( this, GlgAnimationValue.SIN,
                              0, 1000 / k, 20., 80., "RPM/Value" );
      animation_array[ 1 ] =
        new GlgAnimationValue( this, GlgAnimationValue.SIN,
                              0, 1100 / k, 30., 85., "RPM/Value2" );
      animation_array[ 2 ] =
        new GlgAnimationValue( this, GlgAnimationValue.SIN,
                              0, 1400 / k, 3.5, 7.5, "EGT/Value" );
      animation_array[ 3 ] =
        new GlgAnimationValue( this, GlgAnimationValue.SIN,
                              0, 1500 / k, 4.5, 7.8, "EGT/Value2" );
      animation_array[ 4 ] =
        new GlgAnimationValue( this, GlgAnimationValue.SIN,
                              0, 2500 / k, 2000., 8000., "FUEL/Value" );
      animation_array[ 5 ] =
        new GlgAnimationValue( this, GlgAnimationValue.SIN,
                              0, 2200 / k, 0.6, 1., "MACH/Value" );
      animation_array[ 6 ] =
        new GlgAnimationValue( this, GlgAnimationValue.SIN,
                              0, 2300 / k, 0.7, 1.2, "MACH/Value2" );
      animation_array[ 7 ] =
        new GlgAnimationValue( this, GlgAnimationValue.SIN,
                              0, 2100 / k, 0., 20., "ADA/Value" );
      animation_array[ 8 ] =
        new GlgAnimationValue( this, GlgAnimationValue.SIN,
                              0, 1600 / k, 0., 1., "NOZ/Value" );
      animation_array[ 9 ] =
        new GlgAnimationValue( this, GlgAnimationValue.SIN,
                              0, 1700 / k, 0., 1., "NOZ/Value2" );
      animation_array[ 10 ] =
        new GlgAnimationValue( this, GlgAnimationValue.SIN,
                              0, 2600 / k, -10., 10., "HORIZON/Pitch" );
      animation_array[ 11 ] =
        new GlgAnimationValue( this, GlgAnimationValue.SIN,
                              0, 2700 / k, -10., 10., "HORIZON/Roll" );
      animation_array[ 12 ] =
        new GlgAnimationValue( this, GlgAnimationValue.SIN,
                              0, 2700 / k, -20., 20., "HORIZON/LeftRudder" );
      animation_array[ 13 ] =
        new GlgAnimationValue( this, GlgAnimationValue.SIN,
                              0, 1900 / k, -10., 10., "HORIZON/RightRudder" );
      animation_array[ 14 ] =
        new GlgAnimationValue( this, GlgAnimationValue.SIN,
                              0, 2800 / k, 30., 160., "COMPASS/Value" );
   }

   //////////////////////////////////////////////////////////////////////////
   // Stops updates when used as an applet.
   //////////////////////////////////////////////////////////////////////////
   public void stop()
   {
      if( timer != null )
      {
         timer.stop();
         timer = null;
      }

      IsReady = false;
      super.stop();
   }

   //////////////////////////////////////////////////////////////////////////
   // ActionListener method to use the bean as update timer's ActionListener.
   //////////////////////////////////////////////////////////////////////////
   public void actionPerformed( ActionEvent e )
   {
      if( timer != null )
        UpdateAvionics();
   }

   //////////////////////////////////////////////////////////////////////////
   // Inner class for a Runnable interface.
   // Provides an interface between JavaScript and Java: invokes applet's 
   // methods in a synchronous way as required by Swing.
   //////////////////////////////////////////////////////////////////////////
   class GlgBeanRunnable implements Runnable
   {
      GlgAvionicsDemo bean;
      String request_name;
      int value;

      public GlgBeanRunnable( GlgAvionicsDemo bean_p, 
                             String request_name_p, int value_p )
      {
         bean = bean_p;
         request_name = request_name_p;
         value = value_p;
      }

      public void run()
      {
         if( request_name.equals( "Start" ) )
           bean.Start();
         else if( request_name.equals( "Stop" ) )
           bean.Stop();
         else if( request_name.equals( "ToggleAntiAliasing" ) )
           bean.ToggleAntiAliasing();
         else
           PrintToJavaConsole( "Invalid request name: " + 
                              request_name + "\n" );
      }
   }

   //////////////////////////////////////////////////////////////////////////
   // Provides an interface between JavaScript and Java: invokes applet's 
   // methods in a synchronous way as required by Swing.
   //////////////////////////////////////////////////////////////////////////
   public void SendRequest( String request_name, int value )
   {
      GlgBeanRunnable runnable = 
        new GlgBeanRunnable( this, request_name, value );

      SwingUtilities.invokeLater( runnable );
   }
}


