//****************************************************************************
// CLASS NAME:	ImageButton.java
//
// AUTHOR:	Rick Brink
//		    rick@mail.csh.rit.edu
//		    http://www.csh.rit.edu/~rick
//
//          Adapted from an ImageButton class by Adam Doppelt,
//          version 0.90 18 Oct 1995.
//          URL: http://www.cs.brown.edu/people/amd/
//
//
// VERSION:	1.0
//
// HISTORY:	4/16/96		Initial Version
//
// COPYRIGHT INFORMATION:
//
// This program and the Java source is in the public domain.
// Permission to use, copy, modify, and distribute this software
// and its documentation for NON-COMMERCIAL purposes and
// without fee is hereby granted.
//
//    Copyright 1996
//
//    Rick Brink
//    1266 Brighton-Henrietta Townline Rd.
//    Rochester, NY 14623
//
// DISCLAIMER:
//
// The author claims no responsibility for any damage, direct or indirect,
// to any harware or software as a result of using this program.
//****************************************************************************

import java.awt.Image;
import java.awt.Canvas;
import java.awt.Graphics;
import java.awt.Event;

/**
  * A class representing an button with an Image. ImageButton
  * is a button which supports using images to represent
  * the four states of the button (normal, pressed, disabled, and
  * active).
  *
  * @see ControlPanel
  * @see java.awt.Image
  * @see java.awt.Canvas
  * @see java.awt.Graphics
  * @see java.awt.Event
  *
  * @version 1.0 July 3, 1996
  *
  * @author  Rick Brink
**/
public class ImageButton extends Canvas {
    private protected Image normal_;
    private protected Image pressed_;
    private protected Image disabled_;
    private protected Image active_;
    private protected Image current_;
    private protected boolean enabled_;
    private protected boolean down_;
    private protected boolean activated_;
    private protected int width_;
    private protected int height_;
    private protected String buttonName_;
    private protected ControlPanel controlPanel_;


    /**
      * Construct an image button. An image button is composed of
      * four images, one for each possible state of the button.
      * If null is passed for pressed, disabled, or active, then
      * those states will draw using the normal image.
      *
      * @param normal The Image to use for the button when it is
      *               enabled and not being pressed by the user.
      * @param pressed The Image to use for the button when it is
      *                enabled and being pressed by the user.
      * @param disabled The Image to use when the button is disabled.
      * @param active The Image to use for the button when it is
      *               enabled and activated by the user.
      * @param name A String name for the button
      * @param controlPanel A ControlPanel which contains this
      *                     button.
    **/
    public ImageButton(Image normal, Image pressed, Image disabled,
                       Image active, String name,
                       ControlPanel controlPanel) {

        buttonName_ = name;
        controlPanel_ = controlPanel;
	    width_ = normal.getWidth(this);
	    height_ = normal.getHeight(this);

	    if (pressed != null) {
	        width_ = Math.max(width_, pressed.getWidth(this));
	        height_ = Math.max(height_, pressed.getHeight(this));
	    }

	    if (disabled != null) {
	        width_ = Math.max(width_, disabled.getWidth(this));
	        height_ = Math.max(height_, disabled.getHeight(this));
	    }

	    if (active != null) {
	        width_ = Math.max(width_, active.getWidth(this));
	        height_ = Math.max(height_, active.getHeight(this));
	    }

	    normal_ = normal;
	    pressed_ = pressed;
	    disabled_ = disabled;
	    active_ = active;

	    current_ = normal_;
	    enabled_ = true;
	    down_ = false;
	    activated_ = false;

	    resize(width_, height_);
	    instant();
    }

    /**
      * Returns the name of this ImageButton
    **/
    public String getName() {
        return (buttonName_);
    }

    /**
      * This method is called when the button is pressed. Override it to
      * add behavior to the button.
    **/
    public void action() {
        if (controlPanel_ != null) {
            controlPanel_.buttonAction(buttonName_);
        }
    }

    /**
      * Enable the button.
    **/
    public void enable() {
	    enabled_ = true;
	    current_ = normal_;
	    instant();
    }

    /**
      * Disable the button.
    **/
    public void disable() {
	    enabled_ = false;
    	if (disabled_ != null) {
	        current_ = disabled_;
	        instant();
	    }
    }

    /**
      * Deactivate the button.  Used when more than one button are used
      * together and the selecting of one button causes others to be
      * deactivated.
    **/
    public void deactivate() {
	    if (activated_ && enabled_) {
    	    activated_ = false;
    	    enable();
    	    instant();
	    }
	}

    /**
      * Activate the button.  Used when other events cause a
      * button to be activated, such as a MenuItem which duplicates
      * the functionality of the button.
    **/
    public void activate() {
	    if (enabled_) {
    	    activated_ = true;
    	    current_ = active_;
    	    instant();
	    }
	}

    /**
      * An internal method used to handle mouse down events.
      * It should never be called by the user.
    **/
    public boolean mouseDown(Event event, int x, int y) {
	    if (enabled_) {
	        down_ = true;

	        if (activated_) {
	            activated_ = false;
	        }
	        else {
	            activated_ = true;
	            //action(); //Fixes ImageButton bug, may cause others
	                      //so test further
	        }

	        if (pressed_ != null) {
		        current_ = pressed_;
		        instant();
	        }

	    }
	    return true;
    }

    /**
      * An internal method used to handle mouse up events.
      * It should never be called by the user.
    **/
    public boolean mouseUp(Event event, int x, int y) {
	    if (down_) {
	        down_ = false;

	        if (activated_) {
	            current_ = active_;
	        }
	        else {
	            current_ = normal_;
	        }

	        instant();
	        if((x >= 0) && (y >= 0) &&(x < size().width) && (y < size().height)) {
		        action();
		    }
	    }
	    return true;
    }

    /**
      * Updates the image on screen
    **/
    void instant() {
	    Graphics onscreen = getGraphics();
	    if (onscreen != null) {
	        paint(onscreen);
	    }
    }

    /**
      * This method is used to handle repaints.
      * It should never be calledby the user.
    **/
    public void paint(Graphics graphics) {
	    graphics.drawImage(current_, 0, 0, this);
    }

}

