#region Using Statements
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
#endregion

namespace GhostArena3D
{
   public class Ghost
   {
      #region Variables

      bool isDead;
      Vector3 direction, position, viewTarget;      
      Matrix finalTransformation;      
      BoundingSphere collisionSphere;
      
      #endregion
      
      #region Properties
      
      public Vector3 Direction
      {
         get { return direction; }
         set { direction = value; }
      }
      
      
      public Vector3 Position
      {
         get
         {
            return position;
         }
         set
         {
            position = value;
            collisionSphere.Center = position;
         }
      }
      
      
      public Vector3 Target
      {
         get { return viewTarget; }
         set { viewTarget = value; }
      }
      
      
      public Matrix Transformation
      {
         get { return finalTransformation; }
         set { finalTransformation = value; }
      }
      
      
      public bool Alive
      {
         get { return isDead; }
         set { isDead = value; }
      }
      
      
      public BoundingSphere CollisionSphere
      {
         get { return collisionSphere; }
         set { collisionSphere = value; }
      }
      
      #endregion
      
      public Ghost(Vector3 pos, Vector3 dir, float collisionRadius)
      {
         position = pos;
         direction = dir;
         finalTransformation = Matrix.CreateTranslation(position);
         collisionSphere = new BoundingSphere(position, collisionRadius);
         
         isDead = false;
      }
      
      
      public void Move(Vector3 direction, float amount)
      {
         position += direction * amount;
         collisionSphere.Center = position;
      }
      
      
      public Matrix OrientationToTarget(Vector3 target)
      {
         Vector3 vecToTarget = Vector3.Normalize(target - position);
         Vector3 axisToRotate = Vector3.Cross(direction, vecToTarget);

         double angle = Math.Acos((double)Vector3.Dot(direction, vecToTarget));

         // Avoid divide by zero.  Setting to Unit Y is suitable for this
         // game application.  This case would occur if the cross product
         // of the vectors equal 0.
         if(axisToRotate == Vector3.Zero)
            axisToRotate = Vector3.UnitY;
         else
            axisToRotate.Normalize();

         Matrix orientation = Matrix.CreateFromAxisAngle(axisToRotate, (float)angle);
         
         return orientation;
      }
      
      
      public void UpdateFinalMatrix()
      {
         Matrix translation = Matrix.CreateTranslation(position);
         Matrix orientation = OrientationToTarget(viewTarget);
         finalTransformation = orientation * translation;
      }
   }
}
