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

public class SolarSystem extends JComponent implements ActionListener {
    private static final int DEFAULT_WIDTH = 600;
    private static final int DEFAULT_HEIGHT = 400;

    private Body[] bodies;
    private int framesUntilRepaint = 1;

    // Constructs the component for representing the solar system
    public SolarSystem() {
        setPreferredSize(new Dimension(DEFAULT_WIDTH, DEFAULT_HEIGHT));
        setBackground(Color.WHITE);
        bodies = new Body[] {
            addBody(1.9891e30,   0.000, 0.0000,  Color.YELLOW, "Sun"),
            addBody(3.3022e23,  57.909, 0.4787,  Color.CYAN,   "Mercury"),
            addBody(4.8685e24, 108.209, 0.3502,  Color.GREEN,  "Venus"),
            addBody(5.9736e24, 149.598, 0.29783, Color.BLUE,   "Earth"),
            addBody(6.4185e23, 227.939, 0.24077, Color.RED,    "Mars"),
            addBody(1.0000e20,  49.397, 0.7051,  Color.MAGENTA,"Encke"), // Comet Encke
        };

        Timer tim = new Timer(5, system);
        tim.start();
    }

    // Returns the number of bodies in this solar system
    public int getElementCount() {
        return bodies.length;
    }

    // Returns the body in the solar system indexed as given.
    // The index should range between 0 and getElementCount() - 1
    public Body getElement(int index) {
        return bodies[index];
    }

    // You won't need to use this method: It handles processing
    // each frame
    public void actionPerformed(ActionEvent event) {
        for(Body b : bodies) b.updateDirection(this);
        for(Body b : bodies) b.step();
        framesUntilRepaint--;
        if(framesUntilRepaint <= 0) {
            framesUntilRepaint = 5;
            repaint(20);
        }
    }

    // You won't need to use this method: It is invoked whenever
    // the screen needs to be redrawn.
    public void paintComponent(Graphics g) {
        g.setColor(Color.WHITE);
        g.fillRect(0, 0, getWidth(), getHeight());
        for(Body b : bodies) b.paint(g);
    }
    
    // Creates a body with the given parameters.
    private Body addBody(double mass, double dist, double vel,
            Color hue, String name) {
        return new Body(DEFAULT_WIDTH / 2, DEFAULT_HEIGHT / 2 - dist,
            hue, mass, name, vel, 0);
    }

    // Creates a window with a SolarSystem component inside it.
    public static void main(String[] args) {
        JFrame frame = new JFrame("Solar System");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(new SolarSystem());
        frame.pack();
        frame.setVisible(true);
    }
}
