/********************************

Najwaniejsze punkty zachowania GhostHome to:
1. Po aktywacji duch odbija si od cian i zostaje w bazie do jego 
   zakoczenia niezalenie od tego jaki inny stan jest aktywowany.
2. Po zakoczeniu tego stanu wyczamy poruszanie si gracza na czas 
   sekwencji wyjcia z bazy i jest uruchamiana sekwencja wyjcia 
   skadajca si z dwch etapw:
      - przemieszczenia si do wza Inside bdcego w rodku bazy
      - przemieszczenia si do wza Outside bdcego zaraz na zewntrz bazy
3. Po zakoczeniu sekwencji wyjcia z bazy sterowanie jest oddawane do skryptu 
   Movement z losowo ustawionym kierunkiem prawo/lewo i stanem, i stanem ktry 
   jest aktualnie aktywny (bdzie to stan GhostScatter albo GhostChase).

********************************/

using System.Collections;
using UnityEngine;

public class GhostHome : GhostBehaviour
{
    [SerializeField] private Transform inside;
    public Transform Inside => inside;
    [SerializeField] private Transform outside;
    public Transform Outside => outside;

    // uruchamianie sekwencji wyjcia z bazy w momencie wyjcia ze stanu GhostHome
    private void OnDisable()
    {
        if(Ghost && Ghost.Movement && gameObject.activeSelf)
            StartCoroutine(ExitTransition());
    }

    private IEnumerator ExitTransition()
    {
        // wyczenie sterowania i fizyki Rigidbody dla obiektu
        // (isKinematic sprawia e rb siy nie wpywaj na obiekt)
        Ghost.Movement.rb.isKinematic = true;
        Ghost.Movement.SetDirection(Vector2.up);
        Ghost.Movement.enabled = false;

        // pozycja startowa
        Vector3 position = transform.position;

        // czas animacji od pozycji startowej w bazie do Inside
        float duration = 0.5f;
        // czas ktry upyn
        float elapsed = 0.0f;

        // wykonanie tej funkcji bdzie rozoone w czasie
        while (elapsed < duration)
        {
            // ustalamy now pozycj jako pooenie midzy pozycj startow a pozycj Inside
            // w zalenoci od czasu ktry upyn elapsed przez dugo animacji
            Vector3 newPosition = Vector3.Lerp(position, inside.position, elapsed/duration);
            // przywracamy domyln pozycj z (u nas bdzie ona wynosia 0)
            newPosition.z = position.z;
            // przesuwamy ducha na okrelon pozycj
            Ghost.transform.position = newPosition;
            // zwikszamy czas ktry upyn
            elapsed += Time.deltaTime;
            yield return null; // tutaj bdziemy wznawia od kolejnej klatki
        }

        // zerujemy czas ktry upyn
        elapsed = 0f;

        // ponisza ptla jest taka sama jak powysza tylko teraz startem jest pozycja Inide a kocowa to Outside
        while (elapsed < duration)
        {
            Vector3 newPosition = Vector3.Lerp(inside.position, outside.position, elapsed / duration);
            newPosition.z = position.z;
            Ghost.transform.position = newPosition;
            elapsed += Time.deltaTime;
            yield return null; // tutaj bdziemy wznawia od kolejnej klatki
        }

        // losujemy kierunek, uruchamiamy Movement, ustawiamy mu kierunek i wczamy fizyk w Rigidbody
        // (isKinematic sprawia e rb siy nie wpywaj na obiekt)
        Vector2 randomDirection = new Vector2(Random.value < 0.5f ? -1 : 1, 0f);
        Ghost.Movement.enabled = true;
        Ghost.Movement.SetDirection(randomDirection);
        Ghost.Movement.rb.isKinematic = false;
    }


    // Odbijanie si od cian w stanie GhostHome
    private void OnCollisionEnter2D(Collision2D collision)
    {
        if (enabled)
        {
            Ghost.Movement.SetDirection(-Ghost.Movement.direction);
        }
    }
}
