import java.io.*;
import java.nio.FloatBuffer;
import java.util.*;

/**
 * CS400 3DMotionCapture
 * OBJPart
 * 
 * Holds the information of subdivisional obj file
 * @author Kohei Shinkawa*/
public class OBJPart {
	String usemtl,  filename;
	String imageName = null;
	FloatBuffer ka,ks,kd;
	float ns;
	boolean hasImage = false;
	ArrayList<int[]> faces = new ArrayList<int[]>(); //List of indices for vertices
	ArrayList<int[]> vts = new ArrayList<int[]>(); //List of indices for texture coordinates
	ArrayList<int[]> vns = new ArrayList<int[]>(); //List of indices for normal vectors


	public ArrayList<int[]> getVn() {
		return vns;
	}

	/*Constructor, reads the usemtl infomation*/
	public OBJPart(String filename, String usemtl){
		this.filename = filename;
		this.usemtl = usemtl;
		BufferedReader reader = null;
		try{
			FileInputStream fstream = new FileInputStream(filename);
			DataInputStream in = new DataInputStream(fstream);
			reader = new BufferedReader(new InputStreamReader(in));
			String strLine;
			while ((strLine = reader.readLine()) != null)   {
				if(strLine.startsWith("newmtl "+this.usemtl)){
					while(((strLine = reader.readLine()) != null) && (! strLine.startsWith("newmtl"))){
						if(strLine.startsWith("Ka"))setKa(strLine);
						else if(strLine.startsWith("Kd"))setKd(strLine);
						else if(strLine.startsWith("Ks"))setKs(strLine);
						else if(strLine.startsWith("Ns"))setNs(strLine);
						else if(strLine.startsWith("map_Kd")) setImageName(strLine);
					}
				}
			}
		}catch(IOException ioe){
			ioe.printStackTrace();
		}
	}
	/*Set the image name for texturing*/
	private void setImageName(String str){
		hasImage = true;
		StringTokenizer st = new StringTokenizer(str);
		st.nextToken();
		imageName = filename.substring(0, filename.lastIndexOf("/")+1)+st.nextToken();
	}
	
	public String getImageName(){
		return imageName;
	}
	
	private void setKa(String str){
		StringTokenizer st = new StringTokenizer(str);
		st.nextToken();
		float[] coord = new float[3];
		for(int i =0; i < 3; i++){
			coord[i] = Float.valueOf(st.nextToken());
		}
		ka = FloatBuffer.wrap(coord);
	}

	private void setKd(String str){
		StringTokenizer st = new StringTokenizer(str);
		st.nextToken();
		float[] coord = new float[3];
		for(int i =0; i < 3; i++){
			coord[i] = Float.valueOf(st.nextToken());
		}
		kd = FloatBuffer.wrap(coord);
	}

	private void setKs(String str){
		StringTokenizer st = new StringTokenizer(str);
		st.nextToken();
		float[] coord = new float[3];
		for(int i =0; i < 3; i++){
			coord[i] = Float.valueOf(st.nextToken());
		}
		ks = FloatBuffer.wrap(coord);
	}

	private void setNs(String str){
		StringTokenizer st = new StringTokenizer(str);
		st.nextToken();
		ns = Float.valueOf(st.nextToken());
	}

	public void addF(String str){
		StringTokenizer st = new StringTokenizer(str);
		st.nextToken();
		int num = st.countTokens();
		int[] coord = new int[num];
		for(int i =0; i < num; i++){
			coord[i] = Integer.valueOf(st.nextToken().split("/")[0]);
		}
		faces.add(coord);
	}
	
	public void addVt(String str){
		StringTokenizer st = new StringTokenizer(str);
		st.nextToken();
		int num = st.countTokens();
		int[] coord = new int[num];
		for(int i =0; i < 3; i++){
			coord[i] = Integer.valueOf(st.nextToken().split("/")[1]);
		}
		vts.add(coord);
	}
	
	public void addVn(String str){
		StringTokenizer st = new StringTokenizer(str);
		st.nextToken();
		int num = st.countTokens();
		int[] coord = new int[num];
		for(int i =0; i < 3; i++){
			coord[i] = Integer.valueOf(st.nextToken().split("/")[2]);
		}
		vns.add(coord);
	}

	public FloatBuffer getKa() {
		return ka;
	}

	public FloatBuffer getKs() {
		return ks;
	}

	public FloatBuffer getKd() {
		return kd;
	}

	public float getNs() {
		return ns;
	}

	public ArrayList<int[]> getFaces() {
		return faces;
	}
	public ArrayList<int[]> getVt() {
		return vts;
	}

	public boolean HasImage() {
		return hasImage;
	}
	
	/*Join two ObjPart together*/
	public void join(OBJPart other){
		faces.addAll(other.getFaces());
		vts.addAll(other.getVt());
		vns.addAll(other.getVn());
	}
}
