void StatusWindowInit() {
    Window *window = CreateWind();
    StatusBarWindowID = window->id;
    Buffer *buffer = CreateBuffer(SysAllocator, "status_bar");
    buffer->special = true;
    View *view = CreateView(buffer->id);
    view->special = true;
    window->active_view = view->id;
    window->font = &SecondaryFont;
    window->draw_line_numbers = false;
    window->draw_scrollbar = false;
    window->draw_line_highlight = false;
    window->draw_darker = true;
    window->layout = false;
}

void StatusWindowLayout(Rect2I *rect, Int wx, Int wy) {
    Window *n = GetWindow(StatusBarWindowID);
    Rect2I copy_rect = *rect;
    if (!n->visible) {
        rect = &copy_rect;
    }
    Int barsize = GetExpandingBarSize(n);
    n->document_rect = n->total_rect = CutBottom(rect, barsize);
}

void StatusWindowUpdate() {
    ProfileFunction();
    Window *status_bar_window = GetWindow(StatusBarWindowID, NULL);
    if (status_bar_window == NULL) {
        return;
    }

    Scratch scratch;
    BSet main = GetBSet(LastActiveLayoutWindowID);
    BSet title = GetBSet(status_bar_window);
    title.view->scroll.y = 0;

    String16 buffer_string = GetString(title.buffer);
    Range replace_range = {0, title.buffer->len};
    bool found_separator = Seek(buffer_string, u" |", &replace_range.max);

    // Parse the title and line
    if (title.window->id == ActiveWindowID) {
        if (title.buffer->change_id == title.window->status_bar_last_buffer_change_id) {
            return;
        }
        String16 buffer_name = GetString(title.buffer, replace_range);
        buffer_name = Skip(buffer_name, 1);
        buffer_name = Trim(buffer_name);

        Int column = ChopNumber(&buffer_name);
        if (column == -1) return;

        Int line = ChopNumber(&buffer_name);
        if (line == -1) {
            line   = column;
            column = 0;
        }

        Int buffer_pos = XYToPos(main.buffer, {column, line});
        Caret &caret = main.view->carets[0];
        if (GetFront(caret) != buffer_pos) {
            caret = MakeCaret(buffer_pos);
        }
        title.window->status_bar_last_buffer_change_id = title.buffer->change_id;
        return;
    }

    Caret   caret = main.view->carets[0];
    XY      xy    = PosToXY(main.buffer, GetFront(caret));

    // add separator at the end of buffer
    if (!found_separator) {
        SelectRange(title.view, GetBufferEndAsRange(title.buffer));
        Array<Edit> edits = ReplaceEx(scratch, title.view, u" |");
    }


    // replace data up to separator with filename and stuff
    const char *reopen = main.buffer->changed_on_disk ? " Reopen()" : "";
    String s = Format(scratch, "# %S:%lld:%lld%s", main.buffer->name, (long long)xy.line + 1ll, (long long)xy.col + 1ll, reopen);
    For (ActiveProcesses) {
        if (it.view_id == main.view->id.id) {
            s = Format(scratch, "%S %lld Kill()", s, (long long)it.id);
        }
    }

    String16 string            = ToString16(scratch, s);
    String16 string_to_replace = GetString(title.buffer, replace_range);
    if (string_to_replace != string) {
        SelectRange(title.view, replace_range);
        Array<Edit> edits = ReplaceEx(scratch, title.view, string);
    }

    SelectRange(title.view, MakeRange(0));
    ResetHistory(title.buffer);
}
