package OOPLS;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.util.Random;
import javax.swing.JPanel;
import javax.swing.Timer;

public class DroppedBallPanelWithProperties extends JPanel 
                              implements ActionListener {
    final int FREQUENCY = 30; // Timer events per second.
    DroppedBall ball = new DroppedBall();
    Timer timer = new Timer(1000/FREQUENCY,this);
    boolean moving = false,
            bounced = false;
    PropertyChangeSupport pcs = 
        new PropertyChangeSupport(this);
    public DroppedBallPanelWithProperties() {
        ball.setRectangle(getBounds());
        addComponentListener(new ComponentAdapter() {
            public void componentResized(ComponentEvent e) {
                stop();
                ball.setRectangle(getBounds());
                start();
            }
        });
        start();
    }
    public void addPropertyChangeListener(
        PropertyChangeListener pcl) {
        pcs.addPropertyChangeListener(pcl);
    }
    public void actionPerformed(ActionEvent e) {
        ball.cycle(1000/FREQUENCY);
        repaint();
        if (ball.bounced())
            pcs.firePropertyChange("bounce", false, true);
    }
    public void paint(Graphics g) {
        super.paint(g);
        ball.draw(g);
    }
    public void drop() {
        if (!moving) start();
        Random rnd = new Random();
        ball.setColor(
            new Color(rnd.nextFloat(),
                      rnd.nextFloat(),
                      rnd.nextFloat())
        );
        ball.randomizeLocationAndSpeed();
    }
    public void start() {
        if (!moving) {
            timer.addActionListener(this);
            timer.start(); 
            moving = true;
            pcs.firePropertyChange(new PropertyChangeEvent(
                this,"moving",false,true));
        }
    }
    public void stop() {
        if (moving) {
            timer.removeActionListener(this);
            timer.stop(); 
            moving = false;
            pcs.firePropertyChange(new PropertyChangeEvent(
                this,"moving",true,false));    
        }
    }    
    public void setColor(Color c) {
        ball.setColor(c);
    }
    public Color getColor() {
        return ball.getColor();
    }
    public Dimension getPreferredSize() {
        return new Dimension(400,300);
    }
    public Dimension getMinimumSize() {
        return new Dimension(200,150);
    }
    public Dimension getMaximumSize() {
        return new Dimension(1024,768);
    }
    public boolean getMoving() {
        return moving;
    }
    public void setMoving(boolean isMoving) {
        if (moving != isMoving) {
            if (moving) stop();
            else start();
        }
    }
    public boolean getBounce() {
        return ball.bounced();
    }
}
