



class framebuffer{

	
	constructor(  ){

		this.width = 1024;
		this.height = 1024;
		

		this._className = "_framebuffer";
		
		this.glFramebuffer;
		
		
		this.framebuffers 	= [];

		this.renderbuffers 	= [];
		
		
		this.face = false;
		this.renderType = '2d';
		
		this.samplers = []; // render to samplers

		//GL_DEPTH_ATTACHMENT
		
		this.multiSample = false;
		
		this.msaaFramebuffer;
		
		this.msaaColorRenderBuffer;
		this.msaaDepthRenderBuffer;
		
		this.MSAA_level = 4;
	}

	setViewport( viewport ){
		
		this.viewport 	= viewport;
		this.gl			= viewport.gl;
		
		this.target = this.gl.TEXTURE_2D;
		
		this.type = this.gl.FLOAT;
		
		this.attachment = this.gl.COLOR_ATTACHMENT0;
		

	}
	
	addSampler( sampler, face ) { 
		sampler.setViewport( this.viewport );
	
		this.samplers.push( sampler );
		
		if( face ){
			this.face = face;
		}
	}


	addCubeSampler( sampler ) { 

		sampler.addTexture(new texture(), this.gl.TEXTURE_CUBE_MAP_POSITIVE_X);
		sampler.addTexture(new texture(), this.gl.TEXTURE_CUBE_MAP_NEGATIVE_X);
		sampler.addTexture(new texture(), this.gl.TEXTURE_CUBE_MAP_POSITIVE_Y);
		sampler.addTexture(new texture(), this.gl.TEXTURE_CUBE_MAP_NEGATIVE_Y);
		sampler.addTexture(new texture(), this.gl.TEXTURE_CUBE_MAP_POSITIVE_Z);
		sampler.addTexture(new texture(), this.gl.TEXTURE_CUBE_MAP_NEGATIVE_Z);
		
		this.samplers.push( sampler );
	}


	getSampler(  ) { 
		return this.samplers[0];
	}


	/**
	 * Create framebuffer
	 * @param {(int)} width
	 * @param {(int)} height
	 * @param {(object)} properties
	**/
	create() { //type, depth

		//var WEBGL_draw_buffers = kepler.extensions.WEBGL_draw_buffers;
		
		var attachments = [];

	
		
		this.glFramebuffer = this.gl.createFramebuffer();
		
		this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, this.glFramebuffer);

		this.renderbuffer = this.gl.createRenderbuffer();		
			
		this.gl.bindRenderbuffer(this.gl.RENDERBUFFER, this.renderbuffer);
		this.gl.renderbufferStorage(this.gl.RENDERBUFFER, this.gl.DEPTH_COMPONENT32F, this.width, this.height);
		this.gl.framebufferRenderbuffer(this.gl.FRAMEBUFFER, this.gl.DEPTH_ATTACHMENT, this.gl.RENDERBUFFER, this.renderbuffer);
			
		//}
		

		
		for(var c = 0; c<this.samplers.length; c++) {

			var sampler = this.samplers[c];
			
			sampler.isFramebuffer = true; 
			
			sampler.internalFormat = this.gl.RGBA32F;
			
			if(this.target == this.gl.TEXTURE_2D) {	
				
				sampler.setTarget( this.viewport );
				
				var textures = sampler.getTextures();
			
			} else {
				
				//var textures = [ sampler.getTexture( this.face ) ];
				var textures = sampler.getTextures( );
				
				
			}
			
			
			
			
			for(var b = 0; b<textures.length; b++) {
			
				var textureObject = textures[b];

				//var WEBGL_draw_buffers = kepler.extensions.WEBGL_draw_buffers;
				
				if( this.samplers.length == 1 ) {
				
					var attachment = this.attachment;
				
				} else {

					switch( c ) {

						case 0:

							var attachment = this.gl.COLOR_ATTACHMENT0
						
						break;

						case 1:

							var attachment = this.gl.COLOR_ATTACHMENT1;

						break;
						case 2: 
							
							var attachment 	= this.gl.COLOR_ATTACHMENT2;

						break;

						case 3: 

							var attachment 	= this.gl.COLOR_ATTACHMENT3;
						
						break;
					}
				}

				attachments.push( attachment );

				this.gl.bindTexture( sampler.target, textureObject.glTexture );
				
				if( this.multiSample ) {

					this.gl.texParameteri( this.gl.TEXTURE_2D, this.gl.TEXTURE_MIN_FILTER, this.gl.LINEAR);
					
					this.gl.texParameteri( sampler.target, this.gl.TEXTURE_MAG_FILTER, this.gl.NEAREST);
					
					this.gl.texParameteri( sampler.target, this.gl.TEXTURE_MIN_FILTER, this.gl.NEAREST);
				
				} else {

					switch( sampler.filter ) {

						case this.gl.NEAREST:

							this.gl.texParameteri(sampler.target, this.gl.TEXTURE_MAG_FILTER, this.gl.NEAREST);
							
							this.gl.texParameteri(sampler.target, this.gl.TEXTURE_MIN_FILTER, this.gl.NEAREST);
							
							this.gl.texParameteri(sampler.target, this.gl.TEXTURE_WRAP_S, this.gl.CLAMP_TO_EDGE);
							
							this.gl.texParameteri(sampler.target, this.gl.TEXTURE_WRAP_T, this.gl.CLAMP_TO_EDGE);
						
						break;

						case this.gl.LINEAR:

							this.gl.texParameteri( sampler.target, this.gl.TEXTURE_MAG_FILTER, this.gl.LINEAR);
							
							this.gl.texParameteri( sampler.target, this.gl.TEXTURE_MIN_FILTER, this.gl.LINEAR);
							
							this.gl.texParameteri( sampler.target, this.gl.TEXTURE_WRAP_S, this.gl.CLAMP_TO_EDGE);
							
							this.gl.texParameteri( sampler.target, this.gl.TEXTURE_WRAP_T, this.gl.CLAMP_TO_EDGE);
						
						break;

						default:

							this.gl.texParameteri( sampler.target, this.gl.TEXTURE_MAG_FILTER, this.gl.NEAREST);
							
							this.gl.texParameteri( sampler.target, this.gl.TEXTURE_MIN_FILTER, this.gl.NEAREST);
							
							this.gl.texParameteri( sampler.target, this.gl.TEXTURE_WRAP_S, this.gl.CLAMP_TO_EDGE);
							
							this.gl.texParameteri( sampler.target, this.gl.TEXTURE_WRAP_T, this.gl.CLAMP_TO_EDGE);
					}
					
				}
				
				if( this.multiSample ) {
					
					var levels = 1;
					
					this.gl.texStorage2D( this.gl.TEXTURE_2D, levels, this.gl.RGBA32F, this.width, this.height);
					
					this.gl.framebufferTexture2D( this.gl.FRAMEBUFFER, this.gl.COLOR_ATTACHMENT0, this.gl.TEXTURE_2D, textureObject.glTexture, 0);
					
				} else {
					
					this.gl.texImage2D( textureObject.face, 0, sampler.internalFormat, this.width, this.height, 0, sampler.format, sampler.type, null);
					
					this.gl.framebufferTexture2D( this.gl.FRAMEBUFFER, attachment, textureObject.face, textureObject.glTexture, 0);
			
				}
				
				//this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MAG_FILTER, this.gl.NEAREST);
				//this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MIN_FILTER, this.gl.NEAREST);
				
				//const internalFormat = this.gl.RGBA32F;
			
				//this.gl.framebufferTexture2D(this.gl.READ_FRAMEBUFFER, attachment, texture.face, texture.glTexture, 0);	
			
				textureObject.attachment 	= attachment;
				//textureObject.dataType = 'framebuffer'; // weird bug when ob
				textureObject.width 		= this.width;
				textureObject.height 		= this.height;
				textureObject.data 			= textureObject.glTexture;
				
				this.gl.bindTexture(this.gl.TEXTURE_2D, null);

			}
		}




		//}
			
			


		
		
		//this.gl.framebufferRenderbuffer(this.gl.FRAMEBUFFER, this.gl.DEPTH_ATTACHMENT, this.gl.RENDERBUFFER, this.renderbuffer);
		//this.gl.renderbufferStorageMultisample();
		
		//console.log(this, textureObject);
		
		if(this.samplers.length > 1) {
			//kepler.extensions.WEBGL_draw_buffers.drawBuffersWEBGL(attachments);
			this.gl.drawBuffers(attachments);
		}

		if (this.gl.checkFramebufferStatus(this.gl.FRAMEBUFFER) != this.gl.FRAMEBUFFER_COMPLETE) {
		   alert("this combination of attachments does not work");
		}

		
		
		//this.gl.bindFramebuffer(this.gl.TEXTURE_2D, null);
		this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, null);
		//this.gl.bindFramebuffer(this.gl.RENDERBUFFER, null);
		
	}
}

export {framebuffer as default};