import java.awt.*;
import java.applet.*;
import java.awt.event.*;
import javax.swing.*;

class Main {
  public static void main(String[] args) {
    JFrame frame = new JFrame("Click Counter Demo");
    ClickCounterControl theInterface = new ClickCounterControl();
    theInterface.init();
    frame.getContentPane().add(theInterface, "Center");
    frame.pack();
    frame.setVisible(true);
  }
}

class ClickCounterView {
  
  // ** fields **
  private JButton incButton;
  private JButton resetButton;
  private JButton decButton;
  private JLabel valueDisplay;
  
  // ** constructors **
  public ClickCounterView(JApplet itsApplet) {
    JPanel controlPanel = new JPanel();
    
    itsApplet.getContentPane().setLayout(new BorderLayout());
    valueDisplay = new JLabel("000", JLabel.CENTER);
    
    itsApplet.getContentPane().add(valueDisplay, "Center");
    
    incButton = new JButton("+");
    resetButton = new JButton("0");
    decButton = new JButton("-");
    
    controlPanel.add(incButton);
    controlPanel.add(resetButton);
    controlPanel.add(decButton);
    itsApplet.getContentPane().add(controlPanel, "South");
  } 
  
  // ** methods **
  public void setValueDisplay(String setTo) {
    valueDisplay.setText(setTo);
  }
  
  public void addIncListener(ActionListener a) { 
    incButton.addActionListener(a);
  }
  
  public void addDecListener(ActionListener a) { 
    decButton.addActionListener(a);
  }
  
  public void addResetListener(ActionListener a) { 
    resetButton.addActionListener(a);
  }
  
  public void setMinimumState() {
    incButton.setEnabled(true);
    resetButton.setEnabled(false);
    decButton.setEnabled(false);
  }
  
  public void setCountingState() {
    incButton.setEnabled(true);
    resetButton.setEnabled(true);
    decButton.setEnabled(true);
  }
  
  public void setMaximumState() {
    incButton.setEnabled(false);
    resetButton.setEnabled(true);
    decButton.setEnabled(true);
  }
}
class ClickCounter {
  
  private static final int MAXIMUM = 999;
  private static final int MINIMUM = 0;
  private static final int STRING_WIDTH = 3;

  // ** fields **
  private int count = MINIMUM;
  
  // ** constructor **
  public ClickCounter() {}
  
  // ** methods **
  public boolean isAtMinimum() { return count == MINIMUM; }
  public boolean isAtMaximum() { return count == MAXIMUM; }
  
  public int inc() { 
    if (! this.isAtMaximum()) count++; 
    return count;
  }

  public int dec() { 
    if (! this.isAtMinimum()) count--; 
    return count;
  }
  
  public void reset() { count = MINIMUM; }
  
  public int getCount() { return count; }
  
  // ** toString() **
  public String toString() {
    // returns low-order digits of decimal representation of counter value 
    // STRING_WIDTH specifies the number of digits
    StringBuffer buffer = 
    new StringBuffer(Integer.toString(count));
    while (buffer.length() < STRING_WIDTH) buffer.insert(0,0);
    return buffer.toString();
  }
}

class ClickCounterControl extends JApplet {
  
  // ** fields **
  private ClickCounter counter;
  private ClickCounterView view;
  
  // ** constructors **
  // relying on default constructor
  
  // ** methods **
  // relying on inheritance from JApplet
  
  public void init() {
    counter = new ClickCounter();
    view = new ClickCounterView(this);
    view.setMinimumState();
    view.setValueDisplay(counter.toString());
    
    
    view.addIncListener(new ActionListener(){
      public void actionPerformed(ActionEvent event) {
        if (counter.isAtMaximum()) return;
        if (counter.isAtMinimum()) view.setCountingState();
        counter.inc();
        view.setValueDisplay(counter.toString());
        if (counter.isAtMaximum()) view.setMaximumState();
      }
    });
    
    view.addDecListener(new ActionListener(){
      public void actionPerformed(ActionEvent event) {
        if (counter.isAtMinimum()) return;
        if (counter.isAtMaximum()) view.setCountingState();
        counter.dec();
        view.setValueDisplay(counter.toString());
        if (counter.isAtMinimum()) view.setMinimumState();
      }
    });
    
    view.addResetListener(new ActionListener(){
      public void actionPerformed(ActionEvent event) {
        counter.reset();
        view.setMinimumState();
        view.setValueDisplay(counter.toString());
      }
    });
  } 
}
