/// <summary>
        /// Check if a state is currently active.
        /// </summary>
        /// <param name="stateName">The name of the state to check</param>
        /// <returns>True if the state is active, false if the state is not active</returns>
        public bool IsStateActive(string stateName)
        {
            InteractionState state = GetState(stateName);

            if (state == null)
            {
                Debug.LogError($"The {stateName} state is not being tracked, add this state using AddNewState(state) to track whether or not it is active.");
            }

            return(state.Active);
        }
        /// <summary>
        /// Get the event configuration of a state.
        /// </summary>
        /// <param name="stateName">The name of the state that contains the event configuration to be retrieved</param>
        /// <returns>The Interaction Event Configuration of the state</returns>
        internal BaseInteractionEventConfiguration GetEventConfiguration(string stateName)
        {
            InteractionState state = stateManager.GetState(stateName);

            if (state == null)
            {
                Debug.LogError($"An event configuration for the {stateName} state does not exist");
            }

            var eventConfig = state.EventConfiguration;

            return((BaseInteractionEventConfiguration)eventConfig);
        }
        /// <summary>
        /// Sets the event configuration for a given state. This method checks if the state has a valid associated event configuration, creates
        /// an instance of the event configuration class, and initializes the matching runtime class.
        /// </summary>
        /// <param name="state">This state's event configuration will be set</param>
        /// <returns>The set event configuration for the state.</returns>
        internal BaseInteractionEventConfiguration SetEventConfiguration(InteractionState state)
        {
            var eventConfiguration = CreateEventConfigurationInstance(state.Name);

            if (eventConfiguration != null)
            {
                state.EventConfiguration = eventConfiguration;

                InitializeAndAddEventReceiver(state.Name);
            }
            else
            {
                Debug.Log($"The event configuration for the {state.Name} was not set.");
            }

            return(eventConfiguration);
        }
        // Check if a state has additional initialization steps
        private void SetStateSpecificSettings(InteractionState state)
        {
            // If a near interaction state is added, check if a Near Interaction Touchable component attached to the game object
            if (state.InteractionType == InteractionType.Near)
            {
                // A Near Interaction Touchable component is required for an object to receive touch events
                InteractiveElement.AddNearInteractionTouchable();
            }

            if (state.Name == selectFarStateName)
            {
                // Add listeners that monitor whether or not the SelectFar state's Global property has been changed
                AddGlobalPropertyChangedListeners(selectFarStateName);
            }

            if (state.Name == speechKeywordStateName)
            {
                // Add listeners that monitor whether or not the SpeechKeyword state's Global property has been changed
                AddGlobalPropertyChangedListeners(speechKeywordStateName);
            }
        }
        /// <summary>
        /// Create and add a new state given the state name and the associated existing event configuration.
        /// </summary>
        /// <param name="stateName">The name of the state to create</param>
        /// <param name="eventConfiguration">The existing event configuration for the new state</param>
        /// <returns>The new state added</returns>
        public InteractionState AddNewStateWithCustomEventConfiguration(string stateName, BaseInteractionEventConfiguration eventConfiguration)
        {
            InteractionState state = GetState(stateName);

            if (state == null)
            {
                // Check if the new state name defined is considered a core state
                if (!coreStates.Contains(stateName))
                {
                    InteractionState newState = AddNewState(stateName);

                    if (eventConfiguration != null)
                    {
                        // Set the event configuration if one exists for the core interaction state
                        EventReceiverManager.SetEventConfiguration(newState);
                    }
                    else
                    {
                        Debug.LogError("The event configuration entered is null and the event configuration was not set");
                    }

                    // Add the state to the States list to ensure the inspector displays the new state
                    interactionStates.Add(newState);

                    statesDictionary.Add(newState.Name, newState);
                    return(newState);
                }
                else
                {
                    Debug.LogError($"The state name {stateName} is a defined core state, please use AddCoreState() to add to the States list.");
                    return(null);
                }
            }
            else
            {
                Debug.LogError($"The {stateName} state is already tracking, please use another name.");
                return(state);
            }
        }
        /// <summary>
        /// Gets and sets state given the state name and state value.
        /// </summary>
        /// <param name="stateName">The name of the state to set</param>
        /// <param name="value">The new state value</param>
        /// <returns>The state that was set</returns>
        public InteractionState SetState(string stateName, int value)
        {
            InteractionState state = GetState(stateName);

            if (state != null)
            {
                if (value > 0)
                {
                    SetStateOn(stateName);
                }
                else
                {
                    SetStateOff(stateName);
                }
            }
            else
            {
                Debug.LogError($"The {stateName} state is not being tracked, add this state using AddState(state) to set it");
            }

            return(state);
        }
        /// <summary>
        /// Removes a state. The state will no longer be tracked if it is removed.
        /// </summary>
        /// <param name="stateName">The name of the state to remove</param>
        public void RemoveState(string stateName)
        {
            InteractionState state = GetState(stateName);

            if (state != null)
            {
                if (stateName != defaultStateName)
                {
                    // Remove the state from States list to update the changes in the inspector
                    interactionStates.Remove(state);

                    statesDictionary.Remove(state.Name);
                }
                else
                {
                    Debug.LogError($"The {state.Name} state cannot be removed.");
                }
            }
            else
            {
                Debug.LogError($"The {stateName} state is not being tracked and was not removed.");
            }
        }
        /// <summary>
        /// Gets and sets a state to On and invokes the OnStateActivated event. Setting a
        /// state on changes the state value to 1.
        /// </summary>
        /// <param name="stateName">The name of the state to set to on</param>
        /// <returns>The state that was set to on</returns>
        public InteractionState SetStateOn(string stateName)
        {
            InteractionState state = GetState(stateName);

            if (state != null)
            {
                // Only update the state value and invoke events if InteractiveElement is Active
                if (state.Value != 1 && InteractiveElement.Active)
                {
                    state.Value  = 1;
                    state.Active = true;

                    OnStateActivated.Invoke(state);

                    // Only add the state to activeStates if it is not present
                    if (!activeStates.Contains(state))
                    {
                        activeStates.Add(state);
                    }

                    InteractionState defaultState = GetState(defaultStateName);

                    // If the state getting switched on and is NOT the default state, then make sure the default state is off
                    // The default state is only active when ALL other states are not active
                    if (state.Name != defaultStateName && defaultState.Active)
                    {
                        SetStateOff(defaultStateName);
                    }
                }
            }
            else
            {
                Debug.LogError($"The {stateName} state is not being tracked, add this state using AddState(state) to set it");
            }

            return(state);
        }