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

public class Hints : MonoBehaviour {

    public PointAtTarget arrow
    {
        get
        {
            if (_arrow == null)
                _arrow = Game.player.GetComponentInChildren<PointAtTarget>();
            return _arrow;
        }
    }
    PointAtTarget _arrow;
    public PointAtTarget.Target target { get { return arrow.target; } set { arrow.target = value; } }

    public Text textField;
    public Text errorField;
    public int maxErrors;
    public float errorDisplayTime;
    public Color activeColor;

    public GameObject endscreen;
    public AudioSource audioSource;

    int errorCount;
    float lastErrorTime;
    int displayedFlags;
    float lastMessageTime;

	void Start () {
        textField.color = activeColor;
        MouseDragAndAttach.OnFailedConnect += OnFailedWorldConnection;
	}

    void OnFailedWorldConnection(MouseDragAndAttach.ConnectionFailedReason reason)
    {
        if (reason == MouseDragAndAttach.ConnectionFailedReason.distance)
        {
            StartCoroutine(DisplayError("A world prospers only in unity. Bring the new closer."));
        }
        if (reason == MouseDragAndAttach.ConnectionFailedReason.overlap)
        {
            StartCoroutine(DisplayError("Life needs space to thrive. Overlapping worlds will not connect."));
        }
    }

    public void ShowError(string error)
    {
        StartCoroutine(DisplayError(error));
    }

    IEnumerator DisplayError(string error)
    {
        errorField.CrossFadeAlpha(0, 0.1f, true);
        errorField.text += "\n" + error;
        if (++errorCount > maxErrors)
        {
            // cut out first error
            int index = errorField.text.IndexOf('\n');
            errorField.text = errorField.text.Substring(index + 1);
        }
        errorField.CrossFadeAlpha(1, 0.1f, true);
        lastErrorTime = Time.time;
        yield return new WaitForSecondsRealtime(errorDisplayTime);
        if (Time.time - lastErrorTime > errorDisplayTime)
        {
            errorField.CrossFadeAlpha(0, 0.1f, true);
            errorField.text = "";
        }
    }

    IEnumerator UpdateText(string newText)
    {
        lastMessageTime = Time.time;
        textField.CrossFadeAlpha(0, 0.4f, true);
        yield return new WaitForSeconds(0.5f);
        textField.text = newText;
        textField.CrossFadeAlpha(1f, 0.4f, true);
    }

    void Update()
    {
        if (
            ((displayedFlags & 1) == 0) &&
            Time.timeSinceLevelLoad > 10 &&
            Game.player.tiles.Length == 1
            )
        {
            displayedFlags |= 1;
            StartCoroutine(UpdateText("You are World.\nAttract ground."));
            target = PointAtTarget.Target.tile;
        }
        if (
            ((displayedFlags & 4) == 0) &&
            ((displayedFlags & 1) != 0) &&
            Time.timeSinceLevelLoad > 15 &&
            Game.player.tiles.Length == 1
            )
        {
            displayedFlags |= 4;
            StartCoroutine(UpdateText("You are World. Move with WASD.\nAttract ground. Click and drag.\n"));
        }
        if (
            (displayedFlags & 2) == 0 &&
            Game.player.tiles.Length > 1
            )
        {
            displayedFlags |= 2;
            StartCoroutine(UpdateText("Life requires care.\nGather heat and water."));
            target = PointAtTarget.Target.none;
        }
        if (
            (displayedFlags & 8) == 0 &&
            (displayedFlags & 2) != 0 &&
            ((Time.time - lastMessageTime > 30) || (displayedFlags & 64) != 0)
            )
        {
            displayedFlags |= 8;
            StartCoroutine(UpdateText("Worlds cool. Keep a totem of heat around.\nWater flows downhill."));
        }
        if (
            (displayedFlags & 16) == 0 &&
            (displayedFlags & 8) != 0 &&
            (Time.time - lastMessageTime > 30)
            )
        {
            displayedFlags |= 16;
            StartCoroutine(UpdateText("Temperatures between -10 and 50 are ideal.\nAvoid oceans and arid deserts."));
        }
        if (
            (displayedFlags & 32) == 0 &&
            Game.player.tiles.Where(t => t.FavorableForLife()).Count() >= 3
            )
        {
            displayedFlags |= 32;
            StartCoroutine(UpdateText("You are ready.\nAcquire Life."));
            target = PointAtTarget.Target.life;
            HideLife.unhide = true;
        }
        if ((displayedFlags & 64) == 0 &&
            (displayedFlags & 32) != 0 &&
            Game.player.tiles.Where(t => t.abundance > 0).Any() &&
            target == PointAtTarget.Target.life
            )
        {
            displayedFlags |= 64;
            target = PointAtTarget.Target.none;
        }
        if (
            (displayedFlags & 128) == 0 &&
            (displayedFlags & 64) != 0 &&
            (displayedFlags & 16) != 0 &&
            Time.time - lastMessageTime > 10
            )
        {
            displayedFlags |= 128;
            StartCoroutine(UpdateText("You are living.\nGet sun."));
            Sun.gettable = Sun.Orbiter.sun;
            target = PointAtTarget.Target.star;
        }
        if (
            (displayedFlags & 256) == 0 &&
            (displayedFlags & 128) != 0 &&
            Game.player.suns.Count() > 0)
        {
            Game.player.allowedIntelligence++;
            displayedFlags |= 256;
            target = PointAtTarget.Target.none;
            Game.zone.border.SetActive(false);
            Game.zone = Game.instance.zones[1];
            var turtle = GameObject.Find("turtle");
            if (turtle != null) turtle.transform.localScale = new Vector3(3, 3, 3);
            StartCoroutine(UpdateText("You are stronger.\nTravel further. Grow larger."));
        }
        // ZONE 2
        if (
            (displayedFlags & 512) == 0 &&
            (displayedFlags & 256) != 0 &&
            Time.time - lastMessageTime > 10 &&
            Game.player.tiles.Where(t => t.intelligence >= Tile.Intelligence.Feral).Count() > 3
            )
        {
            displayedFlags |= 512;
            StartCoroutine(UpdateText("You are thriving.\nGet god."));
            Sun.gettable = Sun.Orbiter.god;
            target = PointAtTarget.Target.god;
        }
        if (
            (displayedFlags & 1024) == 0 &&
            Game.player.gods.Any()
            )
        {
            target = PointAtTarget.Target.none;
            displayedFlags |= 1024;
            StartCoroutine(UpdateText("Uplift your life.\nGrow in prosperity."));
            Game.player.allowedIntelligence = Tile.Intelligence.Primitive;
        }
        // TODO: force player to build like, 3 huts by getting rid of tiles to get resources
        if ((displayedFlags & 4096) == 0 &&
            (displayedFlags & 1024) != 0 &&
            Game.player.tiles.Any(t => t.intelligence >= Tile.Intelligence.Primitive) &&
            Time.time - lastMessageTime > 10f
            )
        {
            displayedFlags |= 4096;
            Game.zone = Game.instance.zones[2];
            Game.zone.border.SetActive(false);
            var turtle = GameObject.Find("turtle");
            if (turtle != null) turtle.transform.localScale = new Vector3(4, 4, 4);
            StartCoroutine(UpdateText("Grow in prosperity.\nReach further.\nProceed to greatness."));
        }
        if ((displayedFlags & 8192) == 0 &&
            (displayedFlags & 4096) != 0 &&
            Time.time - lastMessageTime > 10f
            )
        {
            displayedFlags |= 8192;
            StartCoroutine(UpdateText("Advance.\nProgress."));
            Game.player.allowedIntelligence = Tile.Intelligence.Advanced;
        }
        if ((displayedFlags & 16384) == 0 &&
            // todo: require some cities
             Game.player.tiles.Where(t => t.intelligence >= Tile.Intelligence.Advanced).Count() > 24
         )
        {
            displayedFlags |= 16384;
            StartCoroutine(Finale());
        }
    }

    IEnumerator Finale()
    {
        StartCoroutine(UpdateText("You have grown far."));
        yield return new WaitForSecondsRealtime(10f);
        StartCoroutine(UpdateText("You have grown.\nYou are great."));
        yield return new WaitForSecondsRealtime(10f);
        StartCoroutine(UpdateText("You are great.\nYou need not god."));
        yield return new WaitForSecondsRealtime(10f);
        StartCoroutine(UpdateText("You have no need for a god.\nDestroy it."));
        yield return new WaitForSecondsRealtime(10f);
        StartCoroutine(UpdateText("Destroy it.\nPress Space."));
        while (!Input.GetKey("space")) yield return new WaitForEndOfFrame();
        endscreen.SetActive(true);
        audioSource.Stop();
    }
}
