#pragma once

#include <list>
#include <set>
#include <Box2D/Box2D.h>

#include "scene.hpp"
#include "block.hpp"
#include "entity/hero.hpp"

#include "collider.hpp"

#include <render/atlas.hpp>

#define TYPE_HERO    0b1000000
#define TYPE_ENEMY   0b0100000
#define TYPE_WALL    0b0010000
#define TYPE_BULLET  0b0001000
#define TYPE_POWERUP 0b0000100
#define TYPE_EBULLET 0b0000010
#define TYPE_TRIGGER 0b0000001

namespace game {

class World: public Scene
{
private:
    std::list<Block*> blocks;
    std::set<entity::Entity*> entities;
    std::set<entity::Entity*> entitiesForRemove;
    entity::Hero *player;

    b2World *physic;

    ColliderListener collider;

    int blocksPassed, scores;

    void SetupWalls();

    bool isGameOver = false;

    render::sprite::Icon gameOverIcon;

public:

    World();
    virtual ~World();

    void Show() noexcept;
    void Hide() noexcept;

    void Restart();

    b2Body* CreateBody(const vec2f &position, b2BodyType type) noexcept;
    void DeleteBody(b2Body *body) noexcept;

    void AddManagedEntity(entity::Entity *entity) noexcept;
    void RemoveManagedEntity(entity::Entity *entity) noexcept;

    vec2f GetPlayerPosition() const noexcept;

    int GetDifficult() const noexcept;
    void AddScores(int value) noexcept;

    void GameOver();

    void Update() noexcept;
    void Render() const noexcept;
};


}
