#ifndef ENGINE_H__
#define ENGINE_H__
#include "define.h"
#include "openglcontext.h"
#include "texture.h"
#include "player.h"
#include "shader.h"
#include "chunk.h"
#include "textureatlas.h"
#include "blockinfo.h"
#include "array2d.h"
#define MAX_SELECTION_DISTANCE (VIEW_DISTANCE * 2 / CHUNK_SIZE_X) 

class Engine : public OpenglContext
{
public:
    Engine();
    virtual ~Engine();
    virtual void Init();
    virtual void DeInit();
    virtual void LoadResource();
    virtual void UnloadResource();
    virtual void Render(float elapsedTime);
    virtual void KeyPressEvent(unsigned char key);
    virtual void KeyReleaseEvent(unsigned char key);
    virtual void MouseMoveEvent(int x, int y);
    virtual void MousePressEvent(const MOUSE_BUTTON &button, int x, int y);
    virtual void MouseReleaseEvent(const MOUSE_BUTTON &button, int x, int y);
    virtual void PrintText(unsigned int x, unsigned int y, const std::string& t);
    virtual void DrawHud(float elapsedTime);
    virtual int GetFps(float elapsedTime);
    Chunk* ChunkAt(float x, float y, float z) const;
    BlockType BlockAt(float x, float y, float z, BlockType defaultBlockType) const;
    void SetBlockAt(float x, float y, float z, BlockType BlockToSet) const;
    Chunk* ChunkAt(const Vector3<float>& pos) const;
    bool IsWalking();
    void GetBlocAtCursor();
    void SaveGame();
    void LoadGame(std::ifstream SaveFile);

public:
    bool m_run = false;
    bool m_walk = false;

private:
    bool LoadTexture(Texture& texture, const std::string& filename, bool stopOnError = true);
    void CreateBloc();
    void DestroyBloc();
    void DestroyBlocGenerateMob();
    void HitMob();
    Mob MobAt(int x, int y, int z);

private:
    bool m_wireframe = false;
    float m_jumpsize = 0.f;
    long m_points = 1;

    TextureAtlas m_textureAtlas;
    Texture m_textureFont;
    Texture m_textureCrosshair;
    Texture m_textureMob;
    Shader m_shader01;
    Chunk m_testChunk;
    Array2d<Chunk*> m_chunks;
    Player m_p1;
    Vector4f m_currentBlock;
    Vector3f m_currentFaceNormal;
    std::list<Vector4f> m_ModifiedBlocks;
    BlockInfo m_bi[BTYPE_LAST];
    Mob m_currentMob;
    Mob m_lastMob;
    std::vector<Mob> m_mobs;
    BlockType m_selectedbloc = BTYPE_DARK;

    bool m_shift = false;
    bool m_keyW = false;
    bool m_keyA = false;
    bool m_keyS = false;
    bool m_keyD = false;
    bool m_space = false;
    bool m_InJump = false;
};

#endif // ENGINE_H__