// Class: openfl._internal.renderer.opengl.GLTilemap

var $global = typeof window != "undefined" ? window : typeof global != "undefined" ? global : typeof self != "undefined" ? self : this

$global.Object.defineProperty(exports, "__esModule", {value: true});

var __map_reserved = {};

// Imports

var $hxClasses = require("./../../../../hxClasses_stub").default;
var $import = require("./../../../../import_stub").default;
function openfl_geom_Rectangle() {return require("./../../../../openfl/geom/Rectangle");}
function openfl_geom_Matrix() {return require("./../../../../openfl/geom/Matrix");}
function openfl_geom_ColorTransform() {return require("./../../../../openfl/geom/ColorTransform");}
function lime_graphics_opengl__$WebGLContext_WebGLContext_$Impl_$() {return require("./../../../../lime/graphics/opengl/_WebGLContext/WebGLContext_Impl_");}
function lime_utils__$DataPointer_DataPointer_$Impl_$() {return require("./../../../../lime/utils/_DataPointer/DataPointer_Impl_");}
function Std() {return require("./../../../../Std");}

// Constructor

var GLTilemap = function(){}

// Meta

GLTilemap.__name__ = ["openfl","_internal","renderer","opengl","GLTilemap"];
GLTilemap.prototype = {
	
};
GLTilemap.prototype.__class__ = $hxClasses["openfl._internal.renderer.opengl.GLTilemap"] = GLTilemap;

// Init



// Statics

GLTilemap.buildBuffer = function(tilemap,renderer) {
	if(!tilemap.__renderable || tilemap.__group.__tiles.length == 0 || tilemap.__worldAlpha <= 0) {
		return;
	}
	GLTilemap.bufferLength = 0;
	GLTilemap.bufferPosition = 0;
	var rect = (openfl_geom_Rectangle().default).__pool.get();
	var matrix = (openfl_geom_Matrix().default).__pool.get();
	var parentTransform = (openfl_geom_Matrix().default).__pool.get();
	var stride = 4;
	if(tilemap.tileAlphaEnabled) {
		++stride;
	}
	if(tilemap.tileColorTransformEnabled) {
		stride += 8;
	}
	GLTilemap.buildBufferTileContainer(tilemap,tilemap.__group,renderer,parentTransform,stride,tilemap.__tileset,tilemap.tileAlphaEnabled,tilemap.__worldAlpha,tilemap.tileColorTransformEnabled,tilemap.__worldColorTransform,null,rect,matrix);
	tilemap.__bufferLength = GLTilemap.bufferLength;
	(openfl_geom_Rectangle().default).__pool.release(rect);
	(openfl_geom_Matrix().default).__pool.release(matrix);
	(openfl_geom_Matrix().default).__pool.release(parentTransform);
}
GLTilemap.buildBufferTileContainer = function(tilemap,group,renderer,parentTransform,stride,defaultTileset,alphaEnabled,worldAlpha,colorTransformEnabled,defaultColorTransform,cacheBitmapData,rect,matrix) {
	var tileTransform = (openfl_geom_Matrix().default).__pool.get();
	var roundPixels = renderer.__roundPixels;
	var tiles = group.__tiles;
	var length = group.__length;
	GLTilemap.resizeBuffer(tilemap,GLTilemap.bufferPosition + length * stride * 6);
	var __bufferData = tilemap.__bufferData;
	var cacheLength;
	var cacheBufferPosition;
	var tile;
	var tileset;
	var alpha;
	var visible;
	var colorTransform = null;
	var id;
	var tileData;
	var tileRect;
	var bitmapData;
	var tileWidth;
	var tileHeight;
	var uvX;
	var uvY;
	var uvHeight;
	var uvWidth;
	var offset;
	var x;
	var y;
	var x2;
	var y2;
	var x3;
	var y3;
	var x4;
	var y4;
	var alphaPosition = 4;
	var ctPosition = alphaEnabled ? 5 : 4;
	var _g = 0;
	while(_g < tiles.length) {
		var tile1 = tiles[_g];
		++_g;
		tileTransform.setTo(1,0,0,1,-tile1.get_originX(),-tile1.get_originY());
		tileTransform.concat(tile1.get_matrix());
		tileTransform.concat(parentTransform);
		if(roundPixels) {
			tileTransform.tx = Math.round(tileTransform.tx);
			tileTransform.ty = Math.round(tileTransform.ty);
		}
		if(tile1.get_tileset() != null) {
			tileset = tile1.get_tileset();
		} else {
			tileset = defaultTileset;
		}
		alpha = tile1.get_alpha() * worldAlpha;
		visible = tile1.get_visible();
		if(!visible || alpha <= 0) {
			continue;
		}
		if(colorTransformEnabled) {
			if(tile1.get_colorTransform() != null) {
				if(defaultColorTransform == null) {
					colorTransform = tile1.get_colorTransform();
				} else {
					if(GLTilemap.cacheColorTransform == null) {
						GLTilemap.cacheColorTransform = new (openfl_geom_ColorTransform().default)();
					}
					colorTransform = GLTilemap.cacheColorTransform;
					colorTransform.redMultiplier = defaultColorTransform.redMultiplier * tile1.get_colorTransform().redMultiplier;
					colorTransform.greenMultiplier = defaultColorTransform.greenMultiplier * tile1.get_colorTransform().greenMultiplier;
					colorTransform.blueMultiplier = defaultColorTransform.blueMultiplier * tile1.get_colorTransform().blueMultiplier;
					colorTransform.alphaMultiplier = defaultColorTransform.alphaMultiplier * tile1.get_colorTransform().alphaMultiplier;
					colorTransform.redOffset = defaultColorTransform.redOffset + tile1.get_colorTransform().redOffset;
					colorTransform.greenOffset = defaultColorTransform.greenOffset + tile1.get_colorTransform().greenOffset;
					colorTransform.blueOffset = defaultColorTransform.blueOffset + tile1.get_colorTransform().blueOffset;
					colorTransform.alphaOffset = defaultColorTransform.alphaOffset + tile1.get_colorTransform().alphaOffset;
				}
			} else {
				colorTransform = defaultColorTransform;
			}
		}
		if(!alphaEnabled) {
			alpha = 1;
		}
		if(tile1.__length > 0) {
			cacheLength = GLTilemap.bufferLength;
			cacheBufferPosition = GLTilemap.bufferPosition;
			GLTilemap.buildBufferTileContainer(tilemap,tile1,renderer,tileTransform,stride,tileset,alphaEnabled,alpha,colorTransformEnabled,colorTransform,cacheBitmapData,rect,matrix);
			GLTilemap.resizeBuffer(tilemap,cacheLength + (GLTilemap.bufferPosition - cacheBufferPosition));
			__bufferData = tilemap.__bufferData;
		} else {
			if(tileset == null) {
				continue;
			}
			id = tile1.get_id();
			bitmapData = tileset.__bitmapData;
			if(bitmapData == null) {
				continue;
			}
			if(id == -1) {
				tileRect = tile1.get_rect();
				if(tileRect == null || tileRect.width <= 0 || tileRect.height <= 0) {
					continue;
				}
				uvX = tileRect.x / bitmapData.width;
				uvY = tileRect.y / bitmapData.height;
				uvWidth = tileRect.get_right() / bitmapData.width;
				uvHeight = tileRect.get_bottom() / bitmapData.height;
			} else {
				tileData = tileset.__data[id];
				if(tileData == null) {
					continue;
				}
				rect.setTo(tileData.x,tileData.y,tileData.width,tileData.height);
				tileRect = rect;
				uvX = tileData.__uvX;
				uvY = tileData.__uvY;
				uvWidth = tileData.__uvWidth;
				uvHeight = tileData.__uvHeight;
			}
			tileWidth = tileRect.width;
			tileHeight = tileRect.height;
			x = tileTransform.__transformX(0,0);
			y = tileTransform.__transformY(0,0);
			x2 = tileTransform.__transformX(tileWidth,0);
			y2 = tileTransform.__transformY(tileWidth,0);
			x3 = tileTransform.__transformX(0,tileHeight);
			y3 = tileTransform.__transformY(0,tileHeight);
			x4 = tileTransform.__transformX(tileWidth,tileHeight);
			y4 = tileTransform.__transformY(tileWidth,tileHeight);
			offset = GLTilemap.bufferPosition;
			__bufferData[offset] = x;
			__bufferData[offset + 1] = y;
			__bufferData[offset + 2] = uvX;
			__bufferData[offset + 3] = uvY;
			__bufferData[offset + stride] = x2;
			__bufferData[offset + stride + 1] = y2;
			__bufferData[offset + stride + 2] = uvWidth;
			__bufferData[offset + stride + 3] = uvY;
			__bufferData[offset + stride * 2] = x3;
			__bufferData[offset + stride * 2 + 1] = y3;
			__bufferData[offset + stride * 2 + 2] = uvX;
			__bufferData[offset + stride * 2 + 3] = uvHeight;
			__bufferData[offset + stride * 3] = x3;
			__bufferData[offset + stride * 3 + 1] = y3;
			__bufferData[offset + stride * 3 + 2] = uvX;
			__bufferData[offset + stride * 3 + 3] = uvHeight;
			__bufferData[offset + stride * 4] = x2;
			__bufferData[offset + stride * 4 + 1] = y2;
			__bufferData[offset + stride * 4 + 2] = uvWidth;
			__bufferData[offset + stride * 4 + 3] = uvY;
			__bufferData[offset + stride * 5] = x4;
			__bufferData[offset + stride * 5 + 1] = y4;
			__bufferData[offset + stride * 5 + 2] = uvWidth;
			__bufferData[offset + stride * 5 + 3] = uvHeight;
			if(alphaEnabled) {
				var _g1 = 0;
				while(_g1 < 6) {
					var i = _g1++;
					__bufferData[offset + stride * i + alphaPosition] = alpha;
				}
			}
			if(colorTransformEnabled) {
				if(colorTransform != null) {
					var _g11 = 0;
					while(_g11 < 6) {
						var i1 = _g11++;
						__bufferData[offset + stride * i1 + ctPosition] = colorTransform.redMultiplier;
						__bufferData[offset + stride * i1 + ctPosition + 1] = colorTransform.greenMultiplier;
						__bufferData[offset + stride * i1 + ctPosition + 2] = colorTransform.blueMultiplier;
						__bufferData[offset + stride * i1 + ctPosition + 3] = colorTransform.alphaMultiplier;
						__bufferData[offset + stride * i1 + ctPosition + 4] = colorTransform.redOffset;
						__bufferData[offset + stride * i1 + ctPosition + 5] = colorTransform.greenOffset;
						__bufferData[offset + stride * i1 + ctPosition + 6] = colorTransform.blueOffset;
						__bufferData[offset + stride * i1 + ctPosition + 7] = colorTransform.alphaOffset;
					}
				} else {
					var _g12 = 0;
					while(_g12 < 6) {
						var i2 = _g12++;
						__bufferData[offset + stride * i2 + ctPosition] = 1;
						__bufferData[offset + stride * i2 + ctPosition + 1] = 1;
						__bufferData[offset + stride * i2 + ctPosition + 2] = 1;
						__bufferData[offset + stride * i2 + ctPosition + 3] = 1;
						__bufferData[offset + stride * i2 + ctPosition + 4] = 0;
						__bufferData[offset + stride * i2 + ctPosition + 5] = 0;
						__bufferData[offset + stride * i2 + ctPosition + 6] = 0;
						__bufferData[offset + stride * i2 + ctPosition + 7] = 0;
					}
				}
			}
			GLTilemap.bufferPosition += stride * 6;
		}
	}
	GLTilemap.bufferLength = GLTilemap.bufferPosition;
	(openfl_geom_Matrix().default).__pool.release(tileTransform);
}
GLTilemap.flush = function(tilemap,renderer) {
	if(GLTilemap.currentShader == null) {
		GLTilemap.currentShader = renderer.__defaultDisplayShader;
	}
	var updatedBuffer = true;
	if(GLTilemap.bufferPosition > GLTilemap.lastFlushedPosition && GLTilemap.currentBitmapData != null && GLTilemap.currentShader != null) {
		var gl = renderer.__gl;
		var shader = renderer.__initDisplayShader(GLTilemap.currentShader);
		renderer.setShader(shader);
		renderer.applyBitmapData(GLTilemap.currentBitmapData,renderer.__allowSmoothing && tilemap.smoothing);
		renderer.applyMatrix(renderer.__getMatrix(tilemap.__renderTransform));
		if(tilemap.tileAlphaEnabled) {
			renderer.useAlphaArray();
		} else {
			renderer.applyAlpha(tilemap.__worldAlpha);
		}
		if(tilemap.tileColorTransformEnabled) {
			renderer.applyHasColorTransform(true);
			renderer.useColorTransformArray();
		} else {
			renderer.applyColorTransform(tilemap.__worldColorTransform);
		}
		renderer.updateShader();
		var stride = 4;
		if(tilemap.tileAlphaEnabled) {
			++stride;
		}
		if(tilemap.tileColorTransformEnabled) {
			stride += 8;
		}
		if(tilemap.__buffer == null || tilemap.__bufferContext != gl) {
			tilemap.__bufferContext = gl;
			tilemap.__buffer = gl.createBuffer();
		}
		gl.bindBuffer(gl.ARRAY_BUFFER,tilemap.__buffer);
		if(updatedBuffer) {
			(lime_graphics_opengl__$WebGLContext_WebGLContext_$Impl_$().default).bufferData(gl,gl.ARRAY_BUFFER,tilemap.__bufferData,gl.DYNAMIC_DRAW);
		}
		if(shader.__position != null) {
			gl.vertexAttribPointer(shader.__position.index,2,gl.FLOAT,false,stride * 4,(lime_utils__$DataPointer_DataPointer_$Impl_$().default).fromInt(0));
		}
		if(shader.__textureCoord != null) {
			gl.vertexAttribPointer(shader.__textureCoord.index,2,gl.FLOAT,false,stride * 4,(lime_utils__$DataPointer_DataPointer_$Impl_$().default).fromInt(8));
		}
		if(tilemap.tileAlphaEnabled) {
			if(shader.__alpha != null) {
				gl.vertexAttribPointer(shader.__alpha.index,1,gl.FLOAT,false,stride * 4,(lime_utils__$DataPointer_DataPointer_$Impl_$().default).fromInt(16));
			}
		}
		if(tilemap.tileColorTransformEnabled) {
			var position = tilemap.tileAlphaEnabled ? 5 : 4;
			if(shader.__colorMultiplier != null) {
				gl.vertexAttribPointer(shader.__colorMultiplier.index,4,gl.FLOAT,false,stride * 4,(lime_utils__$DataPointer_DataPointer_$Impl_$().default).fromInt(position * 4));
			}
			if(shader.__colorOffset != null) {
				gl.vertexAttribPointer(shader.__colorOffset.index,4,gl.FLOAT,false,stride * 4,(lime_utils__$DataPointer_DataPointer_$Impl_$().default).fromInt((position + 4) * 4));
			}
		}
		var start = GLTilemap.lastFlushedPosition == 0 ? 0 : (Std().default)["int"](GLTilemap.lastFlushedPosition / stride);
		var length = (Std().default)["int"]((GLTilemap.bufferPosition - GLTilemap.lastFlushedPosition) / stride);
		gl.drawArrays(gl.TRIANGLES,start,length);
		renderer.__clearShader();
	}
	GLTilemap.lastFlushedPosition = GLTilemap.bufferPosition;
	GLTilemap.lastUsedBitmapData = GLTilemap.currentBitmapData;
	GLTilemap.lastUsedShader = GLTilemap.currentShader;
}
GLTilemap.render = function(tilemap,renderer) {
	if(!tilemap.__renderable || tilemap.__worldAlpha <= 0) {
		return;
	}
	GLTilemap.buildBuffer(tilemap,renderer);
	if(tilemap.__bufferLength == 0) {
		return;
	}
	GLTilemap.bufferLength = tilemap.__bufferLength;
	GLTilemap.bufferPosition = 0;
	GLTilemap.lastFlushedPosition = 0;
	GLTilemap.lastUsedBitmapData = null;
	GLTilemap.lastUsedShader = null;
	GLTilemap.currentBitmapData = null;
	GLTilemap.currentShader = null;
	var stride = 4;
	if(tilemap.tileAlphaEnabled) {
		++stride;
	}
	if(tilemap.tileColorTransformEnabled) {
		stride += 8;
	}
	var gl = renderer.__gl;
	renderer.__setBlendMode(tilemap.__worldBlendMode);
	renderer.__pushMaskObject(tilemap);
	GLTilemap.renderTileContainer(tilemap,renderer,tilemap.__group,tilemap.__worldShader,stride,tilemap.__tileset,tilemap.__worldAlpha,null);
	GLTilemap.flush(tilemap,renderer);
	renderer.__popMaskRect();
	renderer.__popMaskObject(tilemap);
}
GLTilemap.renderTileContainer = function(tilemap,renderer,group,defaultShader,stride,defaultTileset,worldAlpha,cacheBitmapData) {
	var tiles = group.__tiles;
	var length = group.__length;
	var tile;
	var tileset;
	var alpha;
	var visible;
	var id;
	var tileData;
	var tileRect;
	var shader;
	var bitmapData;
	var tileWidth;
	var tileHeight;
	var uvX;
	var uvY;
	var uvHeight;
	var uvWidth;
	var offset;
	var _g = 0;
	while(_g < tiles.length) {
		var tile1 = tiles[_g];
		++_g;
		if(tile1.get_tileset() != null) {
			tileset = tile1.get_tileset();
		} else {
			tileset = defaultTileset;
		}
		alpha = tile1.get_alpha() * worldAlpha;
		visible = tile1.get_visible();
		if(!visible || alpha <= 0) {
			continue;
		}
		if(tile1.get_shader() != null) {
			shader = tile1.get_shader();
		} else {
			shader = defaultShader;
		}
		if(tile1.__length > 0) {
			GLTilemap.renderTileContainer(tilemap,renderer,tile1,shader,stride,tileset,alpha,cacheBitmapData);
		} else {
			if(tileset == null) {
				continue;
			}
			id = tile1.get_id();
			bitmapData = tileset.__bitmapData;
			if(bitmapData == null) {
				continue;
			}
			if(id == -1) {
				tileRect = tile1.get_rect();
				if(tileRect == null || tileRect.width <= 0 || tileRect.height <= 0) {
					continue;
				}
			} else {
				tileData = tileset.__data[id];
				if(tileData == null) {
					continue;
				}
			}
			if(shader != GLTilemap.currentShader && GLTilemap.currentShader != null || bitmapData != GLTilemap.currentBitmapData && GLTilemap.currentBitmapData != null) {
				GLTilemap.flush(tilemap,renderer);
			}
			GLTilemap.currentBitmapData = bitmapData;
			GLTilemap.currentShader = shader;
			GLTilemap.bufferPosition += stride * 6;
		}
	}
}
GLTilemap.renderMask = function(tilemap,renderer) {
}
GLTilemap.resizeBuffer = function(tilemap,length) {
	if(tilemap.__bufferData == null) {
		var this1;
		if(length != null) {
			this1 = new Float32Array(length);
		} else {
			this1 = null;
		}
		tilemap.__bufferData = this1;
	} else if(length > tilemap.__bufferData.length) {
		var this2;
		if(length != null) {
			this2 = new Float32Array(length);
		} else {
			this2 = null;
		}
		var buffer = this2;
		buffer.set(tilemap.__bufferData);
		tilemap.__bufferData = buffer;
	}
	tilemap.__bufferLength = length;
}


// Export

exports.default = GLTilemap;