package com.danitheskunk.skunkworks;

import com.danitheskunk.skunkworks.gfx.IRenderContext;
import com.danitheskunk.skunkworks.gfx.ITexture;
import com.danitheskunk.skunkworks.gfx.Image;
import com.danitheskunk.skunkworks.gfx.threedee.IRenderContext3D;
import com.danitheskunk.skunkworks.gfx.threedee.Mesh;
import org.lwjgl.assimp.*;

import java.nio.IntBuffer;

@SuppressWarnings("ALL")
public class Test3D extends BaseGame {
	private final Mesh[] meshes;

	public Test3D() {
		super(new Vec2i(1920, 1080), "Skunkworks 3d test");
		System.out.printf("assimp version: %d.%d.%d\n",
			Assimp.aiGetVersionMajor(),
			Assimp.aiGetVersionMinor(),
			Assimp.aiGetVersionPatch()
		);
		var path = "C:\\stream\\models\\Dani.glb";
		//path = "C:\\stream\\models\\Amber_Arakada_V5_Blendshape.glb";
		//path = "C:\\stream\\models\\Temp Chan 3.glb";
		var bytes = engine.loadBytes(path);
		var flags = Assimp.aiProcess_Triangulate;
		flags |= Assimp.aiProcess_PreTransformVertices;
		var ai = Assimp.aiImportFile(path, flags);
		if(ai == null) {
			throw new RuntimeException("couldn't load model because: " +
				Assimp.aiGetErrorString());
		}

		int numMaterials = ai.mNumMaterials();
		var matTex = new int[numMaterials];
		var matPB = ai.mMaterials();
		for(int i = 0; i < numMaterials; ++i) {
			var aiMat = AIMaterial.create(matPB.get(i));
			var texCount = Assimp.aiGetMaterialTextureCount(aiMat,
				Assimp.aiTextureType_DIFFUSE
			);
			var tpath = AIString.calloc();
			var tex = Assimp.aiGetMaterialTexture(aiMat,
				Assimp.aiTextureType_DIFFUSE,
				0,
				tpath,
				(IntBuffer) null,
				null,
				null,
				null,
				null,
				null
			);
			var tpathstr = tpath.dataString();
			matTex[i] = tpathstr.startsWith("*") ?
				Integer.parseInt(tpathstr.substring(
					1)) : -1;
			System.out.printf("tex count: %d, path: %s\n",
				texCount,
				tpath.dataString()
			);
		}

		int numTextures = ai.mNumTextures();
		var textures = new ITexture[numTextures];
		var texPB = ai.mTextures();
		for(int i = 0; i < numTextures; ++i) {
			var aiTex = AITexture.create(texPB.get(i));
			var img = new Image(aiTex.pcDataCompressed());
			var tex = window.loadTexture(img);
			textures[i] = tex;
			System.out.printf("tex %dx%d\n", img.getWidth(), img.getHeight());
		}


		var numMeshes = ai.mNumMeshes();
		var meshPB = ai.mMeshes();
		meshes = new Mesh[numMeshes];
		int faces = 0;
		for(int i = 0; i < numMeshes; ++i) {
			var aiMesh = AIMesh.create(meshPB.get(i));
			var mesh = Mesh.fromAIMesh(aiMesh);
			var tex = aiMesh.mMaterialIndex();
			if(tex >= 0) {
				mesh.setTexture(textures[matTex[tex]]);
			}
			meshes[i] = mesh;
			System.out.println(aiMesh.mNumFaces());
			faces += aiMesh.mNumFaces();
		}

		//window.setDebug(true);

		System.out.printf("numMeshes: %d, faces: %d, textures: %d\n",
			numMeshes,
			faces,
			numTextures
		);
	}

	static public void main(String[] args) {
		new Test3D().run();
	}

	@Override
	protected void render(IRenderContext rc) {
		//rc.drawTexture(Vec2i.ZERO, dtex);
	}

	@Override
	protected void render3D(IRenderContext3D rc) {
		for(int i = 0; i < meshes.length; ++i) {
			rc.renderMesh(meshes[i]);
		}
		//rc.renderMesh(meshes[14]);
	}
}
