-- pg_orrery 0.17.0 -> 0.18.0: Saturn ring tilt, penumbral eclipse,
-- rise/set event windows, angular separation rate

-- ============================================================
-- Saturn ring tilt (1)
-- ============================================================

CREATE FUNCTION saturn_ring_tilt(timestamptz) RETURNS float8
    AS 'MODULE_PATHNAME', 'saturn_ring_tilt'
    LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
COMMENT ON FUNCTION saturn_ring_tilt(timestamptz) IS
    'Sub-observer latitude B'' of Earth relative to Saturn ring plane (degrees, [-27, +27]). Uses IAU 2000 pole direction.';

-- ============================================================
-- Penumbral eclipse prediction (4)
-- ============================================================

CREATE FUNCTION satellite_in_penumbra(tle, timestamptz) RETURNS bool
    AS 'MODULE_PATHNAME', 'satellite_in_penumbra'
    LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
COMMENT ON FUNCTION satellite_in_penumbra(tle, timestamptz) IS
    'True if the satellite is in Earth penumbral shadow (partial sunlight) at the given time.';

CREATE FUNCTION satellite_shadow_state(tle, timestamptz) RETURNS text
    AS 'MODULE_PATHNAME', 'satellite_shadow_state'
    LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
COMMENT ON FUNCTION satellite_shadow_state(tle, timestamptz) IS
    'Shadow state of satellite: ''sunlit'', ''penumbra'', or ''umbra''. Uses conical shadow model.';

CREATE FUNCTION satellite_next_penumbra_entry(tle, timestamptz) RETURNS timestamptz
    AS 'MODULE_PATHNAME', 'satellite_next_penumbra_entry'
    LANGUAGE C STABLE STRICT PARALLEL SAFE;
COMMENT ON FUNCTION satellite_next_penumbra_entry(tle, timestamptz) IS
    'Next time the satellite enters Earth penumbral shadow (up to 7-day search). NULL if none found.';

CREATE FUNCTION satellite_next_penumbra_exit(tle, timestamptz) RETURNS timestamptz
    AS 'MODULE_PATHNAME', 'satellite_next_penumbra_exit'
    LANGUAGE C STABLE STRICT PARALLEL SAFE;
COMMENT ON FUNCTION satellite_next_penumbra_exit(tle, timestamptz) IS
    'Next time the satellite exits Earth penumbral shadow (up to 7-day search). NULL if none found.';

-- ============================================================
-- Rise/set event windows (3 SRFs)
-- ============================================================

CREATE FUNCTION planet_rise_set_events(
    body_id int4, observer, start timestamptz, stop timestamptz,
    refracted bool DEFAULT false
) RETURNS TABLE(event_time timestamptz, event_type text)
    AS 'MODULE_PATHNAME', 'planet_rise_set_events'
    LANGUAGE C STABLE STRICT PARALLEL SAFE
    ROWS 10;
COMMENT ON FUNCTION planet_rise_set_events(int4, observer, timestamptz, timestamptz, bool) IS
    'All rise and set events for a planet within a time window. Returns TABLE(event_time, event_type). Max 366-day window.';

CREATE FUNCTION sun_rise_set_events(
    observer, start timestamptz, stop timestamptz,
    refracted bool DEFAULT false
) RETURNS TABLE(event_time timestamptz, event_type text)
    AS 'MODULE_PATHNAME', 'sun_rise_set_events'
    LANGUAGE C STABLE STRICT PARALLEL SAFE
    ROWS 10;
COMMENT ON FUNCTION sun_rise_set_events(observer, timestamptz, timestamptz, bool) IS
    'All rise and set events for the Sun within a time window. Returns TABLE(event_time, event_type). Max 366-day window.';

CREATE FUNCTION moon_rise_set_events(
    observer, start timestamptz, stop timestamptz,
    refracted bool DEFAULT false
) RETURNS TABLE(event_time timestamptz, event_type text)
    AS 'MODULE_PATHNAME', 'moon_rise_set_events'
    LANGUAGE C STABLE STRICT PARALLEL SAFE
    ROWS 10;
COMMENT ON FUNCTION moon_rise_set_events(observer, timestamptz, timestamptz, bool) IS
    'All rise and set events for the Moon within a time window. Returns TABLE(event_time, event_type). Max 366-day window.';

-- ============================================================
-- Angular separation rate (2)
-- ============================================================

CREATE FUNCTION eq_angular_rate(
    equatorial, equatorial, equatorial, equatorial, float8
) RETURNS float8
    AS 'MODULE_PATHNAME', 'eq_angular_rate'
    LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
COMMENT ON FUNCTION eq_angular_rate(equatorial, equatorial, equatorial, equatorial, float8) IS
    'Rate of change of angular separation (deg/hr). Args: pos1_t0, pos2_t0, pos1_t1, pos2_t1, dt_seconds. Positive = separating, negative = approaching.';

CREATE FUNCTION planet_angular_rate(int4, int4, timestamptz) RETURNS float8
    AS 'MODULE_PATHNAME', 'planet_angular_rate'
    LANGUAGE C IMMUTABLE STRICT PARALLEL SAFE;
COMMENT ON FUNCTION planet_angular_rate(int4, int4, timestamptz) IS
    'Rate of angular separation change between two bodies (deg/hr). Body IDs: 0=Sun, 1-8=planets, 10=Moon. Uses 1-minute finite difference.';
