package main.maps;

import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.ArrayList;

import javax.imageio.ImageIO;

import main.DoorTile;
import main.Tile;

public class ImageMap extends Map {

	private static PixelTile[] pixels = { new PixelTile(Tile.STONE_WALL, new Color(100, 100, 100)),
			new PixelTile(Tile.STONE_FLOOR, new Color(127, 127, 127)), new PixelTile(Tile.VOID, new Color(0, 0, 0)),
			new PixelTile(Tile.DOOR, new Color(255, 0, 0)) };

	public DoorTile topDoor;
	public DoorTile leftDoor;
	public DoorTile rightDoor;
	public DoorTile bottomDoor;

	public ImageMap(String path) {
		super(15, 11);

		try {
			BufferedImage img = ImageIO.read(ImageMap.class.getResourceAsStream(path));
			if (img.getWidth() != 15 || img.getHeight() != 11) {
				System.err.println("Odd map size! Use 15x11");
			}
			for (int x = 0; x < img.getWidth(); x++) {
				for (int y = 0; y < img.getHeight(); y++) {
					int id = Tile.VOID;
					int rgb = img.getRGB(x, y);
					for (PixelTile t : pixels) {
						if (t.c == rgb) {
							id = t.id;
							break;
						}
					}
					if (id == Tile.DOOR) {
						DoorTile door = new DoorTile(x, y, this);
						map[x][y] = door;
						if (x == 7) {
							if (y < 5) {
								topDoor = door;
								door.setSide(DoorTile.TOP);
							} else {
								bottomDoor = door;
								door.setSide(DoorTile.BOTTOM);
							}
						}
						if (y == 5) {
							if (x < 7) {
								leftDoor = door;
								door.setSide(DoorTile.LEFT);
							} else {
								rightDoor = door;
								door.setSide(DoorTile.RIGHT);
							}
						}
					} else {
						map[x][y] = new Tile(id, x, y);
					}
					add(map[x][y]);
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	private static class PixelTile {
		public final int c;
		public final int id;

		public PixelTile(int id, Color c) {
			this.c = c.getRGB();
			this.id = id;
		}
	}

	public void generate(ArrayList<ImageMap> dungeon) {
		if (topDoor != null) {
			ImageMap map;
			do {
				map = nextMap();
			} while (!connectDoors(topDoor, map));
			dungeon.add(map);
		}
		if (bottomDoor != null) {
			ImageMap map;
			do {
				map = nextMap();
			} while (!connectDoors(bottomDoor, map));
			dungeon.add(map);
		}
		if (leftDoor != null) {
			ImageMap map;
			do {
				map = nextMap();
			} while (!connectDoors(leftDoor, map));
			dungeon.add(map);
		}
		if (rightDoor != null) {
			ImageMap map;
			do {
				map = nextMap();
			} while (!connectDoors(rightDoor, map));
			dungeon.add(map);
		}
	}

	private ImageMap nextMap() {
		return new ImageMap("/res/images/maps/map" + ((int) (Math.random() * 7) + 1) + ".png");
	}

	private boolean connectDoors(DoorTile door, ImageMap otherMap) {
		switch (door.getSide()) {
		case DoorTile.TOP:
			if (otherMap.bottomDoor == null) {
				return false;
			}
			door.setConnectedDoor(otherMap.bottomDoor);
			otherMap.bottomDoor.setConnectedDoor(door);
			return true;
		case DoorTile.BOTTOM:
			if (otherMap.topDoor == null) {
				return false;
			}
			door.setConnectedDoor(otherMap.topDoor);
			otherMap.topDoor.setConnectedDoor(door);
			return true;
		case DoorTile.LEFT:
			if (otherMap.rightDoor == null) {
				return false;
			}
			door.setConnectedDoor(otherMap.rightDoor);
			otherMap.rightDoor.setConnectedDoor(door);
			return true;
		case DoorTile.RIGHT:
			if (otherMap.leftDoor == null) {
				return false;
			}
			door.setConnectedDoor(otherMap.leftDoor);
			otherMap.leftDoor.setConnectedDoor(door);
			return true;
		}
		return true;
	}
}
