// SunCalc 2.0.1 / Meeus ch.48. BSD-2-Clause.

///|
pub(all) struct Illumination {
  fraction : Double
  phase : Double
  angle : Double
  waxing : Bool
} derive(Eq, Debug)

///|
/// Deterministic: an explicit instant is required, never the host's current date.
/// Fraction measures lit area; phase runs new=0, first quarter=.25, full=.5.
pub fn moon_illumination(date : Instant) -> Illumination {
  let d = to_tt(to_days(date))
  let s = sun_coords(d)
  let m = moon_coords(d)
  let sdist = 149598000.0
  let phi = @math.acos(
    @math.sin(s.dec) * @math.sin(m.dec) +
    @math.cos(s.dec) * @math.cos(m.dec) * @math.cos(s.ra - m.ra),
  )
  let inc = @math.atan2(sdist * @math.sin(phi), m.dist - sdist * @math.cos(phi))
  let angle = @math.atan2(
    @math.cos(s.dec) * @math.sin(s.ra - m.ra),
    @math.sin(s.dec) * @math.cos(m.dec) -
    @math.cos(s.dec) * @math.sin(m.dec) * @math.cos(s.ra - m.ra),
  )
  let waxing = angle < 0.0
  {
    fraction: (1.0 + @math.cos(inc)) / 2.0,
    phase: 0.5 + 0.5 * inc * (if waxing { -1.0 } else { 1.0 }) / @math.PI,
    angle: angle / Rad,
    waxing,
  }
}