#ifndef CMODELLOADER_HPP
#define CMODELLOADER_HPP


#include <assimp/Importer.hpp>
#include <assimp/scene.h>
#include <assimp/postprocess.h>
#include "../../Model/Graphic/Texture/CImageTexture.hpp"
#include <vector>
#include <iostream>
#include "../../Model/Graphic/Mesh/CMesh.hpp"
#include "../../Model/Graphic/CModel.hpp"
#include "../../Model/Node/CScene.hpp"
#include "../../Controller/CKernel.hpp"
#include "../../Context/CContext.hpp"

/**
 * @brief Class allowing to load models from obj files.
 */
class CModelLoader {
private:
	/**
	 * @brief Compute every node in the loaded meshes.
	 * @param[in] node The assimp created node.
	 * @param[in] scene The assimp created scene.
	 * @param[in] meshes The mesh list.
	 * @param[in] material A pointer to a material. It's optionnal and override the obj's material.
	 */
	static void processNode(aiNode* node, const aiScene* scene, std::vector<CMesh*>* meshes, SMaterial* material);

	/**
	 * @brief Compute every meshes.
	 * @param[in] mesh The assimp created mesh.
	 * @param[in] scene The assimp created scene.
	 * @param[in] meshes The list of meshes.
	 * @param[in] material A pointer to a material. It's optionnal and override the obj's material.
	 */
	static void processMesh(aiMesh* mesh, const aiScene* scene, std::vector<CMesh*>* meshes, SMaterial* material);

	/**
	 * @brief Load Textures from the obj file.
	 * @param[in] mat The assimp created material.
	 * @param[in] type The assimp's texture type.
	 * @param[in] typeName The texture's type.
	 */
	static std::vector<CImageTexture*> loadMaterialTextures(aiMaterial* mat, aiTextureType type, ETextureType typeName);
public:

	/**
	 * @brief main function of the class, starts loading the obj file.
	 * @param[in] fileName Path to the OBJ file.
	 * @param[in] material Pointer to a material. It's optionnal and override the obj's material.
	 * @return A dynamically allocated CModel.
	 */
	static CModel* loadModel(std::string fileName, SMaterial* material);

};

#endif