///////////////////////////////////////////////////////////////////////
//
// MathAnimation.java : Demonstrate the use of Java threads to animate
// a math derivation.
//
///////////////////////////////////////////////////////////////////////
//
// Copyright © 1996-97 by the IBM Corporation. All Rights Reserved.
//
// Author:          Angel L. Diaz     aldiaz@us.ibm.com
//                  Robert S. Sutor   sutor@us.ibm.com
//
// IBM MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF
// THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
// TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
// PARTICULAR PURPOSE, OR NON-INFRINGEMENT. IBM SHALL NOT BE LIABLE FOR
// ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING OR MODIFYING
// THIS SOFTWARE OR ITS DERIVATIVES.
//
///////////////////////////////////////////////////////////////////////

import java.awt.*;
import java.applet.Applet;

import ibm.techexplorer.techexplorer;
import ibm.techexplorer.control.techexplorerControl;
import ibm.techexplorer.axtchexp.AxTchExpRaw;
import ibm.techexplorer.event.InstanceEvent;
import ibm.techexplorer.event.InstanceListener;
import ibm.techexplorer.awt.AWTEvent;

public class MathAnimation extends java.applet.Applet implements Runnable, InstanceListener  {
  
  Thread             animatorThread  = null;
  int                nCount          = 0;
  int                delay           = 2000;
  static int         nNumFrames      = 12;
  String             sFrame[]        = new String[nNumFrames];

  Button             stopButton      = null;
  Button             startButton     = null;
  boolean            bAnimating      = false;

  private techexplorer techexplorer  = null;
  private static final boolean debug = true;
  
  public void setPlugin( techexplorer obj )
  {
     if ( obj instanceof techexplorer )
        techexplorer = obj;

     System.out.println("MathAnimation:");
	 registerListener();
  }

  public void setControl( AxTchExpRaw obj )
  {
     if ( obj instanceof AxTchExpRaw )
        techexplorer = new techexplorerControl( obj );

	 registerListener();
  }

  public void init() {
     sFrame[0] = new String( "\\def\\VR{\\vrule height .30in width 0pt}\\large" +
        "\\pagecolor{white}\\color{black}" +
        "$$\\VR \\displaystyle a\\,x^{2} + b\\,x + c=0$$" ); 
     sFrame[1] = new String( "\\def\\VR{\\vrule height .30in width 0pt}\\large" +
        "\\pagecolor{white}\\color{black}" +
        "$$\\VR \\displaystyle 4\\,a\\cdot\\left(a\\,x^{2} + b"+
        "\\,x + c\\right)= 4\\,a\\cdot 0 = 0$$" );
     sFrame[2] = new String( "\\def\\VR{\\vrule height .30in width 0pt}\\large" +
        "\\pagecolor{white}\\color{black}" + 
        "$$\\VR \\displaystyle 4\\,a^{2}\\,x^{2} + 4\\,a\\,b\\,x + " +
        "4\\,a\\,c=0$$" );
     sFrame[3] = new String( "\\def\\VR{\\vrule height .30in width 0pt}\\large" +
        "\\pagecolor{white}\\color{black}" +
        "$$\\VR \\displaystyle 4\\,a^{2}\\,x^{2} + 4\\,a\\,b\\,x = " +
        "- 4\\,a\\,c$$" );
     sFrame[4] = new String( "\\def\\VR{\\vrule height .30in width 0pt}\\large" +
        "\\pagecolor{white}\\color{black}" +
        "$$\\VR \\displaystyle 4\\,a^{2}\\,x^{2} + 4\\,a\\,b\\,x " +
        "+ b^{2}=b^{2} - 4\\,a\\,c$$" );
     sFrame[5] = new String( "\\def\\VR{\\vrule height .30in width 0pt}\\large" +
        "\\pagecolor{white}\\color{black}" +
        "$$\\VR \\displaystyle \\left({2\\,a\\,x+b}\\right)^2 =b^{2} " +
        "- 4\\,a\\,c$$" );
     sFrame[6] = new String( "\\def\\VR{\\vrule height .30in width 0pt}\\large" +
        "\\pagecolor{white}\\color{black}" +
        "$$\\VR \\displaystyle 4\\,a^{2}\\,x^{2} + 4\\,a\\,b\\,x + " +
        "b^{2}=b^{2} - 4\\,a\\,c$$" );
     sFrame[7] = new String( "\\def\\VR{\\vrule height .30in width 0pt}\\large" +
        "\\pagecolor{white}\\color{black}" +
        "$$\\VR \\displaystyle \\left({2\\,a\\,x+b}\\right)^2 =" +
        "b^{2} - 4\\,a\\,c$$" );
     sFrame[8] = new String( "\\def\\VR{\\vrule height .30in width 0pt}\\large" +
        "\\pagecolor{white}\\color{black}" +
        "$$\\VR \\displaystyle{2\\,a\\,x+b} = \\pm\\sqrt{b^{2} - 4" +
        "\\,a\\,c}$$" );
     sFrame[9] = new String( "\\def\\VR{\\vrule height .30in width 0pt}\\large" +
        "\\pagecolor{white}\\color{black}" +
        "$$\\VR \\displaystyle{2\\,a\\,x} = -b\\pm\\sqrt{b^{2} - 4" +
        "\\,a\\,c}$$" );
     sFrame[10] = new String( "\\def\\VR{\\vrule height .30in width 0pt}\\large" +
        "\\pagecolor{white}\\color{black}" +
        "$$\\VR \\displaystyle x = \\frac{-b\\pm\\sqrt{b^{2} - 4" +
        "\\,a\\,c}}{2\\,a}$$" );
     sFrame[11] = new String( "\\def\\VR{\\vrule height .30in width 0pt}\\large" +
        "\\pagecolor{white}\\color{black}" +
        "IBM techexplorer\\newline Technical Publishing for the Internet" );

     startButton = new Button( "Start Animation" );
	 stopButton  = new Button ( "Stop Animation" );

     setLayout(new GridLayout(1, 2));
	 add(startButton);
	 add(stopButton);
  }

  public void registerListener()
  {
     if ( techexplorer == null ) 
	    System.out.println("MathAnimation: registerListener: null techexplorer");
     else {
	    techexplorer.addInstanceListener( (InstanceListener)this );
	    techexplorer.disableEvents( AWTEvent.FOCUS_EVENT_MASK );
	    techexplorer.disableEvents( AWTEvent.KEY_EVENT_MASK);
	    techexplorer.disableEvents( AWTEvent.MOUSE_EVENT_MASK );
	    techexplorer.disableEvents( AWTEvent.MOUSE_MOTION_EVENT_MASK ); 
	 }

	 
  }

  public void start() {
     if (debug) System.out.println("MathAnimation: start()");

	 //Start animating!
     if ( animatorThread == null ) {
	    if (debug) System.out.println("MathAnimation: start(): animatorThread == null");
		
        animatorThread = new Thread(this);
        nCount = 0;
     }
	 animatorThread.start();
  }

  public void stop() {
     if (debug) System.out.println("MathAnimation: stop()");

     if ( techexplorer == null )
        System.out.println("MathAnimation: stop : null techexplorer");
	  	    
     //Stop the animating thread.
     animatorThread = null;
	 bAnimating     = false;
  }

  public void destory()
  {
     techexplorer.removeInstanceListener( (InstanceListener)this );
  }

  public void run() {
    // Lower this thread's priority
    Thread.currentThread().setPriority(Thread.MIN_PRIORITY);

    // Remember the starting time.
    long startTime = System.currentTimeMillis();

    // Remember which thread we are.
    Thread currentThread = Thread.currentThread();

    // This is the animation loop.
    while (currentThread == animatorThread) {
            //Display it.
            repaint();

            //Delay depending on how far we are behind.
            try {
                startTime += delay;
                Thread.sleep(Math.max(0, 
                             startTime-System.currentTimeMillis()));
            } catch (InterruptedException e) {
                break;
            }
        }
  }

  //Draw the current frame of animation.
  public void paint(Graphics g) {
     if ( techexplorer != null ) {
	    if ( nCount >= nNumFrames ) nCount = 0;
		if ( bAnimating == true ) {
	       synchronized( techexplorer ) {
              techexplorer.reloadFromTeXString( sFrame[nCount] );
		   }
           //Advance the animation frame.
           nCount++;
		}
	 }       
  }

  public void instanceDelete( InstanceEvent e ) {
     if (debug) System.out.println("MathAnimation: InstanceDelete" );
  
     //Stop the animating thread.
     animatorThread = null;
  }

  public boolean action(Event evt, Object arg) {
    if ( evt.target == startButton ){
	   bAnimating = true;
	   return true;
	} else
    if ( evt.target == stopButton ){
	   bAnimating = false;
	   return true;
	}
	else
	   return false;
  }

}
