---
title: "Customization Tutorial"
subtitle: "Colors, themes, and advanced styling options"
---

```{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)
```

## Color Palettes

jigsawR works seamlessly with all viridis color palettes.

### Viridis Options

```{r}
#| label: viridis-palettes
#| fig-align: center
#| fig-height: 6
make_palette_demo <- function(pal) {
  ggplot() +
    geom_puzzle_hex(
      aes(fill = after_stat(piece_id)),
      rings = 3, seed = 42
    ) +
    scale_fill_viridis_c(option = pal, guide = "none") +
    coord_fixed() +
    theme_puzzle() +
    labs(title = pal)
}

print((make_palette_demo("viridis") + make_palette_demo("magma") + make_palette_demo("plasma")) /
(make_palette_demo("inferno") + make_palette_demo("cividis") + make_palette_demo("turbo")))
```

### Custom Color Scales

Use any ggplot2 color scale:

```{r}
#| label: custom-colors
#| layout-ncol: 2
#| fig-cap:
#|   - "Gradient Blue to Cyan"
#|   - "Brewer Spectral"

# Custom gradient
print(ggplot() +
  geom_puzzle_rect(
    aes(fill = after_stat(piece_id)),
    cols = 4, rows = 3,
    width = 240, height = 180,
    seed = 42
  ) +
  scale_fill_gradient(
    low = "#2193b0",
    high = "#6dd5ed",
    guide = "none"
  ) +
  coord_fixed() +
  theme_puzzle() +
  labs(title = "Gradient"))

# Brewer palette
print(ggplot() +
  geom_puzzle_rect(
    aes(fill = factor(after_stat(piece_id))),
    cols = 4, rows = 3,
    width = 240, height = 180,
    seed = 42
  ) +
  scale_fill_brewer(palette = "Spectral", guide = "none") +
  coord_fixed() +
  theme_puzzle() +
  labs(title = "Brewer"))
```

## Themes

### Minimal Themes

```{r}
#| label: minimal-themes
#| layout-ncol: 2
#| fig-cap:
#|   - "theme_puzzle()"
#|   - "theme_minimal()"

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

print(ggplot() +
  geom_puzzle_hex(
    aes(fill = after_stat(piece_id)),
    rings = 2, diameter = 150, seed = 42
  ) +
  scale_fill_viridis_c(name = "Piece") +
  coord_fixed() +
  theme_minimal() +
  labs(title = "theme_minimal()"))
```

### Dark Themes

```{r}
#| label: dark-theme
#| fig-align: center
ggplot() +
  geom_puzzle_hex(
    aes(fill = after_stat(piece_id)),
    rings = 3, diameter = 200, seed = 42
  ) +
  scale_fill_viridis_c(option = "plasma") +
  coord_fixed() +
  theme_dark() +
  theme(
    panel.grid = element_blank(),
    plot.background = element_rect(fill = "#1a1a1a"),
    legend.background = element_rect(fill = "#1a1a1a"),
    legend.text = element_text(color = "white"),
    legend.title = element_text(color = "white")
  ) +
  labs(title = "Dark Theme", fill = "Piece ID")
```

### Custom Themes

```{r}
#| label: custom-theme
#| fig-align: center
# Extend theme_puzzle() with custom settings
theme_puzzle_custom <- function() {
  theme_puzzle() +
  theme(
    plot.title = element_text(
      hjust = 0.5,
      size = 16,
      face = "bold",
      margin = margin(b = 10)
    ),
    plot.subtitle = element_text(
      hjust = 0.5,
      size = 12,
      color = "gray50",
      margin = margin(b = 20)
    ),
    legend.position = "bottom",
    legend.title = element_text(size = 10),
    legend.text = element_text(size = 8),
    plot.margin = margin(20, 20, 20, 20)
  )
}

ggplot() +
  geom_puzzle_conc(
    aes(fill = after_stat(ring)),
    rings = 4, diameter = 250, seed = 42
  ) +
  scale_fill_viridis_c(option = "cividis", name = "Ring") +
  coord_fixed() +
  theme_puzzle_custom() +
  labs(
    title = "Concentric Puzzle",
    subtitle = "4 rings, 250mm diameter"
  )
```

## Legends

### Legend Position

```{r}
#| label: legend-position
#| layout-ncol: 2
#| fig-cap:
#|   - "Legend bottom"
#|   - "Legend inside"

# Bottom legend
print(ggplot() +
  geom_puzzle_rect(
    aes(fill = after_stat(piece_id)),
    cols = 4, rows = 3,
    width = 200, height = 150,
    seed = 42
  ) +
  scale_fill_viridis_c(name = "Piece") +
  coord_fixed() +
  theme_minimal() +
  labs(title = "Bottom") +
  theme(legend.position = "bottom"))

# Inside plot
print(ggplot() +
  geom_puzzle_rect(
    aes(fill = after_stat(piece_id)),
    cols = 4, rows = 3,
    width = 200, height = 150,
    seed = 42
  ) +
  scale_fill_viridis_c(name = "Piece") +
  coord_fixed() +
  theme_minimal() +
  labs(title = "Inside") +
  theme(
    legend.position = c(0.85, 0.85),
    legend.background = element_rect(fill = "white", color = "gray80")
  ))
```

### Custom Legend Labels

```{r}
#| label: custom-legend-labels
#| fig-align: center
ggplot() +
  geom_puzzle_conc(
    aes(fill = after_stat(ring)),
    rings = 3, diameter = 200, seed = 42
  ) +
  scale_fill_viridis_c(
    option = "magma",
    name = "Ring Number",
    labels = c("Center", "Ring 1", "Ring 2"),
    breaks = c(0, 1, 2)
  ) +
  coord_fixed() +
  theme_minimal() +
  theme(legend.position = "right")
```

## Annotations

### Add Text

```{r}
#| label: annotation-text
#| fig-align: center
ggplot() +
  geom_puzzle_hex(
    aes(fill = after_stat(ring)),
    rings = 3, diameter = 250, seed = 42
  ) +
  annotate(
    "text",
    x = 0, y = 0,
    label = "CENTER",
    size = 5,
    fontface = "bold",
    color = "white"
  ) +
  scale_fill_viridis_c(option = "plasma", guide = "none") +
  coord_fixed() +
  theme_puzzle() +
  labs(title = "Annotated puzzle")
```

### Add Labels with geom_text

```{r}
#| label: annotation-labels
#| fig-align: center
# Get piece data
puzzle <- generate_puzzle(
  type = "hexagonal",
  grid = c(2),
  size = c(150),
  seed = 42
)

ggplot() +
  geom_puzzle_hex(
    aes(fill = after_stat(piece_id)),
    rings = 2, diameter = 150, seed = 42
  ) +
  scale_fill_viridis_c(guide = "none") +
  coord_fixed() +
  theme_puzzle() +
  labs(title = "7 Hexagonal Pieces")
```

## Borders and Outlines

### Add Borders

```{r}
#| label: borders-basic
#| fig-align: center
ggplot() +
  geom_puzzle_rect(
    aes(fill = after_stat(piece_id)),
    cols = 3, rows = 3,
    width = 200, height = 200,
    seed = 42,
    color = "black",    # Border color
    linewidth = 0.5       # Border width
  ) +
  scale_fill_viridis_c(option = "plasma", guide = "none") +
  coord_fixed() +
  theme_puzzle() +
  labs(title = "With borders")
```

### Thick Borders for Emphasis

```{r}
#| label: borders-thick
#| fig-align: center

make_border_demo <- function(lw, label) {
  ggplot() +
    geom_puzzle_hex(
      aes(fill = after_stat(piece_id)),
      rings = 2, seed = 42,
      color = "white",
      linewidth = lw
    ) +
    scale_fill_viridis_c(option = "magma", guide = "none") +
    coord_fixed() +
    theme_puzzle() +
    labs(title = label)
}

print(make_border_demo(0.25, "Thin borders") + make_border_demo(1.5, "Thick borders"))
```

## Alpha Transparency

```{r}
#| label: alpha-transparency
#| fig-align: center

make_alpha_demo <- function(a, label) {
  ggplot() +
    geom_puzzle_voronoi(
      aes(fill = after_stat(piece_id)),
      n_cells = 15,
      seed = 42,
      alpha = a
    ) +
    scale_fill_viridis_c(option = "turbo", guide = "none") +
    coord_fixed() +
    theme_puzzle() +
    labs(title = label)
}

print(make_alpha_demo(1.0, "alpha = 1.0 (opaque)") + make_alpha_demo(0.5, "alpha = 0.5 (semi-transparent)"))
```

## Saving High-Quality Output

### PNG (Raster)

```{r}
#| label: save-png
#| fig-align: center
p <- ggplot() +
  geom_puzzle_hex(
    aes(fill = after_stat(piece_id)),
    rings = 4, diameter = 300, seed = 42
  ) +
  scale_fill_viridis_c(option = "plasma", guide = "none") +
  coord_fixed() +
  theme_puzzle()
print(p)

# ggsave("puzzle.png", p, width = 8, height = 8, dpi = 150)
# ggsave("puzzle_hq.png", p, width = 8, height = 8, dpi = 300)
# ggsave("puzzle_print.png", p, width = 12, height = 12, dpi = 600)
```

### SVG (Vector)

```{r}
#| label: save-svg
#| eval: false
# Vector format - infinite scalability
ggsave("puzzle.svg", p, width = 8, height = 8)
```

### PDF (Vector, Print-ready)

```{r}
#| label: save-pdf
#| eval: false
ggsave("puzzle.pdf", p, width = 8, height = 8)
```

## Summary

You've learned:

- ✅ Using viridis and custom color palettes
- ✅ Applying and customizing themes
- ✅ Configuring legends
- ✅ Adding annotations and labels
- ✅ Using borders and transparency
- ✅ Saving high-quality output

## Next Steps

- [Fusion Groups Tutorial](fusion-groups.qmd) - Merge pieces
- [Gallery](../gallery/rectangular.qmd) - More visual examples
