#pragma once

#include <glad/glad.h>
#include <vector>
#include <string>
#include <J3ML/LinearAlgebra.h>
#include <chrono>

//Forward declaration of entity.
class Entity;

//Base texture. One texture.
class Texture {
public:
    ///Reference counter.
    std::vector<Entity*> usedBy;
    ///The id OpenGL uses to keep track of where the texture is in vram.
    GLuint id = 0;
    ///Loads a texture for a given entity type from a file you specify.
    void load(Entity* entity, const std::string& file, bool storeOnTextureList);
    ///removes texture from texture list and deletes it.
    virtual void erase();
    void erase(Texture* texture) const;
    ///Constructor. Calls load.
    Texture(Entity* entity, const char *filePath, bool storeOnTextureList);
    Texture() = default;
    //virtual ~Texture() = default;
};

///Multi-Texture. One texture in the base slot, 7 in the following slots.
class MultiTexture : public Texture {
public:
    void erase() override;
    ///Every texture other than the base texture.
    std::vector<Texture> multi;
    ///Loads a list of Textures into a MultiTexture.
    MultiTexture(Entity* entity, const std::vector<std::string>& textures, bool storeOnTextureList);
    MultiTexture() = default;
};

///A list of textures where the one actually displayed depends on how much time has elapsed.
class MotionTexture : public Texture {
private:
    std::chrono::high_resolution_clock::time_point lastUpdate;
    int lastDisplayedIndex = 0;
    u16 msDelay = 0;
    bool doAnim = true;
public:
    std::vector<Texture> motion;
    Texture* current();
    Texture* base();
    void advance();
    void toggleAnim();
    MotionTexture(Entity* entity, const std::vector<std::string>& textures,u16 msBetweenFrames, bool storeOnTextureList, bool doAnim = true);
    MotionTexture() = default;
};