package math.autos;

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

public class AutomatonPanel extends JPanel {
    private static final long serialVersionUID = 4757924446662683415L;
    private static final int w = 800;
    private static final int h = 800;
    private static final int liczbaPol = 100;
    private static final int szer = 8;//szerokosc komorki
    private static final int len = szer * liczbaPol;
    private final int autoNumber;
    private final int[] kombStart;
    private final Ksztalt ksztalt;
    private final Color kolor;
    private final int[][] autos;

    public AutomatonPanel(int autoNumber, int[] kombStart, Ksztalt ksztalt,
                          Color kolor) {
        this.autoNumber = autoNumber;
        this.kombStart = kombStart;
        this.ksztalt = ksztalt;
        this.kolor = kolor;
        autos = new int[liczbaPol * 2][liczbaPol * 2];
        int startCell = liczbaPol;
        autos[0][startCell - 1] = kombStart[0];
        autos[0][startCell] = kombStart[1];
        autos[0][startCell + 1] = kombStart[2];
        for (int m = 1; m < liczbaPol * 2 - 1; m++) {
            for (int n = 1; n < liczbaPol * 2 - 1; n++) {
                int[] arr = new int[3];
                arr[0] = this.autos[m - 1][n - 1];
                arr[1] = this.autos[m - 1][n];
                arr[2] = this.autos[m - 1][n + 1];
                this.autos[m][n] = nextValue(arr, autoNumber);
            }
        }
        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.setColor(new Color(200, 200, 200));
        int z = 0;// polozenie linii
        for (int i = 0; i <= liczbaPol; i++) {
            g2.drawLine(0, z, len, z);
            z += szer;
        }
        z = 0;
        for (int k = 0; k <= liczbaPol; k++) {
            g2.drawLine(z, 0, z, len);
            z += szer;
        }
        g2.setColor(kolor);
        for (int m = 0; m < liczbaPol; m++) {
            for (int j = liczbaPol / 2; j < liczbaPol + liczbaPol / 2; j++) {
                if (autos[m][j] == 1) {
                    int y = m * szer;
                    int x = (j - liczbaPol / 2) * szer;
                    switch (ksztalt) {
                        case KOLO:
                            g2.fillOval(x, y, szer, szer);
                            break;
                        case KWADRAT:
                            g2.fillRect(x, y, szer, szer);
                    }
                }
            }
        }
    }

    public int order(int[] array) {
        int val = 0;
        int len = array.length;
        for (int i = 0; i < len; i++) {
            if (array[len - 1 - i] == 1) {
                val += (int) (Math.pow(2, i));
            }
        }
        return val;
    }

    public int nextValue(int[] array, int automatNumber) {
        int val = order(array);
        String nbin = Integer.toBinaryString(automatNumber);
        if (nbin.length() < 8) {
            int diff = 8 - nbin.length();
            for (int i = 0; i < diff; i++) {
                nbin = "0".concat(nbin);
            }
        }
        int len = nbin.length();
        String sval = nbin.substring(len - val - 1, len - val);
        return Integer.parseInt(sval);
    }

    public int getAutoNumber() {
        return autoNumber;
    }

    public int[] getKombStart() {
        return kombStart;
    }

    public Ksztalt getKsztalt() {
        return ksztalt;
    }
}
