package com.framsticks.net.client3D.graphics.loaders;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.StringTokenizer;

import pl.vorg.mowa.core.graphics.GeometryGroup;
import pl.vorg.mowa.core.graphics.Vec2;
import pl.vorg.mowa.core.graphics.Vec3;

import com.framsticks.net.client3D.Log;

/**
 * Loader plikow w formacie OBJ
 * 
 * na razie zalozylem ze wgrywamy tylko obiekty zlozone z samych trojkatow
 * ze zdefiniowanymi pozycjami wierzcholkow, wspolrzednymi tekstury i normalnymi
 * 
 * @author vorg
 */
public class OBJLoader {	
	public static GeometryGroup load(String filePath) throws IOException {
		Log.getInstance().log("dbg", "OBJLoader.load \"" + filePath + "\"");
		FileReader reader = new FileReader(filePath);
		if (reader == null) {
			Log.getInstance().log("err", "OBJLoader.load error");
			return new GeometryGroup();
		}
		return load(new BufferedReader(reader)); 		
	}
	public static GeometryGroup load(BufferedReader reader) throws IOException {
		OBJMesh objMesh = parse(reader);
		OBJMeshConverter converter = new OBJMeshConverter();
		return converter.convert(objMesh);
	}
	
	private static OBJMesh parse(BufferedReader reader) throws IOException {
		Log.getInstance().log("dbg","OBJLoader.parse");
		OBJMesh mesh = new OBJMesh();
		
		ArrayList<Vec3> vertexList = mesh.getVertices();
		ArrayList<Vec3> normalList = mesh.getNormals();
		ArrayList<Vec2> texCoordList = mesh.getTexCoords();
		ArrayList<OBJFace> faceList = mesh.getFaces();
		
		String line;
		while((line = reader.readLine()) != null) {
			StringTokenizer tokens = new StringTokenizer(line, " ");
			if (!tokens.hasMoreTokens()) {
				continue;
			}
			String section = tokens.nextToken();
			if (section.equals("o")) {
				if (tokens.hasMoreTokens()) {
					mesh.setName(tokens.nextToken());
				}
			}
			else if (section.equals("v")) {
				vertexList.add(new Vec3(
					Float.parseFloat(tokens.nextToken()),
					Float.parseFloat(tokens.nextToken()),
					Float.parseFloat(tokens.nextToken())
				));
			}
			else if (section.equals("vt")) {
				texCoordList.add(new Vec2(
					Float.parseFloat(tokens.nextToken()),
					Float.parseFloat(tokens.nextToken())
				));
			}
			else if (section.equals("vn")) {
				normalList.add(new Vec3(
					Float.parseFloat(tokens.nextToken()),
					Float.parseFloat(tokens.nextToken()),
					Float.parseFloat(tokens.nextToken())
				));
			}
			else if (section.equals("f")) {
				int numTokens = tokens.countTokens();
				OBJFaceVertex[] faceVertices = new OBJFaceVertex[numTokens];
				String faceStr;
				String[] indices;
				for(int i=0; i<numTokens; i++) {
					faceStr = tokens.nextToken();
					indices = faceStr.split("/");
					faceVertices[i] = new OBJFaceVertex();
					if (!indices[0].equals("")) faceVertices[i].setVertexIndex(Integer.parseInt(indices[0]) - 1);
					if (!indices[1].equals("")) faceVertices[i].setTexCoordIndex(Integer.parseInt(indices[1]) - 1);
					if (!indices[2].equals("")) faceVertices[i].setNormalIndex(Integer.parseInt(indices[2]) - 1);
				}
				OBJFace face = new OBJFace();
				face.setVertices(faceVertices);
				faceList.add(face);
			}
		}
		
		Log.getInstance().log("dbg", "OBJLoader.load done");
		return mesh;
	}
}
