#!/bin/sh
# Bananarchy rear camera photo capture utility and Sxmo menu wrapper
# Captures 800x600 24-bit RGB frames from /dev/video0 (msm8905-cam / GC2395)
# via v4l2-ctl and encodes JPEG/PNG images via ffmpeg -f rawvideo.

set -eu

DEV="/dev/video0"
USE_FLASH=0
VIEW_AFTER=0
MENU_MODE=0
OUT_FILE=""

usage() {
  cat <<'EOF'
Usage: bananarchy-photo [options] [output_file]

Options:
  -d, --device <dev>  V4L2 video device (default: /dev/video0)
  -f, --flash         Enable rear flashlight (white:torch) during capture
  -v, --view          Open captured photo in imv after saving
  -m, --menu          Open interactive Sxmo camera menu
  -h, --help          Show this help message

If output_file is omitted, saves to ~/Pictures/photo-YYYYMMDD-HHMMSS.jpg.
EOF
}

while [ $# -gt 0 ]; do
  case "$1" in
    -d|--device)
      DEV="$2"
      shift 2
      ;;
    -f|--flash)
      USE_FLASH=1
      shift
      ;;
    -v|--view)
      VIEW_AFTER=1
      shift
      ;;
    -m|--menu)
      MENU_MODE=1
      shift
      ;;
    -h|--help)
      usage
      exit 0
      ;;
    --)
      shift
      break
      ;;
    -*)
      echo "bananarchy-photo: unknown option: $1" >&2
      usage >&2
      exit 1
      ;;
    *)
      OUT_FILE="$1"
      shift
      ;;
  esac
done

if [ $# -gt 0 ] && [ -z "$OUT_FILE" ]; then
  OUT_FILE="$1"
fi

get_pictures_dir() {
  pic_dir="${XDG_PICTURES_DIR:-$HOME/Pictures}"
  mkdir -p "$pic_dir"
  printf "%s\n" "$pic_dir"
}

notify_msg() {
  if command -v sxmo_notify_user.sh >/dev/null 2>&1 && [ -n "${DISPLAY:-}${WAYLAND_DISPLAY:-}" ]; then
    sxmo_notify_user.sh -t 2000 "$1" >/dev/null 2>&1 || true
  fi
}

take_photo() {
  flash_flag="$1"
  target_path="$2"

  if [ -z "$target_path" ]; then
    pic_dir="$(get_pictures_dir)"
    target_path="$pic_dir/photo-$(date +%Y%m%d-%H%M%S).jpg"
  else
    mkdir -p "$(dirname "$target_path")"
  fi

  if [ ! -e "$DEV" ]; then
    echo "bananarchy-photo: camera device $DEV not found" >&2
    notify_msg "Camera $DEV not found"
    return 1
  fi

  prev_torch=""
  if [ "$flash_flag" -eq 1 ] && [ -w /sys/class/leds/white:torch/brightness ]; then
    prev_torch="$(cat /sys/class/leds/white:torch/brightness 2>/dev/null || echo 0)"
    echo 1 > /sys/class/leds/white:torch/brightness 2>/dev/null || true
    sleep 0.15
  fi

  frame_tmp="/tmp/bananarchy-frame-$$.rgb"
  rc=0

  v4l2-ctl -d "$DEV" \
    --set-fmt-video=width=800,height=600,pixelformat=RGB3 \
    --stream-mmap --stream-count=1 --stream-to="$frame_tmp" >/dev/null 2>&1 || rc=$?

  if [ "$flash_flag" -eq 1 ] && [ -n "$prev_torch" ] && [ -w /sys/class/leds/white:torch/brightness ]; then
    echo "$prev_torch" > /sys/class/leds/white:torch/brightness 2>/dev/null || true
  fi

  if [ "$rc" -ne 0 ] || [ ! -s "$frame_tmp" ]; then
    rm -f "$frame_tmp"
    echo "bananarchy-photo: failed to capture frame from $DEV" >&2
    notify_msg "Photo capture failed"
    return 1
  fi

  if ! ffmpeg -hide_banner -loglevel error \
    -f rawvideo -pixel_format rgb24 -video_size 800x600 \
    -i "$frame_tmp" -frames:v 1 -y "$target_path"; then
    rm -f "$frame_tmp"
    echo "bananarchy-photo: ffmpeg failed to encode $target_path" >&2
    notify_msg "Photo encoding failed"
    return 1
  fi

  rm -f "$frame_tmp"
  printf "%s\n" "$target_path"
  notify_msg "Saved $(basename "$target_path")"

  if [ "$VIEW_AFTER" -eq 1 ] && [ -n "${DISPLAY:-}${WAYLAND_DISPLAY:-}" ]; then
    if command -v feh >/dev/null 2>&1 && [ -n "${DISPLAY:-}" ]; then
      feh --scale-down "$target_path" >/dev/null 2>&1 &
    elif command -v imv >/dev/null 2>&1; then
      imv "$target_path" >/dev/null 2>&1 &
    fi
  fi
  return 0
}

run_menu() {
  if [ -f /usr/share/sxmo/default_hooks/sxmo_hook_icons.sh ]; then
    # shellcheck disable=SC1091
    . /usr/share/sxmo/default_hooks/sxmo_hook_icons.sh
  fi
  ic_cam="${icon_cam:-*}"
  ic_fll="${icon_fll:-*}"
  ic_img="${icon_img:-*}"
  ic_cls="${icon_cls:-x}"

  choice="$(printf "%s\n" \
    "$ic_cam Take photo" \
    "$ic_fll Take photo (flash)" \
    "$ic_img View photos" \
    "$ic_cls Close" | sxmo_dmenu.sh -p "Camera" || true)"

  case "$choice" in
    *"Take photo (flash)"*)
      VIEW_AFTER=1
      take_photo 1 ""
      ;;
    *"Take photo"*)
      VIEW_AFTER=1
      take_photo 0 ""
      ;;
    *"View photos"*)
      pic_dir="$(get_pictures_dir)"
      if ls "$pic_dir"/*.jpg "$pic_dir"/*.png >/dev/null 2>&1; then
        if command -v feh >/dev/null 2>&1 && [ -n "${DISPLAY:-}" ]; then
          feh --scale-down "$pic_dir" >/dev/null 2>&1 &
        else
          imv "$pic_dir" >/dev/null 2>&1 &
        fi
      else
        notify_msg "No photos in $pic_dir"
      fi
      ;;
    *)
      exit 0
      ;;
  esac
}

if [ "$MENU_MODE" -eq 1 ]; then
  if command -v xcamera >/dev/null 2>&1; then
    exec xcamera
  fi
  run_menu
else
  take_photo "$USE_FLASH" "$OUT_FILE"
fi
