#pragma once
#include "img.hpp"
#include "vertex.hpp"
#include "lightmap.hpp"
#include "common.hpp"


class Texture {
    public:
        const bool need_coords;
        const light_t radiosity;

        Texture(bool b, unsigned);
        virtual ~Texture();
        virtual bool max_dim(unsigned&, unsigned&) const = 0;

        virtual const Img::rgb_t& get() const = 0; // constant or average color
        virtual const Img::rgb_t& get(coord_t, coord_t) const = 0; // from coordinates, possibly wrapped
        virtual Img::rgb_t get_uv(coord_t, coord_t) const = 0; // from uv-coordinates in [0,1]
};


class ColorTexture: public Texture {
    private:
        const Img::rgb_t col;

    public:
        ColorTexture(unsigned, const Img::rgb_t& c);

        bool max_dim(unsigned&, unsigned&) const;
        const Img::rgb_t& get() const;
        const Img::rgb_t& get(coord_t, coord_t) const;
        Img::rgb_t get_uv(coord_t, coord_t) const;
};


class DummyTexture: public Texture {
    private:
        const unsigned width;
        const Img::rgb_t b, w;

    public:
        DummyTexture(unsigned);
        DummyTexture(unsigned, const Img::rgb_t bb, Img::rgb_t ww, unsigned w);

        bool max_dim(unsigned&, unsigned&) const;
        const Img::rgb_t& get() const;
        const Img::rgb_t& get(coord_t x, coord_t y) const;
        Img::rgb_t get_uv(coord_t u, coord_t v) const;
};


class ImageTexture: public Texture {
    private:
        const Img* img;
        const Img::rgb_t avgcol;

    public:
        ImageTexture(unsigned, Img* i);
        ~ImageTexture();

        static Texture* load(unsigned, const char* fn, const char* mod=NULL);

        bool max_dim(unsigned&, unsigned&) const;
        const Img::rgb_t& get() const;
        const Img::rgb_t& get(coord_t x, coord_t y) const;
        Img::rgb_t get_uv(coord_t u, coord_t v) const;
};