using UnityEngine;
using System.Collections;
using System.Reflection;

/// <summary>
/// All classes extend from this instead of MonoBehaviour. Adds extra convenience methods
/// </summary>
public abstract class BaseBehaviour : MonoBehaviour
{

    protected bool CheckIfSet(params Component[] targetField)
    {
        for (int i = 0; i < targetField.Length; i++)
        {
            if (targetField[i] == null)
            {
                Debug.LogErrorFormat("[{0}, name:{1}] {2} not set!", GetType(), name, targetField[i].GetType().Name);
                this.enabled = false;
                return false;
            }
        }

        return true;
    }

    protected bool CheckIfSet<T>(T targetObject)
    {
        if (targetObject == null)
        {
            Debug.LogErrorFormat("[{0}, name:{1}] {2} not set!", GetType(), name, typeof(T).Name);
            this.enabled = false;
            return false;
        }

        return true;
    }

    protected bool CheckIfSet<T,U>(T targetObject1, U targetObject2)
    {
        if (!CheckIfSet(targetObject1)) return false;
        if (!CheckIfSet(targetObject2)) return false;

        return true;
    }

    protected bool GetComponentsWithNullCheck<T>(ref T targetField, bool inParent = false)
        where T : Component
    {
        if(!inParent)
            targetField = GetComponent<T>();
        else
            targetField = GetComponentInParent<T>();
        if (targetField == null)
        {
            Debug.LogErrorFormat("[{0}, name:{1}] {2} not found!", this.GetType(), this.name, targetField.GetType().Name);
            this.enabled = false;
            return false;
        }

        return true;
    }

    protected bool GetComponentsWithNullCheck<T, U>(ref T targetField1, ref U targetField2, bool inParent = false)
        where T : Component
        where U : Component
    {
        if (!GetComponentsWithNullCheck(ref targetField1, inParent))
            return false;
        if (!GetComponentsWithNullCheck(ref targetField2, inParent))
            return false;

        return true;
    }

    protected bool GetComponents<T, U, V>(ref T targetField1, ref U targetField2, ref V targetField3, bool inParent = false)
        where T : Component
        where U : Component
        where V : Component
    {
        if (!GetComponentsWithNullCheck(ref targetField1, inParent))
            return false;
        if (!GetComponentsWithNullCheck(ref targetField2, inParent))
            return false;
        if (!GetComponentsWithNullCheck(ref targetField3, inParent))
            return false;

        return true;
    }

	// TODO ReferenceManager convenience methods

	protected void LogError(string errorString, params object[] args)
	{
		Debug.LogErrorFormat("[{0}, name:{1}] {2}", this.GetType(), this.name, string.Format(errorString, args));
	}

	protected void LogWarning(string errorString, params object[] args)
	{
		Debug.LogWarningFormat("[{0}, name:{1}] {2}", this.GetType(), this.name, string.Format(errorString, args));
	}

	protected void Log(string errorString, params object[] args)
	{
		Debug.LogFormat("[{0}, name:{1}] {2}", this.GetType(), this.name, string.Format(errorString, args));
	}

}
