Type TDebug
	
	Global cno ' child no (< and > keys to cycle though child entities)
	Global info=1 ' current info page (keys 1-9)
	Global bsphere=False ' show/hide bounding sphere (F1)
	
	' entities for marker and bounding sphere
	Global marker:TMesh
	Global bounding_sphere:TMesh

	' MiniB3D functions
	
	' Extra - offers extra functionality that Blitz3D does not

	Function DebugWorld()
	
		Local no_ents
		Local no_cams
		Local no_lights
		Local no_pivs
		Local no_meshes
		Local no_sprites
		Local no_bones
		
		For Local ent:TEntity=EachIn TEntity.entity_list
		
			no_ents:+1
			
			If TCamera(ent)<>Null Then no_cams:+1
			If TLight(ent)<>Null Then no_lights:+1
			If TPivot(ent)<>Null Then no_pivs:+1
			If TMesh(ent)<>Null Then no_meshes:+1
			If TSprite(ent)<>Null Then no_sprites:+1
			If TBone(ent)<>Null Then no_bones:+1	
		
		Next
		
		TBlitz2D.Text 0,120,"Entities: "+String(no_ents)
		TBlitz2D.Text 0,140,"Cameras: "+String(no_cams)
		TBlitz2D.Text 0,160,"Lights: "+String(no_lights)
		TBlitz2D.Text 0,180,"Pivots: "+String(no_pivs)
		TBlitz2D.Text 0,200,"Meshes: "+String(no_meshes)
		TBlitz2D.Text 0,220,"Sprites: "+String(no_sprites)
		TBlitz2D.Text 0,240,"Bones: "+String(no_bones)
	
	End Function

	Function DebugEntity:TEntity(ent:TEntity,cam:TCamera=Null)

		If ent=Null Then Return

		Local no_children=0
		Local old_cent:TEntity=ent.GetChildFromAll(cno,no_children)
		If old_cent<>Null Then old_cent.EntityColor 255,255,255
	
		If KeyHit(KEY_PERIOD) Then cno=cno+1
		If KeyHit(KEY_COMMA) Then cno=cno-1
		Local no_childs=TEntity.CountAllChildren(ent)
		If cno<0 Then cno=0
		If cno>no_childs Then cno=no_childs

		no_children=0
		Local cent:TEntity=ent.GetChildFromAll(cno,no_children)
	
		If cent=Null Then cent=ent ' if no children entity then use main entity
		
		If cent<>Null
		
			cent.EntityColor 255,0,0
			TBlitz2D.Text 0,80,String(cno)+". "+cent.name$+" ("+cent.class$+")"
		
			If KeyHit(KEY_1) Then info=1
			If KeyHit(KEY_2) Then info=2
			If KeyHit(KEY_3) Then info=3
			If KeyHit(KEY_4) Then info=4
			If KeyHit(KEY_F1) Then bsphere=1-bsphere
			
			If info=1 Then EntityInfo1(cent)
			If info=2 Then EntityInfo2(cent)
			If info=3 Then EntityInfo3(cent,cam)
			If info=4 Then EntityInfo4(cent,cam)
			
			UpdateMarker(cent)
			UpdateBoundingSphere(cent)
			
		EndIf
		
		Return cent
	
	End Function
	
	Function EntityInfo1(ent:TEntity)
	
		Local xx#=0

		xx#=ent.EntityX#(True)
		If xx#<0.0001 And xx#>-0.0001 Then xx#=0
		TBlitz2D.Text 0,120,"X (g): "+String(xx#)
		
		xx#=ent.EntityY#(True)
		If xx#<0.0001 And xx#>-0.0001  Then xx#=0
		TBlitz2D.Text 0,140,"Y: "+String(xx#)
		
		xx#=ent.EntityZ#(True)
		If xx#<0.0001 And xx#>-0.0001  Then xx#=0
		TBlitz2D.Text 0,160,"Z: "+String(xx#)
		
		xx#=ent.EntityPitch#(True)
		If xx#<0.0001 And xx#>-0.0001  Then xx#=0
		TBlitz2D.Text 0,180,"Pitch: "+String(xx#)
		
		xx#=ent.EntityYaw#(True)
		If xx#<0.0001 And xx#>-0.0001  Then xx#=0
		TBlitz2D.Text 0,200,"Yaw: "+String(xx#)
		
		xx#=ent.EntityRoll#(True)
		If xx#<0.0001 And xx#>-0.0001  Then xx#=0
		TBlitz2D.Text 0,220,"Roll: "+String(xx#)

		xx#=ent.EntityX#(False)
		If xx#<0.0001 And xx#>-0.0001  Then xx#=0
		TBlitz2D.Text 0,260,"X (l): "+String(xx#)
		
		xx#=ent.EntityY#(False)
		If xx#<0.0001 And xx#>-0.0001  Then xx#=0
		TBlitz2D.Text 0,280,"Y: "+String(xx#)
		
		xx#=ent.EntityZ#(False)
		If xx#<0.0001 And xx#>-0.0001  Then xx#=0
		TBlitz2D.Text 0,300,"Z: "+String(xx#)
		
		xx#=ent.EntityPitch#(False)
		If xx#<0.0001 And xx#>-0.0001  Then xx#=0
		TBlitz2D.Text 0,320,"Pitch: "+String(xx#)
		
		xx#=ent.EntityYaw#(False)
		If xx#<0.0001 And xx#>-0.0001  Then xx#=0
		TBlitz2D.Text 0,340,"Yaw: "+String(xx#)
		
		xx#=ent.EntityRoll#(False)
		If xx#<0.0001 And xx#>-0.0001  Then xx#=0
		TBlitz2D.Text 0,360,"Roll: "+String(xx#)
		
		Local tx=0
		Local ty=380
		For Local iy=0 To 3
			tx=0
			ty=ty+20
			For Local ix=0 To 3
				xx#=ent.mat.grid[ix,iy]
				If xx#<0.0001 And xx#>-0.0001 Then xx#=0
				TBlitz2D.Text tx,ty,String(xx#)
				tx=tx+100
			Next
		Next
	
	End Function
	
	Function EntityInfo2(ent:TEntity)
	
		If TMesh(ent)<>Null
	
			Local xx#=0
	
			xx#=TMesh(ent).CountSurfaces()
			TBlitz2D.Text 0,120, "Surfaces: "+String(xx#)
			
			xx#=TMesh(ent).CountVertices()
			TBlitz2D.Text 0,140,"Vertices: "+String(xx#)
			
			xx#=TMesh(ent).CountTriangles()
			TBlitz2D.Text 0,160,"Triangles: "+String(xx#)
			
			xx#=TMesh(ent).MeshWidth()
			TBlitz2D.Text 0,180,"Mesh Width: "+String(xx#)
			
			xx#=TMesh(ent).MeshWidth()
			TBlitz2D.Text 0,200,"Mesh Height: "+String(xx#)
			
			xx#=TMesh(ent).MeshWidth()
			TBlitz2D.Text 0,220,"Mesh Depth: "+String(xx#)
		
		Else
		
			TBlitz2D.Text 0,120, "Entity is not a mesh!"
		
		EndIf
				
	End Function
	
	Function EntityInfo3(ent:TEntity,cam:TCamera)
	
		If cam<>Null
		
			TBlitz2D.Text 0,120,"EntityInView: "+String(cam.EntityInView(ent))
		
		Else

			TBlitz2D.Text 0,120, "Camera entity not specified!"
		
		EndIf
		
		TBlitz2D.Text 0,140, "Hidden: "+ent.hidden
		TBlitz2D.Text 0,160, "Parent Hidden: "+ent.parent_hidden
		
		TBlitz2D.Text 0,180, "Cull Radius: "+ent.cull_radius
		
		If TMesh(ent)<>Null
		
			TBlitz2D.Text 0,200, "Min X: "+TMesh(ent).min_x
			TBlitz2D.Text 0,220, "Min Y: "+TMesh(ent).min_y
			TBlitz2D.Text 0,240, "Min Z: "+TMesh(ent).min_z
			
			TBlitz2D.Text 0,260, "Max X: "+TMesh(ent).max_x
			TBlitz2D.Text 0,280, "Max Y: "+TMesh(ent).max_y
			TBlitz2D.Text 0,300, "Max Z: "+TMesh(ent).max_z
		
		EndIf
		
	End Function

	Function EntityInfo4(ent:TEntity,cam:TCamera)
		
	End Function

	Function UpdateMarker(ent:TEntity)
	
		If marker=Null
			marker=TMesh.CreateSphere(8)
			marker.ScaleEntity(.25,.25,.25)
			marker.EntityColor(255,255,0)
			marker.EntityOrder(-10)
		EndIf
		
		marker.PositionEntity(ent.EntityX(True),ent.EntityY(True),ent.EntityZ(True),True)
		
	End Function
	
	Function UpdateBoundingSphere(ent:TEntity)
			
		If bounding_sphere=Null
			bounding_sphere=TMesh.CreateSphere(16)
			bounding_sphere.EntityAlpha(.75)
			bounding_sphere.EntityColor(255,255,0)
		EndIf
			
		If bsphere=False
			bounding_sphere.HideEntity
			Return
		EndIf
		
		bounding_sphere.ShowEntity
	
		Local radius#=Abs(ent.cull_radius#) ' use absolute value as cull_radius will be negative value if set by MeshCullRadius (manual cull)
	
		' mesh centre
		Local x#=TMesh(ent).min_x
		Local y#=TMesh(ent).min_y
		Local z#=TMesh(ent).min_z
		x#=x#+(TMesh(ent).max_x-TMesh(ent).min_x)/2.0
		y#=y#+(TMesh(ent).max_y-TMesh(ent).min_y)/2.0
		z#=z#+(TMesh(ent).max_z-TMesh(ent).min_z)/2.0
		
		' transform mesh centre into world space
		TEntity.TFormPoint(x#,y#,z#,ent,Null)
		x#=TEntity.TFormedX#()
		y#=TEntity.TFormedY#()
		z#=TEntity.TFormedZ#()
		
		' radius - apply entity scale
		Local rx#=radius#*ent.EntityScaleX(True)
		Local ry#=radius#*ent.EntityScaleY(True)
		Local rz#=radius#*ent.EntityScaleZ(True)
		If rx#>=ry# And rx#>=rz#
			radius#=Abs(rx#)
		Else If ry#>=rx# And ry#>=rz#
			radius#=Abs(ry#)
		Else
			radius#=Abs(rz#)
		EndIf
		
		bounding_sphere.PositionEntity(x#,y#,z#,True)
		bounding_sphere.ScaleEntity(radius#,radius#,radius#)
		
	End Function
		
End Type
