using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;

namespace Camera
{
   public class CameraDemo : Microsoft.Xna.Framework.Game
   {
      GraphicsDeviceManager graphics;
      SpriteBatch spriteBatch;
      
      Model torus;
      Matrix[] torusFinalBones;
      
      Vector3 cameraPos = new Vector3(0, 0, 20);
      Vector3 lookAtPos = Vector3.Zero;
      Vector3 upDir = Vector3.UnitY;

      public CameraDemo()
      {
         graphics = new GraphicsDeviceManager(this);
         Content.RootDirectory = "Content";
      }


      protected override void Initialize()
      {
         base.Initialize();
      }


      protected override void LoadContent()
      {
         spriteBatch = new SpriteBatch(GraphicsDevice);

         torus = Content.Load<Model>("Models\\TorusRing");
         torusFinalBones = new Matrix[torus.Bones.Count];
      }


      protected override void UnloadContent()
      {

      }


      protected override void Update(GameTime gameTime)
      {
         if(Keyboard.GetState().IsKeyDown(Keys.Escape))
            this.Exit();

         float speed = 0.5f + (float)gameTime.ElapsedGameTime.TotalSeconds;
            
         if(Keyboard.GetState().IsKeyDown(Keys.Left))
         {
            cameraPos -= Vector3.UnitX * speed;
            lookAtPos -= Vector3.UnitX * speed;
         }
         
         if(Keyboard.GetState().IsKeyDown(Keys.Right))
         {
            cameraPos += Vector3.UnitX * speed;
            lookAtPos += Vector3.UnitX * speed;
         }
         
         if(Keyboard.GetState().IsKeyDown(Keys.Up))
         {
            cameraPos -= Vector3.UnitZ * speed;
            lookAtPos -= Vector3.UnitZ * speed;
         }
         
         if(Keyboard.GetState().IsKeyDown(Keys.Down))
         {
            cameraPos += Vector3.UnitZ * speed;
            lookAtPos += Vector3.UnitZ * speed;
         }
         
         if(Keyboard.GetState().IsKeyDown(Keys.S))
         {
            cameraPos -= Vector3.UnitY * speed;
            lookAtPos -= Vector3.UnitY * speed;
         }
         
         if(Keyboard.GetState().IsKeyDown(Keys.W))
         {
            cameraPos += Vector3.UnitY * speed;
            lookAtPos += Vector3.UnitY * speed;
         }

         base.Update(gameTime);
      }


      protected override void Draw(GameTime gameTime)
      {
         graphics.GraphicsDevice.Clear(Color.CornflowerBlue);

         torus.CopyAbsoluteBoneTransformsTo(torusFinalBones);
         
         foreach(ModelMesh mesh in torus.Meshes)
         {
            foreach(BasicEffect effect in mesh.Effects)
            {
               effect.World = torusFinalBones[mesh.ParentBone.Index];
               
               effect.View = Matrix.CreateLookAt(cameraPos,
                             lookAtPos, upDir);
               
               effect.Projection = Matrix.CreatePerspectiveFieldOfView(
                                   MathHelper.ToRadians(45.0f),
                                   GraphicsDevice.Viewport.AspectRatio,
                                   0.1f, 10000);
            
               effect.EnableDefaultLighting();
               effect.PreferPerPixelLighting = true;
            
               mesh.Draw();
            }
         }

         base.Draw(gameTime);
      }
   }
}
