/******************************************************************
  
  Module:  areaeffect.h
  
  Author: Sean Craig
  
  Description:  System for active spells and explosions with area 
  effects.
  
  Copyright 2005 Sony Online Entertainment.  All rights reserved.
  
*******************************************************************/

#ifndef AREAEFFECT_H
#define AREAEFFECT_H

//-------------------------------------------------------- Includes

#include "gameobj.h"
#include "rulepacket.h"
//-------------------------------------------------------- Typedefs
//---------------------------------------------- Class Declarations
class Titan;


class cGameEffect
{
public:
  cGameEffect(Titan *titan) : mpTitan(titan){};
  virtual void  OnEnter(tGameObjectID id){};
  virtual void  Update(tGameObjectID id,float time){};
  virtual void  OnExit(tGameObjectID id){};

protected:
  Titan     *mpTitan;
};

class cGameEffect_ScriptCall : public cGameEffect
{
public:
  cGameEffect_ScriptCall(Titan *titan);

  void SetOwner(tGameObjectID id) {mOwner = id;};
  virtual void  OnEnter(tGameObjectID id);
  virtual void  OnExit(tGameObjectID id);

protected:
  tGameObjectID     mOwner;
};

class cGameEffect_Damage : public cGameEffect
{
public:
  cGameEffect_Damage(Titan *titan);

  void  SetSource(tGameObjectID source) {mSource= source;};
  void  SetDamage(int damage,eNormalDamageType normalType,eMagicDamageType magicType);
  
  virtual void  OnEnter(tGameObjectID id);

protected:

  tGameObjectID     mSource;
  int               mDamage;
  eNormalDamageType mNormalType;
  eMagicDamageType  mMagicType;
};

class cGameEffect_Attack : public cGameEffect
{
public:
  cGameEffect_Attack(Titan *titan);

  void  SetSource(tGameObjectID source) {mSource= source;};
  void  SetAttackIndex(int index){mAttackIndex = index;};
  
  virtual void  OnEnter(tGameObjectID id);

protected:

  tGameObjectID     mSource;
  int               mAttackIndex;
};

class cGameEffect_Knockback : public cGameEffect
{
public:
  cGameEffect_Knockback(Titan *titan);

  void  SetLocation(const SyVect3 &location) {mLocation= location;};
  void  SetAmount(float xz,float y){mXZAmount = xz;mYAmount = y;};
  
  virtual void  OnEnter(tGameObjectID id);

protected:

  SyVect3           mLocation;
  float             mXZAmount;
  float             mYAmount;
};

class cAreaEffect
{
public:
  cAreaEffect(Titan *titan); 
  virtual ~cAreaEffect();

  virtual void Update(float time);
  virtual void AddGameEffect(cGameEffect *effect) {mEffects.Add(effect);};
  virtual bool  IsExpired(){return false;}
          void  SetSource(tGameObjectID id){mSource= id;};


protected:
          void  UpdateIncluded(float time);
  virtual bool  IsIncluded(cGameObject *obj);
  virtual bool  IsInside(cGameObject *obj)=0;
          void  OnEnter(cGameObject* obj); 
          void  OnExit(cGameObject* obj); 
          void  UpdateEffect(cGameObject* obj,float time);

  SyVector<tGameObjectID>  mIncluded;
  SyVector<cGameEffect *>  mEffects;
  Titan       *            mpTitan;
  tGameObjectID            mSource;
};


class cAreaEffect_Radius  : public cAreaEffect
{
public:
  cAreaEffect_Radius(Titan *titan);

  void          SetLocation(const SyVect3  &loc){mLocation = loc;};
  void          SetRadius(float radius){mRadius= radius;};

protected:

  virtual bool  IsInside(cGameObject *obj);

  SyVect3       mLocation;
  float         mRadius;
};


class cAreaEffect_Burst  : public cAreaEffect_Radius
{
public:
  cAreaEffect_Burst(Titan *titan);

  virtual void  Update(float time);

  void          SetSpeed(float speed){mSpeed = speed;};
  void          SetMaxRadius(float maxRadius){mMaxRadius = maxRadius;};
  virtual bool  IsExpired();

protected:
  float         mSpeed;
  float         mMaxRadius;
};

class cAreaEffect_ChainLightning : public cAreaEffect
{
public:
  cAreaEffect_ChainLightning(Titan *titan);

  virtual void  Update(float time);
  virtual bool  IsExpired();
  void SetDuration(float time) { mDuration = time; }  
  void SetTargetDelay(float time) { mTargetDelay = time; mTargetDelayTimer = time; }
  void SetMaxTargets(int numTargets) { mMaxTargets = numTargets; }
  void SetMaxDistance(float dist) { mMaxDist = dist; }

protected:
  virtual bool  IsInside(cGameObject *obj);
  virtual tGameObjectID SelectNextTarget(); 

  float mDuration;
  float mTargetDelay, mTargetDelayTimer;
  float mMaxDist;
  int mMaxTargets;
  tGameObjectID mNextTargetID;

};


class cAreaEffect_Arc  : public cAreaEffect
{
public:
  cAreaEffect_Arc(Titan *titan);

  virtual void  Update(float time);

  void          SetArc(const SyVect3 &loc,float speed, float radius,float start,float end);
  virtual bool  IsExpired();

protected:

  virtual bool  IsInside(cGameObject *obj);

  float         mSpeed;
  float         mRadius;
  float         mStart;
  SyVect3       mLoc;
  float         mEnd;

  float         mCur;
  bool          mDone;
};


class cAreaEffectSys 
{

public:
  ~cAreaEffectSys();

  void Add(cAreaEffect *effect);    
  void Clear();
  void Update(float time);
protected:
  SyVector<cAreaEffect *> mAreaEffects;
};



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

#endif                   
