/*
 * Copyright 2013-2018, kaj dijkstra, 
 * Author, Kaj Dijkstra.
 * All rights reserved.
 *
 */

import shader from './shader.js';
import sampler2D from './sampler2D.js';

/**
 * Material
**/
class material{


	name 				= "none";
		
	color;

	properties 			= new Array();

	textures 			= new Array();

	normals 			= new Array();

	displacementMaps 	= new Array();

	transparencyMaps 	= new Array();

	roughnessMaps 		= new Array();

	specularMaps 		= new Array();
		
		
	diffuseColor 		= new Array( 256/256, 256/256,1 );
		
	shadingModelID 		= 0.0;

	useParallax 		= false;
		
	uvScale 			= 1;
		
	roughness 			= 0.1; // 0.75;

	metallic 			= 0.1;

	reflectance 		= 0.1;
		
	uvMultiplier 		= 1.0;

	alpha 				= 1.0;
		
		
	shader;
		
	id 					= kepler.global_material_id++;
		
	entityID 			= 0;
		
	created 			= false;

	updated 			= false;


	/**
	 * set viewport
	 * @param {(viewport)} viewport
	**/
	setViewport( viewport ){
		
		this.viewport = viewport;
		
	}
	
	create (  ) {
		
		this.created = true;
		
		this.shader = new shader();

		this.shader.definePragma("TEXTURE", (this.textures.length > 0) ? 1.0 : 0.0 );

		this.shader.definePragma("NORMAL_MAP", (this.normals.length > 0) ? 1.0 : 0.0 );

		this.shader.definePragma("ROUGHNESS_MAP", (this.roughnessMaps.length > 0) ? 1.0 : 0.0 );

		this.shader.definePragma("SHADING_MODEL_ID", this.shadingModelID );

		this.shader.definePragma("PARALLAX", (this.useParallax) ? 1.0 : 0.0 );

		this.shader.definePragma("DEFERRED", 1.0 );
		
		this.shader.createFromFile("shaders/color.shader");

	}

	updateShader(  ) {

		if( !this.updated ) {

			console.log("shader updated");

			var shader 		= this.shader;
			
			var viewport 	= kepler.viewports[0];
		
			shader.setUniform("far", viewport.mainCamera.far );

			shader.setUniform("reflectionSampler", viewport.system.reflectionSampler );

			shader.setUniform("alpha", this.alpha );

			shader.setUniform("uvMultiplier", this.uvMultiplier );

			shader.setUniform("render_type", 0);
			
			if( this.textures.length > 0 ) {
			
				this.textures[0].anisotropic = 4;
				
				if(	this.textures.length > 0 ) {

					shader.setUniform("diffuseSampler", this.textures[0] );

				}
				
				if(	this.transparencyMaps.length > 0 ) {

					shader.setUniform("transparencyMapSampler", this.transparencyMaps[0] );

				}
				
				if(	this.normals.length > 0 ) {

					shader.setUniform("normalSampler", this.normals[0] );

				}
				
				if(	this.roughnessMaps.length > 0 ) {

					shader.setUniform("normalSampler", this.roughnessMaps[0] );

				}
				
				if( this.displacementMaps.length > 0  ) {

					shader.setUniform("heightSampler", this.displacementMaps[0]);

				} 
				
			} else {
				
				shader.setUniform("diffuseColor", this.diffuseColor );


			}
			
			shader.setUniform("shadingModelID", this.shadingModelID );
			
			//shader.setUniform("roughness", this.roughness );
			
			//shader.setUniform("id", this.id );
			
			
			var shadowNoiseTexure = kepler.resources.getTexture("rotrandom.png");
			var shadowNoiseSampler = new sampler2D();
			
			shadowNoiseSampler.addTexture(shadowNoiseTexure);

			console.log("shadowNoiseSampler", shadowNoiseSampler);
			
			//if forward
			//var depthpass = this.viewport.system.forwardRenderPipeline.getRenderpass("depth")

			var depthPasses = this.viewport.system.depthPasses;
			
			var depthpass = depthPasses[0];
			
			shader.setUniform("shadowDepthSampler", depthpass.framebuffer.getSampler() );
			shader.setUniform("lightViewProjection", depthpass.viewProjection );
			shader.setUniform("lightPosition", depthpass.lightPosition  );
			shader.setUniform("lightType", depthpass.lightType == "pointLight" ? 0 : 1  );
			shader.setUniform("lightDirection", [0.0, -0.7, 0.5]  );
			
			console.log("depthpass.lightPosition", depthpass.lightPosition);
					
			shader.setUniform("shadowNoiseSampler", shadowNoiseSampler );
			
			//shader.setUniform("reflectionSampler", viewport.reflectionSampler );
			shader.setUniform("shadowBias", .1  );
			shader.setUniform("SpotAngles", [30, 0.1]);
			shader.setUniform("LightColor", [1, 1, 1] );
			shader.setUniform("far", viewport.mainCamera.far );
			shader.setUniform("shadowFar", viewport.mainCamera.far );
			shader.setUniform("anisotropy", 0.7 );

			shader.setUniform("lightGeometry", [1.0 / 85.0, 4.0, 0.1] );
			shader.setUniform("clearCoatColor", [1.0, 1.0, 1.0] );
			
			shader.setUniform("lightColor", [1,1,1] ); //colorTemperatureToSRGB(6000.0) );
			//shader.setUniform("lightDirection", [0.0, -0.7, 0.5]  );
			//shader.setUniform("lightPosition", [3, 4, 1] );

			
			shader.setUniform("lightIntensity", .5);
			shader.setUniform("environmentLuminance", 0.4);
			shader.setUniform("roughness", this.roughness  );
			
			shader.setUniform("clearCoatRoughness", this.roughness );
			shader.setUniform("clearCoat", 0.3 );
			shader.setUniform("clearCoatThickness", 0.2 );
			shader.setUniform("clearCoatIOR", .0 );
			shader.setUniform("v_metallic", this.metallic );
			shader.setUniform("v_reflectance", this.reflectance);
			shader.setUniform("cameraPosition", [0,0,0]);
			//shader.setUniform("cameraPosition", [0,0,0]);
			
			//shader.update(this.viewport);

			
			this.updated = true;
		}
	}

	updateColor ( id ) {
		
		this.shadingModelID = id;
	}
	
	setShadingModelID ( id ) {
		
		this.shadingModelID = id;
	}

	getShadingModelID ( id ) {
		return this.shadingModelID;
	}

	addProperty (key, value) {
		this.properties.push([key, value]);
	}

	/**
	 * add texture to material
	 * @param {(texture)} texture
	**/
	addTexture(texture) {
		this.textures = [];
		this.textures.push(texture);
	}


	/**
	 * add normal map to material
	 * @param {(texture)} texture
	**/
	addNormal(texture) {
		this.normals = [];
		this.normals.push(texture);
	}

	/**
	 * add normal map to material
	 * @param {(texture)} texture
	**/
	addRoughness(texture) {
		this.roughnessMaps.push(texture);
	}


	/**
	 * add transparency map to material
	 * @param {(texture)} transparentyMap
	**/
	addTransparentyMap(texture) {
		this.transparencyMaps.push(texture);
	}


	/**
	 * add displacement map to material
	 * @param {(texture)} heightmap
	**/
	addDisplacement( heightmap ) {
		this.useParallax = true;
		this.displacementMaps.push(heightmap);
	}


	/**
	 * add specular map to material
	 * @param {(texture)} specularMap
	**/
	addSpecularMap( specularMap ) {
		this.specularMaps.push(specularMap);
	}
}

export {material as default};