

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

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

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

   Timer timer = null;

   //////////////////////////////////////////////////////////////////////////
   public GlgControlsDemo()
   {
      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( 350, 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 );

      GlgControlsDemo controls = new GlgControlsDemo();
      frame.getContentPane().add( controls );

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

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

   //////////////////////////////////////////////////////////////////////////
   public void UpdateControls()
   { 
      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 the new AntiAliasing setting
      stop();
      start();
   }

   //////////////////////////////////////////////////////////////////////////
   void InitializeArrays()
   {
      // Initilize simulation controlling parameters

      /* 3 top gages */
      animation_array[ 0 ] =
        new GlgAnimationValue( this, GlgAnimationValue.SIN,
                              0, 47, 50., 180., "W1/Value" );
      animation_array[ 1 ] =
        new GlgAnimationValue( this, GlgAnimationValue.SIN,
                              0, 63, 30., 90., "W2/Value" );
      animation_array[ 2 ] =
        new GlgAnimationValue( this, GlgAnimationValue.SIN,
                              0, 91, 1.2, 3.5, "W3/Value" );

      /* Two small gauges in the middle. */
      animation_array[ 3 ] =
        new GlgAnimationValue( this, GlgAnimationValue.SIN,
                              0, 36, 2., 8., "W6/Value" );
      animation_array[ 4 ] =
        new GlgAnimationValue( this, GlgAnimationValue.SIN,
                              0, 59, 2., 8., "W7/Value" );

      /* Sliders */
      animation_array[ 5 ] =
        new GlgAnimationValue( this, GlgAnimationValue.SIN,
                              0, 75, 0.2, 0.8, "W8/ValueY" );
      animation_array[ 6 ] =
        new GlgAnimationValue( this, GlgAnimationValue.SIN,
                              0, 45, 0.2, 0.8, "W9/ValueY" );
      animation_array[ 7 ] =
        new GlgAnimationValue( this, GlgAnimationValue.SIN,
                              0, 84, 0.2, 0.8, "W10/ValueY" );
      animation_array[ 8 ] =
        new GlgAnimationValue( this, GlgAnimationValue.SIN,
                              0, 65, 0.2, 0.8, "W11/ValueY" );
      animation_array[ 9 ] =
        new GlgAnimationValue( this, GlgAnimationValue.SIN,
                              0, 32, 0.2, 0.8, "W12/ValueY" );
      animation_array[ 10 ] =
        new GlgAnimationValue( this, GlgAnimationValue.SIN,
                              0, 58, 0.2, 0.8, "W13/ValueY" );

      /* Thermometer */
      animation_array[ 11 ] =
        new GlgAnimationValue( this, GlgAnimationValue.SIN,
                              0, 80, -20., 105., "W14/ValueY" );

      /* 3 knobs */
      animation_array[ 12 ] =
        new GlgAnimationValue( this, GlgAnimationValue.SIN,
                              0, 46, 5., 80., "W15/Value" );
      animation_array[ 13 ] =
        new GlgAnimationValue( this, GlgAnimationValue.SIN,
                              0, 65, 1., 9., "W16/Value" );
      animation_array[ 14 ] =
        new GlgAnimationValue( this, GlgAnimationValue.SIN,
                              0, 38, 1., 9., "W17/Value" );

      /* 2 switches */
      animation_array[ 15 ] =
        new GlgAnimationValue( this, GlgAnimationValue.RANDOM_INT,
                              0, 100, 0., 2.99, "W18/ValueX" );
      animation_array[ 16 ] =
        new GlgAnimationValue( this, GlgAnimationValue.RANDOM_INT,
                              0, 100, 0., 1.99, "W19/OnState" );

      /* Lights */
      animation_array[ 17 ] =
        new GlgAnimationValue( this, GlgAnimationValue.RANDOM,
                              0, 100, 0., 3., "W20/Value" );
      animation_array[ 18 ] =
        new GlgAnimationValue( this, GlgAnimationValue.RANDOM,
                              0, 100, 0., 3., "W21/Value" );
      animation_array[ 19 ] =
        new GlgAnimationValue( this, GlgAnimationValue.RANDOM,
                              0, 100, 0., 3., "W22/Value" );

      /* Toggles */
      animation_array[ 20 ] =
        new GlgAnimationValue( this, GlgAnimationValue.RANDOM_INT,
                              0, 100, 0., 1.99, "W23/OnState" );
      animation_array[ 21 ] =
        new GlgAnimationValue( this, GlgAnimationValue.RANDOM_INT,
                              0, 100, 0., 1.99, "W24/OnState" );
      animation_array[ 22 ] =
        new GlgAnimationValue( this, GlgAnimationValue.RANDOM_INT,
                              0, 100, 0., 1.99, "W25/OnState" );

      /* Joystick */
      animation_array[ 23 ] =
        new GlgAnimationValue( this, GlgAnimationValue.SIN,
                              0, 23, 0.2, 0.8, "W26/ValueX" );
      animation_array[ 24 ] =
        new GlgAnimationValue( this, GlgAnimationValue.SIN,
                              0, 19, 0.2, 0.8, "W26/ValueY" );
   }

   //////////////////////////////////////////////////////////////////////////
   // 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 )
        UpdateControls();
   }

   //////////////////////////////////////////////////////////////////////////
   // Handles user input: in this demo, it's pressing the start and stop 
   // buttons.
   //////////////////////////////////////////////////////////////////////////
   public void InputCallback( GlgObject vp, GlgObject message_obj )
   {
      String
        origin,
        format,
        action,
        subaction;

      super.InputCallback( vp, message_obj );

      origin = message_obj.GetSResource( "Origin" );
      format = message_obj.GetSResource( "Format" );
      action = message_obj.GetSResource( "Action" );
      subaction = message_obj.GetSResource( "SubAction" );

      if( format.equals( "Button" ) )
      {
         if( !action.equals( "Activate" ) )
           return;
         
         /* The name of the start button in the drawing is W4 (Widget 4) */
         if( origin.equals( "W4" ) )
           Start();
         /* The name of the start button in the drawing is W5 (Widget 5) */
         else if( origin.equals( "W5" ) )
           Stop();
      }

      Update();
   }

   //////////////////////////////////////////////////////////////////////////
   // 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
   {
      GlgControlsDemo bean;
      String request_name;
      int value;

      public GlgBeanRunnable( GlgControlsDemo 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 );
   }
}

