void StatusWindowInit() {
    Window *window = CreateWind();
    StatusBarWindowID = window->id;
    Buffer *buffer = CreateBuffer(SysAllocator, GetUniqueBufferName(WorkDir, "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 = true;
    window->draw_darker = true;
    window->layout = false;
    window->jump_history = false;
    window->lose_focus_on_escape = true;

    AddHook(&view->hooks, "Rename", "ctrl-r", [](){
        BSet active = GetBSet(ActiveWindowID);
        BSet last = GetBSet(LastActiveLayoutWindowID);
        String16 buffer_string = GetString(active.buffer);
        Range replace_range = {0, active.buffer->len};
        bool found_separator = Seek(buffer_string, u" |", &replace_range.max);
        if (!found_separator) {
            ReportErrorf("Failed to :Rename, didn't find '|' separator");
            return;
        }

        Scratch scratch;
        String16 buffer_name = GetString(active.buffer, replace_range);
        String buffer_name8 = ToString(scratch, buffer_name);
        ResolvedOpen o = ResolveOpen(scratch, buffer_name8, "dont_error");
        if (o.kind != OpenKind_Skip) {
            ReportErrorf("%S already exists, either on disk as file or as buffer", buffer_name8);
            return;
        }
        last.buffer->name = Intern(&GlobalInternTable, o.path);
    });
}

void StatusWindowLayout(Rect2I *rect, Int wx, Int wy) {
    Window *command_window = GetWindow(CommandWindowID);
    if (command_window->visible) {
        return;
    }
    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.buffer->begin_frame_change_id) {
            return;
        }
        String16 buffer_name = GetString(title.buffer, replace_range);
        buffer_name = Trim(buffer_name);

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

        Chop(&buffer_name, u":");
        Int line = ChopNumber(&buffer_name);
        if (line == -1) {
            line   = column;
            column = 0;
        }
        Chop(&buffer_name, u":");

        Int buffer_pos = XYToPos(main.buffer, {column, line});
        Caret &caret = main.view->carets[0];
        if (GetFront(caret) != buffer_pos) {
            caret = MakeCaret(buffer_pos);
        }
        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));
        ReplaceEx(scratch, title.view, u" | :Rename");
    }

    // replace data up to separator with filename and stuff
    const char *reopen = main.buffer->changed_on_disk ? " :Reopen" : "";
    const char *case_sens = SearchCaseSensitive ? " C" : "";
    const char *word_bound = SearchWordBoundary ? " W" : "";
    String s = Format(scratch, " %S:%lld:%lld%s%s", main.buffer->name, (long long)xy.line + 1ll, (long long)xy.col + 1ll, case_sens, word_bound, reopen);
    For (ActiveProcesses) {
        if (it.view_id == main.view->id.id) {
            s = Format(scratch, "%S %lld :KillProcess", 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);
}
