package com.framsticks.net.client3D;

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

import javax.media.opengl.GL;

import pl.vorg.mowa.core.graphics.GeometryGroup;
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;

/**
 * Futro - najbardziej wymagajacy sprzetowo styl. Testowany na rad x1600 i gf6600gt
 *  
 * @author vorg
 */
public class FurStyle implements Style {
	private boolean initialized;
	//private Texture muscleTex;
	private Texture partTex;
	//private Texture partTexNormal;
	private Texture jointTex;
	private Texture furTex;
	private GeometryGroup partGeo;
	private GeometryGroup jointGeo;
	//private GeometryGroup muscleGeo;
	private ShaderProgram partShader;
	private ShaderProgram jointShader;
	private ShaderProgram jointBaseShader;
	//private ShaderProgram muscleShader;

	public void init(GL gl) {
		try {
			partGeo = OBJLoader.load("res/obj/part.obj");
			partTex = TextureIO.newTexture(new File("res/img/fur_diffuse_256.jpg"), false);
//			partTexNormal = TextureIO.newTexture(new File("res/img/noise_normal.tga"), 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/diffuse_light.glsl");
			
			jointGeo = OBJLoader.load("res/obj/stick5red.obj");
			jointTex = TextureIO.newTexture(new File("res/img/fur_diffuse_256.jpg"), false);
			jointTex.bind();
			jointTex.setTexParameteri(GL.GL_TEXTURE_WRAP_S, GL.GL_REPEAT);
			jointTex.setTexParameteri(GL.GL_TEXTURE_WRAP_T, GL.GL_REPEAT);
			furTex = TextureIO.newTexture(new File("res/img/fur_bump.tga"), false);
			furTex.bind();
			furTex.setTexParameteri(GL.GL_TEXTURE_WRAP_S, GL.GL_REPEAT);
			furTex.setTexParameteri(GL.GL_TEXTURE_WRAP_T, GL.GL_REPEAT);
		    jointShader = ShaderProgram.load("res/shaders/fur.glsl");
		    jointBaseShader = ShaderProgram.load("res/shaders/diffuse_light.glsl");
		    
//		    muscleGeo = OBJLoader.load("res/obj/muscle_low.obj");
//		    muscleTex = TextureIO.newTexture(new File("res/img/red.jpg"), false);
//			muscleTex.bind();
//			muscleTex.setTexParameteri(GL.GL_TEXTURE_WRAP_S, GL.GL_REPEAT);
//			muscleTex.setTexParameteri(GL.GL_TEXTURE_WRAP_T, GL.GL_REPEAT);
//			muscleShader = ShaderProgram.load("res/shaders/diffuse_light.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();
		//gl.glActiveTexture(GL.GL_TEXTURE1);
		//partTexNormal.bind();
		partShader.bind();	
		partShader.setParam("diffuseMap", 0);
		partShader.setParam("normalMap", 0);
		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.7f, 0.7f, 0.7f);
				partGeo.display(gl);
				gl.glPopMatrix();
			}
		}
		partShader.unbind();	
		partTex.disable();
		
		//joints
		
		gl.glActiveTexture(GL.GL_TEXTURE0); 
		jointTex.bind();
		jointBaseShader.bind();
		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 = 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();
			}		
		}
		jointBaseShader.unbind();
		jointTex.disable();
		
		//fur
		
		gl.glActiveTexture(GL.GL_TEXTURE0); 
		jointTex.bind();
		gl.glActiveTexture(GL.GL_TEXTURE1);
		furTex.bind();
		jointShader.bind();	
		jointShader.setParam("diffuseMap", 0);
		jointShader.setParam("furMap", 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 = 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);
				for(int pass=0; pass<10; pass++) {
					jointShader.setParam("scale", 0.012f * pass);
					jointGeo.display(gl);
				}
				gl.glPopMatrix();
			}	
		}
		jointShader.unbind();
		gl.glActiveTexture(GL.GL_TEXTURE1);
		furTex.disable();
		gl.glActiveTexture(GL.GL_TEXTURE0);
		jointTex.disable();
		
	}

}
