# Image Module data flow

## What It Does
Image subsystem manages insertion, rendering, positioning, persistence and lifecycle of images in the workbook. The Spreadsheet layer handles file input, UI overlays, and user-driven operations (insert/delete/resize/move). The Workbook layer persists image metadata into cell models and reapplies images when the model is imported or deserialized.

Primary implementation files: `src/spreadsheet/integrations/image.ts` (UI) and `src/workbook/integrations/image.ts` (Core/WorkbookImage).

## Entry Points (UI)
**Class:** `SpreadsheetImage`
- Listens: `insertImage`, `refreshImgCellObj`, `createImageElement`, `deleteImage`, `refreshImagePosition`.
- Key handlers:
  - `renderImageUpload()` — create hidden `<input type="file">` host for image selection and wire `onchange` to `imageSelect()`.
  - `imageSelect()` — validate file type and call `insertImage()`.
  - `insertImage(args)` — read file as data URL (FileReader), then call `createImageElement()`.
  - `createImageElement(args)` — create overlay DOM element via overlay service, compute positioning (supports frozen panes), set backgroundImage, compute `ImageModel` metadata and call `parent.notify(setImage, ...)` to persist.
  - `refreshImgCellObj(args)` — update cell attachments when an image is moved/resized between cells (handles undo/redo and fires `actionComplete`).
  - `deleteImage(args)` — locate overlay element or model, remove DOM element, remove image metadata from `CellModel.image`, and notify `completeAction`/`actionComplete` accordingly.

## Entry Points (Core)
**Class:** `WorkbookImage`
- Listens: `setImage`, `importModelUpdate`.
- Key handlers:
  - `setImage(args)` — normalize sheet/range, compute anchor indexes, attach image metadata to `CellModel.image` using `setCell()`, and return flags (e.g., `isElementRemoved`).
  - `updateImagesFromSheet()` — on import, iterate `sheet.imageColl` and attach `ExtendedImageModel` entries into `CellModel.image` arrays.

## ASCII Core Logic Flow
User selects file → Spreadsheet `imageSelect()` → read file → `insertImage()` → `createImageElement()` → overlay inserted & positioned → `parent.notify(setImage, {...})`
         ↓
`WorkbookImage.setImage()` → attach `ImageModel` to `CellModel.image` via `setCell()` (persist metadata)
         ↓
UI `createImageElement()` receives confirmation → overlay shown; `actionComplete`/`beginAction`/`completeAction` events fired for undo/redo integration
         ↓
User moves/resizes/deletes → Spreadsheet notifies `setImage`/`refreshImgCellObj`/`deleteImage` → Core updates `CellModel.image` and UI updates DOM

## Operations (functions & responsibilities)
- `renderImageUpload()` (UI)
  - Creates hidden file input (`{id}_imageUpload`) and sets `accept` to image types; `onchange` triggers `imageSelect()`.

- `imageSelect()` (UI)
  - Validates file MIME type; shows localized unsupported-file dialog for non-image types; calls `insertImage({ file, isAction: true })`.

- `insertImage()` (UI)
  - Reads file via `FileReader` and resolves an object containing `dataUrl`, `width`, `height`; calls `createImageElement()` with those values.

- `createImageElement()` (UI)
  - Computes target `range` and `sheetIndex`; ensures unique overlay id (`getUniqueID`), guards against duplicates and read-only cells (`isReadOnlyCells`), and fires `actionBegin`/`beforeInsertImage` notifications.
  - Uses Overlay service `insertOverlayElement(id, range, sheetIndex)` to create a positioned overlay element and sets CSS `backgroundImage` to the data URL.
  - Computes `ImageModel` metadata: `src`, `id`, `height`, `width`, `top`, `left` (adjusted for frozen panes and DPR via `addDPRValue`).
  - Calls `parent.notify(setImage, { options: [imgData], range: sheet.name + '!' + range, isPositionChanged, isElementRemoved })` to persist through core.
  - On public actions, fires `actionComplete`/`actionComplete` events with `insertImage` payload to integrate undo/redo and telemetry.

- `refreshImgCellObj()` (UI)
  - Handles image re-anchor when position changes: moves metadata from prev cell to curr cell, updates `CellModel.image` via `setCell()`, and emits `actionComplete` if not undo/redo.

- `deleteImage()` (UI)
  - Determine image by DOM id or range; compute anchor cell; fire `beginAction` (allow cancel); remove DOM element; remove metadata from `CellModel.image` and call `setCell()`; notify `completeAction`/`actionComplete` with deletion info (address, id, imageData, width/height).

- `setImage()` (Core)
  - Resolve sheet index and target `indexes` from range; compute `cell` and attach `ImageModel[]` to `cell.image` using `setCell(...)` (true to trigger necessary notifications).
  - When `importModelUpdate` occurs, `updateImagesFromSheet()` attaches `sheet.imageColl` entries to cell objects.

## Validation & Safety
- File validation: only image MIME types accepted; non-image files trigger localized dialog (`UnsupportedFile`).
- Readonly/protected cells: `createImageElement()` checks `isReadOnlyCells` and cancels with `readonlyAlert` when insertion is not allowed.
- Duplicate overlay IDs: `createImageElement()` guards against creating overlays with existing ids or when sheet/panel conditions prevent insertion.
- Event cancellation: `actionBegin`/`beginAction` allow external handlers to cancel insert/delete operations; handlers check `eventArgs.cancel` before proceeding.
- Frozen panes & virtualization: positioning logic accounts for frozen rows/cols (different overlay placement) and uses `getRowIdxFromClientY`/`getColIdxFromClientX` notifications to translate client coords into cell indexes.
- Undo/Redo: `isUndoRedo`, `isAction`, and `preventAction` flags propagate through events (`setImage`, `actionComplete`, `completeAction`) so host pipeline can record/replay operations.
- Async safety: `FileReader` operations are promise-based and UI routines guard against missing `parent` in callbacks.

## Desired Outputs

User-facing
- Visual overlay images placed above the grid with drag/resize handles (overlay element with unique id, backgroundImage set to data URL).
- Image insertion via file dialog, paste, or programmatic API; immediate visual feedback and persisted metadata.
- Deletion and repositioning reflected in the UI and persisted model; undo/redo support for image operations.

System-level
- Events & Notifications:
  - UI → Core: `setImage` (persist image metadata)
  - Core → UI: `importModelUpdate` triggers `updateImagesFromSheet()` to reattach persisted images
  - Management: `insertImage` (UI entry), `createImageElement`, `refreshImgCellObj`, `deleteImage`, `refreshImagePosition`
  - Action pipeline: `actionBegin`/`beginAction`, `actionComplete`/`completeAction`, and `completeAction` used for recording and notifying operation results

- Model artifacts:
  - `CellModel.image` array stores `ImageModel` entries attached to anchor cell: `{ src, id, height, width, top, left }`.
  - `ExtendedSheet.imageColl` used during import to hold images that will be attached on `importModelUpdate`.

- DOM / CSS hooks:
  - Hidden file input id: `{id}_imageUpload` for file selection.
  - Overlay element ids generated via `getUniqueID('{id}_overlay_picture_')` and attached via the Overlay service; overlay element style includes `backgroundImage`, `height`, `width`, `top`, `left`.
  - Use notifications `getRowIdxFromClientY`, `getColIdxFromClientX` to map overlay positions to cell indexes.

## Implementation Notes (short)
- Keep responsibilities split: Spreadsheet layer handles file I/O, overlay positioning and DOM; Workbook layer persists metadata and reattaches images on import.
- Always run `parent.notify(setImage, ...)` after creating/updating overlay metadata so the core and serialization layers stay in sync.
- Use `actionBegin`/`actionComplete` to integrate undo/redo and allow external cancellation or augmentation of image operations.
- Guard against readonly/locked cells and frozen-pane placement edge cases when computing `top`/`left`.

---