package math.fractals;

import math.utils.IOUtil;

import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.image.WritableRaster;

public class GridPanel extends JPanel {
    private static final long serialVersionUID = -5183600697149041028L;
    private static final int w = 512;
    private static final int h = 512;
    private final BufferedImage grid;

    public GridPanel() {
        BufferedImage mapa = IOUtil.fileToBimage("assets/fractals/mapa.jpg");
        int bw1 = mapa.getWidth();
        int bh1 = mapa.getHeight();
        grid = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
        WritableRaster tRaster = grid.getRaster();
        int[] trgb = {255, 255, 255, 255};
        for (int i = 0; i < w; i++) {
            for (int j = 0; j < h; j++) {
                tRaster.setPixel(i, j, trgb);
            }
        }
        grid.getGraphics().drawImage(mapa, (w - bw1) / 2, (h - bh1) / 2, this);
        setPreferredSize(new Dimension(w, h));
        setBackground(Color.WHITE);
        setSize(w, h);
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;
        g2.drawImage(grid, 0, 0, this);
        System.out.println(countCells(grid, 32));
        drawGrid(g2, 16);
    }

    // scale = liczba oczek siatki w poziomie
    // 2 oznacza siatke 2 x 2, 3 = 3 x 3, etc
    public void drawGrid(Graphics2D g2, int scale) {
        BasicStroke stroke = new BasicStroke(1.0f);
        g2.setStroke(stroke);
        g2.drawLine(0, 0, w, 0);
        g2.drawLine(w - 1, 1, w - 1, h - 1);
        g2.drawLine(w - 1, h - 1, 1, h - 1);
        g2.drawLine(0, h, 0, 0);
        BasicStroke stroke1 = new BasicStroke(0.2f);
        g2.setStroke(stroke1);
        drawPart(g2, scale);
    }

    // metoda pomocnicza do metody drawGrid
    public void drawPart(Graphics2D g2, int scale) {
        int szer = w / scale;
        int len = szer * scale;
        int z = 0;// polozenie linii
        for (int i = 0; i <= scale; i++) {
            g2.drawLine(0, z, len, z);
            z += szer;
        }
        z = 0;
        for (int k = 0; k <= scale; k++) {
            g2.drawLine(z, 0, z, len);
            z += szer;
        }
    }

    // gridSize = 2 oznacza siatke, 2 x 2
    // gridSize 4 oznacza siatke 4 x 4, etc.
    public int countCells(BufferedImage bimage, int gridSize) {
        int canvasWidth = w;
        int cellWidth = canvasWidth / gridSize;
        //System.out.println("oczko siatki w pikselach: " + cellWidth);
        WritableRaster raster = bimage.getRaster();
        int[] rgb = new int[4];
        int sum = 0;
        for (int i = 0; i < canvasWidth; i += cellWidth) {
            for (int j = 0; j < canvasWidth; j += cellWidth) {
                br:
                for (int k = i; k < i + cellWidth; k++) {
                    for (int m = j; m < j + cellWidth; m++) {
                        raster.getPixel(k, m, rgb);
                        if ((rgb[0] < 200) || (rgb[1] < 200) || (rgb[2] < 200)) {
                            sum++;
                            break br;
                        }
                    }
                }
            }
        }
        return sum;
    }
}