WORKSPACE_COMMAND(W_Command_SplitPanelHorizontal)
{
	workspace *Workspace = W_GetState();
	W_SplitPanel(Workspace->CurrentPanel, Axis2_X);
}

WORKSPACE_COMMAND(W_Command_SplitPanelVertical)
{
	workspace *Workspace = W_GetState();
	W_SplitPanel(Workspace->CurrentPanel, Axis2_Y);
}

WORKSPACE_COMMAND(W_Command_ClosePanel)
{
	workspace *Workspace = W_GetState();
	
	workspace_panel *Panel = (workspace_panel *)Argument;
	if(!Panel)
	{
		Panel = Workspace->CurrentPanel;
	}
	
	workspace_panel *Parent = Panel->Parent;
	if(Parent)
    {
        Assert(Panel != Workspace->RootPanel);
        
        DLLRemove(Parent->First, Parent->Last, Panel);
        
        b32 OneChildRemains = (Parent->First == Parent->Last);
        if(OneChildRemains)
        {
            workspace_panel *Child = Parent->First;
            Assert(DLLIsEmpty(Parent->FirstView));
            
            Parent->FirstView = Child->FirstView;
            Parent->LastView = Child->LastView;
            Parent->First = Child->First;
            Parent->Last = Child->Last;
            Parent->SplitAxis = Child->SplitAxis;
            Parent->CurrentView = Child->CurrentView;
            
            // sixten: Update the parents of the children.
            for(workspace_view *View = Parent->FirstView;
                View != 0;
                View = View->Next)
            {
                View->Parent = Parent;
            }
            for(workspace_panel *ParentChild = Parent->First;
                ParentChild != 0;
                ParentChild = ParentChild->Next)
            {
                ParentChild->Parent = Parent;
            }
            
            DLLRemove(Parent->First, Parent->Last, Child);
            W_DeletePanel(Child);
        }
        else
        {
            s32 ChildCount = 0;
            for(workspace_panel *Child = Parent->First;
                Child != 0;
                Child = Child->Next)
            {
                ++ChildCount;
            }
            
            r32 ToAppend = Panel->PercentOfParent / ChildCount;
            for(workspace_panel *Child = Parent->First;
                Child != 0;
                Child = Child->Next)
            {
                Child->PercentOfParent += ToAppend;
            }
        }
        
        // sixten: Delete all child views.
        workspace_view *NextChild = 0;
        for(workspace_view *Child = Panel->FirstView;
            Child != 0;
            Child = NextChild)
        {
            NextChild = Child->Next;
            W_DestroyView(Child);
        }
        
        W_DeletePanel(Panel);
    }
}

WORKSPACE_COMMAND(W_Command_OpenView)
{
	workspace *Workspace = W_GetState();
	W_CreateNewView((workspace_view_kind)Argument, Workspace->CurrentPanel);
}

WORKSPACE_COMMAND(W_Command_CloseView)
{
    workspace_view *View = 0;
    if(Argument)
    {
        View = (workspace_view *)U64ToPointer(Argument);
    }
    else
    {
        workspace *Workspace = W_GetState();
        View = Workspace->CurrentPanel->CurrentView;
    }
    
    if(View)
    {
        workspace_panel *Panel = View->Parent;
        
        DLLRemove(Panel->FirstView, Panel->LastView, View);
        if(Panel->CurrentView == View)
        {
            Panel->CurrentView = Panel->FirstView;
        }
        
        W_DestroyView(View);
    }
}
WORKSPACE_COMMAND(W_Command_OpenFile)
{
	temp Scratch = GetScratch();
	
	workspace *Workspace = W_GetState();
	workspace_file_lister_action *Action = (workspace_file_lister_action *)U64ToPointer(Argument);
	
	string Filepath = PushFormat(Scratch.Arena, "%S/%S", Action->Path, Action->Name);
	
	platform_file_handle File = Platform.OpenFile(Filepath, PlatformAccess_Read|PlatformAccess_OpenAlways);
	if(File.IsValid)
	{
		// sixten: retrieve file extension
		string FileExtension = Substring(Action->Name, Range1S64(LastIndexOf(Action->Name, '.')+1, Action->Name.Count));
		if(AreEqual(FileExtension, StrLit("vns")))
		{
			s64 FileSize = Platform.GetFileSize(File);
			string ReplaceString = MakeString(PushArrayNoClear(Scratch.Arena, u8, FileSize+1), FileSize);
			ReplaceString.Data[FileSize] = 0;
			Platform.ReadFile(File, ReplaceString.Data, 0, FileSize);
			
			ReplaceString = RemoveAll(Scratch.Arena, ReplaceString, '\r');
			
			workspace_view *View = W_CreateNewView(W_ViewKind_TextEditor, Workspace->CurrentPanel);
			workspace_view_text_editor *Editor = (workspace_view_text_editor *)View->Data;
			
			MutableStringReplaceRange(&Editor->Text, ReplaceString, Range1S64(0, 0));
			W_TextEditorApplyChanges(Editor);
			Editor->FileName = PushString(View->Arena, Action->Name);
			Editor->FilePath = PushString(View->Arena, Action->Path);
		}
		else if(AreEqual(FileExtension, StrLit("vnn")))
		{
			s64 FileSize = Platform.GetFileSize(File);
			string Contents = MakeString(PushArrayNoClear(Scratch.Arena, u8, FileSize), FileSize);
			Platform.ReadFile(File, Contents.Data, 0, Contents.Count);
			
			workspace_view *View = W_CreateNewView(W_ViewKind_NavEditor, Workspace->CurrentPanel);
			W_NavEditorSetup(View, Action->Path, Action->Name, Contents);
		}
		else if(AreEqual(FileExtension, StrLit("png")) || AreEqual(FileExtension, StrLit("jpg")))
		{
			s64 FileSize = Platform.GetFileSize(File);
			string Contents = MakeString(PushArrayNoClear(Scratch.Arena, u8, FileSize), FileSize);
			Platform.ReadFile(File, Contents.Data, 0, Contents.Count);
			workspace_view *View = W_CreateNewView(W_ViewKind_ImageViewer, Workspace->CurrentPanel);
			b32 CouldOpenImage = W_ImageViewerSetup(View, Action->Name, Contents);
			if(!CouldOpenImage)
			{
				//- sixten: destroy the view and show an error message instead
				workspace_panel *Panel = View->Parent;
				
				DLLRemove(Panel->FirstView, Panel->LastView, View);
				if(Panel->CurrentView == View)
				{
					Panel->CurrentView = Panel->FirstView;
				}
				W_DestroyView(View);
				
				View = W_CreateNewView(W_ViewKind_Error, Workspace->CurrentPanel);
				workspace_view_error *Error = (workspace_view_error *)View->Data;
				Error->Message = PushFormat(View->Arena, "Unknown to open file: %S", Filepath);
			}
		}
		else
		{
			workspace_view *View = W_CreateNewView(W_ViewKind_Error, Workspace->CurrentPanel);
			workspace_view_error *Error = (workspace_view_error *)View->Data;
			Error->Message = PushFormat(View->Arena, "Unknown file extension: %S", FileExtension);
		}
		
		Platform.CloseFile(File);
	}
	else
	{
		// sixten: what happens now??
	}
	
	ReleaseScratch(Scratch);
}

static workspace_panel *W_FindFirstLeaf(workspace_panel *Panel)
{
    for(;Panel->First;) Panel = Panel->First;
    return(Panel);
}

static workspace_panel *W_FindNextPanelParent(workspace_panel *Panel)
{
    workspace_panel *Result = 0;
    if(Panel->Next)
    {
        Result = Panel->Next;
    }
    else if(Panel->Parent)
    {
        Result = W_FindNextPanelParent(Panel->Parent);
    }
    else
    {
        Result = Panel;
    }
    return(Result);
}

WORKSPACE_COMMAND(W_Command_CyclePanel)
{
    workspace *Workspace = W_GetState();
    workspace_panel *Panel = W_FindFirstLeaf(W_FindNextPanelParent(Workspace->CurrentPanel));
    Workspace->CurrentPanel = Panel;
}

static workspace_panel *W_FindLastLeaf(workspace_panel *Panel)
{
    for(;Panel->Last;) Panel = Panel->Last;
    return(Panel);
}

static workspace_panel *W_FindPrevPanelParent(workspace_panel *Panel)
{
    workspace_panel *Result = 0;
    if(Panel->Prev)
    {
        Result = Panel->Prev;
    }
    else if(Panel->Parent)
    {
        Result = W_FindPrevPanelParent(Panel->Parent);
    }
    else
    {
        Result = Panel;
    }
    return(Result);
}

WORKSPACE_COMMAND(W_Command_CyclePanelReverse)
{
    workspace *Workspace = W_GetState();
    workspace_panel *Panel = W_FindLastLeaf(W_FindPrevPanelParent(Workspace->CurrentPanel));
    Workspace->CurrentPanel = Panel;
}

#if VN_INTERNAL
WORKSPACE_COMMAND(W_Command_ToggleRenderUIDebugRects)
{
	DEBUG_DebugSettings->RenderUIDebugRects = !DEBUG_DebugSettings->RenderUIDebugRects;
}
#endif
