using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;

public class World : MonoBehaviour
{

    public SpecialWeight[] specialTiles;
    public float specialTileSpawnChance;

    public GameObject tilePrefab;
    [SerializeField]
    public HexGrid grid;

    public Tile[] tiles { get { return new List<Tile>(grid.grid.Values).ToArray(); } }

    public Int2[] tileCoords { get { return new List<Int2>(grid.grid.Keys).ToArray(); } }

    public List<GameObject> suns;
    public List<GameObject> gods;

    public Tile.Intelligence allowedIntelligence;

	void Start () {
	}

    /// <summary>
    /// create a random world
    /// </summary>
    public void Generate(ZoneData zone, bool isPlayer = false)
    {
        int tileCount = isPlayer ? 1 : Random.Range(zone.minWorldSize, zone.maxWorldSize);
        var startTileGO = Instantiate(tilePrefab);
        startTileGO.transform.SetParent(this.transform);
        startTileGO.transform.localPosition = Vector3.zero;
        var startTile = startTileGO.GetComponent<Tile>();
        startTile.Generate(new Tile[0], isPlayer);
        grid.Add(startTile);

        var startCoords = new Int2(0, 0);
        var placedCoords = new HashSet<Int2>();
        placedCoords.Add(startCoords);
        while (placedCoords.Count < tileCount)
        {
            // find where to place the next tile
            Int2[] asArray = placedCoords.ToArray();
            var parentCoords = asArray[Random.Range(0, asArray.Length-1)];
            var openNeighbors = HexGrid.Neighbors(parentCoords).Where(n=>!placedCoords.Contains(n)).ToArray();
            if (openNeighbors.Length == 0)
                continue;
            var coords = openNeighbors[Random.Range(0, openNeighbors.Count())];
            placedCoords.Add(coords);

            //place it
            bool isSpecial = isPlayer ? false : Random.Range(0f, 1f) < specialTileSpawnChance;
            var prefab = isSpecial ? SpecialWeight.weightedRandom(specialTiles) : tilePrefab;
            var newTileGO = Instantiate(prefab);
            newTileGO.transform.SetParent(this.transform);
            var newPos = HexGrid.Position(coords);
            newTileGO.transform.localPosition = new Vector3(newPos.x, 0, newPos.y);
            var newTile = newTileGO.GetComponent<Tile>();;
            grid.Add(newTile);
            if (!isSpecial) newTile.Generate(grid.Neighbors(newTile).ToArray(), isPlayer);
        }
    }

    public void AttachSun(GameObject sun, Sun.Orbiter orbiter)
    {
        if (orbiter == Sun.Orbiter.sun)
            this.suns.Add(sun);
        if (orbiter == Sun.Orbiter.god)
            this.gods.Add(sun);
        var pivot = new GameObject("sun pivot");
        pivot.transform.SetParent(transform);
        pivot.transform.localPosition = Vector3.zero;
        sun.transform.SetParent(pivot.transform);
        var orbit = pivot.AddComponent<Orbit>();
        StartCoroutine(orbit.Quickie(5f));
    }
}
