/******************************************************************
  
  Module:  animcontroller.h
  
  Author: Sean Craig
  
  Description: Based on input from intel classes (controller input
  or AI), update the currently playing animation.

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

#ifndef ANIMCONTROLLER_H
#define ANIMCONTROLLER_H

//-------------------------------------------------------- Includes
#include "SyTypes.h"
#include "SyMap.h"
#include "gameobj.h"
#include "rulepacket.h" // for eComboType
//-------------------------------------------------------- Typedefs
//---------------------------------------------- Class Declarations

class cGameObject;
// Variables anim controller uses to determine which animation
// to play.  Part of the public interface; just set the variables
// and the anim controller will take care of the rest.

typedef enum 
{
  AS_STAND,
  AS_RUN,
  AS_ATTACK_L,
  AS_ATTACK_H,
  AS_ATTACK_LL,
  AS_ATTACK_LH,
  AS_ATTACK_HL,
  AS_ATTACK_HH,
  AS_ATTACK_LLL,
  AS_ATTACK_LLH,
  AS_ATTACK_LHL,
  AS_ATTACK_LHH,
  AS_ATTACK_HLL,
  AS_ATTACK_HLH,
  AS_ATTACK_HHL,
  AS_ATTACK_HHH,
  AS_JUMP,
  AS_IN_AIR,
  AS_LAND,
  AS_DEATH,
  AS_HITREACT,    
  AS_BLOCK,
  AS_ATTACK_RANGED,
  AS_OVERRIDE,
  AS_RUN_JUMP,
  AS_RUN_IN_AIR,
  AS_RUN_LAND,
  AS_DODGE,
  AS_EMOTE_ANGER,
  AS_KNOCKBACK,
  AS_KNOCKBACK_IN_AIR,
  AS_KNOCKBACK_LAND,
  AS_KNOCKBACK_GETUP,
  AS_KNOCKFORWARD,
  AS_KNOCKFORWARD_IN_AIR,
  AS_KNOCKFORWARD_LAND,
  AS_KNOCKFORWARD_GETUP,
  NUM_ANIM_STATES
} eAnimState;

class cAnimCharControllerInput 
{
public:
  cAnimCharControllerInput();    
  void Clear();

  float         mHeadingRequest; // direction of travel, in radians; 0 = south (0,0,1)
                // PI/4 (90 degrees) = west (-1,0,0)
  float         mSpeedRequest; // 0-1 with 1.0f being a full run in that direction


  bool          mAttackRequestL;  
  bool          mAttackRequestS;  
  bool          mAttackRequestRanged;  
  tGameObjectID mTarget;          // target of attack
  float         mTargetAngle;     // if there is no target, turn to face this angle
  float         mTargetRange;     // used for range attacks, how far away to fire
  bool          mBlockRequest;    // true if a block is requested
  bool          mJumpRequest;     // true if a block is requested
  bool          mHitReact;        // true if a block is requested
  tGameObjectID mHitReactTarget;  // target of attack
  float         mHitReactAmount;
  bool          mDeath;
  bool          mFall;
  float         mHeight;          // for determining when we hit the ground
  float         mYVel;            // Y velocity

  bool          mActionRequest;
  tGameObjectID mActionTarget;

  int32         mAbilityRequest;  // request to perform a particular special ability

  int32         mAnimationOverride; // override whatever animation is playing with this AnimHandle.
  bool          mOverrideCancelEnd; // stop the override as soon as the animation is finished
  bool          mOverrideCancelImmediate; // stop the override immediately

  bool          mDodging;
  float         mDodgeDirection;  // angle in radians  
  bool          mDodgeHigh;      // true until right controller falls below dodge threshold

  bool          mEmoteAnger;      // Play angry animation

  bool          mbKnockback;
  bool          mbKnockforward;
  SyVect3       mKnockbackVect;
  float         mKnockbackHeading;
  
};


class cAnimControllerInterface
{
public:
  virtual ~cAnimControllerInterface() {}

  virtual void            Init(cGameObject *owner)=0;
  virtual void            Reset()=0;
  virtual void            Update(float time)=0;
  virtual cGameObject*    GetOwner()=0;
  virtual void            NetworkReceiveBroadcast(const char *state, int statelen)=0;
};


class cAnimCharControllerInterface : public cAnimControllerInterface
{
public:
  virtual ~cAnimCharControllerInterface();

  cAnimCharControllerInput*   GetInput(){return &mInput;};
  virtual float               GetDamageMultiplier(eComboType combo)=0;
  virtual float               GetStrikethroughMultiplier(eComboType combo)=0;
  virtual float               GetRange(eComboType combo)=0;
  virtual eAnimState          GetAnimState() const = 0;
  virtual const char *        GetAnimStateName() const=0;

  bool                        IsAttacking() const;
  virtual bool                IsBlocking() const=0;

  static cAnimCharControllerInterface *Allocate();

protected:

  cAnimCharControllerInterface(); // call the static function Allocate instead;

  cAnimCharControllerInput mInput;
};

class cAnimPropControllerInterface
{
public:
  enum PropAnimState
  {
    PAS_BASE = 1,
    PAS_DESTROY,
    PAS_ACTIVATE,
    PAS_DEACTIVATE,
    PAS_MISC,
    PAS_NUM_STATES
  };

  virtual ~cAnimPropControllerInterface() {}

  virtual void            Init(cGameObject *owner)=0;
  virtual void            Reset()=0;
  virtual void            Update(float time)=0;
  virtual cGameObject*    GetOwner()=0;
  virtual void            NetworkReceiveBroadcast(const char *state, int statelen)=0;

  virtual void            ChangeAnimState(PropAnimState newState)=0;
  virtual PropAnimState   GetAnimState() const = 0;
  virtual const char *    GetAnimStateName() const=0;

  static cAnimPropControllerInterface *Allocate();
};



typedef int32 tAnimSetID;

class cAnimControllerSetting;  // variables that vary between animation sets; for example, attack frame and timing information...
class cAnimControllerSys
{
public:
  cAnimControllerSys();
  ~cAnimControllerSys();

  void Init();
  void Reload();
  cAnimControllerSetting  *Fetch(tAnimSetID id,int animstate);

protected:
  static void RegisterTuningVariables();

  SyVector<cAnimControllerSetting *>  mSettings;

};
//------------------------------------------- Function Declarations

// todo : move these somewhere else (SyMath.h?)
float AngleDifference(float start, float end );
float AngleNormalize(float start);
//--------------------------------------------------------- Globals
//------------------------------------------------ Inline Functions

#endif
