package com.framsticks.net.client3D;

import java.io.File;
import java.io.IOException;

import javax.media.opengl.GL;

import pl.vorg.mowa.core.graphics.Geometry;
import pl.vorg.mowa.core.graphics.GeometryGroup;
import pl.vorg.mowa.core.graphics.GeometryUtils;
import pl.vorg.mowa.core.graphics.ShaderProgram;

import com.framsticks.net.client3D.graphics.loaders.OBJLoader;
import com.sun.opengl.util.texture.Texture;
import com.sun.opengl.util.texture.TextureIO;

/**
 * Kamienny styl renderowania framstickow
 * @author vorg
 *
 */
public class StoneStyle implements Style {
	private boolean initialized;
	//private Texture muscleTex;
	private Texture partTex;
	private Texture jointTex;
	private GeometryGroup partGeo;
	private GeometryGroup jointGeo;
	private ShaderProgram partShader;
	private ShaderProgram jointShader;

	public void init(GL gl) {
		try {
			partGeo = OBJLoader.load("res/obj/part.obj");
			for(Geometry geom : partGeo.getChildren()) {
				GeometryUtils.generateTangents(geom);
			}			
			partTex = TextureIO.newTexture(new File("res/img/stone2.jpg"), false);			
			partTex.bind();
			partTex.setTexParameteri(GL.GL_TEXTURE_WRAP_S, GL.GL_REPEAT);
			partTex.setTexParameteri(GL.GL_TEXTURE_WRAP_T, GL.GL_REPEAT);
			partShader = ShaderProgram.load("res/shaders/stone.glsl");
			
			jointGeo = OBJLoader.load("res/obj/stick5red.obj");
			for(Geometry geom : jointGeo.getChildren()) {
				GeometryUtils.generateTangents(geom);
			}
			jointTex = TextureIO.newTexture(new File("res/img/stone2.jpg"), false);
			jointTex.bind();
			jointTex.setTexParameteri(GL.GL_TEXTURE_WRAP_S, GL.GL_REPEAT);
			jointTex.setTexParameteri(GL.GL_TEXTURE_WRAP_T, GL.GL_REPEAT);
		    jointShader = ShaderProgram.load("res/shaders/stone.glsl");		    
		}
		catch(IOException e) {
			Log.getInstance().log("err", e.getClass().getName() + " : " + e.getMessage());
			initialized = false;
			return;
		}
		initialized = true;
	}
	
	public boolean isInitialized() {
		return initialized;
	}
	
	public void render(GL gl,Creature[] creatures, Creature.ModelType modelType) {
		
		//parts
		
		gl.glActiveTexture(GL.GL_TEXTURE0);
		partTex.bind();
		partShader.bind();	
		partShader.setParam("diffuseMap", 0);
		partShader.setParam("normalMap", 1);
		for(Creature creature : creatures) {
			float[][] parts = creature.getParts(modelType);
			for(int i=0; i<creature.getParts(modelType).length; i++) {
				gl.glPushMatrix();
				gl.glTranslatef(parts[i][0], parts[i][1], parts[i][2]);
				gl.glScalef(0.68f, 0.68f, 0.68f);
				partGeo.display(gl);
				gl.glPopMatrix();
			}
		}
		partShader.unbind();	
		gl.glActiveTexture(GL.GL_TEXTURE0);
		partTex.disable();
		
		
		//joints
		
		gl.glActiveTexture(GL.GL_TEXTURE0); 
		jointTex.bind();
		jointShader.bind();	
		jointShader.setParam("diffuseMap", 0);
		jointShader.setParam("normalMap", 1);
		for(Creature creature : creatures) {
			int[][] joints = creature.getJoints();
			for(int i=0; i<joints.length; i++) {
				gl.glPushMatrix();
				float[] t = creature.jointTranslation(i, modelType);
				float[] r = creature.jointRotation(i, modelType);
				float l = 0.90f * creature.jointLength(i, modelType);
				gl.glTranslatef(t[0], t[1], t[2]);
				gl.glRotatef(r[0], r[1], r[2], r[3]);
				gl.glScalef(1.0f , 1.0f, l);
				jointGeo.display(gl);
				gl.glPopMatrix();
			}		
		}
		jointShader.unbind();
		gl.glActiveTexture(GL.GL_TEXTURE0);
		jointTex.disable();
	}
}
