/// <summary>
        /// Update component
        /// </summary>
        /// <param name="dT">spend time [sec]</param>
        public override void Update(double dT)
        {
            var mapSys = MapSystem.GetInstance();

            m_coroutine.Update(dT);

            if (!m_coroutine.HasCompleted())
            {
                // wait for end of character operation
                return;
            }

            var cameraSys = CameraSystem.GetInstance();
            var drawSys   = DrawSystem.GetInstance();

            var gameSys = GameSystem.GetInstance();

            switch (gameSys.Config.InputDevice)
            {
            case GameConfig.UserInputDevices.MouseKeyboard:
            {
                IMouseKeyboardInputSource src = InputSystem.GetInstance().MouseKeyboard;

                var v = Vector3.Zero;
                if (src.TestKeyState(Keys.W))
                {
                    v.Z += PositionFactor;
                }
                if (src.TestKeyState(Keys.A))
                {
                    v.X -= PositionFactor;
                }
                if (src.TestKeyState(Keys.D))
                {
                    v.X += PositionFactor;
                }
                if (src.TestKeyState(Keys.S))
                {
                    v.Z -= PositionFactor;
                }

                if (v.X != 0 || v.Z != 0)
                {
                    // @todo
                }
            }
            break;

            case GameConfig.UserInputDevices.Pad:
            {
                IPadInputSource src = InputSystem.GetInstance().Pad;

                // update move
                {
                    _InputType inputType = _InputType.None;

                    var   thumbDir  = src.LeftThumbInput.Direction;
                    float magnitude = src.LeftThumbInput.NormalizedMagnitude;
                    if (magnitude >= MinimumPadMagnitude)
                    {
                        // use pad stick
                        if (thumbDir.Y <= -0.851)
                        {
                            inputType = _InputType.Backward;
                        }
                        else if (thumbDir.Y >= 0.851)
                        {
                            inputType = _InputType.Forward;
                        }
                        else
                        {
                            if (thumbDir.X < 0)
                            {
                                inputType = _InputType.Left;
                            }
                            else
                            {
                                inputType = _InputType.Right;
                            }
                        }
                    }
                    else
                    {
                        // use pad cross key
                        if (src.TestButtonState(InputSystem.PadButtons.Down))
                        {
                            inputType = _InputType.Backward;
                        }
                        else if (src.TestButtonState(InputSystem.PadButtons.Up))
                        {
                            inputType = _InputType.Forward;
                        }
                        else if (src.TestButtonState(InputSystem.PadButtons.Left))
                        {
                            inputType = _InputType.Left;
                        }
                        else if (src.TestButtonState(InputSystem.PadButtons.Right))
                        {
                            inputType = _InputType.Right;
                        }
                    }

#if true
                    switch (inputType)
                    {
                    case _InputType.Forward:
                    {
                        var         nextDir      = MapLocation.GetForwardDirection(m_currentLocation.Direction);
                        MapLocation?nextLocation = mapSys.Walk(m_currentLocation, nextDir);
                        if (nextLocation.HasValue)
                        {
                            m_currentLocation = nextLocation.Value;
                            var pose = mapSys.GetPose(m_currentLocation);
                            m_coroutine.Start(new _MoveToTask(this, pose.TranslationVector));                                                            // no turn
                        }
                    }
                    break;

                    case _InputType.Backward:
                    {
                        var nextDir = MapLocation.GetBackwardDirection(m_currentLocation.Direction);
                        m_currentLocation.Direction = nextDir;
                        var pose = mapSys.GetPose(m_currentLocation);
                        m_coroutine.Start(new _TurnToTask(this, pose.Forward));
                    }
                    break;

                    case _InputType.Left:
                    {
                        var nextDir = MapLocation.GetLeftDirection(m_currentLocation.Direction);
                        m_currentLocation.Direction = nextDir;
                        var pose = mapSys.GetPose(m_currentLocation);
                        m_coroutine.Start(new _TurnToTask(this, pose.Forward));
                    }
                    break;

                    case _InputType.Right:
                    {
                        var nextDir = MapLocation.GetRightDirection(m_currentLocation.Direction);
                        m_currentLocation.Direction = nextDir;
                        var pose = mapSys.GetPose(m_currentLocation);
                        m_coroutine.Start(new _TurnToTask(this, pose.Forward));
                    }
                    break;
                    }
#else
                    switch (inputType)
                    {
                    case _InputType.Forward:
                    {
                        var         nextDir      = MapLocation.GetForwardDirection(m_currentLocation.Direction);
                        MapLocation?nextLocation = mapSys.Walk(m_currentLocation, nextDir);
                        if (nextLocation.HasValue)
                        {
                            m_currentLocation = nextLocation.Value;
                            var pose = mapSys.GetPose(m_currentLocation);
                            m_coroutine.Start(new _MoveToTask(this, pose.TranslationVector));                                                            // no turn
                        }
                    }
                    break;

                    case _InputType.Backward:
                    {
                        var         nextDir      = MapLocation.GetBackwardDirection(m_currentLocation.Direction);
                        MapLocation?nextLocation = mapSys.Walk(m_currentLocation, nextDir);
                        if (nextLocation.HasValue)
                        {
                            m_currentLocation = nextLocation.Value;
                            var pose = mapSys.GetPose(m_currentLocation);
                            m_coroutine.Start(Coroutine.Join(new _TurnToTask(this, pose.Forward), new _MoveToTask(this, pose.TranslationVector)));
                        }
                    }
                    break;

                    case _InputType.Left:
                    {
                        var         nextDir      = MapLocation.GetLeftDirection(m_currentLocation.Direction);
                        MapLocation?nextLocation = mapSys.Walk(m_currentLocation, nextDir);
                        if (nextLocation.HasValue)
                        {
                            m_currentLocation = nextLocation.Value;
                            var pose = mapSys.GetPose(m_currentLocation);
                            m_coroutine.Start(Coroutine.Join(new _TurnToTask(this, pose.Forward), new _MoveToTask(this, pose.TranslationVector)));
                        }
                    }
                    break;

                    case _InputType.Right:
                    {
                        var         nextDir      = MapLocation.GetRightDirection(m_currentLocation.Direction);
                        MapLocation?nextLocation = mapSys.Walk(m_currentLocation, nextDir);
                        if (nextLocation.HasValue)
                        {
                            m_currentLocation = nextLocation.Value;
                            var pose = mapSys.GetPose(m_currentLocation);
                            m_coroutine.Start(Coroutine.Join(new _TurnToTask(this, pose.Forward), new _MoveToTask(this, pose.TranslationVector)));
                        }
                    }
                    break;
                    }
#endif
                }
            }
            break;

            default:
                Debug.Fail("unsupported input device type : " + gameSys.Config.InputDevice);
                break;
            }
        }
 public FpsInputComponent(MapLocation startLocation)
     : base(GameEntityComponent.UpdateLines.Input)
 {
     m_coroutine       = new Coroutine();
     m_currentLocation = startLocation;
 }