//============= Copyright (c) Ludic GmbH, All rights reserved. ==============
//
// Purpose: Part of the My Behaviour Tree Code
//
//=============================================================================

using System;
using UnityEngine;

namespace MyBT {
    /// <summary>
    /// The best solution i found so far to allow access from the Task to the TaskParameters and State is by Storing the 
    /// current action in the TaskController
    /// </summary>
    [System.AttributeUsage(System.AttributeTargets.Method | System.AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
    public class Task : System.Attribute {
        public static ActionNodeRuntimeData currentNodeRuntimeData;
        public static Node currentNode;

        public static void SetTaskHasChanges () {
            currentNodeRuntimeData.taskHasChanges |= true;
        }

        public static NodeState getState {
            get {
                //if (currentNodeRuntimeData == null) {
                //    throw (new NullReferenceException());
                //}
                return currentNodeRuntimeData.nodeState;
            }
        }

        public static bool isStartingOrRunning {
            get {
                //if (currentNodeRuntimeData == null) {
                //    throw (new NullReferenceException());
                //}
                return (currentNodeRuntimeData.nodeState == NodeState.FirstRun || 
                    currentNodeRuntimeData.nodeState == NodeState.Running);
            }
        }

        public static bool isRunning {
            get {
                //if (currentNodeRuntimeData == null) {
                //    throw (new NullReferenceException());
                //}
                return (currentNodeRuntimeData.nodeState == NodeState.Running);
            }
        }

        public static bool isStarting {
            get {
                //if (currentNodeRuntimeData == null) {
                //    throw (new NullReferenceException());
                //}
                return (currentNodeRuntimeData.nodeState == NodeState.FirstRun);
            }
        }

        public static bool isAborting {
            get {
                //if (currentNodeRuntimeData == null) {
                //    throw (new NullReferenceException());
                //}
                return (currentNodeRuntimeData.nodeState == NodeState.Aborting);
            }
        }

        public static bool isDebugging {
            get {
                //if (currentNodeRuntimeData == null) {
                //    throw (new NullReferenceException());
                //}
                return currentNode.logStringDisplay;
            }
        }

        public static string log {
            get {
                //if (currentNodeRuntimeData == null) {
                //    throw (new NullReferenceException());
                //}
                return currentNodeRuntimeData.logString;
            }
            set {
                SetTaskHasChanges();
                //if (currentNodeRuntimeData == null) {
                //    throw (new NullReferenceException());
                //}
                currentNodeRuntimeData.logString = value;
            }
        }

        public static object data {
            get {
                //if (currentNodeRuntimeData == null) {
                //    throw (new NullReferenceException());
                //}
                return currentNodeRuntimeData.userData;
            }
            set {
                SetTaskHasChanges();
                //if (currentNodeRuntimeData == null) {
                //    throw (new NullReferenceException());
                //}
                currentNodeRuntimeData.userData = value;
            }
        }

        public static void SetFailed() {
            SetTaskHasChanges();
            //if (currentNodeRuntimeData == null) {
            //    throw (new NullReferenceException());
            //}
            currentNodeRuntimeData.nodeResult = NodeResult.Failed;
        }

        public static void SetSucceeded() {
            SetTaskHasChanges();
            //if (currentNodeRuntimeData == null) {
            //    throw (new NullReferenceException());
            //}
            currentNodeRuntimeData.nodeResult = NodeResult.Succeeded;
        }

        public static void SetContinue() {
            SetTaskHasChanges();
            //if (currentNodeRuntimeData == null) {
            //    throw (new NullReferenceException());
            //}
            currentNodeRuntimeData.nodeResult = NodeResult.Continue;
        }

        public static void SetError() {
            SetTaskHasChanges();
            //if (currentNodeRuntimeData == null) {
            //    throw (new NullReferenceException());
            //}
            currentNodeRuntimeData.nodeResult = NodeResult.Error;
        }

        public static void SetUndefined() {
            SetTaskHasChanges();
            //if (currentNodeRuntimeData == null) {
            //    throw (new NullReferenceException());
            //}
            currentNodeRuntimeData.nodeResult = NodeResult.Undefined;
        }
    }
}