struct Window;
struct WindowID { Int id; Window *o; };

struct Window {
    WindowID id;
    ViewID active_view;

    Rect2I total_rect;
    Rect2I document_rect;
    Rect2I scrollbar_rect;
    Rect2I line_numbers_rect;
    Rect2I resizer_rect;

    Font  *font;
    double mouse_scroller_offset;
    int    z;
    double weight;
    Caret search_bar_anchor;

    GotoCrumb begin_frame_crumb;
    Array<GotoCrumb> goto_history;
    Array<GotoCrumb> goto_redo;

    ViewID active_goto_list;
    Int goto_list_pos;

    struct {
        uint32_t draw_scrollbar : 1;
        uint32_t draw_line_numbers : 1;
        uint32_t draw_darker : 1;
        uint32_t draw_line_highlight : 1;
        uint32_t visible : 1;
        uint32_t layout : 1;
        uint32_t close : 1;
        uint32_t sync_visibility_with_focus : 1;
        uint32_t lose_focus_on_escape : 1;
        uint32_t lose_visibility_on_escape : 1;
        uint32_t jump_history : 1;
        uint32_t skip_checkpoint : 1;
    };
};

struct Scroller {
    Rect2  rect;
    double begin;
    double end;
    Int    line_count;
};

inline bool operator==(WindowID a, WindowID b) { return a.id == b.id; }
inline bool operator!=(WindowID a, WindowID b) { return a.id != b.id; }
Rect2I GetVisibleCells(Window *window);
Window *CreateWind();

void CommandWindowLayout(Rect2I *rect, Int wx, Int wy);
void CommandWindowInit();

void SearchWindowLayout(Rect2I *rect, Int wx, Int wy);
void SearchWindowInit();

void StatusWindowInit();
void StatusWindowLayout(Rect2I *rect, Int wx, Int wy);

void DebugWindowInit();
void DebugWindowLayout(Rect2I *rect, Int wx, Int wy);
