package math.fractals;

import math.shapes.Triangle;

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

public class Fractal04 extends JFrame {
    private static final long serialVersionUID = 431281611636634328L;
    public static final int fw = 1000;
    public static final int fh = 1000;

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> new Fractal04(new SierpinskiGasketPanel()));
    }

    public Fractal04(JComponent comp) {
        setLayout(null);
        setPreferredSize(new Dimension(fw, fh));
        setBounds((Toolkit.getDefaultToolkit().getScreenSize().width / 2)
                        - (fw / 2),
                (Toolkit.getDefaultToolkit().getScreenSize().height / 2)
                        - (fh / 2), fw, fh);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setTitle("Ramka Graficzna");
        //	setResizable(false);
        JPanel panel = (JPanel) comp;
        panel.setLocation((fw - panel.getWidth()) / 2,
                (fh - panel.getHeight()) / 2);
        add(panel);
        setVisible(true);
    }
}

class SierpinskiGasketPanel extends JPanel {
    private static final long serialVersionUID = 5218506428064759030L;
    private static final int w = 800;
    private static final int h = 800;
    private final Triangle vs = new Triangle(0f, h, w, h, (w / 2),
            (float) (h - Math.sqrt(3) / 2f * h));

    public SierpinskiGasketPanel() {
        setPreferredSize(new Dimension(w, h));
        setSize(w, h);
        setBackground(Color.WHITE);
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);
        g2.drawRect(0, 0, w - 1, h - 1);
        drawSierpinskiGasket(g2, Color.BLUE, 6);
    }

    public void drawSierpinskiGasket(Graphics2D g2, Color color, int steps) {
        g2.setColor(color);
        fillSierpinskiGasket(g2, vs);
        g2.setColor(Color.WHITE);
        calcSierpinskiGasket(g2, new Triangle(vs.x1, vs.y1, vs.x2, vs.y2,
                vs.x3, vs.y3), steps);
        g2.setColor(Color.BLACK);
    }

    public void fillSierpinskiGasket(Graphics2D g2, Triangle vs) {
        g2.fill(vs);
    }

    public void calcSierpinskiGasket(Graphics2D g2, Triangle vd, int steps) {
        if (steps == 0) {
            return;
        }
        steps -= 1;
        Triangle coords = new Triangle(vd.x3, vd.y2, (vd.x3 + vd.x2) / 2,
                (vd.y3 + vd.y1) / 2f, (vd.x1 + vd.x3) / 2f,
                (vd.y3 + vd.y1) / 2f);
        fillSierpinskiGasket(g2, coords);
        Triangle t1 = new Triangle(vd.x1, vd.y1, vd.x3, vd.y2,
                (vd.x1 + vd.x3) / 2, (vd.y3 + vd.y1) / 2);
        calcSierpinskiGasket(g2, t1, steps);
        Triangle t2 = new Triangle(vd.x3, vd.y2, vd.x2, vd.y2,
                (vd.x3 + vd.x2) / 2, (vd.y3 + vd.y1) / 2);
        calcSierpinskiGasket(g2, t2, steps);
        Triangle t3 = new Triangle((vd.x1 + vd.x3) / 2, (vd.y3 + vd.y1) / 2,
                (vd.x3 + vd.x2) / 2, (vd.y3 + vd.y1) / 2, vd.x3, vd.y3);
        calcSierpinskiGasket(g2, t3, steps);
    }
}