package math.prime;

import javax.swing.*;
import java.awt.*;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.util.Objects;

public class Primes03 extends JFrame {
    private static final long serialVersionUID = 1L;

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            new Primes03(Color.LIGHT_GRAY, 100, 2, 1000);
            //spiralaArchimedesa2(10000, "WebContent/primes.html");
        });
    }

    public Primes03(Color color, int dlugosc, int ciasnosc,
                    int liczbaPunktow) {
        SpiralaArchimedesaPrimes panel = new SpiralaArchimedesaPrimes(color, dlugosc, ciasnosc,
                liczbaPunktow);
        setLayout(null);
        setPreferredSize(new Dimension(1000, 1000));
        int frameWidth = 1000;
        int frameHeight = 1000;
        setBounds(
                (Toolkit.getDefaultToolkit().getScreenSize().width / 2)
                        - (frameWidth / 2),
                (Toolkit.getDefaultToolkit().getScreenSize().height / 2)
                        - (frameHeight / 2),
                frameWidth, frameHeight);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setTitle("Ramka Graficzna");
        setResizable(true);
        add(panel);
        setVisible(true);
    }

    /**
     * sprawdza czy podana liczba jest liczbą pierwszą
     *
     * @param n int - liczba do zbadania
     * @return boolean - zwraca true jeśli badana liczba jest liczbą
     * pierwszą, a false w przeciwnym wypadku
     */
    public static boolean isPrime(int n) {
        for (int j = 2; Math.pow(j, 2) <= n; j++) {
            if (n % j == 0) {
                return false;
            }
        }
        return true;
    }

    /**
     * Rysuje spiralę Archimedesa
     *
     * @param g2            Graphics2D - obiekt rysujący
     * @param kolor         Color - kolor spirali
     * @param dlugosc       int - dlugosc spirali. Zmiana znaku przed tym
     *                      parametrem zmienia kierunek skrętu spirali
     * @param ciasnosc      int - zmniejsza odstępy między skrętami spirali. Zmiana znaku
     *                      przed tym parametrem zmienia miejsce startu i zakończenia spirali
     * @param liczbaPunktow int liczba punktów do narysowania
     */
    public static void spiralaArchimedesa(Graphics2D g2, Color kolor,
                                          int dlugosc, int ciasnosc, int liczbaPunktow) {
        g2.translate(500, 500);
        g2.setFont(new Font("Dialog", Font.PLAIN, 8));
        //g2.scale(1, -1);
        int sum1 = -2;
        int sum2 = 2;
        int x1 = 0;
        int y1 = 0;
        int x2;
        int y2;
        for (int i = 0; i < liczbaPunktow; i++) {
            double t = i * dlugosc * Math.PI / liczbaPunktow;
            x2 = (int) (ciasnosc * t * Math.cos(t));
            y2 = (int) (ciasnosc * t * Math.sin(t));
            if (isPrime(i)) {
                g2.setColor(Color.RED);
                sum1++;
                g2.drawString(String.valueOf(i), x1 + 1, y1 + 1);
            } else {
                g2.setColor(kolor);
                sum2++;
            }
            g2.drawLine(x1, y1, x2, y2);
            x1 = x2;
            y1 = y2;
        }
        System.out.println(sum1 + " " + sum2);
    }

    public static void spiralaArchimedesa2(int liczbaPunktow, String path) {
        StringBuilder sb = new StringBuilder();
        sb.append("<!DOCTYPE html>\n");
        sb.append("<html>\n");
        sb.append("<head>\n");
        sb.append(
                "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />\n");
        sb.append("<style type=\"text/css\">\n");
        sb.append(".r{\n");
        sb.append("color:#FF0000;\n");
        sb.append("}\n");
        sb.append(".w{\n");
        sb.append("color:#FFFFFF;\n");
        sb.append("}\n");
        sb.append("</style>\n");
        sb.append("</head>\n");
        sb.append("<body>\n");
        sb.append("<section>\n");
        sb.append("<table border=\"1\">\n");
        sb.append("<caption>Rozkład liczb pierwszych</caption>\n");
        int k = 0;
        for (int i = 0; i < liczbaPunktow / 10; i++) {
            sb.append("<tr>\n");
            for (int j = 0; j < 10; j++) {
                k++;
                if (isPrime(k)) {
                    if (k > 1) {
                        sb.append("<td class=\"r\">");
                    } else {
                        sb.append("<td>");
                    }
                } else {
                    sb.append("<td>");
                }
                sb.append(k);
                sb.append("</td>");
            }
            sb.append("</tr>\n");
        }
        sb.append("</table>\n");
        sb.append("</section>\n");
        sb.append("</body>\n");
        sb.append("</html>");
        PrintWriter pw = null;
        try {
            pw = new PrintWriter(path);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        Objects.requireNonNull(pw).write(sb.toString());
        pw.flush();
        pw.close();
    }
}

/**
 * kreslenie spirali Archimedesa;
 */
class SpiralaArchimedesaPrimes extends JPanel {
    private static final long serialVersionUID = 4145929212344860830L;
    private final Color color;
    private final int dlugosc;
    private final int ciasnosc;
    private final int liczbaPunktow;

    public SpiralaArchimedesaPrimes(Color color, int dlugosc, int ciasnosc,
                                    int liczbaPunktow) {
        this.color = color;
        this.dlugosc = dlugosc;
        this.ciasnosc = ciasnosc;
        this.liczbaPunktow = liczbaPunktow;
        setPreferredSize(new Dimension(1000, 1000));
        setBounds(0, 0, 1000, 1000);
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;
        BasicStroke str = new BasicStroke(3);
        g2.setStroke(str);
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);
        Primes03.spiralaArchimedesa(g2, color, dlugosc, ciasnosc,
                liczbaPunktow);
    }
}
