package programming101.calculBeanz;

import java.awt.Button;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import FR.essi.sander.graphix.mvc.Control;
import FR.essi.sander.graphix.mvc.ControlEvent;
import FR.essi.sander.graphix.mvc.ControlEventImpl;
import FR.essi.sander.graphix.mvc.ControlImpl;
import FR.essi.sander.graphix.mvc.ControlListener;


/**
	* Basic calculator button class.  This is the C-component in the 
	* Model-View-Control (MVC) design pattern.
	* This class
	* <UL>
	* <LI><CODE>extends java.awt.Button</CODE><BR>
	* in order to be a visible bean
	* <LI><CODE>implements java.awt.event.ActionListener</CODE><BR>
	* guarantees code for the <CODE>actionPerformed</CODE> method which is invoked by button events
	* <LI><CODE>implments FR.essi.sander.graphix.mvc.Control</CODE><BR>
	* guarantees code implementing management for <CODE>ControlListener</CODE>s
	* </UL>
  * This class is abstract and cannot be instantiated.  It must be subclassed 
  * to implement the following abstract method(s):
  * <UL>
  * <LI><CODE>op</CODE> - the method specific to each button
  * </UL>
	*
	* @author © 1998 Peter T. Sander
	* @version 1.3 (6/04/98)
	* @since 18/03/98
	* @see FR.essi.sander.graphix.mvc.ControlImpl
	*/

public abstract class CalculatorButton extends Button 
				implements ActionListener, Control {
	// visible attributes
	private int width = 24;
	private int height = 24;
	// other variables
	private ControlImpl controlImpl = new ControlImpl();  // manages listeners
	
	/**
		* No-args constructor (needed for JavaBeans).  
		* Registers itself as a listener for button events.
		*/
	public CalculatorButton() {
		super();
		addActionListener(this);
	}

  /**
		* Registers another listener to be informed when a button is clicked.
		* The actual management is delegated to the <CODE>ControlImpl</CODE> object.
		*
		* @param listener listener to add
	*/
	public void addControlListener(ControlListener listener) {
		controlImpl.addControlListener(listener);
	}
	
  /**
		* Removes a listener.
		* The actual management is delegated to the <CODE>ControlImpl</CODE> object.
		*
		* @param listener listener to remove
	*/
	public void removeControlListener(ControlListener listener) {
		controlImpl.removeControlListener(listener);
	}
	
  /**
		* Fires a button event to registered listeners.
		* The actual management is delegated to the <CODE>ControlImpl</CODE> object.
		*
		* @param be button event encapsulating relevant button information
		*/
	public void fireControlEvent(ControlEvent ce) {
  	controlImpl.fireControlEvent(ce);
	}
	
	/**
		* Setter method for button size attributes.
		*
		* @param width width of button
		* @param height height of buttn
		*/
	public void setSize(int width, int height) {
		this.width = width;
		this.height = height;
		super.setSize(width, height);
	}

	/**
		* Getter method for button size attributes.
		*
		* @return dimensions of the button
		*/
	public Dimension getPreferredSize() {
		return new Dimension(width, height);
	}
	
	/**
		* The method specific to each button.
		*
		* @param cumul the current cumulator value
		* @param entry the newly-entered value
		* @param lastButton the button clicked before this one
		* @return new cumulator value
		*/
	public abstract double op(double cumul, double entry, CalculatorButton lastButton);
	
	/**
		* Method guaranteed by implementing the <CODE>ActionListener</CODE>
		* interface.  Invoked by the underlying windowing system to
		* handle button click events.
		*
		* @param ae action event fired by the windowing system
		*/
	public void actionPerformed(ActionEvent ae) {
		fireControlEvent(new ControlEventImpl(this));
	}
}
