#import "/src/cetz.typ": draw

#import "/src/core/utils.typ": normalize-measure, normalize-units

#let name = "collections"

#let normalize-offset(offset) = {
  let dx = 0pt
  let dy = 0pt
  if type(offset) == array {
    if offset.len() >= 2 {
      dx = offset.at(0)
      dy = offset.at(1)
    }
  } else if type(offset) == dictionary {
    dx = offset.at("dx", default: dx)
    dy = offset.at("dx", default: dy)
  } else {
    dx = offset
    dy = offset
  }
  return (
    x: normalize-units(dx),
    y: normalize-units(dy)
  )
}

#let render(x, y, p, bottom) = {
  let style = p.resolved-style
  let name = box(
    p.display-name,
    inset: style.inset,
    fill: style.fill,
    stroke: style.stroke
  )
  let m = normalize-measure(name)
  let offset = normalize-offset(style.offset)

  let w = m.width
  let h = m.height
  let dx = offset.x
  let dy = offset.y
  let total-w = w + calc.abs(dx)
  let total-h = h + calc.abs(dy)

  let x0 = x - total-w / 2
  let x1 = x0 + calc.abs(dx)
  let x3 = x0 + total-w
  let x2 = x3 - calc.abs(dx)
  
  let y0 = if bottom {y} else {y + total-h}
  let y1 = y0 - calc.abs(dy)
  let y3 = y0 - total-h
  let y2 = y3 + calc.abs(dy)

  let r1 = (x1, y0, x3, y2)
  let r2 = (x0, y1, x2, y3)

  if dx < 0 {
    r1.at(0) = x0
    r1.at(2) = x2
    r2.at(0) = x1
    r2.at(2) = x3
  }

  if dy < 0 {
    r1.at(1) = y1
    r1.at(3) = y3
    r2.at(1) = y0
    r2.at(3) = y2
  }
  draw.rect(
    (r1.at(0), r1.at(1)),
    (r1.at(2), r1.at(3)),
    fill: style.fill,
    stroke: style.stroke
  )
  
  draw.content(
    (
      (r2.at(0) + r2.at(2)) / 2,
      (r2.at(1) + r2.at(3)) / 2
    ),
    name,
    anchor: "mid"
  )
}

#let get-size(par) = {
  let m = normalize-measure(box(
    par.display-name,
    inset: par.resolved-style.inset
  ))
  
  let offset = normalize-offset(par.resolved-style.offset)
  let dx = offset.x
  let dy = offset.y

  return (
    width: m.width + calc.abs(dx),
    height: m.height + calc.abs(dy)
  )
}

#let default-style = (
  inset: (x: 3pt, y: 5pt),
  offset: (3pt, 3pt)
)