# BibliothecaWindow Module Overview

`BibliothecaWindow` is the top-level GTK window that stitches together the data
model (`BookList`) and the UI widgets (`BookShelf`, search bar, placeholders).
It owns the application chrome and orchestrates imports, filtering, and state
transitions between empty / shelf / no-results views.

## Responsibilities

- Build the header bar (add button, search toggle) and main layout (`Gtk::Box`).
- Manage the search UI (`Gtk::SearchBar` + `Gtk::SearchEntry`) and pipe queries
  to `BookShelf::setFilter()`.
- Host a `Gtk::Stack` that swaps between:
  - Empty library placeholder.
  - Library grid (`BookShelf`).
  - "No results" message when filtering yields nothing.
- Handle "Add books" action: open a file dialog, import metadata/covers on a
  worker thread, and enqueue `BookList::upsertMany()`.
- Emit simple debug logging for activated books (placeholder behaviour for now).

## Layout overview

```
Gtk::Window (BibliothecaWindow)
 └── Gtk::Box m_mainBox (vertical)
     ├── Gtk::SearchBar m_searchBar
     │    └── Gtk::SearchEntry m_searchEntry
     └── Gtk::Stack m_stack
          ├── Gtk::Box m_placeholder        // empty library
          ├── BookShelf (GridView)          // main shelf view
          └── Gtk::Box m_noResults          // "no match" placeholder
```

The header bar carries the add (+) button and a search toggle button that
activates the search bar.

## Event flow

1. **Startup**: constructor calls `buildHeaderBar()`, `buildPlaceholder()`,
   creates the shelf, search widgets, and stack, then calls `updateVisibleView()`
   to pick the correct page based on the current library.
2. **Search**:
   - Clicking the search toggle (or pressing Ctrl+F) toggles the `Gtk::SearchBar`.
   - Typing updates `m_lastQuery`, calls `BookShelf::setFilter()`, and refreshes
     the stack (showing “no results” if the filtered shelf is empty).
   - Leaving the search mode clears the entry.
3. **Importing books**:
   - `onAddBookClicked()` opens `Gtk::FileDialog::open_multiple()`.
   - Each selected file is processed on a background thread: compute SHA-256,
     call `import_book_assets()`, merge metadata, collect into a vector.
   - Once done, the vector is enqueued back onto the main loop via
     `BookList::upsertMany()`, and the UI refreshes.
4. **Activation**: `BookShelf::signalBookActivated()` connects to
   `BibliothecaWindow::onBookActivated()`, which currently logs a placeholder
   message (can be extended to open a details pane or reader).

## Signals & slots

BibliothecaWindow subscribes to the relevant `BookList` signals to call
`updateVisibleView()` whenever the library changes. This keeps the stack in sync
with imports, deletions, and resets without manual intervention.

## Extension points

- **Actions on activation**: replace the placeholder logging with navigation to
  a details page or opening the file.
- **Drag-and-drop import**: wire a drop controller onto `m_mainBox` that reuses
  the existing import flow.
- **Search enhancements**: add filters (e.g. tags, formats) or highlight matches
  inside the grid by extending `BookShelf`.

## Expected usage

`BibliothecaWindow` is the root window instantiated in `main.cpp`. Other modules
should construct it with an existing `BookList`:

```cpp
auto window = Gtk::make_managed<BibliothecaWindow>(bookList);
app->add_window(*window);
```

The window takes ownership of the `BookShelf` widget and manages presentation
according to the current state of the library and active search query.
