/**
* WebGL Model Viewer - Material.js
* Copyright © Cyril Diagne 2010.
*
* @author kikko.fr
*/

Material = function(name) {
	
	this.name = name;
	
	this.events = new EventDispatcher();
	this.shader = new DynShader();
	this.shaderHeader = "";
	
	this.shininess	= 64;
	this.ambient	= [0, 0, 0];
	this.diffuse	= [0, 0, 0];
	this.specular	= [1.0, 1.0, 1.0];
	
	this.maps = {};
	
	this.useParallax = true;
	this.useLights = true;
};
	
Material.prototype = {
	
	
	init : function(hasUV, hasNormal, hasTangent) {
		
		this.setShaderHeader(hasUV, hasNormal, hasTangent);
		this.shader.compileAndLink(this.shaderHeader);
		this.getShaderLocations();
	},
	
	addMap : function(map, url) {
		
		this.maps[map] = TextureLibrary.getTexture(url);
		this.maps[map].url = url;
		//log(this.maps[map], this.name, map, url);
	},
	
	setShaderHeader : function(hasUV, hasNormal, hasTangent) {
				
		var h = "";
		var n = "\n";
		
		if(hasUV)		h += "#define UV"+n;
		if(hasNormal)	h += "#define NORMALS"+n;
		if(hasTangent)	h += "#define TBN"+n;
		
		var m = this.maps;
		
		if(m.diffuse)	h += "#define DIFF_MAP"+n;
		if(m.normal)	h += "#define NORMAL_MAP"+n;
		if(m.specular)	h += "#define SPECULAR_MAP"+n;
		if(m.height)	h += "#define HEIGHT_MAP"+n;
		
		if(this.useLights)	 h += "#define LIGHTS"+n
		if(this.useParallax) h += "#define PARALLAX"+n;
		
		h += n;
		
		this.shaderHeader = h;
	},
	
	getShaderLocations : function() {
	
		var program = this.shader.program;
		
		// matrices
		
		this.pMatrixUniform = gl.getUniformLocation(program, "uPMatrix");
		this.mvMatrixUniform = gl.getUniformLocation(program, "uMVMatrix");
		this.nMatrixUniform = gl.getUniformLocation(program, "uNMatrix");
		
		// geom
		
		this.vertexPosAttrib = gl.getAttribLocation(program, "aVertexPosition");
		this.normalAttrib = gl.getAttribLocation(program, "aVertexNormal");
		this.tangentAttrib = gl.getAttribLocation(program, "aVertexTangent");
		this.texCoordAttrib = gl.getAttribLocation(program, "aTextureCoord");
		
		// material
		
		this.shininessUniform = gl.getUniformLocation(program, "shininess");
		this.ambientUniform = gl.getUniformLocation(program, "ambient");
		this.diffuseUniform = gl.getUniformLocation(program, "diffuse");
		this.specularUniform = gl.getUniformLocation(program, "specular");
		
		this.diffuseSampler = gl.getUniformLocation(program, "diffuseMap");
		this.normalSampler = gl.getUniformLocation(program, "normalMap");
		this.specularSampler = gl.getUniformLocation(program, "specularMap");
		this.heightSampler  = gl.getUniformLocation(program, "heightMap");
	},
	
	enable : function() {
		
		gl.useProgram(this.shader.program);
		
		gl.uniform1f(this.shininessUniform, this.shininess);
		gl.uniform3fv(this.diffuseUniform, new WebGLFloatArray(this.diffuse));
		gl.uniform3fv(this.specularUniform, new WebGLFloatArray(this.specular));
		gl.uniform3fv(this.ambientUniform, new WebGLFloatArray(this.ambient));
				
		// bind textures & set shader's uniforms
		var i=0;
		for(mapName in this.maps) {
			gl.activeTexture(gl["TEXTURE"+i]);
			gl.bindTexture(gl.TEXTURE_2D, this.maps[mapName]);
			gl.uniform1i(this[mapName+"Sampler"], i);
			i++;
		}
	},


	disable : function() {

		gl.bindTexture(gl.TEXTURE_2D, null);
	}
}
