#include "Axe.h"

#include "Game.h"

AxeToolItemType::AxeToolItemType() // TODO: add broken Axe
    : BasicToolItemType(ItemTypeEnum::AXE,
        "Axe",
        new AxeToolLevelUpRule(),
        0,
        ModelInfo("tools.m3/axe", "tools.ltdb/stoneaxe.png", 1))
{}

Item* AxeToolItemType::createItem() const
{
    return new BasicToolItem(ItemTypeEnum::AXE, "Axe");
}

ItemSkill* AxeToolItemType::createDefaultItemSkill() const
{
    return new AxeToolSkill();
}

void AxeToolItemType::loadSuperItemSkill(
    ItemSkill* zSkill, Framework::StreamReader* zReader) const
{
    AxeToolSkill* skill = dynamic_cast<AxeToolSkill*>(zSkill);
    zReader->lese((char*)&skill->level, 4);
    zReader->lese((char*)&skill->xp, 4);
    zReader->lese((char*)&skill->maxXP, 4);
}

void AxeToolItemType::saveSuperItemSkill(
    const ItemSkill* zSkill, Framework::StreamWriter* zWriter) const
{
    const AxeToolSkill* skill = dynamic_cast<const AxeToolSkill*>(zSkill);
    zWriter->schreibe((char*)&skill->level, 4);
    zWriter->schreibe((char*)&skill->xp, 4);
    zWriter->schreibe((char*)&skill->maxXP, 4);
}

AxeToolLevelUpRule::AxeToolLevelUpRule()
    : ItemSkillLevelUpRule()
{}

void AxeToolLevelUpRule::applyOn(ItemSkill* zSkill)
{
    AxeToolSkill* skill = dynamic_cast<AxeToolSkill*>(zSkill);
    if (skill->xp >= skill->maxXP)
    {
        skill->level++;
        skill->xp = 0;
        skill->maxXP = skill->maxXP * 2;
    }
}

AxeToolSkill::AxeToolSkill()
    : ItemSkill(ItemTypeEnum::AXE),
      level(1),
      xp(0.f),
      maxXP(10.f)
{}

void AxeToolSkill::use(Entity* zActor, Item* zUsedItem, Block* zTarget)
{
    if (zActor->getStamina() > 0.0001f)
    {
        if (zTarget->zBlockType()->getId() == BlockTypeEnum::WOOD_BEECH
            || zTarget->zBlockType()->getId() == BlockTypeEnum::WOOD_BIRCH
            || zTarget->zBlockType()->getId() == BlockTypeEnum::WOOD_OAK
            || zTarget->zBlockType()->getId() == BlockTypeEnum::WOOD_PINE)
        {
            float damage
                = (1 + ((float)level / 10.f)) / (zTarget->getHardness() + 1);
            zTarget->setHP(zTarget->getHP() - damage);
            xp += damage / 20;
            zActor->setStamina(zActor->getStamina() - 0.0001f);
            zUsedItem->setHp(zUsedItem->getHp() - damage / 50);
        }
        else
        {
            zActor->setStamina(zActor->getStamina() - 0.0001f);
            zUsedItem->setHp(zUsedItem->getHp() - 0.001f);
        }
    }
}

void AxeToolSkill::use(Entity* zActor, Item* zUsedItem, Entity* zTarget)
{
    // an Axe can not be used on an entity
}