var MultiFilterStatics = {};
MultiFilterStatics.usedTextures = [];
MultiFilterStatics.texturePools = {};	// keyed by "width_height" => []
MultiFilterStatics.getPooledTexture = function(gl, width, height)
{
	var tex = null;
	var key = width + "_" + height;
	if (this.texturePools[key] === undefined) this.texturePools[key] = [];
	if (this.texturePools[key].length > 0)
	{
		tex = this.texturePools[key].pop();
	}
	else
	{
		var glTex = new PIXI.glCore.GLTexture(gl, width, height);
		glTex.premultiplyAlpha = true;		
		glTex.enableLinearScaling();
		glTex.enableWrapClamp();
						
		tex = new PIXI.BaseTexture(null);
		tex.hasLoaded = true;
		tex.isLoading = false;
		tex._glTextures[EngineSettings.Pixi.renderer.CONTEXT_UID] = glTex;
		tex.realWidth = width;
		tex.realHeight = height;
		tex._updateDimensions();
	}
	
	return tex;
}

MultiFilterStatics.returnPooledTexture = function(tex)
{
	var key = tex.width + "_" + tex.height;
	if (this.texturePools[key] === undefined) this.texturePools[key] = [];
	if (!this.texturePools[key].contains(tex)) this.texturePools[key].push(tex);
}

MultiFilterStatics.frameDone = function()
{
	for (var t of this.usedTextures)
	{
		this.returnPooledTexture(t);
	}
	this.usedTextures.length = 0;
}

Engine.MultiFilter = class
{
	constructor()
	{
		this._filters = [];
	}
	get filters() { return this._filters; }
	set filters(filters)
	{
		this._filters = filters;
		
		var t = this;
		
		// note the use of let here, and not var
		for (let i = 0; i < filters.length; i++)
		{
			let f = filters[i];
			let old = f.__originalApply === undefined ? f.apply.bind(f) : f.__originalApply;
			f.__originalApply = old;

			f.apply = (function(filterManager, input, output, clear, currentState) { t.startPass(i, filterManager, input, output, clear, currentState); old(filterManager, input, output, clear, currentState); t.endPass(i, filterManager, input, output, clear, currentState); }).bind(f);
		}
	}
	
	grabPassTarget(filterManager, target)
	{
		var gl = filterManager.gl;
		var cID = EngineSettings.Pixi.renderer.CONTEXT_UID;
		
		var oldFramebuffer = gl.getParameter(gl.FRAMEBUFFER_BINDING);
		var oldTexture = gl.getParameter(gl.TEXTURE_BINDING_2D);
		
		gl.bindFramebuffer(gl.FRAMEBUFFER, target.frameBuffer.framebuffer);
		
		var baseTex = MultiFilterStatics.getPooledTexture(gl, target.frameBuffer.width, target.frameBuffer.height);
		var glTex = baseTex._glTextures[cID];
		glTex.bind();
		
		gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, glTex.premultiplyAlpha);
		gl.copyTexImage2D(gl.TEXTURE_2D, 0, glTex.format, 0, 0, glTex.width, glTex.height, 0);
		
		gl.bindTexture(gl.TEXTURE_2D, oldTexture);		
		gl.bindFramebuffer(gl.FRAMEBUFFER, oldFramebuffer);
		
		MultiFilterStatics.usedTextures.push(baseTex);
		
		return baseTex;
	}
	
	
	update() {}
	startPass(index, filterManager, input, output, clear, currentState) {}
	endPass(index, filterManager, input, output, clear, currentState) {}
}