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 AnimationPath
{
   public class AnimationPathDemo : Microsoft.Xna.Framework.Game
   {
      GraphicsDeviceManager graphics;
      SpriteBatch spriteBatch;
      
      Model torus;
      Matrix[] torusFinalBones;
      Vector3 torusPos = Vector3.Zero;
      
      Vector3 cameraPos = new Vector3(0, 0, 50);
      Vector3 lookAtPos = Vector3.Zero;
      Vector3 upDir = Vector3.UnitY;
      
      AnimationRoute torusAnimation;

      public AnimationPathDemo()
      {
         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];
         
         torusAnimation = new AnimationRoute();

         torusAnimation.AddPath(new Vector3(-15, -10, 0),
                                new Vector3( 15, -10, 0));

         torusAnimation.AddPath(new Vector3( 15, -10, 0),
                                new Vector3( 15,  10, 0));

         torusAnimation.AddPath(new Vector3( 15,  10, 0),
                                new Vector3(-15,  10, 0));

         torusAnimation.AddPath(new Vector3(-15,  10, 0),
                                new Vector3(-15, -10, 0));
      }


      protected override void UnloadContent()
      {

      }


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

         torusPos = torusAnimation.GetPosition(gameTime.ElapsedGameTime.Milliseconds,
                                               0.001f);

         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] *
                              Matrix.CreateTranslation(torusPos);

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