#pragma once
#include <vector>

#include "Entity.h"


enum class PreconditionType
{
    ItemEquipped,
    ItemNotEquipped,
    HasItem,
    DoesNotHaveItem,
    HasAchievement,
    MissionAvailable,
    OnMission,
    MissionComplete,
    PetDeployed,
    HasFlag,
    WithinShape,
    InBuild,
    TeamCheck,
    IsPetTaming,
    HasFaction,
    DoesNotHaveFaction,
    HasRacingLicence,
    DoesNotHaveRacingLicence,
    LegoClubMember,
    NoInteraction,
	HasLevel = 22
};


class Precondition final
{
public:
    explicit Precondition(uint32_t condition);
	
    bool Check(Entity* player, bool evaluateCosts = false) const;
	
private:
    bool CheckValue(Entity* player, uint32_t value, bool evaluateCosts = false) const;
	
    PreconditionType type;

    std::vector<uint32_t> values;

    uint32_t count;
};


class PreconditionExpression final
{
public:
    explicit PreconditionExpression(const std::string& conditions);

    bool Check(Entity* player, bool evaluateCosts = false) const;
	
    ~PreconditionExpression();
	
private:
    uint32_t condition = 0;

    bool m_or = false;

    bool empty = false;

    PreconditionExpression* next = nullptr;
};

class Preconditions final
{
public:
    static bool Check(Entity* player, uint32_t condition, bool evaluateCosts = false);

    static PreconditionExpression CreateExpression(const std::string& conditions);

	~Preconditions();
	
private:
    static std::map<uint32_t, Precondition*> cache;
};