/*
<!--
* An example code for a HTML-page, which uses this applet:
* 
* <applet code=ImageMenuApplet.class height=242 width=424>
* <param name=ChangingImage1 value="dal1.gif">
* <param name=ChangingImage2 value="dal2.gif">
* <param name=BackgroundImage value="video2.gif">
* <param name=ChangingImageX value=276>
* <param name=ChangingImageY value=92>
* <param name=RequestedURL value="http://www.it.lut.fi">
* </applet>
-->
*/

import java.awt.*;
import java.awt.event.*;
import java.applet.*;
import java.awt.image.*;
import java.util.*;
import java.net.*;


/** Provides an applet, which consist of a background image and another
*   image. The latter one changes when entered by the mouse. When clicked 
*   another html page will be shown.
*
*   @version 1.0 Jan-08-1999
*   @author <A HREF="mailto:czichy@rcs.urz.tu-dresden.de">Thoralf Czichy</A>
*/
public class ImageMenuApplet extends Applet
  implements MouseListener, MouseMotionListener{
  
  // position of the changing image
  int changingImageX;
  int changingImageY;
  
  // size of the changing image
  int changingImageWidth; //92
  int changingImageHeight; //65
  
  // the URL, which will be shown, when the user clicks on 
  // the changing image
  String requestedURLString;
  
  // the two images, which change when mouse enters or leaves
  // and the backgroundImage
  Image changingImage1, changingImage2, backgroundImage;
  
  // offscreen properties 
  Image offscreenImage;
  Graphics offscreenGraphics;
  
  // contains the actual image which will be drawn in the paint() method
  Image image;
 
  // flag signals which changingImage will be shown 
  int flag = 0;
 
  /** Initializes the applet. Loads the three images, initializes the
  *   MouseListener and the MouseMotionListener and initializes the 
  *   DoubleBuffer.
  */
  public void init() {
  
  // load 3 images 
  changingImage1=getImage(getCodeBase(), getParameter("ChangingImage1"));
  changingImage2=getImage(getCodeBase(), getParameter("ChangingImage2"));
  backgroundImage=getImage(getCodeBase(), getParameter("BackgroundImage"));
  
  // load the requested URL, which will be shown, when 
  // the user clicks on the changing image
  requestedURLString=getParameter("RequestedURL");
  
  // get (x,y) position of the changingImage
  try{
    changingImageX=Integer.parseInt(getParameter("ChangingImageX"));
    changingImageY=Integer.parseInt(getParameter("ChangingImageY"));
  } catch (NumberFormatException nFE){
    changingImageX=0;
    changingImageY=0;
  }
  
  
  // Control the loading process of the images using a MediaTracker
  // First add all Images to the MediaTracker. Then, the MediaTracker
  // takes care of the loading process.
  MediaTracker mediaTracker=new MediaTracker(this);
  mediaTracker.addImage(changingImage1,1);
  mediaTracker.addImage(changingImage2,2);
  mediaTracker.addImage(backgroundImage,3);
  try{
    mediaTracker.waitForAll();
  } catch(InterruptedException interruptedException){
  }
  
  // get the actual size of the changingImage. changingImage1 and
  // changingImage2 are supposed to have the same size
  changingImageWidth=changingImage1.getWidth(this);
  changingImageHeight=changingImage1.getHeight(this);
  
  // Add to Mouse and Motion Listener
  addMouseListener(this);
  addMouseMotionListener(this);
  
  // initialize Double Buffer
  makeDoubleBuffer(backgroundImage.getWidth(this),backgroundImage.getHeight(this));
  
}
  
  
/** Initializes the DoubleBuffer for the offscreen image
*
* @param width width of double buffered image
* @param height height of double buffered image
*/
void makeDoubleBuffer(int width, int height){

  // first create a new Image and then get its graphics object
  offscreenImage = createImage(width, height);
  offscreenGraphics= offscreenImage.getGraphics();
}
    
/** Do not react on this event. The mouse click is handled by 
*   mouseReleased() method.
*
* @param mouseEvent represents the corresponding MouseEvent object
*/
public void mouseClicked(MouseEvent mouseEvent) {}
  
/** Do not react on this event
*
* @param mouseEvent represents the corresponding MouseEvent object
*/
public void mouseEntered(MouseEvent mouseEvent) {}
  
/** Do not react on this event
*
* @param mouseEvent represents the corresponding MouseEvent object
*/
public void mouseExited(MouseEvent mouseEvent) {}

/** Do not react on this event
*
* @param mouseEvent represents the corresponding MouseEvent object
*/
public void mousePressed(MouseEvent mouseEvent) {}
  
/** checks, whether the the point specified by the parameter is
*   is inside the changing image
*   @param x x position of the point
*   @param y y position of the point
*/
private boolean isInsideBounds(int x, int y){
  //if it is inside return true, otherwise return false
  if ((x>=changingImageX) &
      (x<=changingImageX+changingImageWidth) &
      (y>=changingImageY) &
      (y<=changingImageY+changingImageHeight)){
    return true;
  }
  else{
    return false;
  }  
}
  
/** This method checks, whether the mouse cursor is inside the area
*   of the changing image and if so the browser will show the
*   document specified by the RequestedURL parameter 
*
* @param mouseEvent represents the corresponding MouseEvent object
*/
public void mouseReleased(MouseEvent mouseEvent) {
    
  // if mouse cursor inside the changing image 
  if (isInsideBounds(mouseEvent.getX(),mouseEvent.getY())){
    try{
      // the browser will show the specified URL  
      getAppletContext().showDocument(new URL(requestedURLString));
    }
    catch (MalformedURLException malformedURL){
    }
  }
}
  
/** Do not react on this event
*
* @param mouseEvent represents the corresponding MouseEvent object
*/
public void mouseDragged(MouseEvent mouseEvent) {}
  

/** Everytime the mouse is moved this method will be called. It checks
*   if the mouse cursor is inside the changingImage and depending on
*   that the flag will be set, so that the required image will be
*   shown. The repaint() method will be called only when the flag 
*   changed its state (e.g. from one to zero)
*
* @param MouseEvent represents the corresponding MouseEvent object
*/
public void mouseMoved(MouseEvent mouseEvent) {
  // is the mouse cursor inside the area of the changing image  
  if (isInsideBounds(mouseEvent.getX(),mouseEvent.getY())){
    if (flag!=1){ 
      flag=1;
      // repainting is only required, when the flag changed its state 
      repaint();
    }
  }
  else{
    if (flag!=0){
      flag=0;
      // repainting is only required, when the flag changed its state 
      repaint();
    }  
  }    
}
 
/** only called when an update of the graphics area is required
*
* @param g the corresponding Graphics object
*/
public void update(Graphics g) {
  paint(g);
}
   
/** called, when the graphics area should be drawn
*
* @param g the corresponding Graphics object
*/
public void paint(Graphics g) {

  image= null;
  
  // set image to the required changing image
  if (flag==0)
    image=changingImage1;
  else
    image=changingImage2;
  
  if (image != null){
    
    // first paint the whole image black
    offscreenGraphics.setColor(Color.black);
    offscreenGraphics.fillRect(0,0,offscreenImage.getWidth(this),
                               offscreenImage.getHeight(this));
                               
    // draw the background image                          
    offscreenGraphics.drawImage(backgroundImage,0,0,this);
    
    // draw the changing image
    offscreenGraphics.drawImage(image,changingImageX,
                                changingImageY ,this);
    
    //now draw the offscreen image, so that it gets visible
    g.drawImage(offscreenImage,0,0, this);                            
  }
 
}  

} //end of class ImageMenuApplet
