#include "pch.h"

#include "Mesh.h"

#include <print>
#include "Model.h"

void initmesh() {
	// auto positionsAssimp = ai_mesh->mVertices;
	// int num_verts = (int)ai_mesh->mNumVertices;
	// for (int i = 0; i < num_verts; i++) {
	// 	auto pos = positionsAssimp[i];
	// 	this->posList.push_back(pos.x);
	// 	this->posList.push_back(pos.y);
	// 	this->posList.push_back(pos.z);
	// 	this->posList.push_back(0);
	// }
	//
	// if (ai_mesh->HasNormals()) {
	// 	auto normals_assimp = ai_mesh->mNormals;
	// 	for (int i = 0; i < num_verts; i++) {
	// 		auto normal = normals_assimp[i];
	// 		this->normalsList.push_back(normal.x);
	// 		this->normalsList.push_back(normal.y);
	// 		this->normalsList.push_back(normal.z);
	// 		this->normalsList.push_back(0);
	// 	}
	// }

	// if (ai_mesh->mTextureCoords[0]) {
	// 	for (int i = 0; i < num_verts; i++) {
	// 		// glm::vec2 vec;
	// 		// a vertex can contain up to 8 different texture coordinates. We thus make the assumption that we won't
	// 		// use models where a vertex can have multiple texture coordinates so we always take the first set (0).
	// 		float x = ai_mesh->mTextureCoords[0][i].x;
	// 		float y = ai_mesh->mTextureCoords[0][i].y;
	//
	// 		// vertex.TexCoords = vec;
	//
	// 		// // tangent
	// 		// float tan_x = ai_mesh->mTangents[i].x;
	// 		// float tan_y = ai_mesh->mTangents[i].y;
	// 		// float tan_z = ai_mesh->mTangents[i].z;
	// 		//
	// 		// // bitangent
	// 		// float bitan_x = ai_mesh->mBitangents[i].x;
	// 		// float bitan_y = ai_mesh->mBitangents[i].y;
	// 		// float bitan_z = ai_mesh->mBitangents[i].z;
	//
	// 		this->texCoordList.push_back(x);
	// 		this->texCoordList.push_back(y);
	// 	}
	// }
	//
	//
	// aiFace* facesBuffer = ai_mesh->mFaces;
	// if (is_outline) {
	// 	element_count = 0;
	// 	// for (i in 0 until faceCount) {
	// 	for (int i = 0; i < face_count; i++) {
	// 		aiFace face = facesBuffer[i];
	// 		//                check(face.mNumIndices() == 3) { "AIFace.mNumIndices() != 3" }
	// 		//                elementArrayBufferData.put(face.mIndices())
	// 		int numIndices = face.mNumIndices;
	//
	// 		if (numIndices != 3) {
	// 			std::println("wrong face cnt");
	// 		}
	// 		// for (j in 0 until numIndices){
	// 		for (int j = 1; j < numIndices; j++) {
	// 			unsigned idx = face.mIndices[j];
	//
	// 			this->indicesList.push_back(posList[glm::max((int(idx)-1)*3, 0)]);
	// 			this->indicesList.push_back(posList[glm::max((int(idx)-1)*3 + 1, 0)]);
	// 			this->indicesList.push_back(posList[glm::max((int(idx)-1)*3 + 2, 0)]);
	// 			this->indicesList.push_back(0);
	//
	// 			this->indicesList.push_back(posList[idx * 3]);
	// 			this->indicesList.push_back(posList[idx * 3 + 1]);
	// 			this->indicesList.push_back(posList[idx * 3 + 2]);
	// 			this->indicesList.push_back(0);
	// 		}
	// 		// indicesList.push_back(2147483647);
	//
	// 		element_count += numIndices;
	// 	}
	// } else {
	// 	// for (i in 0 until faceCount) {
	// 	for (int i = 0; i < (int)face_count; i++) {
	// 		// val face: AIFace = facesBuffer[i]
	// 		aiFace face = facesBuffer[i];
	//
	// 		//                check(face.mNumIndices() == 3) { "AIFace.mNumIndices() != 3" }
	// 		//                elementArrayBufferData.put(face.mIndices())
	// 		int numIndices = (int)face.mNumIndices;
	// 		if (numIndices != 3) {
	// 			// println("Wrong index cnt")
	// 			std::println("Wrong index cnt");
	// 		}
	// 		for (int j = 0; j < numIndices; j++) {
	// 			int idx = (int)face.mIndices[j];
	// 			this->indicesList.push_back(idx);
	// 		}
	// 	}
	// }
	//
	// // texCoordList
	// if(!texCoordList.empty()) {
	// 	// this->buff_tex_coords = new Buffer(&texCoordList[0], texCoordList.size() * 4);
	// 	this->buff_tex_coords = new Buffer({.byte_len = (int)texCoordList.size() * 4, .upload_data = &texCoordList[0], .name = "Buff Texcoords"});
	// }
	// if(!normalsList.empty()) {
	// 	this->buff_normals = new Buffer({.byte_len = (int)normalsList.size() * 4, .upload_data = &normalsList[0], .name = "Buff Normals"});
	// }
	//
	// this->buff_vert_indices = new Buffer({.byte_len = (int)indicesList.size() * 4, .upload_data = &indicesList[0], .name = "Buff Indices" });
	//
	// this->bufF_verts = new Buffer({.byte_len = (int)posList.size() * 4, .upload_data = &posList[0], .name = "Buff Verts"});
}

Mesh::Mesh(aiMesh* ai_mesh, bool is_outline, Model* model,
	int buff_normals_idx,
	int bufF_verts_idx,
	int buff_vert_indices_idx,
	int buff_tex_coords_idx
	) : buff_normals_idx(buff_normals_idx),
	bufF_verts_idx(bufF_verts_idx),
	buff_vert_indices_idx(buff_vert_indices_idx),
	buff_tex_coords_idx(buff_tex_coords_idx)
{
	face_count = ai_mesh->mNumFaces;
	vertex_count = ai_mesh->mNumVertices;
	element_count = face_count * 3;



	if(ai_mesh->mMaterialIndex >= 0) {
		const aiScene* ai_scene = model->scene_non_triangulated;

		aiMaterial *material = ai_scene->mMaterials[ai_mesh->mMaterialIndex];
		for(unsigned i = 0; i < material->GetTextureCount(aiTextureType_DIFFUSE); i++) {
			aiString path;
			material->GetTexture(aiTextureType_DIFFUSE, i, &path);
			int tex_idx = ai_scene->GetEmbeddedTextureAndIndex(path.C_Str()).second;
			Texture* tex = model->textures[tex_idx];
			this->textures.push_back(tex);
		}
	}

	// auto texCoordsAssip = ai_mesh->mTextureCoords(0);
	// auto num_tex_coords = ai_mesh->mTextureCoords;

	// texture coordinates
	// unsigned num_tex_comps[8] = ai_mesh->mNumUVComponents;


}
