/// <summary>
        /// Constructor
        /// </summary>
        public Core()
        {
            // initialize turn signals
            TurnDecorators.Initialize();

            // set initial state
            CoreCommon.CorePlanningState = new StartUpState();

            // start a new behavioral layer
            this.Behavioral = new BehavioralDirector();

            // start new lane agent
            this.coreLaneAgent = new LaneAgent();

            // create execution stopwatch
            this.executionStopwatch = new Stopwatch();
        }
        public static IState FilterStates(CarMode carMode, BehavioralDirector behavioral)
        {
            // check run mode
            if (carMode == CarMode.Run)
            {
                // check if goals left
                if (CoreCommon.Mission.MissionCheckpoints.Count > 0)
                {
                    // good to go
                    return(CoreCommon.CorePlanningState);
                }
                // otherwise need to stop
                else
                {
                    // no goals left
                    return(new NoGoalsLeftState());
                }
            }
            else if (carMode == CarMode.EStop)
            {
                // move to the estopped state
                return(new eStoppedState());
            }
            else if (carMode == CarMode.Human)
            {
                // clear out standard (non-intersection) queuing values
                TacticalDirector.RefreshQueuingMonitors();

                // clear other timings
                behavioral.ResetTiming();

                // clear intersection timings
                if (IntersectionTactical.IntersectionMonitor != null)
                {
                    IntersectionTactical.IntersectionMonitor.ResetTimers();
                }

                // human mode
                return(new HumanState());
            }
            else if (carMode == CarMode.Pause || carMode == CarMode.TransitioningFromPause || carMode == CarMode.TransitioningToPause)
            {
                // check if the state is a paused state
                if (CoreCommon.CorePlanningState is PausedState)
                {
                    // stay paused
                    return(CoreCommon.CorePlanningState);
                }
                // otherwise we need to go into pause
                else
                {
                    // clear other timings
                    behavioral.ResetTiming();

                    // clear out standard (non-intersection) queuing values
                    TacticalDirector.RefreshQueuingMonitors();
                    behavioral.tactical.ResetTimers();

                    if (IntersectionTactical.IntersectionMonitor != null)
                    {
                        IntersectionTactical.IntersectionMonitor.ResetTimers();
                    }

                    // make a new paused state with the previous state intact
                    return(new PausedState(CoreCommon.CorePlanningState));
                }
            }
            else
            {
                // notify of unknown state
                throw new Exception("Unknown car mode type");
            }
        }