#pragma once

#include <Spiel/2dLayer.h>

#include <Interface/IIOStream.h>

#include <Lang/FastDelegate.h>

#include <list>

#include "BTypes.h"



class Unit;
class XRenderer;

class Level
{

  public:

    typedef std::list<Unit*>         tListUnits;


    GR::Gamebase::TileLayer2D<Birdie2::eFeldTypes>     m_Field;
    GR::Gamebase::TileLayer2D<Birdie2::eFeldTypes>     m_Background;

    tListUnits                        m_Units;

    typedef fastdelegate::FastDelegate1<const Birdie2::CGameEvent&> tEventHandlerFunction;

    tEventHandlerFunction             m_GameEventHandler;

    std::vector<GR::tPoint>           m_ExtraStartPositions;
    std::vector<GR::tPoint>           m_FlashStartPositions;

    GR::f32                           m_StartPause;
    GR::f32                           m_DonePause;
    GR::f32                           m_DeathPause;

    GR::u32                           m_NastiesAlive;

    GR::tFPoint                       m_Offset;

    GR::f32                           m_FixedTime;

    int                               m_ExtraStartDelay;
    int                               m_FlashStartDelay;

    GR::tPoint                        m_BubbleTargetPos;



    Level();
    ~Level();


    void                              Display( XRenderer& Renderer );
    void                              Update( const GR::f32 ElapsedTime );
    void                              UpdateFixed();

    void                              UpdateUnits( GR::f32 ElapsedTime );
    void                              UpdateUnitsFixed();

    void                              Clear();

    bool                              IsFeldBlocking( Unit* pUnit, const Birdie2::eFeldTypes Feld, Birdie2::eDir Dir );
    bool                              CanMove( Unit* pUnit, const GR::tPoint& ptCurPos, Birdie2::eDir Dir );

    bool                              Load( IIOStream& StreamIn );
    bool                              Save( IIOStream& StreamIn );

    GR::u32                           OnCollision( Unit* pUnit1, Unit* pUnit2 );

    bool                              PrepareForStart();
    bool                              IsCompleted();

    bool                              OnTopOfPlatform( Unit* pUnit );

    Unit*                             SpawnExtra();
    Unit*                             SpawnFlash();

    Unit*                             SpawnUnit( int X, int Y, Birdie2::eUnitTypes UnitType );

    void                              CreateBorders();
    bool                              IsTileBorder( Birdie2::eFeldTypes Field );

    bool                              UnitMustStayInBounds( Birdie2::eUnitTypes UnitType );

};
