#pragma once

#include "BasicBlocks.h"
#include "Block.h"
#include "BlockType.h"

class BasicLightSourceBlockType;
class LightSourceItemType;

class LightSourceItem : public BasicBlockItem
{
protected:
    int color;

public:
    LightSourceItem(int itemType, int blockType, Framework::Text name);
    virtual bool canBeStackedWith(const Item* zItem) const override;

    friend LightSourceItemType;
    friend BasicLightSourceBlockType;
};

class LightSourceItemType : public BasicBlockItemType
{
private:
    int color;

public:
    LightSourceItemType(Framework::Text name,
        ModelInfo* model,
        Framework::Text blockTypeName,
        int maxStackSize,
        Framework::RCArray<Framework::Text> groups);

protected:
    virtual void loadSuperItem(
        Item* zItem, Framework::StreamReader* zReader) const override;
    virtual void saveSuperItem(
        const Item* zItem, Framework::StreamWriter* zWriter) const override;
    virtual Item* createItem() const override;

public:
    LightSourceItemType* setColor(int color);
};

class BasicLightSource : public Block
{
public:
    BasicLightSource(int typeId, Framework::Vec3<int> pos, int dimensionId);

protected:
    void setLight(int light);

public:
    virtual bool onTick(
        TickQueue* zQueue, int numTicks, bool& blocked) override;
    virtual void onPostTick() override;

    friend BasicLightSourceBlockType;
};

class BasicLightSourceBlockType : public BlockType
{
private:
    Framework::Text itemTypeName;
    int itemTypeId;
    bool transparent;
    bool passable;
    bool interactable;
    int lightColor;

public:
    BasicLightSourceBlockType();

protected:
    virtual void createSuperBlock(Block* zBlock, Item* zItem) const override;
    virtual void loadSuperBlock(Block* zBlock,
        Framework::StreamReader* zReader,
        int dimensionId) const override;
    virtual void saveSuperBlock(
        Block* zBlock, Framework::StreamWriter* zWriter) const override;

public:
    virtual bool initialize(Game* zGame) override;
    virtual Block* createBlock(
        Framework::Vec3<int> position, int dimensionId) const override;
    virtual Item* createItem() const override;

    virtual ItemType* createItemType() const override;

    void setItemTypeName(Framework::Text itemTypeName);
    Framework::Text getItemTypeName() const;
    void setTransparent(bool transparent);
    bool isTransparent() const;
    void setPassable(bool passable);
    bool isPassable() const;
    void setInteractable(bool interactable);
    bool isInteractable() const;
    void setLightColor(int lightColor);
    int getLightColor() const;
};

class BasicLightSourceBlockTypeFactory
    : public BlockTypeFactoryBase<BasicLightSourceBlockType>
{
public:
    BasicLightSourceBlockTypeFactory();
    BasicLightSourceBlockType* createValue(
        Framework::JSON::JSONObject* zJson) const override;
    BasicLightSourceBlockType* fromJson(
        Framework::JSON::JSONObject* zJson) const override;
    Framework::JSON::JSONObject* toJsonObject(
        BasicLightSourceBlockType* zObject) const override;
    JSONObjectValidationBuilder* addToValidator(
        JSONObjectValidationBuilder* builder) const override;
    const char* getTypeToken() const override;
};