using UnityEngine;
using NeonTea.Quakeball.Players;
using NeonTea.Quakeball.Util;

namespace NeonTea.Quakeball.Animation {
    /// <summary>Animates the parts that can't be animated via the animation system, e.g. aiming.</summary>
    public class SoldierProceduralAnimator : MonoBehaviour {
        public enum SoldierModel {
            Female = 0,
            Male = 1,
        }

        public Animator[] Soldiers;
        public SoldierModel Model;
        public Player Player;
        public Transform HeadCollider;

        [Header("Gun holding")]
        public bool GunGluedToHand = true;
        public Transform Gun;
        public Transform GunHandle;

        private Animator Animator;
        private Transform BehindHand;
        private Transform FrontHand;
        private Transform Torso;

        private float VisualYaw;
        private float VisualPitch;

        private void Awake() {
            foreach (Animator animator in Soldiers) {
                animator.gameObject.SetActive(false);
            }
            Animator = Soldiers[(int)Model].GetComponent<Animator>();
            Animator.gameObject.SetActive(true);
            HeadCollider.parent = TransformUtil.FindChildWithName(Animator.transform, "HEAD");
            Torso = TransformUtil.FindChildWithName(Animator.transform, "RIBS");
            BehindHand = TransformUtil.FindChildWithName(Animator.transform, "HAND.R");
            FrontHand = TransformUtil.FindChildWithName(Animator.transform, "HAND.L");
            if (GunGluedToHand) {
                Gun.parent = Animator.transform;
            }
        }

        private void Update() {
            float Right = Vector3.Dot(Player.GroundVelocity, transform.right) / Player.MoveStyle.TargetVelocity / 0.7f;
            float Forward = Vector3.Dot(Player.GroundVelocity, transform.forward) / Player.MoveStyle.TargetVelocity / 0.7f;
            Animator.SetFloat("Forward", Mathf.Clamp(Forward, -1, 1));
            Animator.SetFloat("Right", Mathf.Clamp(Right, -1, 1));
        }

        private void LateUpdate() {
            VisualYaw = Mathf.Lerp(VisualYaw, Player.Yaw, 10f * Time.deltaTime);
            VisualPitch = Mathf.Lerp(VisualPitch, -Player.Pitch, 10f * Time.deltaTime);

            transform.localEulerAngles = new Vector3(0, VisualYaw, 0);
            Torso.localEulerAngles = new Vector3(VisualPitch, 0, 0);

            if (GunGluedToHand) {
                Vector3 GunOffset = GunHandle.position - Gun.position;
                Vector3 GunDirection = (FrontHand.position - BehindHand.position).normalized;
                Gun.position = BehindHand.position - GunOffset;
                Gun.LookAt(Gun.position + GunDirection);
            }
        }
    }
}
