using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Innovation;
using System;

namespace TestEnvironment
{
    public class Game1 : Game
    {
        // The IGraphicsDeviceService the engine will use
        GraphicsDeviceManager graphics;
        GaussianBlur blur;

        public Game1()
        {
            // Setup graphics
            graphics = new GraphicsDeviceManager(this);
            graphics.PreferredBackBufferWidth = 1280;
            graphics.PreferredBackBufferHeight = 760;
        }

        protected override void LoadContent()
        {
            // Setup engine. We do this in the load method
            // so that we know graphics will be ready for use
            Engine.SetupEngine(graphics);

            // Create a new Camera
            FPSCamera camera = new FPSCamera();

            // Setup its position and target
            camera.Position = new Vector3(138.2664f, 37.25768f, 128.8698f);
            camera.RotateTranslate(new Vector3(-.1417831f * 2f, .4225208f * 2, 0), Vector3.Zero);

            // Add it to the service container
            Engine.Services.AddService(typeof(Camera), camera);

            // Setup physics
            Engine.Services.AddService(typeof(Physics), new Physics());

            Terrain terrain = new Terrain(
                Engine.Content.Load<Texture2D>("Content/heightmap"), 
                Engine.Content.Load<Texture2D>("Content/grass"));

            // Load the model we will use for our boxes
            Model model = Engine.Content.Load<Model>("Content/ig_box");

            // Create the stack of boxes
            for (int y = 0; y < 3; y++)
                for (int x = 0; x < 3; x++)
                {
                    PhysicsActor act = new PhysicsActor(model, new BoxObject(
                        new Vector3(.5f),
                        new Vector3(-.5f + (x * 0.52f), .5f + (y * 0.52f), -1),
                        Vector3.Zero));

                    act.Scale = new Vector3(.5f);
                }

            MouseDevice mouse = new MouseDevice();
            KeyboardDevice keyboard = new KeyboardDevice();

            Engine.Services.AddService(typeof(MouseDevice), mouse);
            Engine.Services.AddService(typeof(KeyboardDevice), keyboard);

            blur = new GaussianBlur(Engine.GraphicsDevice.Viewport.Width, Engine.GraphicsDevice.Viewport.Height);
        }

        protected override void Update(GameTime gameTime)
        {
            // Update the engine and game
            Engine.Update(gameTime);

            KeyboardDevice keyboard = Engine.Services.GetService<KeyboardDevice>();
            MouseDevice mouse = Engine.Services.GetService<MouseDevice>();
            FPSCamera cam = (FPSCamera)Engine.Services.GetService<Camera>();

            Vector3 inputModifier = new Vector3(
                (keyboard.IsKeyDown(Keys.A) ? -1 : 0) + (keyboard.IsKeyDown(Keys.D) ? 1 : 0),
                (keyboard.IsKeyDown(Keys.Q) ? -1 : 0) + (keyboard.IsKeyDown(Keys.E) ? 1 : 0),
                (keyboard.IsKeyDown(Keys.W) ? -1 : 0) + (keyboard.IsKeyDown(Keys.S) ? 1 : 0)
            );

            cam.RotateTranslate(new Vector3(mouse.Delta.Y * -.002f, mouse.Delta.X * -.002f, 0), inputModifier * .5f);

            if (mouse.WasButtonPressed(MouseButtons.Left))
            {
                PhysicsActor act = new PhysicsActor(
                    Engine.Content.Load<Model>("Content/ig_box"),
                    new BoxObject(new Vector3(2.5f), cam.Position, Vector3.Zero));

                act.Scale = new Vector3(2.5f);
                act.PhysicsObject.Mass = 1000;

                Vector3 dir = cam.Target - cam.Position;
                dir.Normalize();

                act.PhysicsObject.Velocity = dir * 10;
            }

            base.Update(gameTime);
        }

        protected override void Draw(GameTime gameTime)
        {
            base.Draw(gameTime);

            // Draw the engine and game
            Engine.Draw(gameTime, ComponentType.All);

            blur.Draw();
        }
    }
}