#pragma once
#include <stdint.h>
#include <GL/glew.h>
#include <set>
#include <string>

namespace M3D
{
class Model;
/**
 * На данный момент всегда используется формат iRGBA
 * @author Denis A. Biryukov <denis.birukov@gmail.com>
 */
class Texture
{
	public:
		Texture();
		~Texture();
		/**
		 * Производит инициализацию статических данных текстурных объектом. При инициализации создается буфер для временного хранения текстуры после ее загрузки/ 
		 * @param msize максимальный размер текстуры по большей стороне в пикселях
		 * @author Denis A. Biryukov <denis.birukov@gmail.com>
		 */
		static void static_init( int msize );

		/**
		 * Получение ширины текстуры
		 * @return ширина текстуры в пикселях
		 * @author Denis A. Biryukov <denis.birukov@gmail.com>
		 */
		uint32_t get_width() const {return _width_;}
		/**
		 * Получение высоты тестуры
		 * @return высота текстуры в пикселях
		 * @author Denis A. Biryukov <denis.birukov@gmail.com>
		 */
		uint32_t get_height() const {return _height_;}
		/**
		 * Получение OpenGL идиентификатора текстуры
		 * @return идиентификатор текстуры
		 * @author Denis A. Biryukov <denis.birukov@gmail.com>
		 */
		GLuint get_tex_id() const {return _tex_id_;}
		/**
		 * Производит загрузку текстуры формата M3DT
		 * @param source_file имя файла из которого была загружена текстура
		 * @author Denis A. Biryukov
		 */
		void load(const std::string &source_file);
		/**
		 * Получение максимально допустимого размера текстуры
		 * @return максимальный размер текстуры по большей стороне в пикселях
		 * @author Denis A. Biryukov <denis.birukov@gmail.com>
		 */
		uint32_t get_max_size() const { return _max_size_; }
		/**
		 * Соединение модели с текстурой
		 * @param obj объект который требуется присоединить к текстуре
		 * @author Denis A. Biryukov <denis.birukov@gmail.com>
		 */
		void link_model(Model *obj);
		/**
		 * Отсоединение модели от текстуры
		 * @param obj объект который требуется отсоединить
		 * @author Denis A. Biryukov <denis.birukov@gmail.com>
		 */
		void unlink_model(Model *obj);
		/**
		 * Применение текстуры
		 */
		void bind();
		
	protected:
		uint32_t _width_;
		uint32_t _height_;
		static uint32_t _max_size_;
		GLuint _tex_id_;
		std::set<Model*> _associated_models_;
		std::string _source_file_; 
};

}
