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

public class Flocon extends Polygon {

    Vector2[] ptable;
    
    public Flocon() {
        super();
    }

    private int floc(int n, int offset, int aoffset) {
        if (n < 0) return offset+1;
        Vector2 local = ptable[offset].toLocal(ptable[offset+1]);
        local.div(3);

        Vector2 s1 = Vector2.add(ptable[offset], local);
        ptable[offset+1] = s1;

        if (n > 0) {
            offset = floc(n-1, offset, aoffset);
        } else offset++;

        Vector2 s2 = Vector2.add(s1, Vector2.rotate(local, -60 - aoffset));
        ptable[offset+1] = s2;

        if (n > 0) {
            offset = floc(n-1, offset, aoffset);
        } else offset++;

        Vector2 s3 = Vector2.add(s2, Vector2.rotate(local, 60 + aoffset));
        ptable[offset+1] = s3;

        if (n > 0) {
            offset = floc(n-1, offset, aoffset);
        } else offset++;

        Vector2 s4 = Vector2.add(s3, local);
        ptable[offset+1] = s4;
        
        if (n > 0) {
            offset = floc(n-1, offset, aoffset);
        } else offset++;

        return offset;
    }

    public void createFloc(int x, int y, int r, int n, int aoffset) {
        int size = 4;
        for (int i = 0; i < n; i++) size = size * 4 - 3;
        this.ptable = new Vector2[size];
        int offset = 0;

        ptable[0] = Vector2.rotate(new Vector2(0, -r),-60).add(new Vector2(x, y));
        ptable[1] = Vector2.rotate(new Vector2(0, -r), 60).add(new Vector2(x, y));
        offset = floc(n-1, offset, aoffset);

        ptable[offset+1] = Vector2.rotate(new Vector2(0, -r), 180).add(new Vector2(x, y));
        offset = floc(n-1, offset, aoffset);

        ptable[offset+1] = Vector2.rotate(new Vector2(0, -r), -60).add(new Vector2(x, y));
        floc(n-1, offset, aoffset);


        for (Vector2 v : ptable) {
            addPoint(v.x, v.y);
        }
    }

    public static void main(String[] args) {
        

        JFrame f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setLocation(100, 100);
        f.setSize(1200, 1200);

        Flocon p = new Flocon();
        p.createFloc(f.getWidth() / 2, f.getHeight() / 2 - 100, 500, 4, 0);

        FloconPanel fp = new FloconPanel(p);
        
        f.add(fp);

        f.setVisible(true);

        int a = 0;
        while(true) {
            try {
                Thread.sleep(16);
            } catch (Exception e) {

            }

            a += 1;
            
            p.xpoints = new int[0];
            p.ypoints = new int[0];
            p.npoints = 0;
            p.createFloc(f.getWidth() / 2, f.getHeight() / 2 - 100, 500, 4, a);
            fp.repaint();
        }
    }
}
