#include "LightSources.h"

LightSourceItem::LightSourceItem(int itemType, int blockType, const char* name)
    : BasicBlockItem(itemType, blockType, name),
      color(0XFFFFFFFF)
{}

bool LightSourceItem::canBeStackedWith(const Item* zItem) const
{
    const LightSourceItem* other = dynamic_cast<const LightSourceItem*>(zItem);
    return BasicBlockItem::canBeStackedWith(zItem) && other->color == color;
}

LightSourceItemType::LightSourceItemType(
    int id, const char* name, const ModelInfo model, int blockTypeId)
    : BasicBlockItemType(id, name, 0, 0, model, blockTypeId)
{
    transparent = 1;
    passable = 1;
    hardness = 0;
}

void LightSourceItemType::loadSuperItem(
    Item* zItem, Framework::StreamReader* zReader) const
{
    LightSourceItem* item = dynamic_cast<LightSourceItem*>(zItem);
    zReader->lese((char*)&item->color, 4);
    BasicBlockItemType::loadSuperItem(zItem, zReader);
}

void LightSourceItemType::saveSuperItem(
    const Item* zItem, Framework::StreamWriter* zWriter) const
{
    const LightSourceItem* item = dynamic_cast<const LightSourceItem*>(zItem);
    zWriter->schreibe((char*)&item->color, 4);
    BasicBlockItemType::saveSuperItem(zItem, zWriter);
}

Item* LightSourceItemType::createItem() const
{
    LightSourceItem* item = new LightSourceItem(id, blockTypeId, name);
    item->color = color;
    return item;
}

LightSourceItemType* LightSourceItemType::setColor(int color)
{
    this->color = color;
    return this;
}

BasicLightSource::BasicLightSource(int typeId, Framework::Vec3<int> pos)
    : Block(typeId, 0, pos, 0)
{}

void BasicLightSource::setLight(int light)
{
    lightEmisionColor[0] = (unsigned char)((light >> 16) & 0xFF);
    lightEmisionColor[1] = (unsigned char)((light >> 8) & 0xFF);
    lightEmisionColor[2] = (unsigned char)(light & 0xFF);
}

bool BasicLightSource::onTick(TickQueue* zQueue, int numTicks, bool& blocked)
{
    return 0;
}

void BasicLightSource::onPostTick() {}

BasicLightSourceBlockType::BasicLightSourceBlockType(
    int typeId, int itemTypeId, ModelInfo model, const char* name)
    : BlockType(typeId, 0, model, 1, 1, 1, name),
      itemType(itemTypeId),
      transparent(1),
      passable(1),
      hardness(1.f),
      interactable(1)
{}

void BasicLightSourceBlockType::createSuperBlock(
    Block* zBlock, Item* zItem) const
{
    BasicLightSource* block = dynamic_cast<BasicLightSource*>(zBlock);
    if (!block)
        throw "BasicLightSourceBlockType::createSuperBlock was called with a "
              "block witch is not an instance of BasicLightSource";
    block->transparent = transparent;
    block->passable = passable;
    block->hp = (float)getInitialMaxHP();
    block->maxHP = (float)getInitialMaxHP();
    block->hardness = hardness;
    block->zTool = 0;
    block->speedModifier = 1;
    block->interactable = interactable;
    block->setLight(color);
    BlockType::createSuperBlock(zBlock, zItem);
    if (zItem)
    {
        dynamic_cast<BasicLightSource*>(zBlock)->setLight(
            dynamic_cast<LightSourceItem*>(zItem)->color);
    }
}

void BasicLightSourceBlockType::loadSuperBlock(
    Block* zBlock, Framework::StreamReader* zReader, int dimensionId) const
{
    BlockType::loadSuperBlock(zBlock, zReader, dimensionId);
    BasicLightSource* block = dynamic_cast<BasicLightSource*>(zBlock);
    if (!block)
        throw "BasicLightSourceBlockType::loadSuperBlock was called with a "
              "block witch is not an instance of BasicLightSource";
    zReader->lese((char*)&block->lightEmisionColor, 4);
}

void BasicLightSourceBlockType::saveSuperBlock(
    Block* zBlock, Framework::StreamWriter* zWriter) const
{
    BlockType::saveSuperBlock(zBlock, zWriter);
    BasicLightSource* block = dynamic_cast<BasicLightSource*>(zBlock);
    if (!block)
        throw "BasicLightSourceBlockType::saveSuperBlock was called with a "
              "block witch is not an instance of BasicLightSource";
    zWriter->schreibe((char*)&block->lightEmisionColor, 4);
}

Block* BasicLightSourceBlockType::createBlock(
    Framework::Vec3<int> position) const
{
    return new BasicLightSource(getId(), position);
}

Item* BasicLightSourceBlockType::createItem() const
{
    return StaticRegistry<ItemType>::INSTANCE.zElement(itemType)->createItem();
}

BasicLightSourceBlockType* BasicLightSourceBlockType::setHardness(
    float hardness)
{
    this->hardness = hardness;
    return this;
}

BasicLightSourceBlockType* BasicLightSourceBlockType::setColor(int color)
{
    this->color = color;
    return this;
}