/* date = May 5th 2023 10:12 am */

#ifndef VN_WORKSPACE_H
#define VN_WORKSPACE_H

////////////////////////////////
//~ sixten: Workspace Types

// sixten(TODO): Remove this type entirely.
enum workspace_toolbar_menu
{
    W_ToolbarMenu_None = 0,
    W_ToolbarMenu_Panel,
    W_ToolbarMenu_View,
    W_ToolbarMenu_Window,
};

struct workspace_panel_view
{
    struct workspace_panel *Parent;
    workspace_panel_view *Next;
    workspace_panel_view *Prev;
    struct workspace_view *View;
};

struct workspace_panel_view_list
{
    workspace_panel_view *First;
    workspace_panel_view *Last;
    s64 Count;
};

struct workspace_panel
{
    workspace_panel *First;
    workspace_panel *Last;
    workspace_panel *Next;
    workspace_panel *Prev;
    workspace_panel *Parent;
    
    workspace_view *FirstView;
    workspace_view *LastView;
    
    workspace_view *CurrentView;
    
    axis2 SplitAxis;
    r32 PercentOfParent;
};

#define WORKSPACE_COMMAND(name, ...) void name(u64 Argument)
typedef WORKSPACE_COMMAND(workspace_command_sig);

struct workspace_command
{
    workspace_command_sig *Command;
    u64 Argument;
    
    workspace_command *Next;
    workspace_command *Prev;
};

struct workspace_keybind
{
    platform_key Key;
    platform_modifiers Modifiers;
    workspace_command_sig *Command;
    u64 Argument;
};

enum workspace_drag_payload_state
{
    W_DragPayload_Inactive = 0,
    W_DragPayload_Active,
    W_DragPayload_Released,
};

struct workspace_drag_payload
{
    ui_key Key;
    workspace_view *View;
};

struct workspace
{
    vn_input *Input;
    platform_event_list *EventList;
    
    // sixten: Command Allocation
    arena *CommandArena;
    
    // sixten: Command List
    workspace_command *FirstCommand;
    workspace_command *LastCommand;
    
    // sixten: Panels
    arena *PanelArena;
    workspace_panel *FirstFreePanel;
    workspace_panel *LastFreePanel;
    workspace_panel *RootPanel;
    workspace_panel *CurrentPanel;
    
    // sixten: Drag Data
    workspace_drag_payload_state DragPayloadState;
    workspace_drag_payload DragPayload;
    
    // sixten: Dropdown Menu
    workspace_toolbar_menu Menu;
    v2_r32 MenuP;
    r32 MenuT;
};

#include "vn_workspace_file_lister.h"
#include "vn_workspace_text_editor.h"
#include "vn_workspace_nav_editor.h"
#include "vn_workspace_view.h"

////////////////////////////////
//~ sixten: Workspace Functions

//- sixten: State management
static void W_SetState(workspace *Workspace);
static workspace *W_GetState(void);

//- sixten: Commands
static void W_IssueCommand(workspace_command_sig *Sig, u64 Argument = 0);
static void W_ProcessCommands(void);
static void W_ProcessKeyBinds();

//- sixten: Builder code
static ui_signal W_BuildToolbarButton(char *Text, workspace_toolbar_menu Menu);
static ui_signal W_BuildMenuItem(u32 Icon, char *Text, char *Shortcut);
static void W_BuildToolbar(void);

static void W_BuildTabItem(workspace_panel *Panel, workspace_view *View);
static void W_BuildPanel(workspace_panel *Panel);
static void W_BuildDragPayload(void);

//- sixten: Panels
static workspace_panel *W_CreateNewPanel(workspace_panel *Parent);
static void W_DeletePanel(workspace_panel *Panel);
static void W_SplitPanel(workspace_panel *Panel, axis2 Axis);

//- sixten: Views
static b32 W_ViewIsDragged(workspace_view *View);

//- sixten: Dragging
inline void W_BeginDrag(workspace_drag_payload *Payload);
inline b32 W_DragPayload(workspace_drag_payload *Dest);

//- sixten: Workspace
static void W_Init(workspace *Workspace);
static void W_Update(workspace *Workspace, vn_render_commands *RenderCommands, vn_input *Input, glyph_atlas *GlyphAtlas);

#endif //VN_WORKSPACE_H
