#!/usr/bin/env bash

set -euo pipefail

# ============================================================
# PDF 页面叠放特效
#
# 输入：
#   page-0.png
#   page-1.png
#   page-2.png
#   page-3.png
#
# 输出：
#   result.png
#
# 代码由 ChatGPT 生成。
# ============================================================

# ------------------------------------------------------------
# 参数
# ------------------------------------------------------------

# 每张后续页面从右侧露出的宽度
REVEAL_WIDTH=800

# 阴影水平/垂直偏移
SHADOW_OFFSET_X=8
SHADOW_OFFSET_Y=8

# 阴影模糊程度
SHADOW_BLUR=12

# 阴影透明度
SHADOW_OPACITY=0.25

# 为阴影在最终画布四周预留的空间
MARGIN=30

# 输出文件
OUTPUT="result.png"

# ------------------------------------------------------------
# 检查输入文件
# ------------------------------------------------------------

for i in {0..3}; do
    if [[ ! -f "page-${i}.png" ]]; then
        echo "错误：找不到 page-${i}.png"
        exit 1
    fi
done

# ------------------------------------------------------------
# 获取页面尺寸
# ------------------------------------------------------------

read WIDTH HEIGHT < <(
    magick identify -format '%w %h\n' page-0.png
)

echo "页面尺寸：${WIDTH} x ${HEIGHT}"

# ------------------------------------------------------------
# 页面数量
# ------------------------------------------------------------

PAGE_COUNT=4

# ------------------------------------------------------------
# 计算最终画布尺寸
#
# 第 1 页：x = 0
# 第 2 页：x = REVEAL_WIDTH
# 第 3 页：x = 2 * REVEAL_WIDTH
# 第 4 页：x = 3 * REVEAL_WIDTH
#
# 所有页面的 y 坐标相同。
# ------------------------------------------------------------

CANVAS_WIDTH=$(
    echo $((WIDTH + (PAGE_COUNT - 1) * REVEAL_WIDTH + 2 * MARGIN))
)

CANVAS_HEIGHT=$(
    echo $((HEIGHT + 2 * MARGIN))
)

echo "最终画布：${CANVAS_WIDTH} x ${CANVAS_HEIGHT}"

# ------------------------------------------------------------
# 创建透明画布
# ------------------------------------------------------------

magick \
    -size "${CANVAS_WIDTH}x${CANVAS_HEIGHT}" \
    xc:none \
    canvas.png

# ------------------------------------------------------------
# 创建临时目录
# ------------------------------------------------------------

TMP_DIR=$(mktemp -d)

trap 'rm -rf "$TMP_DIR" canvas.png' EXIT

# ------------------------------------------------------------
# 预处理每一页
#
# PDF 导出的图片统一设置为白色不透明背景，并生成阴影。
# ------------------------------------------------------------

for i in {0..3}; do

    INPUT="page-${i}.png"

    PAGE="${TMP_DIR}/page-${i}.png"
    SHADOW_MASK="${TMP_DIR}/shadow-mask-${i}.png"
    SHADOW="${TMP_DIR}/shadow-${i}.png"

    echo "准备第 $((i + 1)) 页..."

    # --------------------------------------------------------
    # 将页面背景设置为白色，并确保页面本身完全不透明。
    # --------------------------------------------------------

    magick "$INPUT" \
        -background white \
        -alpha remove \
        -alpha off \
        "$PAGE"

    # --------------------------------------------------------
    # 创建阴影 alpha mask。
    # --------------------------------------------------------

    magick "$PAGE" \
        -alpha extract \
        -blur "0x${SHADOW_BLUR}" \
        -evaluate multiply "$SHADOW_OPACITY" \
        "$SHADOW_MASK"

    # --------------------------------------------------------
    # 创建黑色阴影。
    # 阴影透明度由上面的 alpha mask 控制。
    # --------------------------------------------------------

    magick \
        -size "${WIDTH}x${HEIGHT}" \
        xc:black \
        "$SHADOW_MASK" \
        -alpha off \
        -compose CopyOpacity \
        -composite \
        "$SHADOW"

done

# ------------------------------------------------------------
# 合成页面
#
# 重要：
#
# 页面位置：
#   第 1 页 -> 最左
#   第 2 页 -> 向右
#   第 3 页 -> 更向右
#   第 4 页 -> 最右
#
# 图层顺序：
#   第 4 页 -> 最底层
#   第 3 页
#   第 2 页
#   第 1 页 -> 最顶层
#
# 因此必须按照 3 -> 2 -> 1 -> 0 的顺序绘制。
# ------------------------------------------------------------

for ((i=PAGE_COUNT-1; i>=0; i--)); do

    PAGE="${TMP_DIR}/page-${i}.png"
    SHADOW="${TMP_DIR}/shadow-${i}.png"

    # 当前页面的位置
    X=$((MARGIN + i * REVEAL_WIDTH))
    Y=$MARGIN

    # --------------------------------------------------------
    # 先绘制当前页面的阴影
    # --------------------------------------------------------

    SHADOW_X=$((X + SHADOW_OFFSET_X))
    SHADOW_Y=$((Y + SHADOW_OFFSET_Y))

    magick canvas.png \
        "$SHADOW" \
        -geometry "+${SHADOW_X}+${SHADOW_Y}" \
        -composite \
        canvas.png

    # --------------------------------------------------------
    # 再绘制当前页面
    # --------------------------------------------------------

    magick canvas.png \
        "$PAGE" \
        -geometry "+${X}+${Y}" \
        -composite \
        canvas.png

done

# ------------------------------------------------------------
# 输出最终图片
#
# canvas.png 使用透明背景创建，因此纸张之外的区域
# 保留 alpha 通道。
# ------------------------------------------------------------

magick canvas.png "$OUTPUT"

echo
echo "完成：$OUTPUT"
echo "尺寸：$(magick identify -format '%wx%h' "$OUTPUT")"
