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


import texture from './texture.js';
import {math} from './math.js';


/**
 * Sampler2D
**/
class sampler2D{
	
	constructor(  ){

		this.texture;
		
		this.id = ++kepler.samplerId;
		
		this.alpha = 1.0;
		
		this.binded = false;
		this.anisotropic = false;

	}
	
	setViewport( viewport ){
		
		this.viewport 	= viewport;
		this.gl			= viewport.gl;
		
		this.FLIP_Y = true;
		this.filter = this.gl.NEAREST;
		this.filter = this.gl.LINEAR;
		
		this.MIN_FILTER = this.gl.LINEAR;
		this.MAG_FILTER = this.gl.LINEAR;
		
		this.WRAP_S = this.gl.REPEAT;
		this.WRAP_T = this.gl.REPEAT;
		
		this.datatype = this.gl.RGBA;
		this.format = this.gl.RGBA;
		this.internalFormat = this.gl.RGBA;
		
		this.target = this.gl.TEXTURE_2D;
		
		this.type = this.gl.FLOAT;

	}

	setTarget( viewport ) {
		

		var textureObject = new texture();
		
		textureObject.setViewport( viewport );
		
		this.addTexture( textureObject );
	}

	getTexture( face ) {

		return this.texture;
		
	}

	getTextures( ) {
		return [this.texture];
	}

	addTexture( textureObject ) {

		this.texture =  textureObject;
	}

	setType(type) {

		//this.texture.type = "type";

	}
	/**
	 * bind sampler to shader
	 * @param {(shader)} shader
	**/
	bind(shader) {
		var txt = this.texture;
		var data = this.texture.data;
		var type = txt.dataType;
		var gl = this.gl;
		//this.type = type;
		


		if (type  == "framebuffer" ) {
		
			this.texture.glTexture =  this.texture.data;
			type = txt.type;
			
		} else {
		
			var mips = [];
			var width = txt.width;
			var height = txt.height;
			
			//if(!this.binded) 
				this.id = 1 + shader.samplerId++;
				

			gl.activeTexture(gl.TEXTURE0 + this.id);

			gl.enable ( this.gl.BLEND ) ;
			gl.bindTexture(gl.TEXTURE_2D,  txt.glTexture );
			gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, this.FLIP_Y);

			//serialize txt data type
			switch( type ) {
				case "float":
					this.type = this.gl.FLOAT;
					gl.texImage2D(gl.TEXTURE_2D, 0, kepler.extensions.EXT_sRGB , width, height, 0, this.internalFormat, this.type, data);
				break;
				case "int":
					this.type = this.gl.UNSIGNED_BYTE;
					gl.texImage2D(gl.TEXTURE_2D, 0, this.format, width, height, 0, this.internalFormat, this.type, data);
				break;
				case "depth":
					gl.texImage2D(gl.TEXTURE_2D, 0, this.gl.DEPTH_COMPONENT, width, height, 0, this.gl.DEPTH_COMPONENT, this.gl.UNSIGNED_SHORT, null);
				break;
				case "image":
					this.type = this.gl.UNSIGNED_BYTE;
					gl.texImage2D(gl.TEXTURE_2D, 0, this.format, this.internalFormat,this.type, data);
				break;
				case "canvas":
					gl.texImage2D(gl.TEXTURE_2D, 0, this.format, width, height, 0, this.internalFormat, this.UNSIGNED_BYTE, data);
				break;
				case "COMPRESSED_RGBA":

					//var textureCompression = kepler.extensions.textureCompression;
					var mipmaps = txt.mipmaps;
					
					var width = mipmaps[0].width;
					var height = mipmaps[0].height;
					
					for(var i = 0; i < mipmaps.length; i++) {
						var mipmap = mipmaps[i];
						
						gl.compressedTexImage2D(gl.TEXTURE_2D, i, mipmap.internalFormat, mipmap.width, mipmap.height, 0, mipmap.byteArray);
					}
				
				break;
			}
			
			
			if(this.anisotropic) {

				//var extension = kepler.extensions.anisotropic;
				//gl.texParameteri( this.gl.TEXTURE_2D, extension.TEXTURE_MAX_ANISOTROPY_EXT, this.anisotropic );

			}
			
			
			if (math.isPowerOfTwo(width) && math.isPowerOfTwo(height) ) {
			
				gl.texParameteri(gl.TEXTURE_2D, this.gl.TEXTURE_MAG_FILTER, this.gl.LINEAR);
				gl.texParameteri(gl.TEXTURE_2D, this.gl.TEXTURE_MIN_FILTER, this.gl.LINEAR_MIPMAP_LINEAR);// mipmaps > 1 ? this.gl.LINEAR_MIPMAP_LINEAR : this.gl.LINEAR 
				gl.texParameteri(gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_S, this.WRAP_S);
				gl.texParameteri(gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_T, this.WRAP_T);
				
				if(this.type != this.gl.FLOAT)
					gl.generateMipmap(gl.TEXTURE_2D);
				
			} else {

				gl.texParameteri(gl.TEXTURE_2D, this.gl.TEXTURE_MIN_FILTER, this.gl.LINEAR);
				gl.texParameteri(gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_S, this.gl.CLAMP_TO_EDGE);
				gl.texParameteri(gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_T, this.gl.CLAMP_TO_EDGE);
				
			}
			
			
			gl.bindTexture(gl.TEXTURE_2D, null);
			this.binded = true;
		}
	}
}
export {sampler2D as default};
