#include <SFML/Graphics.hpp>
#include <cmath>
#include <vector>
#include <string>
#include <memory>
#include <iostream>
#include "sfline.hpp"

using std::cout, std::endl;

class Node
{
public:
    Node(sf::Vector2f& position);
    enum class State
    {
        Blocked,
        Unblocked,
        Activated
    };
    void addChild(const std::shared_ptr<Node>& child);
    sf::Vector2f getPosition();
    void unblock();
    void block();
    virtual bool collisionTest(sf::Vector2f mouseCoords) = 0;
    void onMousePressed(sf::Vector2f mouseCoords);
    virtual void draw(sf::RenderWindow& window) const = 0;
protected:
    sf::Vector2f mPosition {0, 0};
    State mState = State::Blocked;

    std::vector<std::shared_ptr<Node>> mChildren {};

    inline static sf::Color sBlockedColor   {40, 40, 40};
    inline static sf::Color sUnlockedColor  {80, 80, 40};
    inline static sf::Color sActivatedColor {160, 160, 40};
};


class HitNode : public Node
{
public:

    HitNode(sf::Vector2f position); 

    virtual sf::String getIconPath() = 0;
    void loadTexture();
    sf::Color getCurrentColor() const;

    void draw(sf::RenderWindow& window) const;

    bool collisionTest(sf::Vector2f mouseCoords) override;

private:

    sf::Texture mTexture;
    sf::Sprite mSprite;

    float mRadius = 24;
    bool mIsActivated = false;
};



class BombSkillNode : public HitNode
{
public:
    BombSkillNode(sf::Vector2f position);

    sf::String getIconPath() override;
};

class SpikesSkillNode : public HitNode
{
public:
    SpikesSkillNode(sf::Vector2f position);

    sf::String getIconPath() override;
};


class LightningSkillNode : public HitNode
{
public:
    LightningSkillNode(sf::Vector2f position);

    sf::String getIconPath() override;
};


class EyeSkillNode : public HitNode
{
public:
    EyeSkillNode(sf::Vector2f position);

    sf::String getIconPath() override;
};


class ClawsSkillNode : public HitNode
{
public:
    ClawsSkillNode(sf::Vector2f position);

    sf::String getIconPath() override;
};

class ShieldSkillNode : public HitNode
{
public:
    ShieldSkillNode(sf::Vector2f position);

    sf::String getIconPath() override;
};


class SwordSkillNode : public HitNode
{
public:
    SwordSkillNode(sf::Vector2f position);

    sf::String getIconPath() override;
};


class ShurikenSkillNode : public HitNode
{
public:
    ShurikenSkillNode(sf::Vector2f position);

    sf::String getIconPath() override;
};

class WindSkillNode : public HitNode
{
public:
    WindSkillNode(sf::Vector2f position);

    sf::String getIconPath() override;
};


class MeteoriteSkillNode : public HitNode
{
public:
    MeteoriteSkillNode(sf::Vector2f position);

    sf::String getIconPath() override;
};

class HandSkillNode : public HitNode
{
public:
    HandSkillNode(sf::Vector2f position);

    sf::String getIconPath() override;
};

class EarthquakeSkillNode : public HitNode
{
public:
    EarthquakeSkillNode(sf::Vector2f position);

    sf::String getIconPath() override;
};
