#pragma once
#include <set>
#include <map>
#include <stdint.h>
#include <string>
#include "Interfaces/shaderprograminterface.h"

namespace M3D
{
class MaterialParams;
class MaterialLayer;
class Model;
class OpenGLState;
class EngineInterface;
class ShaderProgram;
/**
 *@author Denis A. Biryukov <denis.birukov@gmail.com>
 */
class Material
{
	public:
		Material();
		~Material();

		/**
		 * Соединение модели с материалом
		 * @param obj объект который требуется присоединить к данному материалу
		 */
		void link_model( Model *obj );
		/**
		 * Отсоединение модели от материала
		 * @param obj объект который требуется отсоединить от материала
		 */
		void unlink_model( Model *obj );
		/**
		 * Возвращает набор моделей у которых установлен данныйматериал
		 * @return набор моделей
		 */
		std::set<Model*>* get_associated_models();

		/**
		 * Устанавливает текущий материал в контекст OpenGL
		 * @param state текущее состояние OpenGL контекста
		 */
		void set_material( OpenGLState *state );

		/**
		 * Производит загрузку материала из .m3dml файла
		 * @param base_dir базовый путь, по которому требуется искать файл
		 * @param fname имя файла для загрузки
		 * @param engine указатель на интерфейс движка для которого грузится объект
		 */
		void load( const std::string &base_dir, const std::string &fname, EngineInterface *engine );
		
		/**
		 * Возвращает идиентификатор на используемую шейдерную программу
		 * @return идиентификатор шейдерной программы
		 */
		ShaderProgramInterface get_shader(){return _shader_id_;}


	private:
		std::string _source_file_;
		std::string _shader_path_;
		ShaderProgram *_shader_;
		ShaderProgramInterface _shader_id_;
		uint8_t _layer_count_;

		std::set<Model*> _models_;
		std::map<uint16_t, MaterialLayer*> _material_layers_;
};

}


