/******************************************************************
  
  Module:  cameracontroller.h
  
  Author: Sean Craig
  
  Description: Responsible for updating the camera from frame to 
  frame.  An interface wrapper around Bijan's stuff. 

  
  Copyright 2005 Sony Online Entertainment.  All rights reserved.
  
*******************************************************************/

#ifndef CAMERACONTROLLER_H
#define CAMERACONTROLLER_H

//---------------------------------------------- ---------- Includes
#include "nameid.h"
#include "Titan.h"
#include "SyCamera.h"
//-------------------------------------------------------- Typedefs
//---------------------------------------------- Class Declarations

class TiCameraDirector;

typedef enum
{
  CAMERA_NEAR,
  CAMERA_MEDIUM,
  CAMERA_FAR,
  CAMERA_TWOPLAYER,
  NUM_CAMERA_TYPES
} eCameraSetting;


// class for smoothly transitioning a variable over time
class cTransient 
{
public:
  cTransient();
  ~cTransient(){};

  float GetValue(){return mValue;};
  void  SetValue(float value){mValue = value;};

  void  SetTarget(float target){mTarget = target;};
  float GetTarget(){return mTarget ;};
  void  SetVelocity(float vel){mVelocity = vel;};
  void  SetConstants(float maxVelocity, float acceleration)
  {
    mMaxVelocity = maxVelocity;
    mAcceleration = acceleration;
  };

  void  Update(float time);

protected:
  float DetermineDeltaV(float time);
  void  CheckCloseEnough(float time);
  float     mValue;
  float     mTarget;
  float     mVelocity;

  float     mMaxVelocity;
  float     mAcceleration;

};

class cCameraController
{
public:

  cCameraController(Titan *titan);
 
  ~cCameraController();
  /// Initializes the application
  bool OnInit();

  /// Called on exit
  void OnExit();

  static void RegisterTuningVariables();
  void LoadCameraFile(const char *camFileName);

  void SetTarget(tGameID id);
  void Update(float time); 
  SyCamera *GetCamera(){return &mCamera;};

  // returns the camera heading to be used for camera-relative controls
  // time_held_down is the amount of time the controller has been depressed;
  // this is used when the camera cuts to introduce a lag to give the player
  // a chance to respond to the switched camera.

  float GetControlOffset(float time_held_down);

  // Mechanism to allow for outside modules to override normal camera controller camera.
  bool UseOverrideCamera();
  void OverrideCamera (const SyVect3& cameraPosition, const SyVect3& cameraDirection, const float32& cameraFov);
  void ClearOverrideCamera ();

  void Zoom(float amount);
  void Pan(float amount);
  void SetHeading(float heading);

protected:

  void  DetermineSettings();
  void  SettingUp();
  void  SettingDown();
  void  GetCameraLocation(SyVect3 *result,float distance, 
                                           float pitch, 
                                           float heading, 
                                           float lead_distance,
                                           float y_offset);

  bool  Collide(SyVect3 *col_point,SyVect3 start,SyVect3 end);
  void  Drift();


  Titan   *         mTitan;
  tGameID           mTarget;
  SyCamera          mCamera;
  TiCameraDirector *mDirector;
  float32           mCutTime;
  SyVect3           mCutDir;
  bool              mCutStored;
  bool              mPrevDirStored;
  SyVect3           mPrevDir;
  bool              mOverrideCameraFlag;
  SyVect3           mOverrideCameraPosition;
  SyVect3           mOverrideCameraDirection;
  float32           mOverrideCameraFov;

  SyVect3           mPrevLoc;


  typedef enum
  {
    SETTING_CHANGE_DOWN,
    SETTING_CHANGE_NONE,
    SETTING_CHANGE_UP
  } eSettingChangeState;

  eSettingChangeState mSettingChangeState;
  float             mSettingChangeTime;

  eCameraSetting    mSetting;

  cTransient        mDistance;
  cTransient        mHeading;
  cTransient        mPitch;
  cTransient        mYOffset;
  cTransient        mLeadDistance;
  cTransient        mFOV;


};

//------------------------------------------- Function Declarations
//--------------------------------------------------------- Globals
//------------------------------------------------ Inline Functions

#endif
