#import "misc.typ": oblue, ored


/// If false, hide instructor info.
/// If true, show it.
///
/// Solutions are shown by default. This behavior
/// is less surprising than hiding content by default.
#let solutions_state = state("solutions_state", true)

/// Force solutions to be hidden after this point.
///
/// This function produces content that must be
/// included in the document. If it is not included,
/// this function will have no effect.
#let hide_solutions() = {
  return solutions_state.update(x => false)
}

/// Force solutions to be shown after this point.
///
/// This function produces content that must be
/// included in the document. If it is not included,
/// this function will have no effect.
#let show_solutions() = {
  return solutions_state.update(x => true)
}



/// Reset the solution flag to its default value.
/// This value is determined by compile flags:
/// Compile with the following command to hide solutions:
/// `typst compile main.typ --input show_solutions=false`
///
/// Solutions are shown by default.
///
/// This function produces content that must be
/// included in the document. If it is not included,
/// this function will have no effect.
#let reset_solutions() = {
  if "show_solutions" in sys.inputs {
    if (
      sys.inputs.show_solutions == "false" or sys.inputs.show_solutions == "no"
    ) {
      return solutions_state.update(x => false)
    }
  }
}

#let if_solutions(content) = context {
  if solutions_state.get() { content }
}

#let if_no_solutions(content) = context {
  if not solutions_state.get() { content }
}

#let if_solutions_else(if_yes, if_no) = context {
  if solutions_state.get() { if_yes } else { if_no }
}

#let solution(content) = {
  if_solutions(align(center, stack(
    block(
      width: 100%,
      breakable: false,
      fill: ored,
      stroke: ored + 2pt,
      inset: 1.5mm,
      align(left, text(fill: white, weight: "bold", [Solution:])),
    ),

    block(
      width: 100%,
      height: auto,
      breakable: false,
      fill: ored.lighten(80%).desaturate(10%),
      stroke: ored + 2pt,
      inset: 3mm,
      align(left, content),
    ),
  )))
}

#let sample_solution(content) = {
  align(center, stack(
    block(
      width: 100%,
      breakable: false,
      fill: oblue,
      stroke: oblue + 2pt,
      inset: 1.5mm,
      align(left, text(fill: white, weight: "bold", [Sample Solution:])),
    ),

    block(
      width: 100%,
      height: auto,
      breakable: false,
      fill: oblue.lighten(80%).desaturate(10%),
      stroke: oblue + 2pt,
      inset: 3mm,
      align(left, content),
    ),
  ))
}


#let instructornote(content) = {
  if_solutions(align(center, stack(
    block(
      width: 100%,
      breakable: false,
      fill: oblue,
      stroke: oblue + 2pt,
      inset: 1.5mm,
      align(left, text(fill: white, weight: "bold", [Instructor note:])),
    ),

    block(
      width: 100%,
      height: auto,
      breakable: false,
      fill: oblue.lighten(80%).desaturate(10%),
      stroke: oblue + 2pt,
      inset: 3mm,
      align(left, content),
    ),
  )))
}
