# EbookReader - Simple EPUB Reader Application

The `EbookReader` class provides a complete, user-friendly interface for building ebook reader applications with pyWebLayout. It wraps all the complex ereader infrastructure into a simple API.

## Features

- 📖 **EPUB Loading** - Load EPUB files with automatic content extraction
- ⬅️➡️ **Page Navigation** - Forward and backward page navigation
- 🔖 **Position Management** - Save/load reading positions (stable across font changes)
- 📑 **Chapter Navigation** - Jump to chapters by title or index
- 🔤 **Font Size Control** - Increase/decrease font size with live re-rendering
- 📏 **Spacing Control** - Adjust line, block, and word spacing
- 💾 **Persistent Settings** - Save and restore rendering preferences across sessions
- 📊 **Progress Tracking** - Get reading progress and position information
- 🎨 **Text Highlighting** - Highlight words and passages with colors
- 📋 **Overlays** - TOC, Settings, and Bookmarks overlays
- 🖱️ **Gesture Support** - Handle tap, swipe, pinch gestures
- 💾 **Context Manager Support** - Automatic cleanup with `with` statement

## Quick Start

```python
from pyWebLayout.layout.ereader_application import EbookReader

# Create reader
reader = EbookReader(page_size=(800, 1000))

# Load an EPUB
reader.load_epub("mybook.epub")

# Get current page as PIL Image
page_image = reader.get_current_page()
page_image.save("current_page.png")

# Navigate
reader.next_page()
reader.previous_page()

# Close reader
reader.close()
```

## API Reference

### Initialization

```python
reader = EbookReader(
    page_size=(800, 1000),           # Page dimensions (width, height) in pixels
    margin=40,                        # Page margin in pixels
    background_color=(255, 255, 255), # RGB background color
    line_spacing=5,                   # Line spacing in pixels
    inter_block_spacing=15,           # Space between blocks in pixels
    bookmarks_dir="ereader_bookmarks", # Directory for bookmarks
    buffer_size=5                     # Number of pages to cache
)
```

### Loading EPUB

```python
# Load EPUB file
success = reader.load_epub("path/to/book.epub")

# Check if book is loaded
if reader.is_loaded():
    print("Book loaded successfully")

# Get book information
book_info = reader.get_book_info()
# Returns: {
#   'title': 'Book Title',
#   'author': 'Author Name',
#   'document_id': 'book',
#   'total_blocks': 5000,
#   'total_chapters': 20,
#   'page_size': (800, 1000),
#   'font_scale': 1.0
# }
```

### Page Navigation

```python
# Get current page as PIL Image
page = reader.get_current_page()

# Navigate to next page
page = reader.next_page()  # Returns None at end of book

# Navigate to previous page
page = reader.previous_page()  # Returns None at beginning

# Save current page to file
reader.render_to_file("page.png")
```

### Position Management

Positions are saved based on abstract document structure (chapter/block/word indices), making them stable across font size and styling changes.

```python
# Save current position
reader.save_position("my_bookmark")

# Load saved position
page = reader.load_position("my_bookmark")

# List all saved positions
positions = reader.list_saved_positions()
# Returns: ['my_bookmark', 'chapter_2', ...]

# Delete a position
reader.delete_position("my_bookmark")

# Get detailed position info
info = reader.get_position_info()
# Returns: {
#   'position': {'chapter_index': 0, 'block_index': 42, 'word_index': 15, ...},
#   'chapter': {'title': 'Chapter 1', 'level': 'H1', ...},
#   'progress': 0.15,  # 15% through the book
#   'font_scale': 1.0,
#   'book_title': 'Book Title',
#   'book_author': 'Author Name'
# }

# Get reading progress (0.0 to 1.0)
progress = reader.get_reading_progress()
print(f"You're {progress*100:.1f}% through the book")
```

### Chapter Navigation

```python
# Get all chapters
chapters = reader.get_chapters()
# Returns: [('Chapter 1', 0), ('Chapter 2', 1), ...]

# Get chapters with positions
chapter_positions = reader.get_chapter_positions()
# Returns: [('Chapter 1', RenderingPosition(...)), ...]

# Jump to chapter by index
page = reader.jump_to_chapter(1)  # Jump to second chapter

# Jump to chapter by title
page = reader.jump_to_chapter("Chapter 1")

# Get current chapter info
chapter_info = reader.get_current_chapter_info()
# Returns: {'title': 'Chapter 1', 'level': HeadingLevel.H1, 'block_index': 0}
```

### Font Size Control

```python
# Get current font size scale
scale = reader.get_font_size()  # Default: 1.0

# Set specific font size scale
page = reader.set_font_size(1.5)  # 150% of normal size

# Increase font size by 10%
page = reader.increase_font_size()

# Decrease font size by 10%
page = reader.decrease_font_size()
```

### Spacing Control

```python
# Set line spacing (spacing between lines within a paragraph)
page = reader.set_line_spacing(10)  # 10 pixels

# Set inter-block spacing (spacing between paragraphs, headings, etc.)
page = reader.set_inter_block_spacing(20)  # 20 pixels
```

### Context Manager

The reader supports Python's context manager protocol for automatic cleanup:

```python
with EbookReader(page_size=(800, 1000)) as reader:
    reader.load_epub("book.epub")
    page = reader.get_current_page()
    # ... do stuff
# Automatically saves position and cleans up resources
```

## Complete Example

```python
from pyWebLayout.layout.ereader_application import EbookReader

# Create reader with custom settings
with EbookReader(
    page_size=(800, 1000),
    margin=50,
    line_spacing=8,
    inter_block_spacing=20
) as reader:
    # Load EPUB
    if not reader.load_epub("my_novel.epub"):
        print("Failed to load EPUB")
        exit(1)
    
    # Get book info
    info = reader.get_book_info()
    print(f"Reading: {info['title']} by {info['author']}")
    print(f"Total chapters: {info['total_chapters']}")
    
    # Navigate through first few pages
    for i in range(5):
        page = reader.get_current_page()
        page.save(f"page_{i+1:03d}.png")
        reader.next_page()
    
    # Save current position
    reader.save_position("page_5")
    
    # Jump to a chapter
    chapters = reader.get_chapters()
    if len(chapters) > 2:
        print(f"Jumping to: {chapters[2][0]}")
        reader.jump_to_chapter(2)
        reader.render_to_file("chapter_3_start.png")
    
    # Return to saved position
    reader.load_position("page_5")
    
    # Adjust font size
    reader.increase_font_size()
    reader.render_to_file("page_5_larger_font.png")
    
    # Get progress
    progress = reader.get_reading_progress()
    print(f"Reading progress: {progress*100:.1f}%")
```

## Persistent Settings

Settings like font size and spacing are automatically saved and restored across sessions:

```python
from dreader import EbookReader
from dreader.state import StateManager
from pathlib import Path

# Initialize state manager
state_file = Path.home() / ".config" / "dreader" / "state.json"
state_manager = StateManager(state_file=state_file)

# Load saved state
state = state_manager.load_state()
print(f"Saved font scale: {state.settings.font_scale}")

# Create reader with saved settings
reader = EbookReader(
    line_spacing=state.settings.line_spacing,
    inter_block_spacing=state.settings.inter_block_spacing
)

# Load book and apply all saved settings
reader.load_epub("mybook.epub")
reader.apply_settings(state.settings.to_dict())

# User changes settings...
reader.increase_font_size()
reader.set_line_spacing(10)

# Save new settings for next session
current_settings = reader.get_current_settings()
state_manager.update_settings(current_settings)
state_manager.save_state()

# Next time the app starts, these settings will be restored!
```

See [persistent_settings_example.py](persistent_settings_example.py) for a complete demonstration.

## Demo Scripts

Run these demos to see features in action:

```bash
# Comprehensive feature demo
python examples/ereader_demo.py path/to/book.epub

# Persistent settings demo
python examples/persistent_settings_example.py

# TOC overlay demo (generates animated GIF)
python examples/demo_toc_overlay.py

# Settings overlay demo (generates animated GIF)
python examples/demo_settings_overlay.py

# Word highlighting examples
python examples/word_selection_highlighting.py
```

This will demonstrate:
- Basic page navigation
- Position save/load
- Chapter navigation
- Font size adjustments
- Spacing adjustments
- Book information retrieval

The demo generates multiple PNG files showing different pages and settings.

## Position Storage Format

Positions are stored as JSON files in the `bookmarks_dir` (default: `ereader_bookmarks/`):

```json
{
  "chapter_index": 0,
  "block_index": 42,
  "word_index": 15,
  "table_row": 0,
  "table_col": 0,
  "list_item_index": 0,
  "remaining_pretext": null,
  "page_y_offset": 0
}
```

This format is tied to the abstract document structure, making positions stable across:
- Font size changes
- Line spacing changes
- Inter-block spacing changes
- Page size changes

## Integration Example: Simple GUI

Here's a minimal example of integrating with Tkinter:

```python
import tkinter as tk
from tkinter import filedialog
from PIL import ImageTk
from pyWebLayout.layout.ereader_application import EbookReader

class SimpleEreaderGUI:
    def __init__(self, root):
        self.root = root
        self.reader = EbookReader(page_size=(600, 800))
        
        # Create UI
        self.image_label = tk.Label(root)
        self.image_label.pack()
        
        btn_frame = tk.Frame(root)
        btn_frame.pack()
        
        tk.Button(btn_frame, text="Open EPUB", command=self.open_epub).pack(side=tk.LEFT)
        tk.Button(btn_frame, text="Previous", command=self.prev_page).pack(side=tk.LEFT)
        tk.Button(btn_frame, text="Next", command=self.next_page).pack(side=tk.LEFT)
        tk.Button(btn_frame, text="Font+", command=self.increase_font).pack(side=tk.LEFT)
        tk.Button(btn_frame, text="Font-", command=self.decrease_font).pack(side=tk.LEFT)
        
    def open_epub(self):
        filepath = filedialog.askopenfilename(filetypes=[("EPUB files", "*.epub")])
        if filepath:
            self.reader.load_epub(filepath)
            self.display_page()
    
    def display_page(self):
        page = self.reader.get_current_page()
        if page:
            photo = ImageTk.PhotoImage(page)
            self.image_label.config(image=photo)
            self.image_label.image = photo
    
    def next_page(self):
        if self.reader.next_page():
            self.display_page()
    
    def prev_page(self):
        if self.reader.previous_page():
            self.display_page()
    
    def increase_font(self):
        self.reader.increase_font_size()
        self.display_page()
    
    def decrease_font(self):
        self.reader.decrease_font_size()
        self.display_page()

root = tk.Tk()
root.title("Simple Ereader")
app = SimpleEreaderGUI(root)
root.mainloop()
```

## Performance Notes

- The reader uses intelligent page caching for fast navigation
- First page load may take ~1 second, subsequent pages are typically < 0.1 seconds
- Background rendering attempts to pre-cache upcoming pages (you may see pickle warnings, which can be ignored)
- Font size changes invalidate the cache and require re-rendering from the current position
- Position save/load is nearly instantaneous

## Limitations

- Currently supports EPUB files only (no PDF, MOBI, etc.)
- Images in EPUBs may not render in some cases
- Tables are skipped in rendering
- Complex HTML layouts may not render perfectly
- No text selection or search functionality (these would need to be added separately)

## See Also

- `examples/ereader_demo.py` - Comprehensive feature demonstration
- `pyWebLayout/layout/ereader_manager.py` - Underlying manager class
- `pyWebLayout/layout/ereader_layout.py` - Core layout engine
- `examples/README_EPUB_RENDERERS.md` - Lower-level EPUB rendering
