#pragma once

#include "AnimalAI.h"
#include "BasicBlocks.h"
#include "Entity.h"
#include "EntityType.h"

class Animal : public Entity
{
private:
    Framework::Array<SpawnConfig> spawns;
    AnimalAI* ai;

protected:
    void onDeath() override;

public:
    Animal(int typeId,
        Framework::Vec3<float> location,
        int dimensionId,
        int entityId);
    ~Animal();
    void setSpawns(const Framework::Array<SpawnConfig>& spawnConfig);
    void setAI(AnimalAI* ai);
    bool interact(Item* zItem, Entity* zActor) override;
    void takeDamage(Entity* zSource, float damage) override;
    void tick(const Dimension* zDimension) override;
};

class AnimalEntityTypeFactory;

class AnimalEntityType : public EntityType
{
private:
    Framework::JSON::JSONObject* ai;
    Framework::Array<SpawnConfig> spawns;

protected:
    virtual void loadSuperEntity(
        Entity* zEntity, Framework::StreamReader* zReader) const;
    virtual void saveSuperEntity(
        Entity* zEntity, Framework::StreamWriter* zWriter) const;

public:
    AnimalEntityType(Framework::Text name, ModelInfo* model);
    ~AnimalEntityType();

    Entity* createEntity(Framework::Vec3<float> position,
        int dimensionId,
        int entityId) const override;

    friend AnimalEntityTypeFactory;
};

class AnimalEntityTypeFactory
    : public SubTypeFactory<EntityType, AnimalEntityType>
{
public:
    AnimalEntityTypeFactory();
    AnimalEntityType* fromJson(
        Framework::JSON::JSONObject* zJson) const override;
    Framework::JSON::JSONObject* toJsonObject(
        AnimalEntityType* zObject) const override;
    JSONObjectValidationBuilder* addToValidator(
        JSONObjectValidationBuilder* builder) const override;
    const char* getTypeToken() const override;
};