#import "constants.typ": *
#import "helpers.typ": *
#import "state.typ": __get, __set

// Main resume function
#let resume(
  name: "<NAME>",
  tagline: none,
  paper: "us-letter",
  heading-font: HEADING_FONT,
  body-font: BODY_FONT,
  body-size: BODY_SIZE,
  email: none,
  phone: none,
  linkedin-username: none,
  keywords: "",
  thumbnail: none, // check out https://qrframe.kylezhe.ng/ for QR code generation
  body
) = {
  // Document setup, mostly metadata in a PDF
  set document(
    title: "Résumé/CV of " + name,
    author: name,
    keywords: keywords,
  )

  // Page setup, including header and footer
  set page(
    paper: paper,
    margin: PAGE_MARGIN,
    numbering: "1 / 1",
    header: context {
      if here().page() == 1 {
        text(
          size: HEADER_SIZE,
          grid(
            columns: (1fr, auto, auto, auto, auto, auto),
            gutter: 1em,
            align: center+horizon,
            "",
            icon_and_contact("icons/email.svg", link("mailto:" + email, email)),
            sym.divides,
            icon_and_contact("icons/phone.svg", link("tel:" + phone, phone)),
            sym.divides,
            icon_and_contact("icons/linkedin.svg", link("https://www.linkedin.com/in/" + linkedin-username, linkedin-username))
          )
        )
      }
    },
    footer: context {
      let multi_page = counter(page).final().first() > 1
      let date = datetime.today().display("[month repr:long] [day], [year]")
      text(size: FOOTER_SIZE, weight: FOOTER_TEXT_WEIGHT, font: heading-font)[
        #grid(
          columns: (1fr, 1fr, 1fr),
          align: (left, center, right + horizon),
          // left column
          [Last updated: #date],
          // center column
          if multi_page { counter(page).display(both: true, "1 of 1") },
          // right column
          if thumbnail != none {
            move(dy: -0.25in, box(height: 0.5in, thumbnail))
          } else {
            [ ]
          }
        )
      ]
    },
  )

  // Global text settings
  set text(font: body-font, size: body-size, weight: BODY_WEIGHT, fallback: true)
  set par(justify: true)

  // Heading styles
  set heading(numbering: "I.A.")
  show heading.where(level: 1): it => {
    block(
      above: SECTION_HEADING_SPACE_ABOVE,
      below: SECTION_HEADING_SPACE_BELOW,
      breakable: false,
      [
        #text(size: SECTION_HEADING_SIZE, weight: SECTION_HEADING_WEIGHT, font: heading-font)[
          #context counter(heading).display()
          #upper(it.body)
        ]
        #hrule(stroke: SECTION_HEADING_HRULE_STROKE)
      ]
    )
  }

  // Table style
  set table(
    stroke: none,
    fill: (x, y) => {
      if y == 0 {
        TABLE_HEADER_COLOR
      } else if calc.rem(y, 2) == 0 {
        TABLE_ZEBRA_COLOR_0
      } else {
        TABLE_ZEBRA_COLOR_1
      }
    },
  )

  // Save our settings needed in other functions
  __set("heading-font", heading-font)

  // Main Headline
  text(size: HEADLINE_NAME_SIZE, weight: HEADLINE_NAME_WEIGHT, font: heading-font)[#smallcaps(name)]
  h(1fr)
  text(size: TAGLINE_SIZE, style: TAGLINE_STYLE, weight: TAGLINE_WEIGHT)[#tagline]
  hrule(stroke: HEADLINE_HRULE_STROKE)

  // The rest of the content
  body
}

// Alias resume to cv for non-Americans
#let cv = resume

#let company-heading(name, start: none, end: none, icon: none, body) = {
  let icon_spacing = if icon != none { COMPANY_ICON_SPACING } else { 0em }
  block(
    below: COMPANY_BLOCK_BELOW,
    breakable: false,

    grid(
      columns: (auto, auto, 1fr, auto),
      column-gutter: (icon_spacing, 0.5em),
      row-gutter: 0.5em,
      align: (left + horizon, left + horizon, right + horizon),

      // first column, optional icon
      if icon != none { box(height: COMPANY_ICON_SIZE, icon) },

      // second column, company name
      context text(
        weight: COMPANY_NAME_WEIGHT,
        size: COMPANY_NAME_SIZE,
        font: __get("heading-font"),
        name
      ),

      // third column, dots
      if start != none {
        repeat(h(0.3em) + "." + h(0.3em))
      } else {
        []
      },

      // fourth column, optional dates
      context text(
        weight: COMPANY_DATE_WEIGHT,
        size: COMPANY_DATE_SIZE,
        font: __get("heading-font"),

        if start != none {
          [#start -- #end]
        } else {
          [ ]
        }
      ),

      // second row, company content
      grid.cell(colspan: 4, body)
    )
  )
}

// Alias to school heading
#let school-heading = company-heading

#let job-heading(title, location: none, start: none, end: none, comment: none, body) = {
  block(
    above: JOB_BLOCK_ABOVE,
    below: JOB_BLOCK_BELOW,
    breakable: false,

    // heading
    grid(
      columns: (auto, auto, auto, 1fr, auto),
      gutter: 0.5em,
      align: (left + horizon, right + horizon),

      // first column, title
      context text(
        style: JOB_NAME_STYLE,
        weight: JOB_NAME_WEIGHT,
        size: JOB_NAME_SIZE,
        font: __get("heading-font"),
        title
      ),

      // second column, job comment ellipsis
      if comment != none { [ ... ] },

      // third column, job comment ellipsis
      if comment != none { [ #comment ] },

      // fourth column, hfill
      h(1fr),

      // fifth column, optional location
      context text(
        style: JOB_LOCATION_STYLE,
        weight: JOB_LOCATION_WEIGHT,
        size: JOB_LOCATION_SIZE,
        font: __get("heading-font"),

        if location != none and start != none {
          [#location#[;] #h(0.25em)#start#if end != none [ -- #end]]
        } else if location != none {
          location
        } else if start != none {
          [#start#if end != none [ -- #end]]
        }
      ),

      grid.cell(colspan: 5, body)
    )
  )
}

// Alias to degree heading
#let degree-heading = job-heading

