package de.miaurizius.jgame2d.tile;

import de.miaurizius.jgame2d.core.Boot;
import de.miaurizius.jgame2d.core.GamePanel;
import de.miaurizius.jgame2d.core.Utility;
import de.miaurizius.jgame2d.core.enums.Map;

import javax.imageio.ImageIO;
import java.awt.*;
import java.io.*;
import java.util.ArrayList;
import java.util.logging.Level;

public class TileManager {

    GamePanel panel;
    public Tile[] tile;
    public int[][][] mapTileNum;
    ArrayList<String> filesNames = new ArrayList<>();
    ArrayList<String> collisionStatus = new ArrayList<>();

    public TileManager(GamePanel panel) throws IOException {
        this.panel = panel;

        InputStream is = new FileInputStream("assets/maps/tiledata");
        BufferedReader br = new BufferedReader(new InputStreamReader(is));

        // READ TILE DATA FROM FILE
        try {
            String line;
            while((line = br.readLine()) != null) {
                filesNames.add(line);
                collisionStatus.add(br.readLine());
            }
            br.close();
        } catch(IOException e) {
            Boot.logger.log(Level.SEVERE, "Could not read tile data file", e);
        }

        tile = new Tile[filesNames.size()];
        getTileImage();

        // GETTING WORLD SIZES
        is = new FileInputStream("assets/maps/editoredmap.map");
        br = new BufferedReader(new InputStreamReader(is));
        try {
            String line = br.readLine();
            String maxTile[] = line.split(" ");
            panel.maxWorldCol = maxTile.length;
            panel.maxWorldRow = maxTile.length;
            mapTileNum = new int[Map.values().length][panel.maxWorldCol][panel.maxWorldRow];

            br.close();
        } catch(IOException e) {
            Boot.logger.log(Level.SEVERE, "Could not read map size data", e);
        }

        for(Map m : Map.values()) loadMap(m);
    }

    public void initializeTile(int i, String name, boolean col) {
        try {
            tile[i] = new Tile();
            tile[i].image = ImageIO.read(new FileInputStream("assets/tiles/" + name));
            tile[i].collision = col;
        } catch(IOException e) {
            Boot.logger.log(Level.SEVERE, "Could not load tile", e);
        }
    }

    public void getTileImage() {

        for(int i = 0; i < filesNames.size(); i++) {
            String fileName;
            boolean collision;
            fileName = filesNames.get(i);
            collision = Boolean.parseBoolean(collisionStatus.get(i));
            initializeTile(i, fileName, collision);
        }

        for (Tile tile : tile) {
            if(tile == null) continue;
            tile.image = Utility.scaleImage(tile.image, panel.tileSize, panel.tileSize);
        }
    }

    public void loadMap(Map map) {
        try {
            InputStream stream = new FileInputStream("assets/maps/"+map.getName()+".map");
            BufferedReader bReader = new BufferedReader(new InputStreamReader(stream));
            int col = 0;
            int row = 0;
            while(col < panel.maxWorldCol && row < panel.maxWorldRow) {
                String line = bReader.readLine();
                while(col < panel.maxWorldCol) {
                    String[] numbers = line.split(" ");
                    int num = Integer.parseInt(numbers[col]);
                    mapTileNum[map.getIndex()][col][row] = num;
                    col++;
                }
                if(col == panel.maxWorldCol) {
                    col = 0;
                    row++;
                }
            }
            bReader.close();
        } catch(Exception e) {
            Boot.logger.log(Level.SEVERE, "Could not load map", e);
        }
    }

    public void draw(Graphics2D graphics2D) {
        int worldCol = 0;
        int worldRow = 0;

        while(worldCol < panel.maxWorldCol && worldRow < panel.maxWorldRow) {
            int tileNum = mapTileNum[panel.currentMap.getIndex()][worldCol][worldRow];

            int worldX = worldCol * panel.tileSize;
            int worldY = worldRow * panel.tileSize;
            int screenX = worldX - panel.player.worldX + panel.player.screenX;
            int screenY = worldY - panel.player.worldY + panel.player.screenY;

            if(worldX + panel.tileSize > panel.player.worldX - panel.player.screenX &&
               worldX - panel.tileSize < panel.player.worldX + panel.player.screenX &&
               worldY + panel.tileSize > panel.player.worldY - panel.player.screenY &&
               worldY - panel.tileSize < panel.player.worldY + panel.player.screenY
            ) {
                graphics2D.drawImage(tile[tileNum].image, screenX, screenY, null);

//                if(panel.keyH.debug && tile[tileNum].collision) {
//                    graphics2D.setColor(new Color(255, 0, 0, 70));
//                    graphics2D.fillRect(worldX - panel.player.worldX + panel.player.screenX, worldY - panel.player.worldY + panel.player.screenY, panel.tileSize, panel.tileSize);
//                }
            }

            worldCol++;

            if(worldCol == panel.maxWorldCol) {
                worldCol = 0;
                worldRow++;
            }
        }
        if(panel.keyH.debug) {
            graphics2D.setColor(new Color(255, 0, 0, 70));
            for(int i = 0; i < panel.pFinder.pathList.size(); i++) {
                int worldX = panel.pFinder.pathList.get(i).col * panel.tileSize;
                int worldY = panel.pFinder.pathList.get(i).row * panel.tileSize;
                int screenX = worldX - panel.player.worldX + panel.player.screenX;
                int screenY = worldY - panel.player.worldY + panel.player.screenY;

                graphics2D.fillRect(screenX, screenY, panel.tileSize, panel.tileSize);
            }
        }
    }

}
