//- sixten: Views
inline workspace_view *W_CreateNewView(workspace_view_kind Kind, workspace_panel *Parent)
{
	arena *Arena = ArenaAlloc(Kilobytes(4), true);
	workspace_view *View = PushStruct(Arena, workspace_view);
	View->Arena = Arena;
	View->Kind = Kind;
	View->Parent = Parent;
	
	switch(View->Kind)
	{
		case W_ViewKind_Settings:
		{
			View->Data = PushStruct(View->Arena, workspace_view_settings);
		} break;
		
		case W_ViewKind_FileLister:
		{
			workspace_view_file_lister *Lister = PushStruct(View->Arena, workspace_view_file_lister);
			View->Data = Lister;
			Lister->Path = StrLit("data");
			
			Lister->SelectedItem = -1;
		} break;
		
		case W_ViewKind_TextEditor:
		{
			View->Data = PushStruct(View->Arena, workspace_view_text_editor);
			
			workspace_view_text_editor *Editor = (workspace_view_text_editor *)View->Data;
			Editor->ProcessingArena = ArenaAlloc(Gigabytes(1));
			Editor->Text = MutableStringAllocate(Gigabytes(1));
			Editor->HistoryArena = ArenaAlloc(Gigabytes(1));
			
			SenDLLInit(&Editor->History.Sentinel);
			Editor->History.At = &Editor->History.Sentinel;
			Editor->SavePoint = Editor->History.At;
			
			workspace_text_data TextData = W_TextDataFromString(Editor->ProcessingArena, Editor->Text.String);
			Editor->Tokens = TextData.Tokens;
			Editor->Lines = TextData.Lines;
            
            Editor->FontSize = 15.0f;
		} break;
		
		case W_ViewKind_NavEditor:
		{
			View->Data = PushStruct(View->Arena, workspace_view_nav_editor);
		} break;
		
		case W_ViewKind_ImageViewer:
		{
			View->Data = PushStruct(View->Arena, workspace_view_image_viewer);
			workspace_view_image_viewer *Viewer = (workspace_view_image_viewer *)View->Data;
			Viewer->Scale = 1.0f;
			//- sixten(TODO): write an image viewer
			// beign with loading the image from the file lister load thingy
			// show it on build
			// release the handle when done (and add a way to remove texture ig)
		} break;
		
		case W_ViewKind_Error:
		{
			View->Data = PushStruct(View->Arena, workspace_view_error);
		} break;
		
		default: break;
	}
	
	DLLInsertLast(Parent->FirstView, Parent->LastView, View);
	
	if(View->Parent)
	{
		Parent->CurrentView = View;
	}
	
	return(View);
}

inline void W_DestroyView(workspace_view *View)
{
	switch(View->Kind)
	{
		case W_ViewKind_TextEditor:
		{
			workspace_view_text_editor *Editor = (workspace_view_text_editor *)View->Data;
			ArenaRelease(Editor->ProcessingArena);
			MutableStringRelease(&Editor->Text);
			ArenaRelease(Editor->HistoryArena);
		} break;
		
		case W_ViewKind_ImageViewer:
		{
			workspace_view_image_viewer *Viewer = (workspace_view_image_viewer *)View->Data;
			GlobalRenderCommands->DeallocateTexture(Viewer->Texture);
		} break;
		
		default: break;
	}
	
	// sixten(NOTE): This function does not ensure that the view is not being used anywhere else.
	ArenaRelease(View->Arena);
}

inline b32 W_ViewIsCurrent(workspace_view *View)
{
	workspace *Workspace = W_GetState();
	
	b32 Result = (Workspace->CurrentPanel && Workspace->CurrentPanel->CurrentView == View);
	return(Result);
}

inline string W_NameFromView(arena *Arena, workspace_view *View)
{
	string Result = StrLit("Unnamed view");
	switch(View->Kind)
	{
		case W_ViewKind_Startup: { Result = StrLit("Welcome"); } break;
		case W_ViewKind_Settings: { Result = StrLit("Settings"); } break;
		case W_ViewKind_TextEditor:
		{
			workspace_view_text_editor *Editor = (workspace_view_text_editor *)View->Data;
			if(AreEqual(Editor->FileName, StrLit("")))
			{
				Result = StrLit("Open File");
			}
			else
			{
				if(Editor->History.At == Editor->SavePoint)
				{
					Result = PushString(Arena, Editor->FileName);
				}
				else
				{
					Result = PushFormat(Arena, "* %S", Editor->FileName);
				}
			}
		} break;
		case W_ViewKind_SceneView: { Result = StrLit("Scene View"); } break;
		case W_ViewKind_NavEditor: { Result = StrLit("Navigation Editor"); } break;
		case W_ViewKind_FileLister: { Result = StrLit("File Lister"); } break;
		case W_ViewKind_ImageViewer:
		{
			workspace_view_image_viewer *Viewer = (workspace_view_image_viewer *)View->Data;
			Result = PushString(Arena, Viewer->FileName);
		} break;
		case W_ViewKind_Error: { Result = StrLit("Error"); } break;
		default: {} break;
	}
	
	return(Result);
}

static b32 W_ImageViewerSetup(workspace_view *View, string Name, string Contents)
{
	b32 Result = false;
	workspace_view_image_viewer *Viewer = (workspace_view_image_viewer *)View->Data;
	Viewer->Texture = EmptyRenderHandle();
	if(Contents.Count && Contents.Data)
	{
		s32 Width, Height, BPP;
		u8 *TextureData = stbi_load_from_memory(Contents.Data, Contents.Count, &Width, &Height, &BPP, 0);
		if(TextureData)
		{
			render_texture_format TextureFormat = Render_TextureFormat_Invalid;
			switch(BPP)
			{
				InvalidDefaultCase;
				case 1: { TextureFormat = Render_TextureFormat_R8; } break;
				case 3: { TextureFormat = Render_TextureFormat_RGB8; } break;
				case 4: { TextureFormat = Render_TextureFormat_RGBA8; } break;
			}
			
			Viewer->Texture = GlobalRenderCommands->AllocateTexture(V2S32(Width, Height), TextureFormat, true, TextureData);
			
			Result = true;
			
			stbi_image_free(TextureData);
		}
	}
	Viewer->FileName = PushString(View->Arena, Name);
	
	return(Result);
}

//- sixten: Builder code

static void W_BuildSettingsTabButton(workspace_view_settings *Settings, char *Name, workspace_settings_category Category)
{
	b32 IsSelected = (Settings->Category == Category);
	
	v4 Color = LinearBlend(Theme_TextColor, Theme_HighlightBorderColor, AC_AnimateValueF(IsSelected, IsSelected, 0.3, "Workspace Settings %s %p", Name, Settings));
	
	UI_SetNextFont(Font_Bold);
	UI_SetNextHeight(UI_TextContent(0, 1));
	UI_SetNextTextColor(Color);
	
	ui_box *Box = UI_MakeBoxF(UI_BoxFlag_DrawText |
                              UI_BoxFlag_Clickable,
                              Name);
	
	ui_signal Signal = UI_SignalFromBox(Box);
	if(Signal.Hovering)
	{
		Platform.SetCursor(PlatformCursor_Hand);
	}
	if(Signal.Pressed)
	{
		Settings->Category = Category;
	}
}

static b32 UI_DropdownSelection(char **Alternatives, s32 AlternativeCount, b32 *Open, s32 *Selected)
{
	b32 Result = false;
	b32 ActiveInDropdown = false;
	
	UI_SetNextLayoutAxis(Axis2_X);
	ui_box *DropdownBox = UI_MakeBoxF(UI_BoxFlag_DrawBackground  |
                                      UI_BoxFlag_DrawBorder      |
                                      UI_BoxFlag_HotAnimation    |
                                      UI_BoxFlag_ActiveAnimation |
                                      UI_BoxFlag_Clickable,
                                      "Dropdown");
	UI_Parent(DropdownBox)
	{
		UI_Width(UI_Percent(1, 0)) UI_LabelF(Alternatives[*Selected]);
		UI_BackgroundColor(Theme_BorderColor) UI_Width(UI_Pixels(1, 1)) UI_MakeBoxF(UI_BoxFlag_DrawBackground, "");
		UI_Width(UI_Pixels(25, 1)) UI_Font(Font_Icons) UI_LabelF("%U", *Open?FontIcon_DownDir:FontIcon_RightDir);
	}
	
	ui_signal DropdownSignal = UI_SignalFromBox(DropdownBox);
	if(DropdownSignal.Pressed)
	{
		*Open = !(*Open);
	}
	
	if(AreEqual(UI_ActiveKey(), DropdownBox->Key))
	{
		ActiveInDropdown = true;
	}
	
	r32 OpenTransition = AC_AnimateValueF(*Open, 0, 0.175, "UI Dropdown %p%p", Alternatives, Open);
	
	if(OpenTransition > 0.1)
	{
		UI_Tooltip
		{
			UI_SetNextFixedP(V2(DropdownBox->Rect.Min.x, DropdownBox->Rect.Max.y));
			UI_SetNextCornerRadius(4);
			UI_SetNextWidth(UI_Pixels(200, 1));
			UI_SetNextHeight(UI_ChildrenSum(OpenTransition, 1));
			UI_Parent(UI_MakeBoxF(UI_BoxFlag_Clip           |
                                  UI_BoxFlag_DrawDropShadow |
                                  UI_BoxFlag_FloatingX      |
                                  UI_BoxFlag_FloatingY, "Dropdown Contents %p%p", Alternatives, Open))
			{
				UI_PushWidth(UI_Percent(1, 1));
				
				for(s64 Index = 0;
                    Index < Round(AlternativeCount*OpenTransition);
                    ++Index)
				{
					ui_signal ButtonSignal = UI_ButtonF(Alternatives[Index]);
					if(AreEqual(UI_ActiveKey(), ButtonSignal.Box->Key))
					{
						ActiveInDropdown = true;
					}
					
					if(ButtonSignal.Pressed)
					{
						*Selected = Index;
						Result = true;
					}
				}
				
				UI_PopWidth();
			}
		}
	}
	
	if(!ActiveInDropdown && !AreEqual(UI_ActiveKey(), UI_EmptyKey()))
	{
		*Open = false;
	}
	
	return(Result);
}


UI_CUSTOM_DRAW_CALLBACK(W_ImageViewerUICallback)
{
	workspace_view_image_viewer *Viewer = (workspace_view_image_viewer *)Data;
	v2_r32 ImageDim = ConvertV2ToR32(DimFromTexture(Viewer->Texture));
	v2_r32 ScaleImageDim = ImageDim*Viewer->Scale;
	
	v4 Color = Color_White;
	range2_r32 Dest;
	Dest.Min = (Box->Rect.Max+Box->Rect.Min)*0.5-ScaleImageDim*0.5+Viewer->Offset*Viewer->Scale;
	Dest.Max = Dest.Min+ScaleImageDim;
	range2_r32 Source = Range2R32(V2R32(0, 0), ImageDim);
	PushTexturedQuad(Group, Dest, Source, Color, Color, Color, Color, 0, 0, 0, Viewer->Texture);
}

static void W_BuildImageViewer(workspace_view *View)
{
	workspace_view_image_viewer *Viewer = (workspace_view_image_viewer *)View->Data;
	
	//- sixten: find image dim
	v2_r32 ImageDim = ConvertV2ToR32(DimFromTexture(Viewer->Texture));
	
	UI_WidthFill UI_HeightFill
	{
		ui_box *ImageBox = UI_MakeBoxF(UI_BoxFlag_DrawBorder|UI_BoxFlag_Clickable, "Workspace View Image Viewer %p", View);
		UI_EquipBoxCustomDrawCallback(ImageBox, W_ImageViewerUICallback, Viewer);
		
		//- sixten: handle scrolling
		if(AreEqual(UI_HotKey(), ImageBox->Key))
		{
			for(platform_event *Event = UI_EventList()->First;
                Event != 0;
                Event = Event->Next)
			{
				if(Event->Type == PlatformEvent_MouseScroll && Event->Scroll.y != 0)
				{
					Viewer->Scale *= Pow(1.10f, Event->Scroll.y);
					Platform_ConsumeEvent(UI_EventList(), Event);
				}
			}
		}
		
		ui_signal Signal = UI_SignalFromBox(ImageBox);
		if(Signal.Dragging)
		{
			if(Signal.Pressed)
			{
				UI_StoreDragV2(Viewer->Offset);
			}
			v2_r32 StartOffset = UI_GetDragV2();
			v2_r32 EndOffset = StartOffset+Signal.DragDelta*(1.0f/Viewer->Scale);
			
			Viewer->Offset = EndOffset;
		}
	}
	UI_WidthFill UI_Height(UI_Em(3, 1))
		UI_Row(UI_BoxFlag_DrawBackground|UI_BoxFlag_DrawBorder)
	{
		UI_Width(UI_TextContent(15, 1))
		{
			UI_Label(Viewer->FileName);
			UI_LabelF("Width: %i Height: %i", (int)ImageDim.x, (int)ImageDim.y);
		}
		UI_Spacer(UI_Percent(1, 0));
	}
}

static void W_BuildSceneView(workspace_view *View)
{
	workspace *Workspace = W_GetState();
	SV_BuildSceneView(Workspace->Input);
}

static void W_BuildSettings(workspace_view *View)
{
	workspace_view_settings *Settings = (workspace_view_settings *)View->Data;
	workspace *Workspace = W_GetState();
	
	UI_Height(UI_ChildrenSum(1, 1))
		UI_Column() UI_Padding(UI_Pixels(50, 0))
		UI_Row() UI_Padding(UI_Pixels(50, 0))
	{
		UI_Size(UI_TextContent(0, 1), UI_TextContent(10, 1))
			UI_Font(Font_Bold) UI_FontSize(36)
			UI_LabelF("Settings");
	}
	
	UI_LayoutAxis(Axis2_X)
		UI_Size(UI_Percent(1, 0), UI_Percent(1, 0))
		UI_Parent(UI_MakeBoxF(0, ""))
	{
		UI_Width(UI_Pixels(300, 1))
			UI_Parent(UI_MakeBoxF(0, "Navigation"))
		{
			UI_Row() UI_Padding(UI_Pixels(50, 1))
				UI_Width(UI_Percent(1, 0)) UI_Column() UI_Padding(UI_Percent(1, 0))
				UI_Height(UI_ChildrenSum(1, 1)) UI_LayoutAxis(Axis2_Y) UI_Parent(UI_MakeBoxF(0, ""))
			{
				W_BuildSettingsTabButton(Settings, "All", W_Settings_All);
				UI_Spacer(UI_Pixels(30, 1));
				W_BuildSettingsTabButton(Settings, "General", W_Settings_General);
				UI_Spacer(UI_Pixels(30, 1));
				W_BuildSettingsTabButton(Settings, "Developer", W_Settings_Developer);
				
				UI_Spacer(UI_Pixels(150, 1));
			}
		}
		
		UI_CornerRadius(5)
			UI_Width(UI_Pixels(1.25, 1))
			UI_BackgroundColor(Color_Grey)
			UI_MakeBoxF(UI_BoxFlag_DrawBackground, "Separator");
		
		UI_Padding(UI_Pixels(70, 0))
			UI_LayoutAxis(Axis2_Y)
			UI_Width(UI_Percent(1, 0))
			UI_Parent(UI_MakeBoxF(0, "Tab"))
			UI_Size(UI_TextContent(0, 1), UI_TextContent(10, 1))
		{
			UI_SetNextSize(UI_Percent(1, 0), UI_Percent(1, 0));
			UI_Scroll(0, &Settings->GlobalScroll, UI_BoxFlag_Clip)
			{
				workspace_settings_category Category = Settings->Category;
				if(!Category || (Category == W_Settings_General))
				{
					UI_Font(Font_Bold) UI_FontSize(36) UI_LabelF("General");
					
					char *Alternatives[] = {"15 Hz", "30 Hz", "60 Hz", "120 Hz", "144 Hz", "Uncapped", "V-Sync"};
					s64 AlternativeMapping[] = {15, 30, 60, 120, 144, -1, 0};
					
					s32 DropdownSelected;
					FindIndexOfElement(DropdownSelected, AlternativeMapping, 0, Workspace->Input->RefreshRate);
					
					UI_Row()
					{
						UI_LabelF("Refresh Rate:");
						UI_Spacer(UI_Pixels(10, 1));
						
						UI_SetNextWidth(UI_Pixels(200, 1));
						UI_SetNextCornerRadius(4);
						if(UI_DropdownSelection(Alternatives, ArrayCount(Alternatives),
                                                &Settings->GeneralDropdownOpen, &DropdownSelected))
						{
							Workspace->Input->RefreshRate = AlternativeMapping[DropdownSelected];
							Settings->GeneralDropdownOpen = false;
						}
					}
					
					UI_Spacer(UI_Pixels(50, 1));
				}
				
				if(!Category || (Category == W_Settings_Developer))
				{
					UI_Font(Font_Bold) UI_FontSize(36) UI_LabelF("Developer");
					UI_Checkbox(&DEBUG_DebugSettings->RenderUIDebugRects, StrLit("Render UI Debug Rects"));
					UI_Spacer(UI_Pixels(5, 1));
					UI_Checkbox(&DEBUG_DebugSettings->RenderFPSCounter, StrLit("Render FPS Counter"));
					UI_Spacer(UI_Pixels(5, 1));
					UI_Checkbox(&DEBUG_DebugSettings->ListHotAndActive, StrLit("List Hot & Active"));
					
					UI_Spacer(UI_Pixels(50, 1));
				}
			}
		}
	}
	
	UI_Spacer(UI_Pixels(50, 1));
}

static void W_BuildView(workspace_view *View)
{
	r32 ViewHighlightTransition =
		AC_AnimateValueF(W_ViewIsCurrent(View), 0, 0.25, "Workspace View Highlight %p", View);
	UI_SetNextBorderColor(LinearBlend(Theme_BorderColor, Theme_HighlightBorderColor, ViewHighlightTransition));
	UI_PushBackgroundColor(Theme_BackgroundColor);
	UI_SetNextCornerRadius(3);
	
	ui_box *ViewBox = UI_MakeBoxF(UI_BoxFlag_Clickable      |
                                  UI_BoxFlag_DrawBackground |
                                  UI_BoxFlag_DrawBorder     |
                                  UI_BoxFlag_Clip,
                                  "Workspace View %p", View);
	
	UI_Parent(ViewBox)
		UI_Size(UI_Percent(1, 0), UI_Percent(1, 0))
	{
		switch(View->Kind)
		{
			case W_ViewKind_None: {} break;
			
			case W_ViewKind_Startup:
			{
				UI_Row() UI_Padding(UI_Pixels(50, 0))
					UI_Width(UI_ChildrenSum(1, 1)) UI_Column() UI_Padding(UI_Pixels(50, 0))
				{
					UI_Size(UI_TextContent(0, 1), UI_TextContent(10, 1))
					{
						UI_Font(Font_Bold) UI_FontSize(36)
							UI_LabelF("Welcome to VN");
						UI_TextColor(Theme_BorderColor) UI_LabelF("An impractical way to make a game");
						
						UI_Spacer(UI_Percent(1, 0));
						
						UI_Checkbox(&DEBUG_DebugSettings->ShowWelcomeMessage, StrLit("Show this message on startup"));
					}
				}
			} break;
			
			case W_ViewKind_Settings:
			{
				W_BuildSettings(View);
			} break;
			
			case W_ViewKind_ImageViewer:
			{
				W_BuildImageViewer(View);
			} break;
			
			case W_ViewKind_TextEditor:
			{
				W_BuildTextEditor(View);
			} break;
			
			case W_ViewKind_SceneView:
			{
				W_BuildSceneView(View);
			} break;
			case W_ViewKind_NavEditor:
			{
				W_BuildNavEditor(View);
			} break;
			case W_ViewKind_FileLister:
			{
				workspace_file_lister_action Action = W_BuildFileLister(View);
				if(Action.HasRequestedFile)
				{
					workspace_file_lister_action *ActionOnDataArena = W_FileListerActionCopy(W_GetState()->CommandDataArena, &Action);
					W_IssueCommand(W_Command_OpenFile, PointerToU64(ActionOnDataArena));
					
					W_IssueCommand(W_Command_CloseView, PointerToU64(View));
				}
			} break;
			
			case W_ViewKind_Error:
			{
				workspace_view_error *Error = (workspace_view_error *)View->Data;
				UI_WidthFill UI_HeightFill 
					UI_Column()
				{
					UI_Label(Error->Message);
					
					UI_Height(UI_Em(2, 1)) UI_Row()
					{
						UI_Spacer(UI_Percent(1, 0));
						
						UI_Width(UI_TextContent(15, 1)) UI_CornerRadius(4.0f)
							if(UI_Button(StrLit("Close View")).Clicked)
						{
							W_IssueCommand(W_Command_CloseView, PointerToU64(View));
						}
						UI_Spacer(UI_Em(1, 1));
					}
					UI_Spacer(UI_Em(1, 1));
				}
			} break;
		}
	}
	
	UI_PopBackgroundColor();
	
	UI_SignalFromBox(ViewBox);
}
