using UnityEngine;
using System.Collections.Generic;
using ScrambleKit.Extensions;

public class MapGenerator : MonoBehaviour 
{

    public int Width;
    public int Height;

    public float XInterval;
    public float YInterval;
    public Vector3 WorldBottomLeft;

    public List<ItemPlacer> ItemPlacers;

    public ChunkLibrary ExitChunks;
    public ChunkLibrary NormalChunks;

    private MonsterPlacer monsterPlacer;

    private Transform[,] chunkmap;

    private class Point
    {
        public int x;
        public int y;
        public Point(int a, int b)
        {
            x = a;
            y = b;
        }
        public override string ToString()
        {
            return "(" + x + ", " + y + ")";
        }
        public override bool Equals(object obj)
        {
            Point o = obj as Point;
            return o != null && x == o.x && y == o.y;
        }
        public override int GetHashCode()
        {
            return x.GetHashCode() + y.GetHashCode();
        }
    }

	void Start () 
	{
        chunkmap = new Transform[Width, Height];
        PlanChunkMap();
        InstantiateChunkMap();

        monsterPlacer = GetComponent<MonsterPlacer>();
        if(monsterPlacer != null)
            monsterPlacer.PlaceMonsters();

        foreach (ItemPlacer placer in ItemPlacers)
            placer.PlaceItems();
    }

    private void InstantiateChunkMap()
    {
        for (int x = 0; x < Width; x++)
            for (int y = 0; y < Width; y++)
            {
                float wx = WorldBottomLeft.x + x * XInterval;
                float wy = WorldBottomLeft.y + y * YInterval;
                Instantiate(chunkmap[x, y], new Vector3(wx, wy, 0), RandomRotation());
            }
    }

    private void PlanChunkMap()
    {
        PlaceExit();
        FillUnusedSpots();
    }

    private void PlaceExit()
    {
        Point exit = new Point(Random.Range(0, Width), Random.Range(0, Height));
        chunkmap[exit.x, exit.y] = ExitChunks.ChunkPrefabs.DrawFromAtRandom();
    }

    private void FillUnusedSpots()
    {
        for (int x = 0; x < Width; x++)
            for (int y = 0; y < Width; y++)
                if (chunkmap[x, y] == null)
                    chunkmap[x, y] = NormalChunks.ChunkPrefabs.DrawFromAtRandom();
    }

    private Quaternion rot90 = Quaternion.Euler(0, 0, 90);
    private Quaternion rot180 = Quaternion.Euler(0, 0, 180);
    private Quaternion rot270 = Quaternion.Euler(0, 0, 270);

    private Quaternion RandomRotation()
    {
        float roll = Random.Range(0f, 1f);
        if (roll < 0.25f)
            return rot90;
        if (roll < 0.5f)
            return rot180;
        if (roll < 0.75f)
            return rot270;

        return Quaternion.identity;
    }
}
