///////////////////////////////////////////////////////////////////////
//
// GraphITControl: Update the GraphIT and techexplorer display in 
//                 response to user input  
//
///////////////////////////////////////////////////////////////////////
//
// Copyright (c) 1997-98 by the IBM Corporation. All Rights Reserved.
//
// Author:          Angel L. Diaz     aldiaz@us.ibm.com
//                  Barry M. Trager   bmt@watson.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.techexplorerListener;
import ibm.techexplorer.event.InstanceEvent;
import ibm.techexplorer.awt.AWTEvent;
import ibm.techexplorer.awt.event.KeyEvent;
import ibm.techexplorer.awt.event.MouseEvent;
import ibm.techexplorer.awt.event.FocusEvent;
import GraphIT;

public class GraphITControl extends Applet implements techexplorerListener { 
  private static final boolean debug  = false;

  private Applet             receiver =	null;
  private String             GraphITAppName   = null;
  private GraphIT            GraphITApp       = null;

  private String             GraphITControlAppName = null;

  private int                curveID          = GraphIT.SINCURVE; 
  private String             techexplorerDisp = "";
  private Slider             graphITSlider    = null;
  private techexplorer       techexplorer     = null;

  public void setPlugin( techexplorer obj )
  {
     if ( obj instanceof techexplorer )
        techexplorer = obj;

	registerListener();
  }

  public void setControl( AxTchExpRaw obj )
  {
     if ( obj instanceof AxTchExpRaw )
         techexplorer = new techexplorerControl( obj );

	registerListener();
  }

  public void init() {
    GridBagLayout gridBag = new GridBagLayout();
    GridBagConstraints c = new GridBagConstraints();

    setLayout(gridBag);

	c.anchor = GridBagConstraints.WEST;
    c.fill = GridBagConstraints.NONE;
    c.weighty = 1.0;
	c.weightx = 1.0;
	c.gridheight = 1;
    c.gridwidth  = 1;
	c.ipadx = c.ipady = 5;
	c.insets = new Insets(4,4,4,4); 
     
  	c.gridx = 3;
	c.gridy = 0;
	c.fill = GridBagConstraints.BOTH;
	graphITSlider = new Slider( 0, this );
  	gridBag.setConstraints(graphITSlider, c);
    add(graphITSlider);

  }

  public void registerListener()
  {
    techexplorer.addtechexplorerListener( (techexplorerListener)this );
    techexplorer.disableEvents( AWTEvent.MOUSE_EVENT_MASK );
  }

  public void start() {
    GraphITControlAppName = getParameter("name");
    GraphITAppName        = getParameter("graphitname");
     
    // get a handle to the GraphIT applet
  	receiver = getAppletContext().getApplet(GraphITAppName);
  }

  public void stop() {
	techexplorer   = null;
    GraphITAppName = null;
	GraphITApp     = null;
  }

  public void destroy() {
    techexplorer.removetechexplorerListener( (techexplorerListener)this );
  }

  public String getAppletInfo() {
     return "GraphITControl (named " + GraphITControlAppName + ") by A. Diaz, B. Trager, R. Sutor";
  }
 
  public void updateAll( ) {
     if ( receiver != null ) {   
        if ( curveID == GraphIT.SINCURVE ) {
		   techexplorerDisp = "\\pagecolor{lightgray}\\colorbox{white}{Select:"   +
		      "\\makebox[1.5in][r]{\\color{black}\\begin{eqnarray}" +
              "\\color{red}y & \\color{red}= & \\color{red}\\sin("     +
		      graphITSlider.getSliderLoc() + "x)\\\\" +
		      "y & = & \\cos(x)\\end{eqnarray}}}";
		}
		if ( curveID == GraphIT.COSCURVE ) {
		   techexplorerDisp = "\\pagecolor{lightgray}\\colorbox{white}{Select:"   +
		      "\\makebox[1.5in][r]{\\color{black}\\begin{eqnarray}y & = & \\sin(x)\\\\" +
		      "\\color{red}y & \\color{red}= & \\color{red}\\cos(" + 
		      graphITSlider.getSliderLoc() + " x)\\end{eqnarray}}}";
		}

		graphITSlider.repaint();
		repaint();
	}
	else
	   System.out.println("GraphITControl: gan not get GraphIT applet");
  }


 public void paint(Graphics g) {
    techexplorer.reloadFromTeXString( techexplorerDisp );
    ((GraphIT)receiver).setParam( graphITSlider.getSliderLoc() );
    ((GraphIT)receiver).setCurve( curveID );
 }

  public boolean handleEvent(Event evt) { 
    if (evt.target == graphITSlider) {
	  updateAll( );
 	  return true; 
	}
	return super.handleEvent(evt);
  }

  // implementation of the techexplorerListener interface
  public void mouseClicked( MouseEvent e ) { }
  public void mouseEntered( MouseEvent e ) { }
  public void mouseExited( MouseEvent e )  { }
  public void mousePressed( MouseEvent e ) { }
  public void focusGained( FocusEvent e )  { }
  public void focusLost( FocusEvent e )    { }
  public void keyPressed( KeyEvent e )     { }
  public void keyReleased( KeyEvent e )    { } 
  public void keyTyped( KeyEvent e )       { }
  public void mouseDragged( MouseEvent e ) { } 

  public void mouseRelease( MouseEvent e ) {
     if (debug)
        System.out.println(mouseInfo(e));

     int y = e.getY();
	 if ( y > 15 && y < 42 ) 
	    curveID = GraphIT.SINCURVE;
	 if ( y > 41 && y < 77 ) 
	    curveID = GraphIT.COSCURVE;

     updateAll( );
  }

  public void mouseMoved( MouseEvent e ) {
     if (debug)
        System.out.println(mouseInfo(e));
  }

  public void instanceDelete( InstanceEvent e ) {
    if (debug) System.out.println("GraphITControl: instanceDelete" );
  }

  protected String mouseInfo( MouseEvent e ) {
     int mods = e.getModifiers();
	 String s = "GraphITControl:";
	 switch(e.getID()) {
	    case MouseEvent.MOUSE_CLICKED:	s +="MOUSE_CLICKED:"; break;
		case MouseEvent.MOUSE_PRESSED:	s +="MOUSE_PRESSED:"; break;
		case MouseEvent.MOUSE_RELEASED: s +="MOUSE_RELEASED:"; break;
		case MouseEvent.MOUSE_MOVED:	s +="MOUSE_MOVED:"; break;
		case MouseEvent.MOUSE_ENTERED:	s +="MOUSE_ENTERED:"; break;
		case MouseEvent.MOUSE_EXITED:	s +="MOUSE_EXITED:"; break;
		case MouseEvent.MOUSE_DRAGGED:  s +="MOUSE_DRAGGED:"; break;
     }
	 if (e.isShiftDown()) s += "Shift ";
	 if (e.isControlDown()) s += "Ctrl ";
	 if ( (mods & MouseEvent.BUTTON1_MASK) != 0 ) s += "Button 1 ";
	 if ( (mods & MouseEvent.BUTTON2_MASK) != 0 ) s += "Button 2 ";
	 if ( (mods & MouseEvent.BUTTON3_MASK) != 0 ) s += "Button 3 ";
	 s += ": [" +e.getX() + "," + e.getY() + "] " + "num clicks = " + e.getClickCount();
	 return s;
  }
}

class Slider extends Panel {
  private GraphITControl GraphITControlApp = null;
  private int            sliderLoc         = 0;
  private int            value             = 0;

  private Dimension offDimension;
  private Image offImage       = null;
  private Graphics offGraphics = null;

  public Slider( int sliderLoc, GraphITControl GraphITControlApp ) {
    this.sliderLoc         = sliderLoc;
	this.GraphITControlApp = GraphITControlApp;
  }

  public int getSliderLoc( ) {
     return sliderLoc;
  }
 
  public void paint(Graphics g) {
     update(g);
  }
 	
  public void update(Graphics g) {
    Dimension d = this.size();

    //Create the offscreen graphics context, if no good one exists.
    if ( (offGraphics == null)
         || (d.width != offDimension.width)
         || (d.height != offDimension.height) ) {
         offDimension = d;
         offImage = createImage(d.width, d.height);
         offGraphics = offImage.getGraphics();
    }

	offGraphics.setColor(new Color(255, 255, 255));
	offGraphics.fill3DRect(0, 0, d.width, d.height, false);
   	offGraphics.setColor(Color.lightGray);
   	offGraphics.fill3DRect(sliderLoc, 2, d.height/3-1, d.height-4, true);

    //Paint the image onto the screen.
    g.drawImage(offImage, 0, 0, this);
  }

  private void setSliderLoc(int loc) {
    Dimension d = this.size();

    if ( loc > 0 && loc < d.width - d.height/3-1 ) {
		sliderLoc = loc;
	  }
	  else {
	    if ( loc < 0 )
	       sliderLoc = 0;
		else
		   sliderLoc = d.width - d.height/3-1;
	  }
	     
	  repaint();
	  Event scrollEvent = new Event(this, Event.SCROLL_ABSOLUTE, new Integer(sliderLoc));
	  deliverEvent(scrollEvent);
  }

  public boolean mouseDrag(Event evt, int x, int y) {
    repaint();
    setSliderLoc(x);
    return true;
  }

  public boolean mouseMove(Event evt, int x, int y) {
    return true;
  }

  public boolean mouseEnter(Event evt, int x, int y) {
    return true;
  }

  public boolean mouseExit(Event evt, int x, int y) {
    return true;
  }

  public boolean mouseDown(Event evt, int x, int y) {
    setSliderLoc(x);
	return true;
  }
}
