
Friend Class frmMain
	'3D Cursor
	Friend Model_Cursor As Integer
	Friend Instance_Cursor As Integer
	
	Private Sub tmrRender_Tick(sender As System.Object, e As System.EventArgs) Handles tmrRender.Tick
		'Render from a timer to avoid overheating the graphics card with redundant frame rates
		RenderWorld()
	End Sub
	
	Private Sub Initialize()
		'Regression test
		RunRegressonTest()
		
		'Load shaders
		Shader_Init()
		
		'Load textures
		Texture_Init()
		
		'Create cameras
		TopCamera.CameraRef = DGE.Camera_Create : RE()
			DGE.Camera_SetOrthogonal(TopCamera.CameraRef, True) : RE()
			TopCamera.Direction = MakeVector3(0,-1,0)
			TopCamera.Up = MakeVector3(0,0,1)
			TopCamera.Zoom = 64
		RightCamera.CameraRef = DGE.Camera_Create : RE()
			DGE.Camera_SetOrthogonal(RightCamera.CameraRef, True) : RE()
			RightCamera.Direction = MakeVector3(-1,0,0)
			RightCamera.Up = MakeVector3(0,1,0)
			RightCamera.Zoom = 64
		BackCamera.CameraRef = DGE.Camera_Create : RE()
			DGE.Camera_SetOrthogonal(BackCamera.CameraRef, True) : RE()
			BackCamera.Direction = MakeVector3(0,0,1)
			BackCamera.Up = MakeVector3(0,1,0)
			BackCamera.Zoom = 64
		PerspectiveCamera.CameraRef = DGE.Camera_Create : RE()
		
		'Place cameras for the first time
		UpdateCameras()
		
		'Initialize component system
		Components_Init()
		
		'Load and use editor's models
		InsertStringToEngine("Editor_Model_NotFound") : Model_NotFound = DGE.Model_LoadFromFile_InSB() : RE() 'Load the default model
		If Model_NotFound <= 0 Then
			MsgBox("Can't find the default model.", MsgBoxStyle.Critical, "Error!")
			End
		End If
		
		'Create the 3D cursor
		Model_Cursor = LoadModel("Editor_Model_Cursor")
		Instance_Cursor = DGE.Instance_Create(Model_Cursor) : RE()
		DGE.Instance_SetColor(Instance_Cursor, 2, 2, 0.5, 1) : RE() 'Very bright yellow
		
		UpdateLayout()
		
		'Set the depth atlas resolution
		DGE.LightSource_SetDepthAtlasResolution(1024 * 8) : RE()
		
		'¤¤¤¤ Store the settings below as properties in the database so that they are loaded with the world into the game.
		
		'Set the amount of ambient light
		DGE.LightSource_SetAmbientLight(0.3, 0.3, 0.3) : RE()
		
		'Create shadow casting sun light
		LightSource_Sun_Pos = MakeVector3(0, 0, 0)
		LightSource_Sun_Dir = MakeVector3(-0.2, -1, 0.5)
		LightSource_Sun = DGE.LightSource_Create_Sun_Shadowcasting_SingleLayer(LightSource_Sun_Pos.x, LightSource_Sun_Pos.y, LightSource_Sun_Pos.z, LightSource_Sun_Dir.x, LightSource_Sun_Dir.y, LightSource_Sun_Dir.z, 0, 1, 0, -100, 100, 1, 1, 1, 30, 30, 0, 0, 1, 0.2) : RE()
		
		'Set the background color
		DGE.Enviroment_SetBackgroundColor(0.4, 0.5, 0.6, 1) : RE()
		
		'Set fog
		NearClip = 0.1
		FarClip = 80
		DGE.Enviroment_SetNearClipPlane(NearClip) : RE()
		DGE.Enviroment_SetFarClipPlane(FarClip) : RE()
		DGE.Enviroment_SetMaxFogIntensity(1) : RE()
		
		'Set detail level distances
		DGE.Enviroment_SetMediumHighDetailLimit(20) : RE()
		DGE.Enviroment_SetLowMediumDetailLimit(40) : RE()
	End Sub
	
	Private Sub PlaceOrthogonalCamera(ByRef Camera As FlatCamera, ByRef View As Comp_Surface)
		DGE.Camera_Place(Camera.CameraRef,
			Camera.Pos.x - (Camera.Direction.x * FarClip * 0.5), Camera.Pos.y - (Camera.Direction.y * FarClip * 0.5), Camera.Pos.z - (Camera.Direction.z * FarClip * 0.5),
			Camera.Pos.x + Camera.Direction.x, Camera.Pos.y + Camera.Direction.y, Camera.Pos.z + Camera.Direction.z,
			Camera.Up.x, Camera.Up.y, Camera.Up.z) : RE()
		DGE.Camera_SetHalfWidth(Camera.CameraRef, Rect_GetWidth(View.Location) / Camera.Zoom)
		DGE.Camera_SetHalfHeight(Camera.CameraRef, Rect_GetHeight(View.Location) / Camera.Zoom)
	End Sub
	
	Private Sub UpdateCameras()
		'Place orthogonal cameras
		PlaceOrthogonalCamera(TopCamera, UpperLeftSurface)
		PlaceOrthogonalCamera(RightCamera, UpperRightSurface)
		PlaceOrthogonalCamera(BackCamera, LowerLeftSurface)
		
		'Place perspective camera
		PerspectiveCamera.Lattitude = Clamp(-1.57, PerspectiveCamera.Lattitude, 1.57)
		PlaceCameraUsingDirection(PerspectiveCamera.CameraRef, PerspectiveCamera.Pos, MakeVector3(System.Math.Sin(PerspectiveCamera.Longitude) * System.Math.Cos(PerspectiveCamera.Lattitude), System.Math.Sin(PerspectiveCamera.Lattitude), System.Math.Cos(PerspectiveCamera.Longitude) * System.Math.Cos(PerspectiveCamera.Lattitude)), MakeVector3(0, 1, 0))
	End Sub
	
	Private Sub RenderWorld()
		Components_TimeEvents()
		
		'Place cameras
		UpdateCameras()
		
		'Update detail levels on items
		DGE.Enviroment_UpdateAutomaticDetailLevels(PerspectiveCamera.Pos.X, PerspectiveCamera.Pos.Y, PerspectiveCamera.Pos.Z) : RE()
		
		'Update the sun
		LightSource_Sun_Pos = PerspectiveCamera.Pos
		DGE.LightSource_SetPos(LightSource_Sun, LightSource_Sun_Pos.X, LightSource_Sun_Pos.Y, LightSource_Sun_Pos.Z) : RE()
		
		'Render the scene
		Components_Redraw()
	End Sub
	
	Private Sub frmMain_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
		If StartEngine Then
			SetRelativeWorkingDirectory("..\..\Graphics")
			Initialize()
			tmrRender.Enabled = True
			DGE.Focus() 'Go around a severe bug in the split container that causes it to appear selected and make you want to throw up from the uglyness.
		End If
	End Sub
	
	Friend Sub LargeUpdate()
		lstModels.Items.Clear()
		If Not(World Is Nothing) Then
			Dim I As Integer
			For I = 0 to World.Models.Count - 1
				lstModels.Items.Add(New NamedIndex(World.Models(I).FileName, I))
			Next I
			If Not(frmLoadModels is Nothing) Then
				frmLoadModels.lstMissingModels.Items.Clear()
				frmLoadModels.lstExistingModels.Items.Clear()
				For I = 0 to World.Models.Count - 1
					If World.Models(I).ModelRef = Model_NotFound Then
						frmLoadModels.lstMissingModels.Items.Add(New NamedIndex(World.Models(I).FileName, I))
					Else
						frmLoadModels.lstExistingModels.Items.Add(New NamedIndex(World.Models(I).FileName, I))
					End If
				Next I
			End If
		End If
		ItemUpdate()
	End Sub
	
	Friend Sub ItemUpdate()
		lstItems.Items.Clear()
		If Not(World Is Nothing) Then
			For I = 0 to World.Items.Count - 1
				lstItems.Items.Add(World.Models(World.Items(I).ModelIndex).FileName)
			Next I
		End If
		NeedToRedraw = True
	End Sub
	
	Private Sub NewToolStripMenuItem_Click(sender As System.Object, e As System.EventArgs) Handles NewToolStripMenuItem.Click
		Dim saveFileDialog As New SaveFileDialog()
		saveFileDialog.Title = "Save your new world file"
		saveFileDialog.Filter = "World files (*.world)|*.world"
		If saveFileDialog.ShowDialog() = DialogResult.OK Then
			If Not(World Is Nothing) Then
				World.UnloadEngineContent()
			End If
			World = New WorldClass(saveFileDialog.FileName, False)
			SetWorldFileName(saveFileDialog.FileName)
			World.Save()
			LargeUpdate()
		End If
	End Sub
	
	Private Sub LoadToolStripMenuItem_Click(sender As System.Object, e As System.EventArgs) Handles LoadToolStripMenuItem.Click
		Dim openFileDialog As New OpenFileDialog()
		openFileDialog.Title = "Load an existing world file"
		openFileDialog.Filter = "World files (*.world)|*.world"
		If openFileDialog.ShowDialog() = DialogResult.OK Then
			If Not(World Is Nothing) Then
				World.UnloadEngineContent()
			End If
			World = New WorldClass(openFileDialog.FileName, True)
			SetWorldFileName(openFileDialog.FileName)
			LargeUpdate()
		End If
	End Sub
	
	Private Sub SaveToolStripMenuItem_Click(sender As System.Object, e As System.EventArgs) Handles SaveToolStripMenuItem.Click
		If World Is Nothing Then
			MsgBox("There is no world to save.", MsgBoxStyle.OkOnly, "Error!")
		Else
			'Save the world
			World.Save()
			LargeUpdate()
		End If
	End Sub
	
	Private Sub SaveAsToolStripMenuItem_Click( sender As System.Object,  e As System.EventArgs) Handles SaveAsToolStripMenuItem.Click
		Dim saveFileDialog As New SaveFileDialog()
		saveFileDialog.Title = "Save your new world file"
		saveFileDialog.Filter = "World files (*.world)|*.world"
		If saveFileDialog.ShowDialog() = DialogResult.OK Then
			SetWorldFileName(saveFileDialog.FileName)
			World.Save()
			LargeUpdate()
		End If
	End Sub
	
	Private Sub SetWorldFileName(FileName As String)
		World.SetFileName(FileName) 'Change the filename that is used for fast saving
		Me.Text = "David Piuva's world editor - " & FileName 'Update the filename in the main window title
	End Sub
	
	Private Sub DGE_MouseDownEvent(sender As Object, e As AxDFPGELib._DDFPGEEvents_MouseDownEvent) Handles DGE.MouseDownEvent
		Components_MouseDown(e)
	End Sub
	
	Private Sub DGE_MouseMoveEvent(sender As Object, e As AxDFPGELib._DDFPGEEvents_MouseMoveEvent) Handles DGE.MouseMoveEvent
		Components_MouseMove(e)
	End Sub
	
	Private Sub frmMain_MouseWheel(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseWheel
		Components_Scroll(e)
	End Sub
	
	Private Sub frmMain_Resize(sender As Object, e As System.EventArgs) Handles Me.Resize
		UpdateLayout()
	End Sub
	
	Private Sub UpdateLayout()
		Dim FullRect As Rect
		Dim BelowToolbarRect As Rect
		FullRect = MakeRect(0, 0, DGE.Width, DGE.Height)
		Toolbar.Location = MakeRect(0, 0, DGE.Width, Toolbar_Height)
		BelowToolbarRect = MakeRect(0, Toolbar_Height, DGE.Width, DGE.Height)
		
		If QuadToolStripMenuItem.Checked Then
			'Quad layout
			UpperLeftSurface.Location = MakeRect(BelowToolbarRect.Left + 2,										BelowToolbarRect.Top + 2,									((BelowToolbarRect.Left + BelowToolbarRect.Right) / 2) - 1,	((BelowToolbarRect.Top + BelowToolbarRect.Bottom) / 2) - 1)
			UpperLeftSurface.Visible = True
			UpperRightSurface.Location = MakeRect(((BelowToolbarRect.Left + BelowToolbarRect.Right) / 2) + 1,	BelowToolbarRect.Top + 2,									BelowToolbarRect.Right - 2,									((BelowToolbarRect.Top + BelowToolbarRect.Bottom) / 2) - 1)
			UpperRightSurface.Visible = True
			LowerLeftSurface.Location = MakeRect(BelowToolbarRect.Left + 2,										((BelowToolbarRect.Top + BelowToolbarRect.Bottom) / 2) + 1,	((BelowToolbarRect.Left + BelowToolbarRect.Right) / 2) - 1,	BelowToolbarRect.Bottom - 2)
			LowerLeftSurface.Visible = True
			LowerRightSurface.Location = MakeRect(((BelowToolbarRect.Left + BelowToolbarRect.Right) / 2) + 1,	((BelowToolbarRect.Top + BelowToolbarRect.Bottom) / 2) + 1,	BelowToolbarRect.Right - 2,									BelowToolbarRect.Bottom - 2)
			LowerRightSurface.Visible = True
		ElseIf PerspectiveOnlyToolStripMenuItem.Checked Then
			'Only show perspective view
			UpperLeftSurface.Visible = False
			UpperRightSurface.Visible = False
			LowerLeftSurface.Visible = False
			LowerRightSurface.Location = BelowToolbarRect
			LowerRightSurface.Visible = True
		End If
		Components_Resize()
	End Sub
	
	Private Sub PerspectiveOnlyToolStripMenuItem_Click(sender As System.Object, e As System.EventArgs) Handles PerspectiveOnlyToolStripMenuItem.Click
		If PerspectiveOnlyToolStripMenuItem.Checked Then
			QuadToolStripMenuItem.Checked = False
		Else
			PerspectiveOnlyToolStripMenuItem.Checked = True
		End If
		UpdateLayout()
	End Sub
	
	Private Sub QuadToolStripMenuItem_Click(sender As System.Object, e As System.EventArgs) Handles QuadToolStripMenuItem.Click
		If QuadToolStripMenuItem.Checked Then
			PerspectiveOnlyToolStripMenuItem.Checked = False
		Else
			QuadToolStripMenuItem.Checked = True
		End If
		UpdateLayout()
	End Sub
	
	Private Sub lstItems_SelectedIndexChanged(sender As System.Object, e As System.EventArgs) Handles lstItems.SelectedIndexChanged
		Dim I As Integer
		If Not(World Is Nothing) Then
			For I = 0 to World.Items.Count - 1
				'Select one item in the world
				World.Items(I).SetSelected(I = lstItems.SelectedIndex)
			Next I
			NeedToRedraw = True
		End If
	End Sub
	
	Private Sub ResetCamerasToolStripMenuItem_Click(sender As System.Object, e As System.EventArgs) Handles ResetCamerasToolStripMenuItem.Click
		'Reset camera
		TopCamera.Pos = MakeVector3(0,0,0)
		TopCamera.Zoom = 64
		NeedToRedraw = True
		
		'Reset camera
		RightCamera.Pos = MakeVector3(0,0,0)
		RightCamera.Zoom = 64
		NeedToRedraw = True
		
		BackCamera.Pos = MakeVector3(0,0,0)
		BackCamera.Zoom = 64
		NeedToRedraw = True
		
		'Reset cameras
		PerspectiveCamera.Pos = MakeVector3(0,0,0)
		PerspectiveCamera.Longitude = 0
		PerspectiveCamera.Lattitude = 0
		NeedToRedraw = True
	End Sub
	
	Private Sub DeleteSelectedToolStripMenuItem_Click(sender As System.Object, e As System.EventArgs) Handles DeleteSelectedToolStripMenuItem.Click
		If Not(World Is Nothing) Then
			Dim I As Integer
			For I = World.Items.Count - 1 to 0 Step -1
				If World.Items(I).GetSelected() Then
					World.DeleteItem(I)
				End If
			Next I
			NeedToRedraw = True
		End If
	End Sub
	
	Private Sub LockSelectedToolStripMenuItem_Click( sender As System.Object,  e As System.EventArgs) Handles LockSelectedToolStripMenuItem.Click
		If Not(World Is Nothing) Then
			Dim I As Integer
			For I = 0 to World.Items.Count - 1
				If World.Items(I).GetSelected() Then
					World.Items(I).Locked = True
					World.Items(I).SetSelected(False)
					NeedToRedraw = True
				End If
			Next I
			NeedToRedraw = True
		End If
	End Sub
	
	Private Sub UnlockEverythingToolStripMenuItem_Click( sender As System.Object,  e As System.EventArgs) Handles UnlockEverythingToolStripMenuItem.Click
		If Not(World Is Nothing) Then
			Dim I As Integer
			For I = 0 to World.Items.Count - 1
				World.Items(I).Locked = False
			Next I
		End If
	End Sub
	
	Private Sub FaceDir1_Click(sender As System.Object, e As System.EventArgs) Handles FaceDir1.Click
		SetDirection(0)
	End Sub
	
	Private Sub FaceDir2_Click(sender As System.Object, e As System.EventArgs) Handles FaceDir2.Click
		SetDirection(45)
	End Sub
	
	Private Sub FaceDir3_Click(sender As System.Object, e As System.EventArgs) Handles FaceDir3.Click
		SetDirection(90)
	End Sub
	
	Private Sub FaceDir4_Click(sender As System.Object, e As System.EventArgs) Handles FaceDir4.Click
		SetDirection(135)
	End Sub
	
	Private Sub FaceDir5_Click(sender As System.Object, e As System.EventArgs) Handles FaceDir5.Click
		SetDirection(180)
	End Sub
	
	Private Sub FaceDir6_Click(sender As System.Object, e As System.EventArgs) Handles FaceDir6.Click
		SetDirection(225)
	End Sub
	
	Private Sub FaceDir7_Click(sender As System.Object, e As System.EventArgs) Handles FaceDir7.Click
		SetDirection(270)
	End Sub
	
	Private Sub FaceDir8_Click(sender As System.Object, e As System.EventArgs) Handles FaceDir8.Click
		SetDirection(315)
	End Sub
	
	Private Sub SetDirection(Degrees As Double)
		If Not(World Is Nothing) Then
			Dim I As Integer
			Dim Radians As Double
			Radians = Degrees * RadiansPerDegree
			For I = 0 to World.Items.Count - 1
				If World.Items(I).GetSelected() Then
					World.Items(I).XAxis = MakeVector3(System.Math.Cos(Radians), 0, -System.Math.Sin(Radians))
					World.Items(I).ZAxis = MakeVector3(System.Math.Sin(Radians), 0, System.Math.Cos(Radians))
					World.Items(I).YAxis = MakeVector3(0, 1, 0)
					World.Items(I).Update()
				End If
			Next I
			NeedToRedraw = True
		End If
	End Sub
	
	Private Sub ReloadResourcesToolStripMenuItem_Click( sender As System.Object,  e As System.EventArgs) Handles ReloadResourcesToolStripMenuItem.Click
		If Not(World is Nothing) Then
			'Use default cursor model to allow deleting any non default model
			DGE.Instance_ReplaceModel(Instance_Cursor, Model_Cursor) : RE()
			
			'Clean up and reload
			World.UnloadEngineContent()
			DGE.Engine_RemoveUnusedResources()
			World.LoadEngineContent()
		End If
	End Sub
	
	Private Sub LoadModelFromFileToolStripMenuItem_Click( sender As System.Object,  e As System.EventArgs) Handles LoadModelFromFileToolStripMenuItem.Click
		If Not(World is Nothing) Then
			frmLoadModels.Show() 'Show the menu loading window
		End If
	End Sub
	
	Private Sub SelectAllToolStripMenuItem_Click( sender As System.Object,  e As System.EventArgs) Handles SelectAllToolStripMenuItem.Click
		Dim I As Integer
		If Not(World is Nothing) Then
			For I = 0 to World.Items.Count - 1
				World.Items(I).SetSelected(True)
			Next I
			NeedToRedraw = True
		End If
	End Sub
	
	Private Sub SelectNoneToolStripMenuItem_Click( sender As System.Object,  e As System.EventArgs) Handles SelectNoneToolStripMenuItem.Click
		Dim I As Integer
		If Not(World is Nothing) Then
			For I = 0 to World.Items.Count - 1
				World.Items(I).SetSelected(False)
			Next I
			NeedToRedraw = True
		End If
	End Sub
	
	Private Sub RemoveUnusedModelsToolStripMenuItem_Click( sender As System.Object,  e As System.EventArgs) Handles RemoveUnusedModelsToolStripMenuItem.Click
		If Not(World is Nothing) Then
			World.RemoveUnusedModels()
			LargeUpdate()
		End If
	End Sub
	
	Private Sub DirectSunAsCameraToolStripMenuItem_Click( sender As System.Object,  e As System.EventArgs) Handles DirectSunAsCameraToolStripMenuItem.Click
		Dim CameraSystem As Matrix4
		Dim Up As Vector3
		DGE.Camera_Get4x4System_OutM4(PerspectiveCamera.CameraRef) : CameraSystem = GetMatrix4FromMatrixBuffer() : RE()
		LightSource_Sun_Dir = Vector4ToVector3(CameraSystem.ZAxis)
		Up = Vector4ToVector3(CameraSystem.YAxis)
		DGE.LightSource_SetDirection(LightSource_Sun, LightSource_Sun_Dir.X, LightSource_Sun_Dir.Y, LightSource_Sun_Dir.Z, Up.X, Up.Y, Up.Z)
	End Sub
End Class
