using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.XR.Interaction.Toolkit;
using TMPro; // Zones de texte dans l'espace 3D visualisables par un Casque en particulier

public class SelectionObjetXR : MonoBehaviour
{
    XRBaseInteractable m_Interactable; // Permet de grer l'interaction de l'objet avec un RayCasting ou Main Virtuelle Simple
    static Color s_SelectionnableColor = new Color(0.929f, 0.094f, 0.278f); // Couleur de l'objet slectionnable
    static Color s_SelectionneColor = new Color(0.019f, 0.733f, 0.827f); // Couleur de l'objet slectionn
    static Color s_EnChuteColor = new Color(0.019f, 0.13f, 0.827f); // Couleur de l'objet En chute
    static Color s_TombeAuSolColor = new Color(0.019f, 0.827f, 0.13f); // Couleur de l'objet Tomb au sol
    Renderer renderer;
    private Color oldColor;
    public enum EtatsObjets { Idle, Slectionnable, Slectionn, Manipul, EnChute, TombAuSol };
    public EtatsObjets etatObjets;
    public Camera cameraAuSol;

    // L'affichage de cette classe se rsume  un affichage sur la console
    private void Affiche(string text)
    {
        Debug.Log(text);
    }
    // Met  jour etatObjet
    // dans l'tat Idle
    public void SetIdle()
    {
        if (etatObjets == EtatsObjets.Slectionnable)
        {
            etatObjets = EtatsObjets.Idle;
            transform.GetComponent<Rigidbody>().isKinematic = false; // On physicalise l'objet
            renderer.material.color = oldColor;
            Affiche(this.transform.name + " est Idle.");
        }
    }
    // dans l'tat Selectionnable
    public void SetSelectionnable()
    {
        if (etatObjets == EtatsObjets.Idle)
        {
            etatObjets = EtatsObjets.Slectionnable;
            renderer.material.color = s_SelectionnableColor;
            Affiche(this.transform.name + " est slectionnable.");
        }
    }
    // retourne dans l'tat Idle
    public void ResetSelectionnable()
    {
        if (etatObjets == EtatsObjets.Slectionnable)
        {
            etatObjets = EtatsObjets.Idle;
            renderer.material.color = oldColor;
            Affiche(this.transform.name + " est dslectionn.");
        }
    }
    // dans l'tat Selectionne
    public void SetSelectionne()
    {
        if (etatObjets == EtatsObjets.Slectionnable)
        {
            renderer.material.color = s_SelectionneColor;
            etatObjets = EtatsObjets.Slectionn;
            Affiche(this.transform.name + " est slectionn.");
            transform.GetComponent<Rigidbody>().isKinematic = true; // On arrte la physicalisation de l'objet
        }
    }
    // dans l'tat Manipule
    public void SetManipule()
    {
        if (etatObjets == EtatsObjets.Slectionn)
        {
            etatObjets = EtatsObjets.Manipul;
            Affiche(this.transform.name + " est manipul.");
        }
    }
    // dans l'tat EnChute
    public void SetEnChute()
    {
        if (etatObjets == EtatsObjets.Manipul)
        {
            renderer.material.color = s_EnChuteColor;
            etatObjets = EtatsObjets.EnChute;
            cameraAuSol.enabled = true;
            Affiche(this.transform.name + " est en chute.");
            transform.GetComponent<Rigidbody>().isKinematic = false; // On physicalise l'objet
        }
    }
    // dans l'tat TombeAuSol
    public void SetTombeAuSol()
    {
        etatObjets = EtatsObjets.TombAuSol;
    }
    private void LateUpdate()
    {
        
    }

    // Cration des liaisons entre le component Interactable et la classe SelectionObjetXR  la fin de la cration de l'objet courant qui supporte le script
    protected void OnEnable()
    {
        renderer = this.transform.GetComponent<Renderer>();
        oldColor = renderer.material.color;
        Affiche("*** " + transform.name + " ENABLED");
        etatObjets = EtatsObjets.Idle;
        cameraAuSol.enabled = false;
        m_Interactable = GetComponent<XRBaseInteractable>(); // Rcupre le Component Interactable qui doit se trouver sur le GameObject courant
        m_Interactable.firstHoverEntered.AddListener(OnFirstHoverEntered); // AJoute un vnement d'entre dans l'tat Slectionnable de l'I3D
        m_Interactable.lastHoverExited.AddListener(OnLastHoverExited); // Ajoute un vnement de sortie de l'tat Slectionnable de l'I3D
        m_Interactable.selectEntered.AddListener(OnSelectEntered); // Ajoute un vnement li l'tat Slectionn de l'I3D
        m_Interactable.firstSelectEntered.AddListener(OnFirstSelectEntered); // Ajoute un vnement d'entre dans l'tat Slectionn de l'I3D
        m_Interactable.lastSelectExited.AddListener(OnLastSelectExited); // Ajoute un vnement de sortie de l'tat Slectionn de l'I3D
    }

    protected void OnDisable()
    {
        Affiche("*** " + transform.name + " DISABLED");
        m_Interactable.firstHoverEntered.RemoveListener(OnFirstHoverEntered);
        m_Interactable.lastHoverExited.RemoveListener(OnLastHoverExited);
        m_Interactable.selectEntered.RemoveListener(OnSelectEntered);
        m_Interactable.firstSelectEntered.RemoveListener(OnFirstSelectEntered);
        m_Interactable.lastSelectExited.RemoveListener(OnLastSelectExited);
    }

    // Gestion des vnements par des fonctions de la classe SelectionObjetXR
    protected virtual void OnFirstHoverEntered(HoverEnterEventArgs args) => SetSelectionnable(); 
    protected virtual void OnLastHoverExited(HoverExitEventArgs args) => ResetSelectionnable();
    protected virtual void OnSelectEntered(SelectEnterEventArgs args) => SetManipule();
    protected virtual void OnFirstSelectEntered(SelectEnterEventArgs args) => SetSelectionne();
    protected virtual void OnLastSelectExited(SelectExitEventArgs args) => SetEnChute();

    // Gestion de la collision de l'objet portant le script avec l'objet de name 'Sol'
    private void OnCollisionEnter(Collision collision)
    {
        if ((collision.gameObject.name == "Sol") && (etatObjets == EtatsObjets.EnChute))
        {
            transform.GetComponent<Rigidbody>().isKinematic = true; // On arrte la physicalisation de l'objet
            etatObjets = EtatsObjets.TombAuSol;
            Affiche(this.transform.name + " est tomb au sol.");
            renderer.material.color = s_TombeAuSolColor;
            cameraAuSol.enabled = false; // La camra au sol est dsactive aprs la chute
        }
        else if (collision.gameObject.transform.GetComponent<SelectionObjetXR>().etatObjets == EtatsObjets.TombAuSol) // Si l'objet rentre en collision avec un objet dont l'tat est TombAuSol, son tat devient galement TombAuSol
        {
            transform.GetComponent<Rigidbody>().isKinematic = true; // On arrte la physicalisation de l'objet
            etatObjets = EtatsObjets.TombAuSol;
            Affiche(this.transform.name + " est tomb sur l'objet " + collision.transform.name + ", qui est tomb au sol.");
            renderer.material.color = s_TombeAuSolColor;
            cameraAuSol.enabled = false; // La camra au sol est dsactive aprs la chute
        }
    }
}
