public void AddListener(GameObject obj, ActableTypes type)
 {
     if (obj.GetComponent <AutomationListener>() == null)
     {
         AutomationListener listener = obj.AddComponent <AutomationListener> ();
         listener.type = type;
         ActiveListeners.Add(listener);
     }
 }
        public void Dismantle()
        {
            StopCoroutine("Runner");

            List <GameObject> all = SceneMaster.GetObjectPool();

            for (int x = 0; x < all.Count; x++)
            {
                AutomationListener al = all[x].GetComponent <AutomationListener>();
                if (al != null)
                {
                    Destroy(al);
                }
            }
        }
        /// <summary>
        /// Remove Automation listener from all objects.
        /// </summary>
        public static void AutomationRelevantActionTaken(AutomationListener listener)
        {
            List <Component> components = listener.gameObject.GetComponents <Component>().ToList();

            //Ignore if no components.
            if (!components.Any())
            {
                return;
            }

            RecordedGameObjectData data = new RecordedGameObjectData();;

            data.Name = listener.gameObject.name.Replace("(Clone)", string.Empty);
            KeyValuePair <string, List <string> > parents = GetTopLevelParentObject(listener.gameObject);

            data.ParentNames        = parents.Value;
            data.TopLevelParentName = parents.Key;
            data.Tag = listener.gameObject.tag;
            data.Components.Add("GameObject");
            data.Components.AddRange(listener.gameObject.GetComponents <Component>().ToList().ToListOfNames());
            data.AsComponent = data.Components.FindIndexOf("GameObject");

            List <KeyValuePair <Type, ActableTypes> > matches = GameSpecificActableTypes.FindAll(x => data.Components.Contains(x.Key.Name));

            Button b = listener.gameObject.GetComponent <Button>();
            Toggle t = listener.gameObject.GetComponent <Toggle>();

            if (b != null || t != null || matches.FindAll(x => x.Value == ActableTypes.Clickable).Any())
            {
                if (b != null)
                {
                    data.AsComponent = data.Components.FindIndexOf("Button");
                }
                else if (t != null)
                {
                    data.AsComponent = data.Components.FindIndexOf("Toggle");
                }
                else
                {
                    data.AsComponent = data.Components.FindIndexOf(matches.Find(x => x.Value == ActableTypes.Clickable).Key.Name);
                }
                data.ID     = CurrentStepID++;
                data.Action = ActableTypes.Clickable;
                RecordedActions.Add(data);
                return;
            }

            if (components.FindAll(z => z.GetType().Name.ToLower().ContainsOrEquals("collider")).Any())
            {
                data.ID     = CurrentStepID++;
                data.Action = ActableTypes.Clickable;
                RecordedActions.Add(data);
                return;
            }

            ScrollRect sr = listener.gameObject.GetComponent <ScrollRect>();

            if (sr != null || matches.FindAll(x => x.Value == ActableTypes.Scroll).Any())
            {
                if (sr != null)
                {
                    data.AsComponent = data.Components.FindAll(x => x == "ScrollRect").Any() ? data.Components.FindIndexOf("ScrollRect") : data.Components.FindIndexOf("ScrollRectEx");
                }
                else
                {
                    data.AsComponent = data.Components.FindIndexOf(matches.Find(x => x.Value == ActableTypes.Scroll).Key.Name);
                }

                data.ID     = CurrentStepID++;
                data.Action = ActableTypes.Scroll;
                data.InitialScrollPosition = sr.verticalScrollbar == null ? (sr.horizontalScrollbar == null ? 0 : sr.horizontalScrollbar.value) : sr.verticalScrollbar.value;
                data.Duration = 1;
                RecordedActions.Add(data);
                return;
            }

            InputField i = listener.gameObject.GetComponent <InputField>();

            if (i != null || matches.FindAll(x => x.Value == ActableTypes.Input).Any())
            {
                data.AsComponent = data.Components.FindIndexOf("InputField");
                data.ID          = CurrentStepID++;
                data.Action      = ActableTypes.Input;
                RecordedActions.Add(data);
                return;
            }

            for (int a = 0; a < GameMaster.AdditionalAssetsAll.Count; a++)
            {
                Component c = listener.gameObject.GetComponent(GameMaster.AdditionalAssetsAll[a].Key.Name);
                if (c != null || matches.FindAll(x => x.Value == GameSpecificActableTypes[a].Value).Any())
                {
                    data.AsComponent = data.Components.FindIndexOf(GameMaster.AdditionalAssetsAll[a].Key.Name);
                    data.ID          = CurrentStepID++;
                    data.Action      = ActableTypes.Input;
                    RecordedActions.Add(data);
                    return;
                }
            }

            for (int ty = 0; ty < GameSpecificActableTypes.Count; ty++)
            {
                Component c = listener.gameObject.GetComponent(GameSpecificActableTypes[ty].Key.Name);
                if (c != null || matches.FindAll(x => x.Value == GameSpecificActableTypes[ty].Value).Any())
                {
                    data.AsComponent = data.Components.FindIndexOf(GameSpecificActableTypes[ty].Key.Name);
                    data.ID          = CurrentStepID++;
                    data.Action      = ActableTypes.Input;
                    RecordedActions.Add(data);
                    return;
                }
            }

            /*TODO: Update around text clickable for floating assertions.
             * Text txt = listener.gameObject.GetComponent<Text>();
             * TMPro.TextMeshProUGUI tmp = listener.gameObject.GetComponent<TMPro.TextMeshProUGUI>();
             * if(txt != null || tmp != null) {
             *
             * data.AsComponent = txt != null ? data.Components.FindIndexOf("Text") : data.Components.FindIndexOf("TextMeshProUGUI");
             * data.ID = CurrentStepID++;
             * data.Action = ActableTypes.TextForAssert;
             * RecordingAssertionData assert = new RecordingAssertionData(CurrentAssertionID++);
             * assert.Type = AssertionType.IsTrue;
             * assert.AssertionIsTrue = AssertionIsTrue.TextContainsOrEquals;
             * RecordedActions.Add(data);
             * return;
             *
             * }
             */
        }
        IEnumerator Runner()
        {
            while (true)
            {
                if (forceRefresh || Time.time - lastRunTime > UPDATE_COOLDOWN)
                {
                    forceRefresh = false;
                    all          = all.GetUniqueObjectsBetween(SceneMaster.GetObjectPool().GetActiveAndVisibleObjectsInList());

                    for (int x = 0; x < all.Count; x++)
                    {
                        if (all[x] == null)
                        {
                            continue;
                        }

                        AutomationListener al = all[x].GetComponent <AutomationListener>();
                        if (al == null)
                        {
                            List <MonoBehaviour> components = all[x].GetComponents <MonoBehaviour>().ToList();

                            for (int co = 0; co < components.Count; co++)
                            {
                                string scriptName = components[co].GetType().Name;

                                #region Clickables
                                if (scriptName == "Button" || scriptName == "Toggle" || components[co].GetType().IsAssignableFrom(typeof(Button)) || components[co].GetType().IsAssignableFrom(typeof(Toggle)))
                                {
                                    AddListener(all[x], ActableTypes.Clickable);
                                    continue;
                                }

                                if (scriptName == "Collider" || components[co].GetType().IsAssignableFrom(typeof(Collider)))
                                {
                                    if (all[x].GetComponent <Collider>().isTrigger)
                                    {
                                        AddListener(all[x], ActableTypes.Clickable);
                                        continue;
                                    }
                                }
                                #endregion

                                #region Inputs
                                if (scriptName == "InputField" || components[co].GetType().IsAssignableFrom(typeof(InputField)))
                                {
                                    AddListener(all[x], ActableTypes.Input);
                                    continue;
                                }
                                #endregion

                                #region Movables
                                if (scriptName == "ScrollRect" || components[co].GetType().IsAssignableFrom(typeof(ScrollRect)))
                                {
                                    AddListener(all[x], ActableTypes.Scroll);
                                    continue;
                                }
                                #endregion

                                #region Fall Backs
                                for (int t = 0; t < GameSpecificActableTypes.Count; t++)
                                {
                                    if (scriptName == GameSpecificActableTypes[t].Key.Name)
                                    {
                                        AddListener(all[x], GameSpecificActableTypes[t].Value);
                                        continue;
                                    }
                                }

                                for (int a = 0; a < GameMaster.AdditionalAssetsAll.Count; a++)
                                {
                                    if (scriptName == GameMaster.AdditionalAssetsAll[a].Key.Name || components[co].GetType().IsAssignableFrom(GameMaster.AdditionalAssetsAll[a].Key))
                                    {
                                        AddListener(all[x], GameMaster.AdditionalAssetsAll[a].Value);
                                        continue;
                                    }
                                }

                                //Fallback on Selectable as many interactive objects and extensions of them inheret from Selectable.
                                if (scriptName == "Selectable" || components[co].GetType().IsAssignableFrom(typeof(Selectable)))
                                {
                                    AddListener(all[x], ActableTypes.Clickable);
                                    continue;
                                }
                                #endregion

                                /*
                                 * for(int t = 0; t < GameMaster.AdditionalTextAssets.Count; t++) {
                                 *
                                 * if(all[x].GetComponent(GameMaster.AdditionalTextAssets[t]) != <span class='value'>null</span>) {
                                 *
                                 * al = all[x].AddComponent<AutomationListener>();
                                 * al.type =  ActableTypes.TextForAssert;
                                 * ActiveListeners.Add(al);
                                 * continue;
                                 *
                                 * }
                                 *
                                 * }
                                 */
                            }
                        }
                    }

                    lastRunTime = Time.time;
                }

                yield return(StartCoroutine(Q.driver.WaitRealTime(0.05f)));
            }
        }