-----------------------------------------------------------
-- RENDER ENTITIES
-----------------------------------------------------------
local r, g, b
local temp = mat4()


function scene.updateEntityRenderInfo(entity)
	if not editor.forceProject then 
		entity.projected  = false
	end
	if (editor.forceProject and entity.projected == false and  selectBounds.h>4 and selectBounds.w>4) or not (entity.render and entity.render.x) then
		entity.render  		=  	entity.render  		or {} 
		entity.projected  = true
		local unp = camera.project(entity.position or entity)
		entity.render.x,	entity.render.y		=	unp.x,unp.y
		return entity.render
	end
end

local tMat1,tMat2,tMat3,tMat4 = mat4(),mat4(),mat4(),mat4()

function scene.getMatrix(model)
	model.matrix = model.matrix or mat4()
	model.transform = model.transform or mat4()
	return model.matrix:transpose(tMat3:mul(tMat1:invert(model.transform),tMat2:invert(model.parent and model.parent.transform or tMat4 ))) 
end

local color = {r=0,g=0,b=0,a=0}
local selectedE 	
local hoveredE  	
local hoveredM 		

function drawModel(model,update)
	gfx.setShader(shaders.forwardRender)
	-- if LOVR then trace("nodrawlovr") return end
	model.parent = model.parent or room

	if (not editingLevel and model.parent.visible==false) or (model.visible~=nil and model.visible==false) then return end
	selectedE 	= model.parent.selected
	hoveredE  	= model.parent == editor.entityHovered
	hoveredM 		= model == editor.modelHovered

	local offsetMesh

	if (((model.parent.light and model.parent.light.enabled) or  model.noCastShadow or model.parent.surface ) and scene.drawingShadow) then return end

	model.transform = model.transform or mat4()
	model.matrix = LOVE and scene.getMatrix(model) or mat4()
	--update and scene.getMatrix(model) or (model.matrix or scene.getMatrix(model))

	-- model.transform:transpose(model.transform)
	if hiSpec or not model.skipMVP then
		MVPmat:transpose(MVPmat:mul(mat4():translate(mat4(),vec3(1)),cam.vp))
		shaders.forwardRender:send("modelMatrix", model.transform)
		-- shaders.forwardRender:send("MVP","column", MVPmat)
		shaders.forwardRender:send("MVP", "column",MVPmat:mul(gfx.camera.vp, model.transform))
	end

	if editingLevel then 
		--shaders.forwardRender:send("wobble",(animationPanel.open or model.isTerrain or model.isEdge) and 0 or (selectedE and time*16 or (((hoveredE or hoveredM) and not pathsPanel.open)  and time*4 or 0)))

		if model.isEdge and room[model.mode][model.id] then 
			model.walled = room[model.mode][model.id].walled=="closed" or (room[model.mode][model.id].walled~="open" and room[model.mode][model.id].points[model.index].walled)
		end

		local brightness =1

		if editState~="Cutting" then 
		 brightness=(model.isEdge and (model.walled and 0.8 or 0.9) or 1) * (animationPanel.open and 1 or (hoveredM and 0.95 or (selectedE and 0.7 or (hoveredE and 0.8 or 1		))))
		end

		if model.color then 
			if model.parent and model.parent.color then 
				color.r,color.g,color.b,color.a = (model.color[1] or 1)*(model.parent.color.r or 1),(model.color[2] or 1)*(model.parent.color.g or 1),(model.color[3] or 1)*(model.parent.color.b or 1),(model.color[4] or 1)*(model.parent.color.a or 1)
			else
				color.r,color.g,color.b,color.a=model.color[1],model.color[2],model.color[3],model.color[4]
			end
		else 
			color.r,color.g,color.b,color.a=1,1,1,1
		end

		model.hoverBrightness = model.hoverBrightness and easeTo(model.hoverBrightness,brightness,4) or 1

		gfx.setColor(gfx.brightness(color,(model.brightness or 1)*(model.hoverBrightness or 1),true))

		if model.mesh and model.isFrame and (editor.debug.draw_frame_bounds or ( animationPanel.open and (model.parent.drawBounds or model.drawBounds) and not model.onion  )) then 
			if editor.debug.draw_frame_bounds then 
				shaders.forwardRender:send("layer",-1)
			end
			-- gfx.setWireframe(true)
			-- 	shaders.forwardRender:send("wire",0.2)
			-- 		shaders.forwardRender:send("colID", {1,1,1})
			-- 		gfx.draw(model.mesh)
			-- 	shaders.forwardRender:send("wire",0)
			-- gfx.setWireframe(false)

			if not level.isAnim and animationPanel and animationPanel.f and not animationPanel.playing then 
				local p1,p2 = -model.parent.transform*vec3(0,0,0),-model.transform*-model.parent.transform*vec3(0,0,0)
				local base = animationPanel.f.blank and 0 or 1
				offsetMesh = gfx.newMesh(zformat,{{p1.x,p1.y,p1.z,1},{p2.x,p2.y,p2.z,1},{p1.x,p1.y,p1.z,1}},"fan")
			end
		end
	else 
		gfx.setColor(gfx.brightness(model.color,(model.brightness or 1)*(model.hoverBrightness or 1)))
	end

	

	if model.skelly and ((model.anim and model.anim.current_pose) or model.current_pose) then 
		shaders.forwardRender:send("skellyman",1)
		shaders.forwardRender:send("u_pose", "column", unpack(model.current_pose or model.anim.current_pose))
		model.front = true
	end
	if (model.front or model.thicknessEnabled) and (not model.isCustom) then 
		gfx.setMeshCullMode("front")
	else
		gfx.setMeshCullMode("none")
	end


	if model.overlay then 
		shaders.forwardRender:send("overlay",2)
	end

	if model.fadeDist then 
		shaders.forwardRender:send("fadeDist",model.fadeDist)
	end

	
	if model.wireframe or editor.debug.wireframe then 
		gfx.setWireframe(true)
	end

	if model.stripe  then 
		shaders.forwardRender:send("stripe",model.stripe)
	elseif model.hoverBrightness  then 
		shaders.forwardRender:send("stripe",(1-model.hoverBrightness)*20)
	end

	local base = ((model.parent.layer or 0)+(model.layer or 0))*-1
	gfx.setBlendMode("alpha","alphamultiply")
	if level.isAnim then 
		gl.Clear(gle.DEPTH_BUFFER_BIT)
	end
	-- if editingLevel and model.onion then 
	-- 	shaders.forwardRender:send("onion",model.m)
	-- 	shaders.forwardRender:send("tint",{model.tint.r,model.tint.g,model.tint.b,0})
	-- 	shaders.forwardRender:send("layer",base)

	-- 		if not model.vector then  gfx.draw(model.mesh) end --------------

	-- 		if model.strokeMesh then 
	-- 			shaders.forwardRender:send("vector",1)
	-- 			gfx.setWireframe(animationPanel.debugView)
	-- 			shaders.forwardRender:send("layer",base+1)
	-- 			gfx.draw(model.strokeMesh)
	-- 			gfx.setWireframe(false)
	-- 			shaders.forwardRender:send("vector",0)
	-- 		end
			
	-- 	shaders.forwardRender:send("onion",0)
	-- else
		if  not (model.hoverOnly and not hoveredM and not editor.selectionDraw) then 
			if model.mesh then 
				shaders.forwardRender:send("layer",base)
				if model.dither then 	shaders.forwardRender:send("dither",1)						end
				if model.unlit 	then 	shaders.forwardRender:send("drawShadowed",false)	end
				if model.indexed then shaders.forwardRender:send("drawIndexed",true)  	shaders.forwardRender:send("palette",unpack(model.palette)) end
				if model.alpha  then shaders.forwardRender:send("alpha", model.alpha) end
				if model.onion then 
					trace("oni",model.index)
					shaders.forwardRender:send("onion",1)
					-- print("trysend")
					shaders.forwardRender:send("tint",{model.tint.r,model.tint.g,model.tint.b,model.tint.a})
					-- shaders.forwardRender:send("layer",base+1)
				else 
					trace("frm",model.index)
				end

				-------------------
				if not model.vector then  

					gfx.setMeshCullMode("none")
					-- gfx.setWireframe(true)
					-- gfx.setBlendMode("alpha")
					gfx.push("all")
					gfx.setBlendMode("alpha")
					-- gfx.setShader(shaders.unmul)
					-- gl.BlendEquation(gle.FUNC_ADD);
					-- gl.BlendFuncSeparate(gle.SRC_ALPHA,gle.ONE_MINUS_SRC_ALPHA,gle.ONE,gle.ONE_MINUS_SRC_ALPHA)
					gfx.draw3D(model.mesh,model.transform)  
					gfx.pop()
				end  
				-------------------
					
				if model.indexed then shaders.forwardRender:send("drawIndexed",false) end

				shaders.forwardRender:send("vector",1)

				if model.strokeMesh then 
					gfx.setWireframe(animationPanel.debugView)
					
					if model.strokeWire>0 then 
						model.strokeMesh:setDrawRange( model.strokeWire+1 ,model.strokeMesh:getVertexCount())
					end
					gfx.push("all")
					gfx.setColor(1,1,1,1)
					gfx.setBlendMode("alpha")
					gl.BlendEquation(gle.FUNC_ADD);
					gl.BlendFuncSeparate(gle.SRC_ALPHA,gle.ONE_MINUS_SRC_ALPHA,gle.ONE,gle.ONE_MINUS_SRC_ALPHA)
					gfx.draw(model.strokeMesh)
					gfx.pop()
					if model.strokeWire>0 or model.strokeWire==-1 then 
						gfx.setWireframe(true)
						if model.strokeWire>0 then 
							model.strokeMesh:setDrawRange( 1, model.strokeWire )
						end
						gfx.draw(model.strokeMesh)
					end

					gfx.setWireframe(false)
				end
				
				if model.strokePreview then 
					shaders.forwardRender:send("layer",base-0.15 )
					gfx.setWireframe(model.strokeWire==-1 or animationPanel.debugView)
					gfx.draw(model.strokePreview)
					gfx.setWireframe(false)
				end

				shaders.forwardRender:send("onion",0)
				shaders.forwardRender:send("vector",0)

				if model.alpha  then shaders.forwardRender:send("alpha", 1) end

				if model.unlit 	then 	shaders.forwardRender:send("drawShadowed",drawShadowed)		end
				if model.dither then 	shaders.forwardRender:send("dither",0)										end

				if not scene.drawingShadow and model.dotlines and (model.dots or model.lines) then
					if  model.dots then 
						gfx.setPointSize(4)
						shaders.forwardRender:send("layer",-1)
						gfx.draw(model.dots)
					end
					if model.lines then 
						shaders.forwardRender:send("layer",-1)
						gfx.setWireframe(true)
						gfx.draw(model.lines)
					end
					gfx.setWireframe(false)
				end
				shaders.forwardRender:send("layer",0)
			end
		end
	-- end
	
	if model.fadeDist then 
		shaders.forwardRender:send("fadeDist",0)
	end


	if model.overlay then 
		shaders.forwardRender:send("overlay",0)
	end

	if model.skelly then 
		shaders.forwardRender:send("skellyman",0)
	end

	if model.stripe or model.hoverBrightness then 
		shaders.forwardRender:send("stripe",0)
	end
	
	if offsetMesh then 
		gfx.setWireframe(true)
		shaders.forwardRender:send("MVP", zcam.vp)
		gfx.draw(offsetMesh)
		gfx.setWireframe(false)
	end

	if model.color then 
		gfx.setColor(1,1,1,1)
	end

	if model.wireframe or (editor.debug.wireframe and not editor.selectionDraw) then 
		gfx.setWireframe(false)
	end
	
	if model.poseMesh then 
		shaders.forwardRender:send("overlay",3)
		shaders.forwardRender:send("MVP",(zcam.vp))
		shaders.forwardRender:send("modelMatrix", mat4())
		gfx.setWireframe(true)
		gfx.draw(model.poseMesh) 
		gfx.setWireframe(false)
	end

end

function vecPalette(palette)
	local p = {{0,0,0,0}}

	for c,color in ipairs(palette) do 
		table.insert(p,{color.r,color.g,color.b,1})
	end

	return p
end
function sendPalette(palette) 
	local test = {{0,0,0,0}}
	for i=1,255,1 do 
		local s = i/255
		table.insert(test,{s,s,s,1})
	end
	shaders.forwardRender:send("palette",unpack(test))
end


function scene.renderRegPoint(entity)
	
	gfx.setColor(1,1,1,0.8) 
	gfx.draw (	
		getImage("BodyCenter"),
		mf(entity.render.x),
		mf(entity.render.y),
		0,
		0.5,
		0.5,
		10, 
		10
	)
	
end

function scene.renderBBox(entity)

	if entity.bbox == nil or entity.simple then return end
	local box= entity.bbox
	gfx.setLineWidth(1)
	gfx.setColor(1,1,1,0.2) 
	gfx.polygon("line",{ box[1], box[2], box[3], box[2], box[3], box[4],  box[1], box[4], })
	gfx.setColor(0,0,0,0.2) 
	gfx.polygon("line",{ box[1]+1, box[2]+1, box[3]+1, box[2]+1, box[3]+1, box[4]+1,  box[1]+1, box[4]+1, })

end

function scene.drawEntityLinks(entity)

	-- PARENT LINK -----------------------
	if entity.parentE~=nil and entity.parent.r2~=nil  and game.state=="Edit" and not entity.simple then 
--		pushDraw(function()
			gfx.setCanvas(canvasMain)
				if entity.parent.ptype == "Weld" then 
				gfx.setColor(1,0.5,0.75,1)
			else 
				gfx.setColor(0.75,0.5,1,1)
			end
			gfx.polygon(
				"fill",
				entity.parentE.render.x+math.cos(entity.parent.r2+pi/2)*8*cam.zoom,
				entity.parentE.render.y+math.sin(entity.parent.r2+pi/2)*8*cam.zoom,
				entity.render.x, 				entity.render.y,
				entity.parentE.render.x, 		entity.parentE.render.y
			)
	--	end)
	end

end