-- gen_player.lua: generate player sprite sheet (16x24 frames).
-- Layout: 4 cols x 4 rows. Row order: walk-down, walk-up, walk-left, walk-right.
-- Each row 4 frames: frame 0 = idle, 1-3 = walk frames.
-- Produces assets/sprites/player.png
local FW = 16
local FH = 24
local COLS = 4
local ROWS = 4
local W = COLS*FW
local H = ROWS*FH
app.command.NewFile{ width=W, height=H, colorMode=ColorMode.RGB }
local spr = app.activeSprite
local img = app.activeImage
for y=0,H-1 do for x=0,W-1 do img:drawPixel(x,y, app.pixelColor.rgba(0,0,0,0)) end end

local function px(x,y,c) img:drawPixel(x,y,c) end
local function rect(ox,oy,w,h,c) for y=oy,oy+h-1 do for x=ox,ox+w-1 do px(x,y,c) end end end

-- gender-neutral candy palette
local skin   = app.pixelColor.rgba(255,214,176,255)
local skinS  = app.pixelColor.rgba(224,176,140,255)
local hair   = app.pixelColor.rgba(150,110,80,255)  -- chestnut
local hairD  = app.pixelColor.rgba(110,80,56,255)
local shirt  = app.pixelColor.rgba(120,200,230,255) -- sky blue
local shirtD = app.pixelColor.rgba(86,160,200,255)
local pants  = app.pixelColor.rgba(110,90,150,255)  -- muted purple
local pantsD = app.pixelColor.rgba(80,64,116,255)
local shoe   = app.pixelColor.rgba(90,70,60,255)
local eye    = app.pixelColor.rgba(60,40,40,255)
local cheek  = app.pixelColor.rgba(255,170,170,255)
local mouth  = app.pixelColor.rgba(200,110,110,255)

-- draw a character frame at ox,oy facing dir, walk phase p (0=idle, 1-3)
local function frame(ox, oy, dir, p)
  -- common body
  -- head (cols 4..11, rows 1..9)
  rect(ox+5, oy+1, 6, 7, skin)
  -- hair cap depending on direction
  if dir == "up" then
    -- back of head: hair covers
    rect(ox+5, oy+1, 6, 6, hair)
    rect(ox+5, oy+1, 6, 2, hairD)
  else
    rect(ox+4, oy+1, 8, 3, hair)
    rect(ox+5, oy+0, 6, 2, hair)
    rect(ox+4, oy+1, 8, 1, hairD)
  end
  -- face details for down
  if dir == "down" then
    px(ox+6, oy+5, eye); px(ox+9, oy+5, eye)
    px(ox+7, oy+7, mouth); px(ox+8, oy+7, mouth)
    px(ox+6, oy+6, cheek); px(ox+9, oy+6, cheek)
  elseif dir == "side" then
    -- left or right handled by caller mirroring via draw order
    px(ox+7, oy+5, eye)
    px(ox+8, oy+7, mouth)
    px(ox+6, oy+6, cheek)
  end
  -- torso (rows 8..15)
  rect(ox+5, oy+9, 6, 6, shirt)
  rect(ox+5, oy+9, 6, 1, shirtD)
  rect(ox+5, oy+14, 6, 1, shirtD)
  -- arms
  rect(ox+4, oy+10, 1, 4, shirt)
  rect(ox+10, oy+10, 1, 4, shirt)
  px(ox+4, oy+14, skin); px(ox+10, oy+14, skin)
  -- legs / walk animation
  local L, R = oy+15, oy+15
  if p == 0 then
    -- idle: legs together
    rect(ox+5, oy+15, 2, 6, pants)
    rect(ox+9, oy+15, 2, 6, pants)
    px(ox+5, oy+21, shoe); px(ox+6, oy+21, shoe)
    px(ox+9, oy+21, shoe); px(ox+10, oy+21, shoe)
  elseif p == 1 then
    -- step: left leg forward (down/up), or side-step
    rect(ox+5, oy+15, 2, 5, pants)
    rect(ox+9, oy+15, 2, 5, pants)
    px(ox+5, oy+20, shoe); px(ox+6, oy+20, shoe)
    px(ox+9, oy+21, shoe); px(ox+10, oy+21, shoe)
  elseif p == 2 then
    -- mid
    rect(ox+5, oy+15, 2, 6, pants)
    rect(ox+9, oy+15, 2, 6, pants)
    px(ox+5, oy+21, shoe); px(ox+6, oy+21, shoe)
    px(ox+9, oy+21, shoe); px(ox+10, oy+21, shoe)
  elseif p == 3 then
    -- step: right leg forward
    rect(ox+5, oy+15, 2, 5, pants)
    rect(ox+9, oy+15, 2, 5, pants)
    px(ox+5, oy+21, shoe); px(ox+6, oy+21, shoe)
    px(ox+9, oy+20, shoe); px(ox+10, oy+20, shoe)
  end
end

-- mirror helper for left/right by copying pixels
local function mirrorRow(srcRow, dstRow)
  for f=0,3 do
    local sx = f*FW
    local dx = f*FW
    local sy = srcRow*FH
    local dy = dstRow*FH
    for y=0,FH-1 do
      for x=0,FW-1 do
        local c = img:getPixel(sx + (FW-1-x), sy + y)
        img:drawPixel(dx + x, dy + y, c)
      end
    end
  end
end

-- Row 0: walk-down
for f=0,3 do frame(f*FW, 0*FH, "down", f) end
-- Row 1: walk-up
for f=0,3 do frame(f*FW, 1*FH, "up", f) end
-- Row 2: walk-right (side)
for f=0,3 do frame(f*FW, 2*FH, "side", f) end
-- Row 3: walk-left = mirror of right
mirrorRow(2, 3)

local out = "assets/sprites/player.png"
spr:saveCopyAs(out)
print("Saved " .. out)
app.exit()
