using System.Collections;
using System.Collections.Generic;
using UnityEngine;

//public interface Interactable
//{
//    void OnHit();
//    void OnHurt();
//    void OnGrab();
//}

public class UnitController : MonoBehaviour/*, Interactable*/
{
    public enum UnitType
    {
        PC, 
        Monster,
        Prop,
    }

    public virtual UnitType type { get; }

	// 角色共有的组件

    public UnitRender unitRender;

    public UnitState unitState;
    public PCState pcState { get { return unitState as PCState; } }
    public MonsterState monsterState { get { return unitState as MonsterState; } }

    public UnitAnimation unitAnimation;
    public PCAnimation pcAnimation { get { return unitAnimation as PCAnimation; } }
    public MonsterAnimation monsterAnimation { get { return unitAnimation as MonsterAnimation; } }

    public UnitSkill unitSkill;

	public UnitRootMotion unitRootMotion;

    public UnitCollider unitCollider;

	public UnitDetail unitDetail;

    public UnitBody unitBody;

	public GameObject unitObj; // 角色模型

    protected List<UnitComponent> unitComponents;

	#region 事件监听
	public delegate void OnTimelineEventHandle(AnimationEventBase animEvent);
	public OnTimelineEventHandle onTimelineEvent { get; set; }
	#endregion 

	public bool isTowardRight
	{
		get
		{
            return transform.rotation.eulerAngles.y == 0;
		}
	}

    public virtual bool isOnGround
    {
        get
        {
            return transform.position.y <= 0f;
        }
    }

    public bool isInAir
    {
        get
        {
            return !isOnGround;
        }
    }

    private string m_Folder;
    public string folder
    {
        get
        {
            return m_Folder;
        }
    }

	private bool m_Visible;
	public bool visible
	{
		get
		{
			return m_Visible;
		}
	}

    public virtual Vector3 center
    {
        get
        {
            return GetComponentInChildren<Renderer>().bounds.center;
        }
        set
        {
            Vector3 offset = new Vector3(0, -GetComponentInChildren<Renderer>().bounds.size.y / 2f, 0);
            transform.position = value + offset;
        }
    }

    public virtual void Initialize( GameObject obj , string folder)
    {
		unitObj = obj;
        m_Folder = folder;
        unitComponents = new List<UnitComponent>();

        Initialize();

        OnPostInitailize();
    }

    protected virtual void Initialize()
    {
        unitSkill = GetOrAddUnitComponent<UnitSkill>();
        unitSkill.Initialize();

        unitRootMotion = GetOrAddUnitComponent<UnitRootMotion>();
        unitRootMotion.Initialize();

        unitCollider = GetOrAddUnitComponent<UnitCollider>();
        unitCollider.Initialize();

        unitBody = GetOrAddUnitComponent<UnitBody>();
        unitBody.Initialize();

        unitRender = GetOrAddUnitComponent<UnitRender>();
        unitRender.Initialize();

        unitDetail = gameObject.GetComponentInChildren<UnitDetail>();
    }

    private void OnPostInitailize()
    {
        if (unitComponents == null)
            return;
        for(int i = 0; i < unitComponents.Count; ++i)
        {
            unitComponents[i].OnPostInitialize();
        }
    }

    protected T GetOrAddUnitComponent<T>() where T : UnitComponent
    {
        T comp = gameObject.GetOrAddComponent<T>();
        Debug.Assert(unitComponents != null);
        unitComponents.Add(comp);
        return comp;
    }

    public virtual void Update()
	{
		unitRender.OnUpdate();
		unitState.OnUpdate();
		unitAnimation.OnUpdate();
		unitSkill.OnUpdate();
		unitRootMotion.OnUpdate();
	}

	public virtual void OnDestroy()
	{
	}

    public virtual void OnHit(CollisionInfo info)
    {
    }

    public virtual void OnGetHit(CollisionInfo info)
    {
    }

    public virtual void OnGetShot(CollisionInfo info)
    {
    }


    public virtual void OnGrab()
    {
    }

    public virtual void OnPull()
    {
    }

	public void SetYPosition(float y)
	{
		Vector3 pos = transform.position;
		pos.y = y;
		transform.position = pos;
	}

}