#pragma once
#include <stdint.h>
#include <string>
#include <map>
#include "mmap.h"

namespace M3D
{
const uint16_t M3DT_VER_MAGIC = 1;
const char M3DT_SIGNATURE[] = "M3DT";
#pragma pack(push, 1)
	struct M3DT_Header
	{
		char signature[4];
		uint16_t version;
		uint8_t lod_number;
		uint8_t is_comressed;
		uint32_t internal_format;
		uint32_t type;
	};
	struct M3DT_Lod
	{
		uint16_t width;
		uint16_t height;
		uint16_t line_size;
		uint32_t data_offset;
		uint32_t data_size;
	};
#pragma pack(pop)
	struct M3DT_Lod_Data
	{
		M3DT_Lod *lod_info;
		char *data_pointer;
                M3DT_Lod_Data(M3DT_Lod *lod, char *data) : lod_info(lod), data_pointer(data){}
		M3DT_Lod_Data() : lod_info(0), data_pointer(0) {}
	};
	/**
	 * Класс для работы с текстурными файлами в формате M3DT.
	 * @author Denis A. Biryukov <denis.birukov@gmail.com>
	 */
	class M3DT
	{
		public:
			M3DT();
			~M3DT();
			/**
			 * Производит загрузку указанного файла в память.
			 * @param fname имя файла для загрузки.
			 */
			void load ( std::string fname );

			/**
			 * Производит сохранение данных в указанный файл. Если такой файл уже существует то он заменяется. При сохранении для каждого нового уровня производится пересчет смещения в структуре M3DT_Lod смещения от начала файла
			 * @param fname имя файла для сохранения данных
			 */
			void save ( std::string fname );

			/**
			 * Устанавливает данные соответствующего уровня детализации. 
			 * @param lod уровень детализации. 0 - базовый уровень, сама текстура.
			 * @param lod_data даные о соответствующем уровне
			 */
			void set_lod_data ( int lod, const M3DT_Lod_Data &lod_data );
			/**
			 * Получение информации о уровне детализации
			 * @param lod уровень детализации о котором требуется получить информацию
			 * @return константная ссылка на данные о запрошенном уровне детализации
			 */
			const M3DT_Lod_Data* get_lod_data ( int lod ) const;

			/**
			 * Производит установку информации для заголовка файла. Информация о кол-ве уровней автоматически обновляется при каждом добавлении нового уровня
                         * @param value заголовок
			 */
			void set_header_ ( M3DT_Header* value ) ;
                        /**
                         * Получение информации из заголовка файла.
                         * @return константный указатель на заголовок
                         */
			const M3DT_Header* get_header() const {return _header_;};


		private:
			M3DT_Header *_header_;
			std::map<int, M3DT_Lod_Data> _lod_data_;
                        MMAP mapped_file;
	};

}

