BSet GetBSet(Window *window) {
    BSet set   = {window};
    set.view   = GetView(set.window->active_view);
    set.buffer = GetBuffer(set.view->active_buffer);
    return set;
}

BSet GetBSet(WindowID window_id) {
    Window *window = GetWindow(window_id);
    BSet    result = GetBSet(window);
    return result;
}

BSet GetConsoleSet() {
    BSet result = {};
    result.window = GetWindow(NullWindowID);
    result.view = GetView(NullViewID);
    result.buffer = GetBuffer(NullBufferID);
    return result;
}

String GetCurrentFilename() {
    BSet main = GetBSet(LastActiveLayoutWindowID);
    return main.buffer->name;
}

String GetDir(Buffer *buffer) {
    String name = ChopLastSlash(buffer->name);
    return name;
}

String GetMainDir() {
    BSet main = GetBSet(LastActiveLayoutWindowID);
    String name = ChopLastSlash(main.buffer->name);
    return name;
}

void GarbageCollect() {
    Allocator sys_allocator = GetSystemAllocator();


    ActiveWindowID = NextActiveWindowID;

    For (Windows) {
        if (it->sync_visibility_with_focus) {
            if (it->id == ActiveWindowID) {
                it->visible = true;
            } else {
                it->visible = false;
            }
        }
    }

    if (ActiveWindowID.id != LastActiveLayoutWindowID.id) {
        Window *window = GetWindow(ActiveWindowID);
        if (window->layout) {
            LastActiveLayoutWindowID = ActiveWindowID;
        }
    }

    For(Buffers) {
        if (it->file_mod_time) {
            int64_t new_file_mod_time = GetFileModTime(it->name);
            if (it->file_mod_time != new_file_mod_time) {
                it->changed_on_disk = true;
                if (it->dirty == false) ReopenBuffer(it);
            }
        }
    }

    IterRemove(Views) {
        IterRemovePrepare(Views);

        Buffer *buffer = GetBuffer(it->active_buffer);
        if (!buffer->garbage) {
            continue;
        }

        bool ref = ViewIsReferenced(it->id);
        if (ref) {
            continue;
        }

        remove_item = true;
        Dealloc(&it->carets);
        Dealloc(sys_allocator, it);
    }

    IterRemove(Buffers) {
        IterRemovePrepare(Buffers);

        if (!it->garbage) {
            continue;
        }

        bool ref = BufferIsReferenced(it->id);
        if (ref) {
            continue;
        }

        remove_item = true;
        DeallocBuffer(it);
    }

    IterRemove(Windows) {
        IterRemovePrepare(Windows);
        if (it->kill) {
            Dealloc(&it->goto_history);
            Dealloc(&it->goto_redo);
            Dealloc(sys_allocator, it);
            remove_item = true;
        }
   }
}
