#pragma once
#include <fstream>
#include <vector>
#include <QMatrix4x4>

enum ModelTyp {
	null,
	dynamicMesh,
	cloth,
	bone,
	staticMesh,
	shadowMesh = 6
};

struct BoundingBox {
	float quaternion[4];
	float center[3];
	float extents[3];
};

struct ChunkHeader {
	char name[5];
	std::uint32_t size;
	std::streampos position;
};

struct Segment {
	std::uint32_t textureIndex	= 0;
	float* vertex				= nullptr;
	float* uv					= nullptr;
	std::vector<std::vector<std::uint32_t>> polyIndices;	// indices into vertex array
};

struct Model {
	std::string name			= "";
	std::string parent			= "";
	ModelTyp type				= null;
	std::int32_t renderFlags	= -1;
	QMatrix4x4 m4x4Translation;
	std::vector<Segment*> segmList;
};


class MshFile
{
public:
	MshFile(const char* path);
	~MshFile();

private:
	std::vector<Model*>* m_vModels;
	std::fstream m_fsMesh;
	std::vector<std::string> m_vTextureNames;
	BoundingBox m_sceneBbox;

private:
	void loadChunks(std::list<ChunkHeader*> &destination, std::streampos start, const std::uint32_t length);

	void analyseMsh2Chunks(std::list<ChunkHeader*> &chunkList);

	void analyseMatdChunks(std::list<ChunkHeader*> &chunkList);

	void analyseModlChunks(Model* dataDestination, std::list<ChunkHeader*> &chunkList);
	void analyseGeomChunks(Model* dataDestination, std::list<ChunkHeader*> &chunkList);
	void analyseSegmChunks(Model* dataDestination, std::list<ChunkHeader*> &chunkList);
	void analyseClthChunks(Model* dataDestination, std::list<ChunkHeader*> &chunkList);

	void readVertex(Segment* dataDestination, std::streampos position);
	void readUV(Segment* dataDestination, std::streampos position);

public:
	std::vector<Model*>* getModels() const;
	std::vector<std::string> getTextureNames() const;
	BoundingBox getBoundingBox() const;
};