#pragma once

#include <GR/GRTypes.h>

#include <Interface/IAnimationManager.h>

#include <list>

#include "BTypes.h"



class XRenderer;
class Level;

class Unit
{

  public:

    enum eUnitEvent
    {
      ET_INVALID,
      ET_INIT,
      ET_BLOCKED_LEFT,
      ET_BLOCKED_RIGHT,
      ET_BLOCKED_UP,
      ET_BLOCKED_DOWN,
      ET_FALL_START,
      ET_FALL_END,
      ET_DIE,
      ET_CARRY,
      ET_DROP,
      ET_MOVED_LEFT,
      ET_MOVED_RIGHT,
      ET_MOVED_UP,
      ET_MOVED_DOWN,
      ET_ENTER_PLATFORM,
      ET_LEAVE_PLATFORM,
      ET_GET_CAUGHT
    };


    Birdie2::eUnitTypes       m_Type;

    std::list<Unit*>          m_CarriedUnits;

    bool                      m_RemoveMe,
                              m_Jumping,
                              m_OnGround,
                              m_FaceLeft,
                              m_Floating,
                              m_IsPlatform,
                              m_IsNasty,
                              m_NoAutoAdjustFacing,
                              m_DisplayHit,
                              m_CoordinatesWrapAround;

    std::string               m_Image;
    std::string               m_Animation;

    GR::tPoint                m_Position;
    GR::tPoint                m_StartPosition;
    GR::tPoint                m_Speed;

    int                       m_JumpSpeed;
    int                       m_FallSpeed;
    int                       m_FallSpeedDelay;
    int                       m_HP;

    GR::f32                   m_LifeTime;
    GR::f32                   m_HitDisplayTime;

    GR::tRect                 m_MovementBounds;
    GR::tRect                 m_CollisionBounds;

    tAnimationPos             m_AnimPos;

    GR::u32                   m_ExtraData;
    GR::u32                   m_ExtraData2;

    Unit*                     m_pOnUnit;


    Unit();
    virtual ~Unit();


    virtual void              Display( const GR::tPoint& ptOffset, XRenderer& Renderer );
    virtual void              Update( Level& Level, const GR::f32 fElapsedTime );
    virtual void              UpdateFixed( Level& Level );

    GR::tRect                 MovementBounds();
    GR::tRect                 CollisionBounds();

    void                      SetAnimation( const std::string& Animation );
    void                      SetImage( const std::string& Image );

    virtual void              ProcessEvent( Level& Level, const eUnitEvent& Event );

    bool                      Jump( int Power );

    static Unit*              FromType( const Birdie2::eUnitTypes UnitType );

    bool                      Move( Level& Level, const GR::tPoint& Delta, bool bMovedByPlatform = false );
    void                      MoveUnblocked( Level& Level, int DX, int DY );
    void                      MoveCarriedUnits( Level& Level, int iDX, int iDY );

    virtual void              OnLoad( Level& Level );

};


