-- pg_orrery 0.15.0 -> 0.16.0: twilight, lunar phase, planet magnitude

-- ============================================================
-- Twilight functions (6)
-- ============================================================

CREATE FUNCTION sun_civil_dawn(observer, timestamptz) RETURNS timestamptz
    AS 'MODULE_PATHNAME', 'sun_civil_dawn'
    LANGUAGE C STABLE STRICT PARALLEL SAFE;
COMMENT ON FUNCTION sun_civil_dawn(observer, timestamptz) IS
    'Next civil dawn (Sun crosses -6 deg rising). Outdoor activities without artificial light.';

CREATE FUNCTION sun_civil_dusk(observer, timestamptz) RETURNS timestamptz
    AS 'MODULE_PATHNAME', 'sun_civil_dusk'
    LANGUAGE C STABLE STRICT PARALLEL SAFE;
COMMENT ON FUNCTION sun_civil_dusk(observer, timestamptz) IS
    'Next civil dusk (Sun crosses -6 deg setting). Artificial light needed.';

CREATE FUNCTION sun_nautical_dawn(observer, timestamptz) RETURNS timestamptz
    AS 'MODULE_PATHNAME', 'sun_nautical_dawn'
    LANGUAGE C STABLE STRICT PARALLEL SAFE;
COMMENT ON FUNCTION sun_nautical_dawn(observer, timestamptz) IS
    'Next nautical dawn (Sun crosses -12 deg rising). Horizon visible at sea.';

CREATE FUNCTION sun_nautical_dusk(observer, timestamptz) RETURNS timestamptz
    AS 'MODULE_PATHNAME', 'sun_nautical_dusk'
    LANGUAGE C STABLE STRICT PARALLEL SAFE;
COMMENT ON FUNCTION sun_nautical_dusk(observer, timestamptz) IS
    'Next nautical dusk (Sun crosses -12 deg setting). Horizon no longer visible at sea.';

CREATE FUNCTION sun_astronomical_dawn(observer, timestamptz) RETURNS timestamptz
    AS 'MODULE_PATHNAME', 'sun_astronomical_dawn'
    LANGUAGE C STABLE STRICT PARALLEL SAFE;
COMMENT ON FUNCTION sun_astronomical_dawn(observer, timestamptz) IS
    'Next astronomical dawn (Sun crosses -18 deg rising). Sky was fully dark.';

CREATE FUNCTION sun_astronomical_dusk(observer, timestamptz) RETURNS timestamptz
    AS 'MODULE_PATHNAME', 'sun_astronomical_dusk'
    LANGUAGE C STABLE STRICT PARALLEL SAFE;
COMMENT ON FUNCTION sun_astronomical_dusk(observer, timestamptz) IS
    'Next astronomical dusk (Sun crosses -18 deg setting). Sky becomes fully dark.';

-- ============================================================
-- Lunar phase functions (4)
-- ============================================================

CREATE FUNCTION moon_phase_angle(timestamptz) RETURNS float8
    AS 'MODULE_PATHNAME', 'moon_phase_angle'
    LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
COMMENT ON FUNCTION moon_phase_angle(timestamptz) IS
    'Sun-Earth-Moon phase angle in degrees [0,360). 0=new, 90=first quarter, 180=full, 270=last quarter.';

CREATE FUNCTION moon_illumination(timestamptz) RETURNS float8
    AS 'MODULE_PATHNAME', 'moon_illumination'
    LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
COMMENT ON FUNCTION moon_illumination(timestamptz) IS
    'Illuminated fraction of the Moon disk [0.0, 1.0].';

CREATE FUNCTION moon_phase_name(timestamptz) RETURNS text
    AS 'MODULE_PATHNAME', 'moon_phase_name'
    LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
COMMENT ON FUNCTION moon_phase_name(timestamptz) IS
    'Moon phase name: new_moon, waxing_crescent, first_quarter, waxing_gibbous, full_moon, waning_gibbous, last_quarter, waning_crescent.';

CREATE FUNCTION moon_age(timestamptz) RETURNS float8
    AS 'MODULE_PATHNAME', 'moon_age'
    LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
COMMENT ON FUNCTION moon_age(timestamptz) IS
    'Days since last new moon [0, ~29.53), approximated from phase angle.';

-- ============================================================
-- Planet magnitude (1)
-- ============================================================

CREATE FUNCTION planet_magnitude(int4, timestamptz) RETURNS float8
    AS 'MODULE_PATHNAME', 'planet_magnitude'
    LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
COMMENT ON FUNCTION planet_magnitude(int4, timestamptz) IS
    'Apparent visual magnitude of a planet (Mallama & Hilton 2018). Body IDs 1-8. Saturn ring tilt not modeled.';
