import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.Line2D;
import java.util.ArrayList;
import java.util.List;

public class ColorManager {
    private List<Observer> observers = new ArrayList<>();

    public void addObserver(Observer observer) {
        observers.add(observer);
    }

    public void removeObserver(Observer observer) {
        observers.remove(observer);
    }

    // Уведомление всех подписчиков
    public void notifyObservers(Color color) {
        for (Observer observer : observers) {
            observer.update(color);
        }
    }

    // Метод, имитирующий изменение статуса игрока
    public void changePlanetsColor(Color color) {
        System.out.println("\nSun color changed: " + color);
        notifyObservers(color);
    }
}

class Planet {
    public Point cord;
    public Point sunCord;
    public double orbRad;
    public double orbSpeed;
    public double orbAngle;
    public int planetRadius;

    public Planet(int sunX, int sunY, double orbRad, double orbSpeed, double orbAngle, int planetRadius) {
        this.cord = new Point(
                (int) (sunX + orbRad * Math.cos(orbAngle)),
                (int) (sunY + orbRad * Math.sin(orbAngle))
        );
        this.sunCord = new Point(sunX, sunY);
        this.orbRad = orbRad;
        this.orbSpeed = Math.toRadians(orbSpeed);
        this.orbAngle = orbAngle;
        this.planetRadius = planetRadius;
    }

    public void updateCord() {
        cord.x = (int) (sunCord.x + orbRad * Math.cos(orbAngle));
        cord.y = (int) (sunCord.y + orbRad * Math.sin(orbAngle));
    }

    public void updateAngle() {
        orbAngle += orbSpeed;
    }
}

class RotatingLine extends JPanel implements ActionListener {
    private Planet[] planets;
    private final int W;
    private final int H;

    private final Color[] colors = new Color [] { Color.RED, Color.BLUE, Color.GREEN, Color.ORANGE};

    private final double length = 300;
    private final Point pivot;
    private final double delta = Math.toRadians(1.0);
    private double angle = 0.0;
    private Line2D line;

    private final Timer timer;

    public RotatingLine(int width, int height, Planet[] planets) {
        this.planets = planets;
        W = width;
        H = height;
        setPreferredSize(new Dimension(W, H));
        setBackground(Color.WHITE);
        pivot = new Point(W/2, H/2);
        line = new Line2D.Double(
                pivot.x,
                pivot.y,
                pivot.x + length * Math.cos(angle),
                pivot.y + length * Math.sin(angle)
        );
        timer = new Timer(10, this);
        timer.start();
    }

    @Override
    public void actionPerformed(ActionEvent arg0) {
        angle += delta;
        for (Planet planet : planets) {
            planet.updateAngle();
        }
        repaint();
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D gr = (Graphics2D) g;
        gr.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

        double x = pivot.x + length * Math.cos(angle);
        double y = pivot.y + length * Math.sin(angle);
        for (Planet planet : planets) {
            planet.updateCord();
        }

        double deg = Math.toDegrees(angle);
        deg = (deg % 360);
        int sectorCount = colors.length;
        double sectorSize = 360.0 / sectorCount;
        int sector = (int)(deg / sectorSize) % sectorCount;
        Color color = colors[sector];

//        gr.setStroke(new BasicStroke(4f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
//        gr.setColor(color);
//        line.setLine(pivot.x, pivot.y, x, y);
//        gr.draw(line);

        int r = 30;
        gr.setColor(color);
        gr.fillOval(pivot.x - r, pivot.y - r, r * 2, r * 2);
        gr.setColor(color.darker().darker());
        for (Planet planet : planets) {
            color = color.darker();
            gr.setColor(color);
            gr.fillOval(
                    planet.cord.x - planet.planetRadius,
                    planet.cord.y - planet.planetRadius,
                    planet.planetRadius * 2,
                    planet.planetRadius * 2
            );
        }

        gr.setFont(gr.getFont().deriveFont(20f));
        gr.setColor(Color.BLACK);
        gr.drawString("Angle: " + String.format("%.1f°", deg), 20, 40);
    }
}

public class Main {
    public static void main(String[] args) {
        JFrame fr = new JFrame("Lab10-Var4");
        fr.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        int W = 1000;
        int H = 1000;
        Planet mercury = new Planet(W/2, H/2, 100, 2.0, 0.0, 3);
        Planet venus = new Planet(W/2, H/2, 150, 1.4, 0.0, 7);
        Planet earth = new Planet(W/2, H/2, 200, 1.0, 0.0, 7);
        Planet mars = new Planet(W/2, H/2, 250, 0.7, 0.0, 5);
        Planet jupiter = new Planet(W/2, H/2, 350, 0.3, 0.0, 15);
        Planet[] planets = { mercury, venus, earth, mars, jupiter };
        RotatingLine panel = new RotatingLine(W, H, planets);
        fr.setVisible(true);
        fr.getContentPane().add(panel);
        fr.setLocationRelativeTo(null);
        fr.pack();
    }
}
