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

/**
 * Code Inspired by these tutorial
 * Source: https://www.youtube.com/watch?v=KuMe6Iz8pFI, https://www.youtube.com/watch?v=B_NnQQKiw6I
 * Consulted on : 24/10/2022
 */
public class Ragdoll : MonoBehaviour
{
    [SerializeField]
    private bool _startsRagdolled;
    private List<Rigidbody> _ragdollRigidbodies;
    private Animator _animator;
    private Transform _hipBone; 

    private bool _isRagdoll 
    {
        get { return _ragdollRigidbodies != null && !_ragdollRigidbodies.Select(x => x.isKinematic).FirstOrDefault(); }
    }

    // Start is called before the first frame update
    private void Start()
    {
    }

    private void Awake()
    {
        _ragdollRigidbodies = GetComponentsInChildren<Rigidbody>().ToList();
        _animator = GetComponent<Animator>();
        _hipBone = _animator.GetBoneTransform(HumanBodyBones.Hips);

        void setRagdollState()
        {
            if (_startsRagdolled)
            {
                EnableRagdoll();
            }
            else
            {
                DisableRagdoll();
            }
        }

        setRagdollState();
       
    }


    // Update is called once per frame
    private void Update()
    {
        if(Input.GetKeyDown(KeyCode.Space))
        {
            if (_isRagdoll)
            {
                DisableRagdoll();
            }
            else
            {
                EnableRagdoll();
            }
        }
    }
    private void EnableRagdoll()
    {
        _ragdollRigidbodies.ForEach(rigidbody => rigidbody.isKinematic = false);
        _animator.enabled = false;
    }
    private void DisableRagdoll()
    {
        _ragdollRigidbodies.ForEach(rigidbody => rigidbody.isKinematic = true);
        _animator.enabled = true;
        StandBackUp();
    }

    private void StandBackUp()
    {
        Vector3 originalHipsPosition = _hipBone.position;
        transform.position = originalHipsPosition;

        void setRightHeight()
        {
            if (Physics.Raycast(transform.position, Vector3.down, out RaycastHit hitInfo))
            {
                transform.position = new Vector3(transform.position.x, hitInfo.point.y, transform.position.z);

            }
        }

        setRightHeight();

        _hipBone.position = originalHipsPosition;
    }


}
