using UnityEngine;

/// <summary>
/// Base class used for the collision interactions between anything that isnt the blackhole, which has its own special class.
/// </summary>
public class ColliderManager : MonoBehaviour
{
    protected AudioSource _attachedAudioSource;
    protected Rigidbody _attachedRigidbody;
    public GameObject shipModel;

    /// <summary>
    /// An enum to pass which direction the collision happened.
    /// </summary>
    public enum CollisionDirection
    {
        None,
        Top,
        Bottom
    }

    private void Awake()
    {
        // Get the objects audio source, if one is present
        _attachedAudioSource = gameObject.GetComponent<AudioSource>();
        _attachedRigidbody = gameObject.GetComponent<Rigidbody>();

        // Do any tasks the child has to process
        DoAwakeTasks();
    }

    /// <summary>
    /// Method to deal with Awake tasks that a child script needs since you can only have 1 awake between the parent and child.
    /// </summary>
    public virtual void DoAwakeTasks()
    {
    }

    /// <summary>
    /// Method to trigger the attached objects death without a collision but should simulate a collision
    /// </summary>
    public virtual void TriggerDeath()
    {
    }

    /// <summary>
    /// Process the game objects collision.
    /// </summary>
    /// <param name="direction">Direction the collision happened, typically checking if hit from above or below.</param>
    /// <param name="collision">Collision object holding the details on the collided object.</param>
    /// <param name="wasChild">Was the hit collider a child of this game object.</param>
    public virtual void ProcessCollision(CollisionDirection direction, Collision collision, bool wasChild)
    {
    }

    /// <summary>
    /// Custom method to deal with child collisions on the game object, this was a test really and most likely wont be used in the final.
    /// </summary>
    /// <param name="collision"></param>
    public void OnCollisionEnterChild(Collision collision)
    {
        DoCollisionEnter(collision, true);
    }

    private void OnCollisionEnter(Collision collision)
    {
        DoCollisionEnter(collision);
    }

    /// <summary>
    /// Helper method to process the collision since when testing we needed to different collision detections.
    /// </summary>
    /// <param name="collision">Collider that we hit.</param>
    /// <param name="wasChild">Check if it was a child that was hit.</param>
    private void DoCollisionEnter(Collision collision, bool wasChild = false)
    {
        // Get the collided objects collision manager, if they dont have one then we ignore it since we only want objects to interact when they have to.
        ColliderManager hitCM = collision.gameObject.GetComponent<ColliderManager>();
        if (hitCM != null)
        {            
            CollisionDirection direction = CollisionDirection.None;

            if (_attachedRigidbody != null)
            {
                if (collision.contacts.Length > 0)
                {
                    Vector3 collisionDirLocal = gameObject.transform.InverseTransformPoint(collision.gameObject.transform.position);
                    if (collisionDirLocal.y > 0.5f)
                    {
                        direction = CollisionDirection.Top;
                    }
                    else if (collisionDirLocal.y < -0.5f)
                    {
                        direction = CollisionDirection.Bottom;
                    }
                }              
            }

            // Once we know process the collision.
            ProcessCollision(direction, collision, wasChild);
        }
    }
}
