
Module Shaders
	'Draw shaders
	Friend DrawShader_0Tex As Integer
	Friend DrawShader_1Tex As Integer
	
	'Post effect shaders
	Friend PostEffect_Blend2 As Integer

	'Material shaders
	Friend MaterialShader_FixedWireFrame As Integer
	Friend MaterialShader_SimpleColor As Integer
	
	Friend Function LoadDrawShader(Filename As String) As Integer
		InsertStringToEngine(Filename)
		LoadDrawShader = frmMain.DGE.Shader_LoadAsDrawShader_InSB: RE()
	End Function
	
	Friend Function LoadPostEffect(Filename As String) As Integer
		InsertStringToEngine(Filename)
		LoadPostEffect = frmMain.DGE.Shader_LoadAsPostEffect_InSB: RE()
	End Function

	Friend Function LoadMaterialShader(Filename As String) As Integer
		InsertStringToEngine(Filename)
		LoadMaterialShader = frmMain.DGE.Shader_LoadAsMaterial_InSB: RE()
	End Function
	
	'Generate UV coordinates from a rectangle
	Friend Sub UVSourceFromRect(ByRef Location As Rect)
		frmMain.DGE.Draw_GiveInputSourceRectangleUV1(0,Rect_GetWidth(Location),0,Rect_GetHeight(Location)): RE()
	End Sub
	
	Friend Sub Draw_SetInputColor(ByRef Color As Vector4)
		frmMain.DGE.Draw_GiveInputColor(Color.X, Color.Y, Color.Z, Color.W): RE()
	End Sub
	
	Friend Sub Shader_Init()
		'Load draw shaders
		DrawShader_0Tex = LoadDrawShader("Editor_D_FullQuad_Color")
		DrawShader_1Tex = LoadDrawShader("Editor_D_FullQuad_1Tex")
		
		'Load post effect shaders
		PostEffect_Blend2 = LoadPostEffect("PE_Blend2")
		
		'Load material shaders
		frmMain.DGE.Shader_UseAsDefaultMaterialShader(LoadMaterialShader("Editor_DefaultMaterialShader"))
		MaterialShader_FixedWireFrame = LoadMaterialShader("Editor_M_FixedWire")
		MaterialShader_SimpleColor = LoadMaterialShader("Editor_M_SimpleColor")
	End Sub
	
	'Draw using pixel coordinates
	Friend Sub DrawRect(ByVal OutputDrawSurface As integer, ByVal DrawShader As integer, ByRef Location As Rect, ByVal Filter As integer)
		Dim OutputWidth As integer
		Dim OutputHeight As integer
		OutputWidth = frmMain.DGE.DrawSurface_GetWidth(OutputDrawSurface): RE()
		OutputHeight = frmMain.DGE.DrawSurface_GetHeight(OutputDrawSurface): RE()
		frmMain.DGE.Draw_RenderQuad(OutputDrawSurface, DrawShader, Lerp(-1,1,(Location.Left + Location.Right) / (2 * OutputWidth)), _
		  Lerp(-1,1,(Location.Top + Location.Bottom) / (2 * OutputHeight)), Rect_GetWidth(Location) / (OutputWidth), 0, _
		  0, Rect_GetHeight(Location) / (OutputHeight), Filter): RE()
	End Sub
	
	Friend Sub DrawLine(ByVal OutputDrawSurface As integer, ByRef StartPoint As Vector2, ByRef EndPoint As Vector2, ByVal Thickness As Single)
		Dim OutputWidth As integer
		Dim OutputHeight As integer
		Dim Center_Pixel As Vector2
		Dim LengthAxis_Pixel As Vector2
		Dim WidthAxis_Pixel As Vector2
		Dim Center As Vector2
		Dim LengthAxis As Vector2
		Dim WidthAxis As Vector2
		OutputWidth = frmMain.DGE.DrawSurface_GetWidth(OutputDrawSurface): RE()
		OutputHeight = frmMain.DGE.DrawSurface_GetHeight(OutputDrawSurface): RE()
		Center_Pixel = MiddleVector2(StartPoint, EndPoint)
		LengthAxis_Pixel = ToVector2(StartPoint, EndPoint)
		WidthAxis_Pixel = MulVector2(NormalVector2(MakeVector2(LengthAxis_Pixel.Y, -LengthAxis_Pixel.x)), Thickness)
		Center.x = Center_Pixel.X / OutputWidth
		Center.y = Center_Pixel.y / OutputHeight
		LengthAxis.x = LengthAxis_Pixel.X / OutputWidth
		LengthAxis.y = LengthAxis_Pixel.y / OutputHeight
		WidthAxis.x = WidthAxis_Pixel.X / OutputWidth
		WidthAxis.y = WidthAxis_Pixel.y / OutputHeight
		frmMain.DGE.Draw_RenderQuad(OutputDrawSurface, DrawShader_0Tex, Lerp(-1,1,Center.X), Lerp(-1,1,Center.y), WidthAxis.X, WidthAxis.y, LengthAxis.X, LengthAxis.y, 1): RE()
	End Sub
	
	Friend Sub DrawRectWithinBound(ByVal OutputDrawSurface As integer, ByRef Location As Rect, ByRef Bound As Rect, ByRef UV As RectUV, ByRef Color As Vector4, ByVal Texture As integer, ByVal Filter As integer)
		Dim FinalLocation As Rect
		Dim FinalUV As RectUV
		Dim DrawShader As integer
		FinalLocation = Location
		FinalUV = UV
		If FinalLocation.Right > Bound.Left andalso Bound.right > FinalLocation.left andalso FinalLocation.Bottom > Bound.Top andalso Bound.Bottom > FinalLocation.Top then
			If FinalLocation.Left < Bound.Left Then
				Dim LeftClipRatio As Double
				LeftClipRatio = InverseLerp(FinalLocation.Left, FinalLocation.Right, Bound.Left)
				FinalLocation.Left = Bound.Left
				FinalUV.MinU = Lerp(FinalUV.MinU, FinalUV.MaxU, LeftClipRatio)
			End If
			If FinalLocation.Right > Bound.Right Then
				Dim RightClipRatio As Double
				RightClipRatio = InverseLerp(FinalLocation.Left, FinalLocation.Right, Bound.Right)
				FinalLocation.Right = Bound.Right
				FinalUV.MaxU = Lerp(FinalUV.MinU, FinalUV.MaxU, RightClipRatio)
			End If
			If FinalLocation.Top < Bound.Top Then
				Dim TopClipRatio As Double
				TopClipRatio = InverseLerp(FinalLocation.Top, FinalLocation.Bottom, Bound.Top)
				FinalLocation.Top = Bound.Top
				FinalUV.MinV = Lerp(FinalUV.MinV, FinalUV.MaxV, TopClipRatio)
			End If
			If FinalLocation.Bottom > Bound.Bottom Then
				Dim BottomClipRatio As Double
				BottomClipRatio = InverseLerp(FinalLocation.Top, FinalLocation.Bottom, Bound.Bottom)
				FinalLocation.Bottom = Bound.Bottom
				FinalUV.MaxV = Lerp(FinalUV.MinV, FinalUV.MaxV, BottomClipRatio)
			End If
			If Texture = 0 Then
				DrawShader = DrawShader_0Tex
			Else
				DrawShader = DrawShader_1Tex
			End If
			frmMain.DGE.Draw_GiveInputSurface(0, Texture): RE()
			Draw_SetInputColor(Color)
			frmMain.DGE.Draw_GiveInputSourceRectangleUV1(FinalUV.MinU, FinalUV.MaxU, FinalUV.MinV, FinalUV.MaxV): RE()
			DrawRect(OutputDrawSurface, DrawShader, FinalLocation, Filter)
		End If
	End Sub
	
	Friend Sub DrawRectWithinBound_Wide(ByVal OutputDrawSurface As integer, ByRef Location As Rect, ByRef Bound As Rect, ByRef UV As RectUV, ByRef Color As Vector4, ByVal Texture As integer, ByVal Filter As integer, ByVal Texture_Width As Integer, ByVal UnstretchedColumns As Integer)
		Dim Location_Left As Rect
		Dim Location_Center As Rect
		Dim Location_Right As Rect
		Dim LeftU As Single
		Dim RightU As Single
		Dim SubUV As RectUV
		'Subdivide the area
		Location_Left = MakeRect(Location.Left, Location.Top, Location.Left + UnstretchedColumns, Location.Bottom)
		Location_Center = MakeRect(Location.Left + UnstretchedColumns, Location.Top, Location.Right - UnstretchedColumns, Location.Bottom)
		Location_Right = MakeRect(Location.Right - UnstretchedColumns, Location.Top, Location.Right, Location.Bottom)
		
		LeftU = Lerp(UV.MinU, UV.MaxU, UnstretchedColumns / Texture_Width)
		RightU = Lerp(UV.MaxU, UV.MinU, UnstretchedColumns / Texture_Width)
		
		If Rect_GetWidth(Location) <= Texture_Width Then
			'One section
			DrawRectWithinBound(OutputDrawSurface, Location_Left, Bound, UV, Color, Texture, Filter)
		Else
			'Left
			SubUV = MakeRectUV(UV.MinU, LeftU, UV.MinV, UV.MaxV)
			DrawRectWithinBound(OutputDrawSurface, Location_Left, Bound, SubUV, Color, Texture, Filter)
			
			'Center
			SubUV = MakeRectUV(LeftU, RightU, UV.MinV, UV.MaxV)
			DrawRectWithinBound(OutputDrawSurface, Location_Center, Bound, SubUV, Color, Texture, Filter)
			
			'Right
			SubUV = MakeRectUV(RightU, UV.MaxU, UV.MinV, UV.MaxV)
			DrawRectWithinBound(OutputDrawSurface, Location_Right, Bound, SubUV, Color, Texture, Filter)
		End If
	End Sub
	
	Friend Sub PrintTextFromPoint(OutputDrawSurface As integer, Message As String, Start As Vector2, Color As Vector4)
		Dim I As integer
		Dim StringLength As integer
		StringLength = Len(Message)
		For I = 1 To StringLength
			Dim X As Single
			Dim Y As Single
			Dim CharCode As Integer
			frmMain.DGE.Draw_GiveInputSurface(0, FontAtlas_LucidaConsole_10): RE()
			CharCode = Asc(Mid(Message, I, 1))
			X = Int(CharCode Mod 16)
			Y = Int(CharCode / 16)
			frmMain.DGE.Draw_GiveInputSourceRectangleUV1(X / 16, (X + 1) / 16, Y / 16, (Y + 1) / 16): RE()
			Draw_SetInputColor(Color)
			DrawRect(OutputDrawSurface, DrawShader_1Tex, MakeRect(Start.x + ((I - 1) * FontTileWidth), Start.y, Start.x + (I * FontTileWidth), Start.y + FontTileHeight), 1)
		Next I
	End Sub
	
	'The message to print should not contain it's own line breaks to keep the text compact.
	Friend Sub PrintMultiLineTextWithinRect(ByVal OutputDrawSurface As integer, ByRef Message As String, ByRef Bounds As Rect, ByRef Color As Vector4)
		Dim Columns As Integer
		Dim Rows As Integer
		Dim WordStartColumn As Integer
		Dim WordStartRow As Integer
		Dim CurrentWord As String
		Dim I As integer
		Dim StringLength As integer
		Columns = Rect_GetWidth(Bounds) / FontTileWidth
		Rows = Rect_GetHeight(Bounds) / FontTileHeight
		WordStartColumn = 0
		WordStartRow = 0
		StringLength = Len(Message)
		CurrentWord = ""
		For I = 1 To StringLength
			Dim Character As string
			frmMain.DGE.Draw_GiveInputSurface(0, FontAtlas_LucidaConsole_10): RE()
			Character = Mid(Message, I, 1)
			
			If Character = " " Then
				If WordStartColumn + Len(CurrentWord) > Columns Then
					'Break line.
					WordStartRow = WordStartRow + 1
					WordStartColumn = 0
					
					'End printing
					If WordStartRow >= Rows Then
						Exit Sub
					End If
				End If
				
				'Print the word
				PrintTextFromPoint(OutputDrawSurface, CurrentWord, MakeVector2(Bounds.Left + (WordStartColumn * FontTileWidth), Bounds.Top + (WordStartRow * FontTileHeight)), Color)
				WordStartColumn = WordStartColumn + Len(CurrentWord) + 1
				CurrentWord = ""
			Else
				CurrentWord = CurrentWord & Character
			End If
		Next I
		If WordStartColumn + Len(CurrentWord) > Columns Then
			'Break line.
			WordStartRow = WordStartRow + 1
			WordStartColumn = 0
			
			'End printing
			If WordStartRow >= Rows Then
				Exit Sub
			End If
		End If
		
		'Print the word
		PrintTextFromPoint(OutputDrawSurface, CurrentWord, MakeVector2(Bounds.Left + (WordStartColumn * FontTileWidth), Bounds.Top + (WordStartRow * FontTileHeight)), Color)
		WordStartColumn = WordStartColumn + Len(CurrentWord) + 1
		CurrentWord = ""
	End Sub
End Module
