using Assets.Scripts.MapGeneration;
using Assets.Scripts.Utils;
using UnityEngine;
using System;

namespace Assets.Scripts
{
    internal class CADelegates
    {
        static System.Random r = new System.Random();

        public static bool CanGrow(Cell cell)
        {
            if (cell.Position.y == 0)
                return true;
            if (cell.Position.x%4 == 0)
                return cell.Position.y < 16 && ((100/cell.Position.y)) > 6 + r.Next(94);
            return false;
        }
    }

    public class GameController : MonoBehaviour
    {
        public static int PoolSize = 256;

        public GameObject Wall;

        private Map _map;

        private ObjectPool _pooledWalls;
        private ObjectPool _pooledActors;
        private ObjectPool _pooledProjectiles;

        private CellularAutomaton _ca;

        private GameObject[] _tiles;

        void Start()
        {
            _map = new Map(128, 128);

            _pooledActors = new ObjectPool(PoolSize);
            _pooledProjectiles = new ObjectPool(PoolSize);
            _pooledWalls = new ObjectPool(PoolSize);

            _ca = new CellularAutomaton(_map, TileType.Wall) {CanGrowRule = CADelegates.CanGrow};
            _tiles = new GameObject[_map.Columns*_map.Rows];

            for (uint i = 0 ; i < _map.Columns * _map.Rows ; i++)
            {
                _tiles[i] = (GameObject) Instantiate(Wall, new Vector3(0, 0, 0), Quaternion.identity);
                _tiles[i].SetActive(false);
            }
        }

        void Update()
        {
            Camera.main.transform.Translate(new Vector3(0.5f * Time.deltaTime, 0, 0));
            var rightBorder = Camera.main.ScreenToWorldPoint(new Vector3(Screen.width,
                Screen.height, 0)).x;
            var leftBorder = Camera.main.ScreenToWorldPoint(new Vector3(0, 0, 0)).x;
            _ca.Step(rightBorder);

            DrawMap(leftBorder, rightBorder);
            // Debug.Log(_map);
        }

        void DrawMap(float min, float max)
        {
            for (uint y = 0; y < _map.Rows; y++)
            {
                for (uint x = (uint) min % _map.Columns; x < max + 1 % _map.Columns; x++)
                {
                    if (_map[x, y] == TileType.Wall)
                    {
                        var tile = _tiles[_map.Columns * y + x];
                        var newX = (uint) (min / _map.Columns) * _map.Columns + x;

                        tile.transform.position = new Vector3(newX, y, 0);
                        tile.SetActive(true);
                    }
                }
            }
        }
    }
}