using System;
using ComponentFramework.Modules;
using MTV3D65;
using ComponentFramework;

namespace OctreeRendering
{
    [AutoLoad]
    class CameraControl : Component
    {
        const float MovementSpeed = 25;
        const float CameraRotationSpeed = 1 / 400.0f;

        Vector2f cameraAngles;

        public CameraControl(ICore core) : base(core) { }

        public override void Initialize()
        {
            Core.Engine.SetAngleSystem(CONST_TV_ANGLE.TV_ANGLE_RADIAN);

            CameraState.Camera.SetViewFrustum(60, 500, 0.01f);
            CameraState.OnProjectionChanged();
        }

        public override void Update(TimeSpan elapsedTime)
        {
            bool isRunning = KeyboardState.GetKeyState(CONST_TV_KEY.TV_KEY_LEFTSHIFT).IsDown();
            float moveSpeed = 0, strafeSpeed = 0;
            float actualSpeed = (isRunning ? 1 : 0.5f) * MovementSpeed * (float)elapsedTime.TotalSeconds;

            if (KeyboardState.GetKeyState(CONST_TV_KEY.TV_KEY_W).IsDown())
                moveSpeed += actualSpeed;
            if (KeyboardState.GetKeyState(CONST_TV_KEY.TV_KEY_S).IsDown())
                moveSpeed -= actualSpeed;
            if (KeyboardState.GetKeyState(CONST_TV_KEY.TV_KEY_A).IsDown())
                strafeSpeed -= actualSpeed;
            if (KeyboardState.GetKeyState(CONST_TV_KEY.TV_KEY_D).IsDown())
                strafeSpeed += actualSpeed;

            int mouseX = 0, mouseY = 0, dummyInt = 0;
            bool leftButton = false, dummy = false;

            InputEngine.GetMouseState(ref mouseX, ref mouseY, ref leftButton, ref dummy, ref dummy, ref dummy, ref dummyInt);

            cameraAngles.X = MathHelper.Clamp(cameraAngles.X + mouseY * CameraRotationSpeed, -MathHelper.HalfPi, MathHelper.HalfPi);
            cameraAngles.Y += mouseX * CameraRotationSpeed;

            CameraState.Camera.SetRotation(cameraAngles.X, cameraAngles.Y, 0);
            CameraState.Camera.MoveRelative(moveSpeed, 0, strafeSpeed);

            CameraState.OnViewChanged();
        }

        [ServiceDependency]
        public ICameraState CameraState { private get; set; }
        [ServiceDependency]
        public IKeyboardState KeyboardState { private get; set; }
    }
}
