using System;
using ComponentFramework;
using ComponentFramework.Modules;
using MTV3D65;
using FullScreenShaders.Services;

namespace FullScreenShaders.Components.Controllers
{
    [AutoLoad]
    class CameraControl : Component
    {
        const float MovementSpeed = 5;
        const float CameraRotationSpeed = 1 / 400.0f;

        TVCamera camera;
        TV_2DVECTOR cameraAngles;

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

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

            camera = CameraFactory.GetCamera(0);
            camera.SetViewFrustum(50, 30, 0.01f);
            camera.SetPosition(0, 0, -3);

            base.Initialize();
        }

        public override void Update(TimeSpan elapsedTime)
        {
            bool isRunning = InputEngine.IsKeyPressed(CONST_TV_KEY.TV_KEY_LEFTSHIFT);
            float moveSpeed = 0, strafeSpeed = 0;

            if (InputEngine.IsKeyPressed(CONST_TV_KEY.TV_KEY_W))
                moveSpeed = isRunning ? 1 : 0.5f;
            if (InputEngine.IsKeyPressed(CONST_TV_KEY.TV_KEY_S))
                moveSpeed = isRunning ? -0.6f : -0.4f;
            if (InputEngine.IsKeyPressed(CONST_TV_KEY.TV_KEY_A))
                strafeSpeed = isRunning ? -0.6f : -0.4f;
            if (InputEngine.IsKeyPressed(CONST_TV_KEY.TV_KEY_D))
                strafeSpeed = isRunning ? 0.6f : 0.4f;

            moveSpeed *= MovementSpeed * (float)elapsedTime.TotalSeconds;
            strafeSpeed *= MovementSpeed * (float)elapsedTime.TotalSeconds;

            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);

            if (Core.Settings.Fullscreen || (leftButton && SampleState.MouseInViewport))
            {
                cameraAngles.x += mouseY * CameraRotationSpeed;
                cameraAngles.y += mouseX * CameraRotationSpeed;

                camera.SetRotation(cameraAngles.x, cameraAngles.y, 0);
            }

            camera.MoveRelative(moveSpeed, 0, strafeSpeed);                
        }
        
        [ServiceDependency]
        public ISampleState SampleState { private get; set; }
    }
}