#pragma once

#include <render/core/texture/texture.h>
#include <render/render.h>
#include <vector>

namespace render{
namespace sprite{
struct textureAtlasNode
{
    float angle, _angle;
    vec2f scale;
    vec2f center, _center;
    vec2f rotMatrix[6];
    vec2f pos, size;
    std::string name;

    inline bool operator!=(const textureAtlasNode &a) const noexcept{
        return a.angle != angle ||
               a.scale != scale ||
               a.center!= center||
               a.pos   != pos   ||
               a.size  != size;}
};

class textureAtlas;

class icon
{
    friend class textureAtlas;
public:
    const textureAtlas *parent() const;

    vec4f color;
    vec2f size;
    vec2f scale;
    vec2f center;
    float angle;

    icon();
    void draw(const vec2f &) noexcept;
    void draw(const vec2f &) const noexcept;
    const vec2f* getVertices() const noexcept;

    icon& operator=(const textureAtlasNode&);
private:
    const textureAtlas *_parent;

    float _angle;
    vec2f _center;
    vec2f _rotMatrix[6];
    vec2f _pos, _isize, _size;

};

class textureAtlas:public virtual texture
{
public:
    textureAtlas() = default;
    textureAtlas(const std::string&, bool = 0);
    ~textureAtlas();

    virtual bool load(const std::string&, bool = 0, bool = 1);

    void draw(const vec2f&, uint) noexcept;
    void draw(const vec2f&, icon&) const noexcept;
    void draw(const vec2f&, const icon&) const noexcept;

    icon getIcon(uint) const noexcept;
    void getIcon(const std::string&, icon&) const noexcept;

    int getNodeId(const std::string&) const noexcept;
    uint getNodesCount() const noexcept;

    vec4f getTexCoord(uint) const;
    inline textureAtlasNode &operator[](uint a){return elements.at(a);}
private:

    std::vector<textureAtlasNode> elements;
    void mathRotate(textureAtlasNode&) noexcept ;
    void mathRotate(icon&) const noexcept;
};

}}
