#pragma once

#include "Block.h"
#include "BlockType.h"
#include "Item.h"

class BlockType;
class ItemType;
class BasicBlockType;

class BasicBlock : public Block
{
public:
    BasicBlock( const BlockType* zType, ItemType* zTool, Framework::Vec3<int> pos );
    virtual bool onTick( TickQueue* zQueue, int numTicks, bool& blocked ) override;
    virtual void onPostTick() override;

    friend BasicBlockType;
};

class BasicBlockType : public BlockType
{
private:
    int itemType;

protected:
    bool transparent;
    bool passable;
    float maxHp;
    float hardness;
    ItemType* zTool;
    float speedModifier;
    bool interactable;

    BasicBlockType( int typeId, int itemTypeId );
    virtual void createSuperBlock( Block* zBlock, Item* zItem ) const override;

public:
    virtual Block* createBlock( Framework::Vec3<int> position ) const override;
    virtual Item* createItem() const override;
};

// Dirt
class DirtBlockItemType : public BasicBlockItemType
{
    REGISTRABLE( DirtBlockItemType )

protected:
    DirtBlockItemType();

public:
    virtual Item* createItem() const override;
};
REGISTER( DirtBlockItemType, ItemType )

class DirtBlockType : public BasicBlockType
{
    REGISTRABLE( DirtBlockType )

protected:
    DirtBlockType();
};
REGISTER( DirtBlockType, BlockType )

// Stone
class StoneBlockItemType : public BasicBlockItemType
{
    REGISTRABLE( StoneBlockItemType )

protected:
    StoneBlockItemType();

public:
    virtual Item* createItem() const override;
};
REGISTER( StoneBlockItemType, ItemType )

class StoneBlockType : public BasicBlockType
{
    REGISTRABLE( StoneBlockType )

protected:
    StoneBlockType();
};
REGISTER( StoneBlockType, BlockType )

// Sand
class SandBlockItemType : public BasicBlockItemType
{
    REGISTRABLE( SandBlockItemType )

protected:
    SandBlockItemType();

public:
    virtual Item* createItem() const override;
};
REGISTER( SandBlockItemType, ItemType )

class SandBlockType : public BasicBlockType
{
    REGISTRABLE( SandBlockType )

protected:
    SandBlockType();
};
REGISTER( SandBlockType, BlockType )

// Oak Wood
class OakBlockItemType : public BasicBlockItemType
{
    REGISTRABLE( OakBlockItemType )

protected:
    OakBlockItemType();

public:
    virtual Item* createItem() const override;
};
REGISTER( OakBlockItemType, ItemType )

class OakBlockType : public BasicBlockType
{
    REGISTRABLE( OakBlockType )

protected:
    OakBlockType();
};
REGISTER( OakBlockType, BlockType )

// Leaves
class LeavesBlockItemType : public BasicBlockItemType
{
    REGISTRABLE( LeavesBlockItemType )

protected:
    LeavesBlockItemType();

public:
    virtual Item* createItem() const override;
};
REGISTER( LeavesBlockItemType, ItemType )

class LeavesBlockType : public BasicBlockType
{
    REGISTRABLE( LeavesBlockType )

protected:
    LeavesBlockType();
};
REGISTER( LeavesBlockType, BlockType )

// Gravel
class GravelBlockItemType : public BasicBlockItemType
{
    REGISTRABLE( GravelBlockItemType )

protected:
    GravelBlockItemType();

public:
    virtual Item* createItem() const override;
};
REGISTER( GravelBlockItemType, ItemType )

class GravelBlockType : public BasicBlockType
{
    REGISTRABLE( GravelBlockType )

protected:
    GravelBlockType();
};
REGISTER( GravelBlockType, BlockType )

// Granite
class GraniteBlockItemType : public BasicBlockItemType
{
    REGISTRABLE( GraniteBlockItemType )

protected:
    GraniteBlockItemType();

public:
    virtual Item* createItem() const override;
};
REGISTER( GraniteBlockItemType, ItemType )

class GraniteBlockType : public BasicBlockType
{
    REGISTRABLE( GraniteBlockType )

protected:
    GraniteBlockType();
};
REGISTER( GraniteBlockType, BlockType )

// Cobble
class CobbleBlockItemType : public BasicBlockItemType
{
    REGISTRABLE( CobbleBlockItemType )

protected:
    CobbleBlockItemType();

public:
    virtual Item* createItem() const override;
};
REGISTER( CobbleBlockItemType, ItemType )

class CobbleBlockType : public BasicBlockType
{
    REGISTRABLE( CobbleBlockType )

protected:
    CobbleBlockType();
};
REGISTER( CobbleBlockType, BlockType )

// Birch Wood
class BirchBlockItemType : public BasicBlockItemType
{
    REGISTRABLE( BirchBlockItemType )

protected:
    BirchBlockItemType();

public:
    virtual Item* createItem() const override;
};
REGISTER( BirchBlockItemType, ItemType )

class BirchBlockType : public BasicBlockType
{
    REGISTRABLE( BirchBlockType )

protected:
    BirchBlockType();
};
REGISTER( BirchBlockType, BlockType )

// Beech Wood
class BeechBlockItemType : public BasicBlockItemType
{
    REGISTRABLE( BeechBlockItemType )

protected:
    BeechBlockItemType();

public:
    virtual Item* createItem() const override;
};
REGISTER( BeechBlockItemType, ItemType )

class BeechBlockType : public BasicBlockType
{
    REGISTRABLE( BeechBlockType )

protected:
    BeechBlockType();
};
REGISTER( BeechBlockType, BlockType )

// Basalt
class BasaltBlockItemType : public BasicBlockItemType
{
    REGISTRABLE( BasaltBlockItemType )

protected:
    BasaltBlockItemType();

public:
    virtual Item* createItem() const override;
};
REGISTER( BasaltBlockItemType, ItemType )

class BasaltBlockType : public BasicBlockType
{
    REGISTRABLE( BasaltBlockType )

protected:
    BasaltBlockType();
};
REGISTER( BasaltBlockType, BlockType )