---
title: "Basic Usage Tutorial"
subtitle: "Step-by-step guide to creating your first puzzles"
---

```{r}
#| label: setup
#| include: false
# Flexible path: works from project root (Quarto) or quarto/tutorials/ (RStudio interactive)
setup_path <- if (file.exists("quarto/_setup.R")) "quarto/_setup.R" else "../_setup.R"
source(setup_path)
```

## Introduction

This tutorial walks you through creating puzzles with jigsawR, from simple examples to more complex configurations.

## Step 1: Installation

```{r}
#| label: installation
#| eval: false
# Install from GitHub
devtools::install_github("pjt222/jigsawR")

# Load the package
library(jigsawR)
```

## Step 2: Your First Puzzle

Let's create a simple rectangular puzzle. Choose your approach:

::: {.panel-tabset}

## ggpuzzle

The ggpuzzle approach integrates with ggplot2 for quick visualization:

```{r}
#| label: first-puzzle-ggpuzzle
#| fig-align: center
library(ggplot2)
library(viridis)

ggplot() +
  geom_puzzle_rect(
    aes(fill = after_stat(piece_id)),
    cols = 4, rows = 3,
    width = 400, height = 300,
    seed = 42
  ) +
  scale_fill_viridis_c(name = "Piece ID") +
  coord_fixed() +
  theme_minimal() +
  labs(title = "My First Puzzle")
```

::: {.callout-tip}
`geom_puzzle_rect()` computes piece geometry and provides `piece_id`, `row`, `col` for mapping.
:::

## API

The API approach gives you full control and access to the SVG data:

```{r}
#| label: first-puzzle-api
# Generate a 3x4 rectangular puzzle
result <- generate_puzzle(
  type = "rectangular",
  grid = c(3, 4),      # 3 rows, 4 columns
  size = c(300, 400),  # height=300mm, width=400mm
  seed = 42,           # For reproducibility
  fill_palette = "viridis"
)

# What did we get?
n_pieces <- length(result$pieces)
canvas_w <- result$canvas_size[1]
canvas_h <- result$canvas_size[2]
cli::cli_alert_info("Number of pieces: {n_pieces}")
cli::cli_alert_info("Canvas size: {canvas_w} x {canvas_h} mm")

# Visualize
render_puzzle_preview(result)
```

::: {.callout-tip}
The API returns a list with `$svg_content`, `$pieces`, `$canvas_size`, and `$files`.
:::

:::

## Step 3: Save Your Puzzle

::: {.panel-tabset}

## ggpuzzle

```{r}
#| label: save-puzzle-ggpuzzle
#| fig-align: center
# Save ggplot as PNG
p <- ggplot() +
  geom_puzzle_rect(
    aes(fill = after_stat(piece_id)),
    cols = 4, rows = 3,
    seed = 42
  ) +
  scale_fill_viridis_c(guide = "none") +
  coord_fixed() +
  theme_puzzle()
print(p)

# ggsave("my_puzzle.png", p, width = 8, height = 6, dpi = 300)
```

## API

```{r}
#| label: save-puzzle-api
#| eval: false
# Save as SVG (from API result)
writeLines(result$svg_content, "my_puzzle.svg")
```

:::

::: {.callout-note}
API generates SVG files, while ggpuzzle uses ggplot2's `ggsave()` for PNG/PDF export.
:::

## Step 4: Try Different Puzzle Types

### Hexagonal

::: {.panel-tabset}

## ggpuzzle

```{r}
#| label: type-hexagonal-ggpuzzle
#| fig-align: center
ggplot() +
  geom_puzzle_hex(
    aes(fill = after_stat(piece_id)),
    rings = 3,
    seed = 42
  ) +
  scale_fill_viridis_c(option = "plasma", guide = "none") +
  coord_fixed() +
  theme_puzzle() +
  labs(title = "Hexagonal Puzzle")
```

## API

```{r}
#| label: type-hexagonal-api
hex_result <- generate_puzzle(
  type = "hexagonal",
  grid = c(3),      # 3 rings
  size = c(200),    # 200mm diameter
  seed = 42,
  fill_palette = "plasma"
)

render_puzzle_preview(hex_result)
```

:::

### Concentric

::: {.panel-tabset}

## ggpuzzle

```{r}
#| label: type-concentric-ggpuzzle
#| fig-align: center
ggplot() +
  geom_puzzle_conc(
    aes(fill = after_stat(ring)),
    rings = 3,
    seed = 42
  ) +
  scale_fill_viridis_c(option = "cividis", name = "Ring") +
  coord_fixed() +
  theme_puzzle() +
  labs(title = "Concentric Puzzle")
```

## API

```{r}
#| label: type-concentric-api
conc_result <- generate_puzzle(
  type = "concentric",
  grid = c(3),      # 3 rings
  size = c(200),    # 200mm diameter
  seed = 42,
  fill_palette = "cividis"
)

render_puzzle_preview(conc_result)
```

:::

### Voronoi

::: {.panel-tabset}

## ggpuzzle

```{r}
#| label: type-voronoi-ggpuzzle
#| fig-align: center
ggplot() +
  geom_puzzle_voronoi(
    aes(fill = after_stat(piece_id)),
    n_cells = 20,
    width = 250, height = 200,
    seed = 42
  ) +
  scale_fill_viridis_c(option = "turbo", guide = "none") +
  coord_fixed() +
  theme_puzzle() +
  labs(title = "Voronoi Puzzle")
```

## API

```{r}
#| label: type-voronoi-api
vor_result <- generate_puzzle(
  type = "voronoi",
  grid = c(20),            # 20 cells
  size = c(200, 250),      # height=200mm, width=250mm
  seed = 42,
  fill_palette = "turbo"
)

render_puzzle_preview(vor_result)
```

:::

## Step 5: Customize Parameters

### Change Separation

::: {.panel-tabset}

## ggpuzzle

```{r}
#| label: separation-modes-ggpuzzle
#| fig-align: center
make_offset_plot <- function(off) {
  ggplot() +
    geom_puzzle_rect(
      aes(fill = after_stat(piece_id)),
      cols = 3, rows = 2,
      offset = off,
      seed = 42
    ) +
    scale_fill_viridis_c(guide = "none") +
    coord_fixed() +
    theme_puzzle() +
    labs(title = paste0("offset = ", off))
}

print(make_offset_plot(0) + make_offset_plot(10) + make_offset_plot(20))
```

## API

```{r}
#| label: separation-modes-api
#| layout-ncol: 3
#| fig-cap:
#|   - "Complete puzzle (offset = 0)"
#|   - "Slightly separated (offset = 10)"
#|   - "More separated (offset = 20)"

# Generate with different offset values
r0 <- generate_puzzle(type = "rectangular", grid = c(2, 3), size = c(200, 300), offset = 0, seed = 42, fill_palette = "viridis")
r10 <- generate_puzzle(type = "rectangular", grid = c(2, 3), size = c(200, 300), offset = 10, seed = 42, fill_palette = "viridis")
r20 <- generate_puzzle(type = "rectangular", grid = c(2, 3), size = c(200, 300), offset = 20, seed = 42, fill_palette = "viridis")

render_puzzle_preview(r0)
render_puzzle_preview(r10)
render_puzzle_preview(r20)
```

:::

### Change Colors

The ggpuzzle approach makes it easy to apply different color schemes using ggplot2's scale functions.

```{r}
#| label: color-palettes-ggpuzzle
#| layout-ncol: 2
#| fig-cap:
#|   - "Plasma palette"
#|   - "Magma palette"

print(ggplot() +
  geom_puzzle_hex(
    aes(fill = after_stat(piece_id)),
    rings = 2, diameter = 150, seed = 42
  ) +
  scale_fill_viridis_c(option = "plasma", guide = "none") +
  coord_fixed() +
  theme_puzzle() +
  labs(title = "Plasma"))

print(ggplot() +
  geom_puzzle_hex(
    aes(fill = after_stat(piece_id)),
    rings = 2, diameter = 150, seed = 42
  ) +
  scale_fill_viridis_c(option = "magma", guide = "none") +
  coord_fixed() +
  theme_puzzle() +
  labs(title = "Magma"))
```

::: {.callout-note}
For the API approach, colors are controlled through SVG styling. See the [Customization Tutorial](customization.qmd) for advanced coloring techniques.
:::

## Step 6: Reproducibility

The `seed` parameter ensures you get the same puzzle every time:

::: {.panel-tabset}

## ggpuzzle

```{r}
#| label: reproducibility-ggpuzzle
#| layout-ncol: 2
#| fig-cap:
#|   - "seed = 42"
#|   - "seed = 123"

# Same seed produces identical geometry
plot_with_seed <- function(s) {
  ggplot() +
    geom_puzzle_hex(
      aes(fill = after_stat(piece_id)),
      rings = 2,
      seed = s
    ) +
    scale_fill_viridis_c(guide = "none") +
    coord_fixed() +
    theme_puzzle() +
    labs(title = paste("seed =", s))
}

print(plot_with_seed(42))
print(plot_with_seed(123))
```

## API

```{r}
#| label: reproducibility-api
# Same seed = same puzzle
p1 <- generate_puzzle(type = "hexagonal", grid = c(2), size = c(100), seed = 42)
p2 <- generate_puzzle(type = "hexagonal", grid = c(2), size = c(100), seed = 42)

identical(p1$svg_content, p2$svg_content)  # TRUE

# Different seed = different puzzle
p3 <- generate_puzzle(type = "hexagonal", grid = c(2), size = c(100), seed = 123)
identical(p1$svg_content, p3$svg_content)  # FALSE
```

:::

::: {.callout-tip}
Both approaches use the same deterministic RNG, so `seed = 42` generates identical piece shapes whether you use the API or ggpuzzle.
:::

## Summary

You've learned to:

1. ✅ Install and load jigsawR
2. ✅ Generate puzzles using both **API** and **ggpuzzle** approaches
3. ✅ Save puzzles as SVG (API) or PNG (ggpuzzle)
4. ✅ Create different puzzle types (rectangular, hexagonal, concentric, voronoi, random, snic)
5. ✅ Customize offset and colors
6. ✅ Use seeds for reproducibility

**Choosing an approach:**

- **API** (`generate_puzzle()`): Best for SVG export, programmatic manipulation, and custom rendering
- **ggpuzzle** (`geom_puzzle_*()`): Best for quick visualization, ggplot2 integration, and color customization

## Next Steps

- [Customization Tutorial](customization.qmd) - Colors, themes, and advanced styling
- [Fusion Groups Tutorial](fusion-groups.qmd) - Merge pieces with PILES notation
- [API Reference](../api/generate-puzzle.qmd) - Complete parameter documentation
