﻿using UnityEngine;
using UnityEngine.UI;
using System.Collections.Generic;

#if USING_TMP
using TMPro;
#endif


namespace SimplifyXR
{
    /// <summary>
    /// Changes the Text field inside of an UI Selectable component.
    /// </summary>
    [DirectiveCategory(DirectiveCategories.Action, DirectiveSubCategory.UI, 
        prettyName ="Change UI Selectable Text",
        directiveInfo ="This action will change the <b>Text</b> or <b>Text Mesh Pro</b> field inside of " +
        " a <b>UI Selectable</b> component.")]
    public class ChangeUISelectableText : Actions, IChangeWhatGameObjectExecutes, ICanToggle, IChangeString
    {
        /// <summary>
        /// The type of text to modify
        /// </summary>
        //#if USING_TMP
        [Tooltip("The type of text to modify.")]
        public TextType textType;
        //#endif

        /// <summary>
        /// The Text field to change selectable.
        /// </summary>
        #if UNITY_EDITOR
        [Tooltip("The Text field to change selectable."),
            Conditional("textType", TextType.Standard,ComparisonType.Equals)]
        #endif
        public Text TextFieldToChange;


#if USING_TMP
        // <summary>
        /// The Text Mesh field to change selectable.
        /// </summary>
#if UNITY_EDITOR
        [Tooltip("The Text Mesh Pro field to change selectable."),
            Conditional("textType", TextType.TextMeshPro, ComparisonType.Equals)]
        #endif
        public TMP_Text TextMeshFieldToChange;
#endif

        /// <summary>
        /// The Text Field Area to change selectable.
        /// </summary>
#if UNITY_EDITOR
        [Tooltip("The Text Field Area to change selectable.")]
        #endif
        [TextArea]
        public string TextFieldArea;
        /// <summary>
        /// The font color to change selectable..
        /// </summary>
        #if UNITY_EDITOR
        [Tooltip("The font color to change selectable.")]
        #endif
        public Color TextColor = new Color(0, 0, 0, 1);
        /// <summary>
        /// The font style to change selectable..
        /// </summary>
        
        #if UNITY_EDITOR
        [Tooltip("The font style to change selectable.")
            ,Conditional("textType", TextType.Standard, ComparisonType.Equals)]
        #endif
        public FontStyle TextStyle;
        /// <summary>
        /// The Bool that Enables Text field to change selectable.
        /// </summary>


        #if USING_TMP
        #if UNITY_EDITOR
        [Tooltip("The font style to change selectable."), 
            Conditional("textType", TextType.TextMeshPro, ComparisonType.Equals)]
        #endif
        public TMPro.FontStyles TMPTextStyle;
        /// <summary>
        /// The Bool that Enables Text field to change selectable.
        /// </summary>
        #endif

#if UNITY_EDITOR
        [Tooltip("The Bool that Enables Text field to change selectable.")]
        #endif
        public bool ChangeText = true;
        /// <summary>
        /// The Bool that Enables Text field to change Font Style.
        /// </summary>
        #if UNITY_EDITOR
        [Tooltip("The Bool that Enables Text field to change Font Style.")]
        #endif
        public bool ChangeFontStyle = true;
        /// <summary>
        /// The Bool that Enables Text field to change Font Color.
        /// </summary>
        #if UNITY_EDITOR
        [Tooltip("The Bool that Enables Text field to change Font Color.")]
        #endif
        public bool ChangeFontColor = true;
        /// <summary>
        /// The Bool that Enables Text from Toggling from Original Text to New Text and back.
        /// </summary>
        #if UNITY_EDITOR
        [Tooltip("The Bool that Enables Text from Toggling from Original Text to New Text and back..")]
        #endif
        public bool ToggleText = true;
        /// <summary>
        /// The List Used to Keep Track of All Text Components within a UI Component.
        /// </summary>
        private List<Text> textObjects = new List<Text>();
        /// <summary>
        /// The List Used to Keep Track of All Text Mesh Pro Components within a UI Component.
        /// </summary>
        #if USING_TMP 
        private List<TMP_Text> tmpObjects = new List<TMP_Text>();
        #endif
        /// <summary>
        /// Text to change or pass
        /// </summary>
        private string newText;
        /// <summary>
        /// The GameObject to change selectable.
        /// </summary>
        private GameObject textFieldGameObjectToChange;
        /// <summary>
        /// Text to change back to original
        /// </summary>
        private string originalUIText;
        /// <summary>
        /// FontStyle to change back to original
        /// </summary>
        private FontStyle originalFontStyle;

        #if USING_TMP
        /// <summary>
        /// Font color32 to change back to original
        /// </summary>
        private TMPro.FontStyles originalTMPFontStyle;
        #endif
        /// <summary>
        /// Font color32 to change back to original
        /// </summary>
        private Color originalFontColor;
        /// <summary>
        /// Bool to make text selectable
        /// </summary>
        private bool changeUIText;
        /// <summary>
        /// Bool to indicate if original attributes were saved.
        /// </summary>
        private bool gotOriginalAttributes = false;
        /// <summary>
        /// The Bool that Enables Text Area to change text rather than ModifyString.
        /// </summary>
        private bool useTextArea = true;
        /// <summary>
        /// The Bool that indicates if IModifyToggle is being used.
        /// </summary>
        private bool useModifyToggle = false;

        /// <summary>
        /// The Dictionary used to keep track of all text.
        /// </summary>
        private Dictionary<Text, string> textObjectDic = new Dictionary<Text, string>();

        #if USING_TMP
        /// <summary>
        /// The Dictionary used to keep track of all text.
        /// </summary>
        private Dictionary<TMP_Text, string> tmpObjectDic = new Dictionary<TMP_Text, string>();
        #endif

        public override List<KnobKeywords> ReceiveKeywords()
        {
            return new List<KnobKeywords> {
                new KnobKeywords("TextFieldObjectToChange", typeof(GameObject)),
                new KnobKeywords("TextFieldToChange", TextAdapter.GetTextType(textType)),
                new KnobKeywords("TextStringToChange", typeof(string)),
                new KnobKeywords("TextFieldStyleToChange", TextAdapter.GetFontStyleType(textType)),
                new KnobKeywords("TextFieldColorToChange", typeof(Color)),
                new KnobKeywords("ChangeText", typeof(bool)),
                new KnobKeywords("ChangeFontStyle", typeof(bool)),
                new KnobKeywords("ChangeFontColor", typeof(bool)),
                new KnobKeywords("useTextArea", typeof(bool)),
                new KnobKeywords("ToggleText", typeof(bool)),
                new KnobKeywords("textObjects", TextAdapter.GetTextType(textType, true))
            };
        }

        public override List<KnobKeywords> SendKeywords()
        {
            return new List<KnobKeywords> {
                new KnobKeywords("TextFieldObjectChanged", typeof(GameObject)),
                new KnobKeywords("TextFieldChanged", TextAdapter.GetTextType(textType)),
                new KnobKeywords("TextStringChanged", typeof(string)),
                new KnobKeywords("TextFieldStyleChanged", TextAdapter.GetFontStyleType(textType)),
                new KnobKeywords("TextFieldColorChanged", typeof(Color)),
                new KnobKeywords("ChangedText", typeof(bool)),
                new KnobKeywords("ChangedFontStyle", typeof(bool)),
                new KnobKeywords("ChangedFontColor", typeof(bool)),
                new KnobKeywords("UsedTextArea", typeof(bool)),
                new KnobKeywords("ToggledText", typeof(bool)),
                new KnobKeywords("textObjects", TextAdapter.GetTextType(textType, true))
            };
        }

        public override void Execute()
        {
            GetPassedObject(); 
            ChangeSelectableText();
            CheckIfDropDown();
            CheckIfScrollRect();
            SendData();
            ThisActionCompleted();
        }

        private void GetPassedObject()
        {
            var objectPassed = GetPassableData();
            if (objectPassed == null) return;
            if (KeywordInUse == "TextFieldObjectToChange")
            {
                var myObject = objectPassed as GameObject;
                textFieldGameObjectToChange = myObject;
                if (textFieldGameObjectToChange != null)
                    TextFieldToChange = textFieldGameObjectToChange.GetComponent<Text>();
            }
            else if (KeywordInUse == "TextFieldToChange")
            {
                var myObject = objectPassed;
                switch (textType)
                {
                    case TextType.Standard:
                        TextFieldToChange = (Text)myObject;
                        break;
                    #if USING_TMP
                    case TextType.TextMeshPro:
                        TextMeshFieldToChange = (TMP_Text)myObject;
                        break;
                    #endif
                }
            }
            else if (KeywordInUse == "TextStringToChange")
            {
                var myString = objectPassed as string;
                newText = myString;
                useTextArea = false;
            }
            else if (KeywordInUse == "TextFieldStyleToChange")
            {
                var myFontStyle = (FontStyle)objectPassed;
                TextStyle = myFontStyle;
            }
            else if (KeywordInUse == "TextFieldColorToChange")
            {
                var myColor = (Color)objectPassed;
                TextColor = myColor;
            }
            else if (KeywordInUse == "ChangeText")
            {
                var myBoolText = (bool)objectPassed;
                ChangeText = myBoolText;
            }
            else if (KeywordInUse == "ChangeFontStyle")
            {
                var myBoolFontStyle = (bool)objectPassed;
                ChangeFontStyle = myBoolFontStyle;
            }
            else if (KeywordInUse == "ChangeFontColor")
            {
                var myBoolFontColor = (bool)objectPassed;
                ChangeFontColor = myBoolFontColor;
            }
            else if (KeywordInUse == "useTextArea")
            {
                var myBoolTextArea = (bool)objectPassed;
                useTextArea = myBoolTextArea;
            }
            else if (KeywordInUse == "TextToggle")
            {
                var myBoolToggleText = (bool)objectPassed;
                ToggleText = myBoolToggleText;
            }
            else if (KeywordInUse == "textObjects")
            {
                switch (textType)
                {
                    case TextType.Standard:
                        var myList = (List<Text>)objectPassed;
                        textObjects = myList;
                        break;
                #if USING_TMP
                    case TextType.TextMeshPro:
                        var myList2 = (List<TMP_Text>)objectPassed;
                        tmpObjects = myList2;
                        break;
                #endif
                }
            }
            else
            {
                SimplifyXRDebug.SimplifyXRLog(SimplifyXRDebug.Type.Warning, "No objects of type Text to pass {0}", SimplifyXRDebug.Args(this));
            }
        }

        /// <summary>
        /// Change the Text Field string. 
        /// </summary>
        private void ChangeSelectableText()
        {
            CheckIfOriginalAttributesSaved();
        #if USING_TMP
            if((textType == TextType.TextMeshPro && TextMeshFieldToChange != null) 
                || (textType == TextType.Standard && TextFieldToChange != null))
        #else
            if (TextFieldToChange != null)
        #endif
            {
                if (useModifyToggle)
                {
                    if (changeUIText)
                    {
                        GetAndSetText();
                        FontStyleHandler();
                        GetAndSetTextFontColor();
                    }
                    else
                    {
                        ReturnAttributesSaved();
                    }
                }
                else
                {
                    changeUIText = !changeUIText;
                    if (changeUIText)
                    {
                        GetAndSetText();
                        FontStyleHandler();
                        GetAndSetTextFontColor();
                    }
                    else
                    {
                        ReturnAttributesSaved();
                    }
                }
            }
            else
            {
                SimplifyXRDebug.SimplifyXRLog(SimplifyXRDebug.Type.Warning, "No Text Field to Change of type Text to pass {0}", SimplifyXRDebug.Args(this));
            }
        }      


        private void FontStyleHandler()
        {
            if(ChangeFontStyle)
            {
                switch (textType)
                {
                    case TextType.Standard:
                        GetAndSetTextFontStyle();
                        break;
                #if USING_TMP
                    case TextType.TextMeshPro:
                        GetAndSetTMPProFontStyle();
                        break;
                #endif
                }
            }
        }

        #if USING_TMP
        private void GetAndSetTMPProFontStyle()
        {
            if (ChangeFontStyle) TextMeshFieldToChange.fontStyle = TMPTextStyle;
            else
            {
                SimplifyXRDebug.SimplifyXRLog(SimplifyXRDebug.Type.Warning, "No TMP field to Change of type Text to pass {0}", SimplifyXRDebug.Args(this));
            }
        }
        #endif

        /// <summary>
        /// Change the Text Field to the selected font style.
        /// </summary>
        private void GetAndSetTextFontStyle()
        {
            if (ChangeFontStyle)
            {
                if (TextFieldToChange != null)
                {
                    TextFieldToChange.fontStyle = TextStyle;

                    /*
                    
                    if (TextStyle == FontStyle.Normal)
                    {
                        TextFieldToChange.fontStyle = FontStyle.Normal;
                    }
                    else if (TextStyle == FontStyle.Italic)
                    {
                        TextFieldToChange.fontStyle = FontStyle.Italic;
                    }
                    else if (TextStyle == FontStyle.Bold)
                    {
                        TextFieldToChange.fontStyle = FontStyle.Bold;
                    }
                    else if (TextStyle == FontStyle.BoldAndItalic)
                    {
                        TextFieldToChange.fontStyle = FontStyle.BoldAndItalic;
                    }
                    */
                }
                else
                {
                    SimplifyXRDebug.SimplifyXRLog(SimplifyXRDebug.Type.Warning, "No Text Field to Change of type Text to pass {0}", SimplifyXRDebug.Args(this));
                }
            }
        }

        /// <summary>
        /// Change the Text Field to the selected color.
        /// </summary>
        private void GetAndSetTextFontColor()
        {
            if (ChangeFontColor)
            {                
                    switch (textType)
                    {
                        case TextType.Standard:
                            if (TextFieldToChange != null) TextFieldToChange.color = TextColor;
                            else SimplifyXRDebug.SimplifyXRLog(SimplifyXRDebug.Type.Warning, 
                                "No Text Field to Change of type Text to pass {0}", SimplifyXRDebug.Args(this));
                            break;
                    #if USING_TMP   
                        case TextType.TextMeshPro:
                            if (TextMeshFieldToChange != null) TextMeshFieldToChange.color = TextColor;
                            else  SimplifyXRDebug.SimplifyXRLog(SimplifyXRDebug.Type.Warning,
                                "No Text Field to Change of type Text Mesh Pro to pass {0}", SimplifyXRDebug.Args(this));
                            break;
                    #endif
                    }                   
                }        
        }

        /// <summary>
        /// Change the Text Field string. 
        /// </summary>
        private void GetAndSetText()
        {         
                switch (textType)
                {                     
                    case TextType.Standard:
                        if (!TextFieldToChange.GetComponentInParent<Dropdown>()
                        && !TextFieldToChange.GetComponentInParent<ScrollRect>())
                        {
                            if (!useTextArea)
                            {
                                if (ChangeText)
                                    TextFieldToChange.text = newText;
                            }
                            else
                            {
                                newText = TextFieldArea;
                                if (ChangeText)
                                    TextFieldToChange.text = newText;
                            }
                        }                        
                        break;
                #if USING_TMP
                    case TextType.TextMeshPro:
                        if (!TextMeshFieldToChange.GetComponentInParent<Dropdown>()
                       && !TextMeshFieldToChange.GetComponentInParent<ScrollRect>())
                        {
                            if (!useTextArea)
                            {
                                if (ChangeText)
                                    TextMeshFieldToChange.text = newText;
                            }
                            else
                            {
                                newText = TextFieldArea;
                                if (ChangeText)
                                    TextMeshFieldToChange.text = newText;
                            }
                        }
                            break;                        
                 #endif                           
                }
        }

        /// <summary>
        /// Check if the Text Field to Change saved the original attributes.
        /// </summary>
        private void CheckIfOriginalAttributesSaved()
        {
            if (!gotOriginalAttributes)
            {
                if ( textType == TextType.Standard &&
                    TextFieldToChange != null)
                {
                    originalUIText = TextFieldToChange.text;
                    originalFontStyle = TextFieldToChange.fontStyle;
                    originalFontColor = TextFieldToChange.color;
                    gotOriginalAttributes = true;
                }

#if USING_TMP
                else if( textType == TextType.TextMeshPro 
                    && TextMeshFieldToChange != null)
                {
                    originalUIText = TextMeshFieldToChange.text;
                    originalTMPFontStyle = TextMeshFieldToChange.fontStyle;
                    originalFontColor = TextMeshFieldToChange.color;
                    gotOriginalAttributes = true;
                }
#endif

                else
                {
                    SimplifyXRDebug.SimplifyXRLog(SimplifyXRDebug.Type.Warning, "No Text Field to Change of type GameObject to pass {0}", SimplifyXRDebug.Args(this));
                }
            }
        }

        /// <summary>
        /// Return the Text Field to Change to its saved original attributes.
        /// </summary>
        private void ReturnAttributesSaved()
        {
            if (ToggleText)
            {
                if (textType == TextType.Standard
                    && TextFieldToChange != null)
                {
                    TextFieldToChange.text = originalUIText;
                    TextFieldToChange.fontStyle = originalFontStyle;
                    TextFieldToChange.color = originalFontColor;
                }
                #if USING_TMP
                else if(textType == TextType.TextMeshPro &&
                    TextMeshFieldToChange != null)
                {
                    TextMeshFieldToChange.text = originalUIText;
                    TextMeshFieldToChange.fontStyle = originalTMPFontStyle;
                    TextMeshFieldToChange.color = originalFontColor;
                }
                #endif
                else
                {
                    SimplifyXRDebug.SimplifyXRLog(SimplifyXRDebug.Type.Warning, "No Text Field to Change of type GameObject to pass {0}", SimplifyXRDebug.Args(this));
                }
            }
        }

        /// <summary>
        /// Get All the Text Components, Add them to a List
        /// </summary>
        private void GetAndListAllTextsWithinTransform(Transform transform)
        {
            // For each child transform in Parent Object
            foreach (Transform child in transform)
            {
                switch(textType)
                {
                    case TextType.Standard:
                        ListTextsWithinTranformAbstract<Text, 
                            List<Text>>(child.gameObject, textObjects);
                        break;
                #if USING_TMP
                    case TextType.TextMeshPro:
                        ListTextsWithinTranformAbstract<TMP_Text,
                            List<TMP_Text>>(child.gameObject, tmpObjects);
                        break;
                #endif
                }
                GetAndListAllTextsWithinTransform(child);
            }
        }


        private void ListTextsWithinTranformAbstract<T, B>(GameObject child, B textObjects) where B : List<T>
        {
            if (child.GetComponent<T>() != null)
            {
                // Don't Add child Gameobject if it's already in the list
                if (!textObjects.Contains(child.GetComponent<T>()))
                {
                    textObjects.Add(child.GetComponent<T>());
                }
            }
        }

        /// <summary>
        /// Check if the GameObject being passed has a dropdown component attached.
        /// </summary>
        private void CheckIfDropDown()
        {
            switch(textType)
            {
                case TextType.Standard:
                    if (TextFieldToChange != null)
                    {
                        if (TextFieldToChange.GetComponentInParent<Dropdown>())
                        {
                            textObjects.Clear();
                            GetAndListAllTextsWithinTransform(TextFieldToChange.transform);
                        }
                    }
                    break;
                #if USING_TMP
                case TextType.TextMeshPro:
                    if(TextMeshFieldToChange != null)
                    {
                        if (TextMeshFieldToChange.GetComponentInParent<TMP_Dropdown>())
                        {
                            tmpObjects.Clear();
                            GetAndListAllTextsWithinTransform(TextMeshFieldToChange.transform);
                        }
                    }
                    break;
                #endif
            }

        }

        /// <summary>
        /// Check if the GameObject being passed has a ScrollRect component attached.
        /// </summary>
        private void CheckIfScrollRect()
        {
           switch(textType)
            {
                case TextType.Standard:
                    CheckIfScrollRectStandard();
                    break;
                #if USING_TMP
                case TextType.TextMeshPro:
                    CheckIfScrollRectTMP();
                    break;
                #endif
            }
        }


        /*
        void CheckIfScrollRectAbstract<A,B,C,D>(
            A textFieldObject, B fontStyle, C objectList, D objectDictionary) 
            where A : MonoBehaviour
            where C : List<A>
            where D : Dictionary<A, string>
        {
            if (textFieldObject != null)
            {
                if (textFieldObject.transform.parent != null)
                {
                    if (textFieldObject.GetComponentInParent<ScrollRect>() != null)
                    {
                        if (ToggleText)
                        {
                            GetAndListAllTextsWithinTransform(textFieldObject.GetComponentInParent<ScrollRect>().gameObject.transform);
                            for (int i = 0; i < objectList.Count; i++)
                            {
                                objectList[i].fontStyle = fontStyle;
                                objectList[i].color = originalFontColor;
                                if (!objectDictionary.ContainsKey(
                                    objectList[i].GetComponent<A>()))
                                {
                                    objectDictionary.Add(
                                        objectList[i].GetComponent<A>(), 
                                        objectList[i].GetComponent<A>().text);
                                }
                                tmpObjects[i].text = tmpObjectDic[tmpObjects[i]];
                            }
                            if (ChangeText)
                            {
                                if (!useTextArea)
                                {
                                    if (ChangeText)
                                        textFieldObject.text = newText;
                                }
                                else
                                {
                                    newText = TextFieldArea;
                                    if (ChangeText)
                                        textFieldObject.text = newText;
                                }
                            }
                            FontStyleHandler();
                            GetAndSetTextFontColor();
                        }
                    }
                }
            }
        }
        */



    #if USING_TMP
        void CheckIfScrollRectTMP()
        {
            if (TextMeshFieldToChange != null)
            {
                if (TextMeshFieldToChange.transform.parent != null)
                {
                    if (TextMeshFieldToChange.GetComponentInParent<ScrollRect>() != null)
                    {
                        if (ToggleText)
                        {
                            GetAndListAllTextsWithinTransform(TextMeshFieldToChange.GetComponentInParent<ScrollRect>().gameObject.transform);
                            for (int i = 0; i < tmpObjects.Count; i++)
                            {
                                tmpObjects[i].fontStyle = originalTMPFontStyle;
                                tmpObjects[i].color = originalFontColor;
                                if (!tmpObjectDic.ContainsKey(tmpObjects[i].GetComponent<TMP_Text>()))
                                {
                                    tmpObjectDic.Add(tmpObjects[i].GetComponent<TMP_Text>(), tmpObjects[i].GetComponent<TMP_Text>().text);
                                }
                                tmpObjects[i].text = tmpObjectDic[tmpObjects[i]];
                            }
                            if (ChangeText)
                            {
                                if (!useTextArea)
                                {
                                    if (ChangeText)
                                        TextMeshFieldToChange.text = newText;
                                }
                                else
                                {
                                    newText = TextFieldArea;
                                    if (ChangeText)
                                        TextMeshFieldToChange.text = newText;
                                }
                            }
                            FontStyleHandler();
                            GetAndSetTextFontColor();
                        }
                    }
                }
            }
        }
#endif


        void CheckIfScrollRectStandard()
        {
            if (TextFieldToChange != null)
            {
                if (TextFieldToChange.transform.parent != null)
                {
                    if (TextFieldToChange.GetComponentInParent<ScrollRect>() != null)
                    {
                        if (ToggleText)
                        {
                            GetAndListAllTextsWithinTransform(TextFieldToChange.GetComponentInParent<ScrollRect>().gameObject.transform);
                            for (int i = 0; i < textObjects.Count; i++)
                            {
                                textObjects[i].fontStyle = originalFontStyle;
                                textObjects[i].color = originalFontColor;
                                if (!textObjectDic.ContainsKey(textObjects[i].GetComponent<Text>()))
                                {
                                    textObjectDic.Add(textObjects[i].GetComponent<Text>(), textObjects[i].GetComponent<Text>().text);
                                }
                                textObjects[i].text = textObjectDic[textObjects[i]];
                            }
                            if (ChangeText)
                            {
                                if (!useTextArea)
                                {
                                    if (ChangeText)
                                        TextFieldToChange.text = newText;
                                }
                                else
                                {
                                    newText = TextFieldArea;
                                    if (ChangeText)
                                        TextFieldToChange.text = newText;
                                }
                            }
                            GetAndSetTextFontStyle();
                            GetAndSetTextFontColor();
                        }
                    }
                }
            }
        }


        private void SendData()
        {
            switch (textType)
            {
                case TextType.Standard:
                    SendTextDataAbstract(TextFieldToChange, TextStyle, textObjects);
                    break;
            #if USING_TMP
                case TextType.TextMeshPro:
                    SendTextDataAbstract(TextMeshFieldToChange, TMPTextStyle, tmpObjects);
                    break;
            #endif
            }
        }

        void SendTextDataAbstract<T, B, C>(T textObject, B textStyle, C objects) where T : MonoBehaviour
        {
            if (textObject != null)
            {
                AddPassableData(new List<string> { "TextFieldObjectChanged", "TextFieldChanged", "TextStringChanged", "TextFieldStyleChanged", "TextFieldColorChanged", "ChangedText", "ChangedFontStyle", "ChangedFontColor", "UsedTextArea", "ToggledText", "textObjects" },
                    new List<object> {
                        textObject.gameObject, textObject, newText, textStyle, TextColor, ChangeText, ChangeFontStyle, ChangeFontColor, useTextArea, ToggleText, objects});
            }
            else
                SimplifyXRDebug.SimplifyXRLog(SimplifyXRDebug.Type.Warning, "No Text Field to Change of type Text to pass {0}", SimplifyXRDebug.Args(this));
        }

#region IChangeWhatGameObjectExecutes implementation
        string IModify<IChangeWhatGameObjectExecutes>.ModifyObjectName {get {return "Object with Text field";}}

        public void ChangeWhatGameObjectExecutes(GameObject newObject)
        {
            if (newObject != null)
            {
                var passedGameObject = newObject;
                textFieldGameObjectToChange = passedGameObject;
                switch(textType)
                {
                    case TextType.Standard:
                        ObjectToChange<Text>(TextFieldToChange, textFieldGameObjectToChange);
                        break;
                #if USING_TMP
                    case TextType.TextMeshPro:
                        ObjectToChange<TMP_Text>(TextMeshFieldToChange, textFieldGameObjectToChange);
                        break;
                #endif
                }

              
            }
            else
            {
                SimplifyXRDebug.SimplifyXRLog(SimplifyXRDebug.Type.Warning, "No objects available to execute {0}", SimplifyXRDebug.Args(this));
            }
        }



        void ObjectToChange<T>(T textObjectToChange, GameObject gameObjectToChange) where T : MonoBehaviour
        {
            if (gameObjectToChange.GetComponentInChildren<T>())
            {
                textObjectToChange = gameObjectToChange.GetComponentInChildren<T>();
            }

            if (gameObjectToChange.GetComponent<T>())
            {
                textObjectToChange = gameObjectToChange.GetComponent<T>();
            }
        }


#endregion

            #region IChangeToggle implementation
        string IModify<ICanToggle>.ModifyObjectName {get {return "Change UI Text";}}

        public void SetTrue()
        {
            changeUIText = true;
            useModifyToggle = true;
        }

        public void SetFalse()
        {
            changeUIText = false;
            useModifyToggle = true;
        }

        public void Toggle()
        {
            changeUIText = !changeUIText;
            useModifyToggle = true;
        }
#endregion

#region IChangeString implementation
        string IModify<IChangeString>.ModifyObjectName {get { return "New Text";}}

        public void ChangeString(string s)
        {
            if (s == "")
            {
                useTextArea = true;
            }
            else
            {
                useTextArea = false;
                newText = s;
            }
        }
#endregion
    }
}