// Type-bearing number formats prevent Office applications from rewriting the
// ODF currency/percentage/time/dateTime type as an unformatted float.

///|
fn typed_format_key(value : Value) -> String {
  match value {
    Percentage(_) => "percentage"
    Currency(_, code) => "currency_" + code
    Duration(_) => "duration"
    DateTime(_) => "datetime"
    _ => ""
  }
}

///|
fn typed_number_format(value : Value) -> String {
  let key = typed_format_key(value)
  if key == "" {
    return ""
  }
  let name = "__ods_number_" + key
  match value {
    Percentage(_) =>
      "%"
    Currency(_, code) =>
      "\{code} "
    Duration(_) =>
      "::"
    DateTime(_) =>
      "--T::"
    _ => ""
  }
}

///|
fn Cell::output_style(self : Cell) -> String {
  let key = typed_format_key(self.value)
  if key == "" {
    self.style.id()
  } else {
    "__ods_" + self.style.id() + "_" + key
  }
}

///|
fn Workbook::typed_styles(self : Workbook) -> String raise OdsError {
  let number_defs : Map[String, String] = Map([])
  let cell_defs : Map[String, String] = Map([])
  for sheet in self.sheets {
    for _, cell in sheet.cells {
      let key = typed_format_key(cell.value)
      if key == "" {
        continue
      }
      if !number_defs.contains(key) {
        number_defs.set(key, typed_number_format(cell.value))
      }
      if !cell_defs.contains(cell.output_style()) {
        cell_defs.set(
          cell.output_style(),
          "",
        )
      }
      if number_defs.length() + cell_defs.length() > 1024 {
        raise Invalid("typed number-format definition budget exceeded")
      }
    }
  }
  let names = number_defs.keys().to_array()
  names.sort()
  let cells = cell_defs.keys().to_array()
  cells.sort()
  let out = StringBuilder()
  for name in names {
    out.write_string(number_defs[name])
  }
  for name in cells {
    out.write_string(cell_defs[name])
  }
  out.to_string()
}