

unit astronomy;
{$ifdef windows}

                   {$ifdef CPU64}

//linkare le dipende di mingw installate nel vostro pc
{$link astronomywin64.o} //il file astronomy.c compilato

                   {$endif}

                   {$ifdef CPU32}

//linkare le dipende di mingw installate nel vostro pc
                          {$link win32astronomy.o}  //il file astronomy.c compilato

                   {$endif}

{$endif}

{$ifdef linux}
   {$link astronomy_linux.o}  //il file astronomy.c compilato


    {$linklib libc}
    {$linklib libm}
{$endif}

{$ifdef darwin}

{$link astronomydarwin64.o}  //il file astronomy.c compilato


{$linklib libc}
{$linklib libm}
{$endif}


interface

  uses
  DateUtils, SysUtils;



  { Pointers to basic pascal types}
  Type
    PLongint  = ^Longint;
    PSmallInt = ^SmallInt;
    PByte     = ^Byte;
    PWord     = ^Word;
    PDWord    = ^DWord;
    PDouble   = ^Double;



  const
    C_AUDAY = 173.1446326846693;    

    KM_PER_AU = 1.4959787069098932e+8;    

    AU_PER_LY = 63241.07708807546;    

    DEG2RAD = 0.017453292519943296;    

    HOUR2RAD = 0.2617993877991494365;    

    RAD2DEG = 57.295779513082321;    

    RAD2HOUR = 3.819718634205488;    

    SUN_RADIUS_KM = 695700.0;    

    MERCURY_EQUATORIAL_RADIUS_KM = 2440.5;    

    MERCURY_POLAR_RADIUS_KM = 2438.3;    

    VENUS_RADIUS_KM = 6051.8;    

    EARTH_EQUATORIAL_RADIUS_KM = 6378.1366;    

    EARTH_FLATTENING = 0.996647180302104;

      MOON_EQUATORIAL_RADIUS_KM = 1738.1;      

      MOON_POLAR_RADIUS_KM = 1736.0;      

      MARS_EQUATORIAL_RADIUS_KM = 3396.2;      

      MARS_POLAR_RADIUS_KM = 3376.2;      


      JUPITER_EQUATORIAL_RADIUS_KM = 71492.0;      

      JUPITER_POLAR_RADIUS_KM = 66854.0;      

      JUPITER_MEAN_RADIUS_KM = 69911.0;      


      IO_RADIUS_KM = 1821.6;      

      EUROPA_RADIUS_KM = 1560.8;      

      GANYMEDE_RADIUS_KM = 2631.2;      

      CALLISTO_RADIUS_KM = 2410.3;      

      SATURN_EQUATORIAL_RADIUS_KM = 60268.0;      

      SATURN_POLAR_RADIUS_KM = 54364.0;      

      URANUS_EQUATORIAL_RADIUS_KM = 25559.0;      

      URANUS_POLAR_RADIUS_KM = 24973.0;      

      NEPTUNE_EQUATORIAL_RADIUS_KM = 24764.0;      

      NEPTUNE_POLAR_RADIUS_KM = 24341.0;      

      PLUTO_RADIUS_KM = 1188.3;




    type
      Pastro_status_t = ^astro_status_t;
      astro_status_t =  Longint;
      Const
        ASTRO_SUCCESS = 0;
        ASTRO_NOT_INITIALIZED = 1;
        ASTRO_INVALID_BODY = 2;
        ASTRO_NO_CONVERGE = 3;
        ASTRO_BAD_TIME = 4;
        ASTRO_BAD_VECTOR = 5;
        ASTRO_SEARCH_FAILURE = 6;
        ASTRO_EARTH_NOT_ALLOWED = 7;
        ASTRO_NO_MOON_QUARTER = 8;
        ASTRO_WRONG_MOON_QUARTER = 9;
        ASTRO_INTERNAL_ERROR = 10;
        ASTRO_INVALID_PARAMETER = 11;
        ASTRO_FAIL_APSIS = 12;
        ASTRO_BUFFER_TOO_SMALL = 13;
        ASTRO_OUT_OF_MEMORY = 14;
        ASTRO_INCONSISTENT_TIMES = 15;

    type
      Pastro_time_t = ^astro_time_t;
      astro_time_t = record
          ut : double;
          tt : double;
          psi : double;
          eps : double;
          st : double;
        end;

      Pastro_utc_t = ^astro_utc_t;
      astro_utc_t = record
          year : longint;
          month : longint;
          day : longint;
          hour : longint;
          minute : longint;
          second : double;
        end;


      Pastro_vector_t = ^astro_vector_t;
      astro_vector_t = record
          status : astro_status_t;
          x : double;
          y : double;
          z : double;
          t : astro_time_t;
        end;


      Pastro_state_vector_t = ^astro_state_vector_t;
      astro_state_vector_t = record
          status : astro_status_t;
          x : double;
          y : double;
          z : double;
          vx : double;
          vy : double;
          vz : double;
          t : astro_time_t;
        end;






      Pastro_spherical_t = ^astro_spherical_t;
      astro_spherical_t = record
          status : astro_status_t;
          lat : double;
          lon : double;
          dist : double;
        end;




      Pastro_angle_result_t = ^astro_angle_result_t;
      astro_angle_result_t = record
          status : astro_status_t;
          angle : double;
        end;


      Pastro_body_t = ^astro_body_t;
      astro_body_t =  Longint;
      Const
        BODY_INVALID = -(1);
        BODY_MERCURY = (-(1))+1;
        BODY_VENUS = (-(1))+2;
        BODY_EARTH = (-(1))+3;
        BODY_MARS = (-(1))+4;
        BODY_JUPITER = (-(1))+5;
        BODY_SATURN = (-(1))+6;
        BODY_URANUS = (-(1))+7;
        BODY_NEPTUNE = (-(1))+8;
        BODY_PLUTO = (-(1))+9;
        BODY_SUN = (-(1))+10;
        BODY_MOON = (-(1))+11;
        BODY_EMB = (-(1))+12;
        BODY_SSB = (-(1))+13;
        BODY_STAR1 = 101;
        BODY_STAR2 = 102;
        BODY_STAR3 = 103;
        BODY_STAR4 = 104;
        BODY_STAR5 = 105;
        BODY_STAR6 = 106;
        BODY_STAR7 = 107;
        BODY_STAR8 = 108;



    type
      Pastro_observer_t = ^astro_observer_t;
      astro_observer_t = record
          latitude : double;
          longitude : double;
          height : double;
        end;




      Pastro_equatorial_t = ^astro_equatorial_t;
      astro_equatorial_t = record
          status : astro_status_t;
          ra : double;
          dec : double;
          dist : double;
          vec : astro_vector_t;
        end;


      Pastro_ecliptic_t = ^astro_ecliptic_t;
      astro_ecliptic_t = record
          status : astro_status_t;
          vec : astro_vector_t;
          elat : double;
          elon : double;
        end;

      Pastro_horizon_t = ^astro_horizon_t;
      astro_horizon_t = record
          azimuth : double;
          altitude : double;
          ra : double;
          dec : double;
        end;


      Pastro_rotation_t = ^astro_rotation_t;
      astro_rotation_t = record
          status : astro_status_t;
          rot : array[0..2] of array[0..2] of double;
        end;


      Pastro_refraction_t = ^astro_refraction_t;
      astro_refraction_t =  Longint;
      Const
        REFRACTION_NONE = 0;
        REFRACTION_NORMAL = 1;
        REFRACTION_JPLHOR = 2;

    type
      Pastro_atmosphere_t = ^astro_atmosphere_t;
      astro_atmosphere_t = record
          status : astro_status_t;
          pressure : double;
          temperature : double;
          density : double;
        end;




      Pastro_search_result_t = ^astro_search_result_t;
      astro_search_result_t = record
          status : astro_status_t;
          time : astro_time_t;
        end;







      Pastro_seasons_t = ^astro_seasons_t;
      astro_seasons_t = record
          status : astro_status_t;
          mar_equinox : astro_time_t;
          jun_solstice : astro_time_t;
          sep_equinox : astro_time_t;
          dec_solstice : astro_time_t;
        end;





      Pastro_moon_quarter_t = ^astro_moon_quarter_t;
      astro_moon_quarter_t = record
          status : astro_status_t;
          quarter : longint;
          time : astro_time_t;
        end;




      Pastro_func_result_t = ^astro_func_result_t;
      astro_func_result_t = record
          status : astro_status_t;
          value : double;
        end;


      astro_search_func_t = function (context:pointer; time:astro_time_t):astro_func_result_t;cdecl;


      astro_deltat_func = function (ut:double):double;cdecl;

    function Astronomy_DeltaT_EspenakMeeus(ut:double):double;cdecl;external;

    function Astronomy_DeltaT_JplHorizons(ut:double):double;cdecl;external;

    procedure Astronomy_SetDeltaTFunction(func:astro_deltat_func);cdecl;external;





    type
      Pastro_visibility_t = ^astro_visibility_t;
      astro_visibility_t =  Longint;
      Const
        VISIBLE_MORNING = 0;
        VISIBLE_EVENING = 1;



    type
      Pastro_elongation_t = ^astro_elongation_t;
      astro_elongation_t = record
          status : astro_status_t;
          time : astro_time_t;
          visibility : astro_visibility_t;
          elongation : double;
          ecliptic_separation : double;
        end;

      Pastro_hour_angle_t = ^astro_hour_angle_t;
      astro_hour_angle_t = record
          status : astro_status_t;
          time : astro_time_t;
          hor : astro_horizon_t;
        end;



      Pastro_illum_t = ^astro_illum_t;
      astro_illum_t = record
          status : astro_status_t;
          time : astro_time_t;
          mag : double;
          phase_angle : double;
          phase_fraction : double;
          helio_dist : double;
          ring_tilt : double;
        end;





      Pastro_apsis_kind_t = ^astro_apsis_kind_t;
      astro_apsis_kind_t =  Longint;
      Const
        APSIS_PERICENTER = 0;
        APSIS_APOCENTER = 1;
        APSIS_INVALID = 2;








    type
      Pastro_apsis_t = ^astro_apsis_t;
      astro_apsis_t = record
          status : astro_status_t;
          time : astro_time_t;
          kind : astro_apsis_kind_t;
          dist_au : double;
          dist_km : double;
        end;







      Pastro_eclipse_kind_t = ^astro_eclipse_kind_t;
      astro_eclipse_kind_t =  Longint;
      Const
        ECLIPSE_NONE = 0;
        ECLIPSE_PENUMBRAL = 1;
        ECLIPSE_PARTIAL = 2;
        ECLIPSE_ANNULAR = 3;
        ECLIPSE_TOTAL = 4;





    type
      Pastro_lunar_eclipse_t = ^astro_lunar_eclipse_t;
      astro_lunar_eclipse_t = record
          status : astro_status_t;
          kind : astro_eclipse_kind_t;
          obscuration : double;
          peak : astro_time_t;
          sd_penum : double;
          sd_partial : double;
          sd_total : double;
        end;



      Pastro_global_solar_eclipse_t = ^astro_global_solar_eclipse_t;
      astro_global_solar_eclipse_t = record
          status : astro_status_t;
          kind : astro_eclipse_kind_t;
          obscuration : double;
          peak : astro_time_t;
          distance : double;
          latitude : double;
          longitude : double;
        end;




      Pastro_eclipse_event_t = ^astro_eclipse_event_t;
      astro_eclipse_event_t = record
          time : astro_time_t;
          altitude : double;
        end;


      Pastro_local_solar_eclipse_t = ^astro_local_solar_eclipse_t;
      astro_local_solar_eclipse_t = record
          status : astro_status_t;
          kind : astro_eclipse_kind_t;
          obscuration : double;
          partial_begin : astro_eclipse_event_t;
          total_begin : astro_eclipse_event_t;
          peak : astro_eclipse_event_t;
          total_end : astro_eclipse_event_t;
          partial_end : astro_eclipse_event_t;
        end;







      Pastro_transit_t = ^astro_transit_t;
      astro_transit_t = record
          status : astro_status_t;
          start : astro_time_t;
          peak : astro_time_t;
          finish : astro_time_t;
          separation : double;
        end;




      Pastro_aberration_t = ^astro_aberration_t;
      astro_aberration_t =  Longint;
      Const
        ABERRATION = 0;
        NO_ABERRATION = 1;





    type
      Pastro_equator_date_t = ^astro_equator_date_t;
      astro_equator_date_t =  Longint;
      Const
        EQUATOR_J2000 = 0;
        EQUATOR_OF_DATE = 1;





    type
      Pastro_direction_t = ^astro_direction_t;
      astro_direction_t =  Longint;
      Const
        DIRECTION_RISE = +(1);
        DIRECTION_SET = -(1);



(* Const before type ignored *)

(* Const before type ignored *)




    type
      Pastro_constellation_t = ^astro_constellation_t;
      astro_constellation_t = record
          status : astro_status_t;
          symbol : Pchar;
          name : Pchar;
          ra_1875 : double;
          dec_1875 : double;
        end;






      Pastro_time_format_t = ^astro_time_format_t;
      astro_time_format_t =  Longint;
      Const
        TIME_FORMAT_DAY = 0;
        TIME_FORMAT_MINUTE = 1;
        TIME_FORMAT_SECOND = 2;
        TIME_FORMAT_MILLI = 3;









    type
      Pastro_libration_t = ^astro_libration_t;
      astro_libration_t = record
          elat : double;
          elon : double;
          mlat : double;
          mlon : double;
          dist_km : double;
          diam_deg : double;
        end;







      Pastro_axis_t = ^astro_axis_t;
      astro_axis_t = record
          status : astro_status_t;
          ra : double;
          dec : double;
          spin : double;
          north : astro_vector_t;
        end;


    const
      TIME_TEXT_BYTES = 28;      






    type
      Pastro_jupiter_moons_t = ^astro_jupiter_moons_t;
      astro_jupiter_moons_t = record
          io : astro_state_vector_t;
          europa : astro_state_vector_t;
          ganymede : astro_state_vector_t;
          callisto : astro_state_vector_t;
        end;





      Pastro_node_kind_t = ^astro_node_kind_t;
      astro_node_kind_t =  Longint;
      Const
        INVALID_NODE = 0;
        ASCENDING_NODE = +(1);
        DESCENDING_NODE = -(1);






    type
      Pastro_node_event_t = ^astro_node_event_t;
      astro_node_event_t = record
          status : astro_status_t;
          time : astro_time_t;
          kind : astro_node_kind_t;
        end;
     {

      astro_grav_sim_s = astro_grav_sim_t;
      }


    procedure Astronomy_Reset;cdecl;external;

    function Astronomy_VectorLength(vector:astro_vector_t):double;cdecl;external;

    function Astronomy_AngleBetween(a:astro_vector_t; b:astro_vector_t):astro_angle_result_t;cdecl;external;

    function Astronomy_BodyName(body:astro_body_t):Pchar;cdecl;external;

    function Astronomy_BodyCode(name:Pchar):astro_body_t;cdecl;external;

    function Astronomy_MakeObserver(latitude:double; longitude:double; height:double):astro_observer_t;cdecl;external;



    function Astronomy_CurrentTime:astro_time_t;cdecl;external;

    function Astronomy_MakeTime(year:longint; month:longint; day:longint; hour:longint; minute:longint; second:double):astro_time_t;cdecl;external;

    function Astronomy_TimeFromUtc(utc:astro_utc_t):astro_time_t;cdecl;external;

    function Astronomy_UtcFromTime(time:astro_time_t):astro_utc_t;cdecl;external ;


    function Astronomy_TimeFromDays(ut:double):astro_time_t;cdecl;external ;

    function Astronomy_TerrestrialTime(tt:double):astro_time_t;cdecl;external ;

    function Astronomy_AddDays(time:astro_time_t; days:double):astro_time_t;cdecl;external;

    function Astronomy_SiderealTime(var time:astro_time_t):double;cdecl;external;

    function Astronomy_HelioDistance(body:astro_body_t; time:astro_time_t):astro_func_result_t;cdecl;external;

    function Astronomy_HelioVector(body:astro_body_t; time:astro_time_t):astro_vector_t;cdecl;external;

    function Astronomy_GeoVector(body:astro_body_t; time:astro_time_t; aberration:astro_aberration_t):astro_vector_t;cdecl;external ;

    function Astronomy_GeoMoon(time:astro_time_t):astro_vector_t;cdecl;external;

    function Astronomy_EclipticGeoMoon(time:astro_time_t):astro_spherical_t;cdecl;external;

    function Astronomy_GeoMoonState(time:astro_time_t):astro_state_vector_t;cdecl;external;

    function Astronomy_GeoEmbState(time:astro_time_t):astro_state_vector_t;cdecl;external;

    function Astronomy_Libration(time:astro_time_t):astro_libration_t;cdecl;external;

    function Astronomy_BaryState(body:astro_body_t; time:astro_time_t):astro_state_vector_t;cdecl;external;

    function Astronomy_HelioState(body:astro_body_t; time:astro_time_t):astro_state_vector_t;cdecl;external;

    function Astronomy_MassProduct(body:astro_body_t):double;cdecl;external;

    function Astronomy_PlanetOrbitalPeriod(body:astro_body_t):double;cdecl;external;

    function Astronomy_LagrangePoint(point:longint; time:astro_time_t; major_body:astro_body_t; minor_body:astro_body_t):astro_state_vector_t;cdecl;external;

    function Astronomy_LagrangePointFast(point:longint; major_state:astro_state_vector_t; major_mass:double; minor_state:astro_state_vector_t; minor_mass:double):astro_state_vector_t;cdecl;external ;

    function Astronomy_JupiterMoons(time:astro_time_t):astro_jupiter_moons_t;cdecl;external;

    function Astronomy_Equator(body:astro_body_t; var time:astro_time_t; observer:astro_observer_t; equdate:astro_equator_date_t; aberration:astro_aberration_t):astro_equatorial_t;cdecl;external;

    function Astronomy_ObserverVector(var time:astro_time_t; observer:astro_observer_t; equdate:astro_equator_date_t):astro_vector_t;cdecl;external;

    function Astronomy_ObserverState(var time:astro_time_t; observer:astro_observer_t; equdate:astro_equator_date_t):astro_state_vector_t;cdecl;external;

    function Astronomy_VectorObserver(var vector:astro_vector_t; equdate:astro_equator_date_t):astro_observer_t;cdecl;external;

    function Astronomy_ObserverGravity(latitude:double; height:double):double;cdecl;external;

    function Astronomy_SunPosition(time:astro_time_t):astro_ecliptic_t;cdecl;external;

    function Astronomy_Ecliptic(eqj:astro_vector_t):astro_ecliptic_t;cdecl;external;

    function Astronomy_EclipticLongitude(body:astro_body_t; time:astro_time_t):astro_angle_result_t;cdecl;external;

    function Astronomy_Horizon(var time:astro_time_t; observer:astro_observer_t; ra:double; dec:double; refraction:astro_refraction_t):astro_horizon_t;cdecl;external;

    function Astronomy_AngleFromSun(body:astro_body_t; time:astro_time_t):astro_angle_result_t;cdecl;external;

    function Astronomy_Elongation(body:astro_body_t; time:astro_time_t):astro_elongation_t;cdecl;external;

    function Astronomy_SearchMaxElongation(body:astro_body_t; startTime:astro_time_t):astro_elongation_t;cdecl;external;

    function Astronomy_PairLongitude(body1:astro_body_t; body2:astro_body_t; time:astro_time_t):astro_angle_result_t;cdecl;external;


  function Astronomy_SearchRelativeLongitude(body:astro_body_t; targetRelLon:double; startTime:astro_time_t):astro_search_result_t;cdecl;external;

  function Astronomy_MoonPhase(time:astro_time_t):astro_angle_result_t;cdecl;external;

  function Astronomy_SearchMoonPhase(targetLon:double; startTime:astro_time_t; limitDays:double):astro_search_result_t;cdecl;external;

  function Astronomy_SearchMoonQuarter(startTime:astro_time_t):astro_moon_quarter_t;cdecl;external;

  function Astronomy_NextMoonQuarter(mq:astro_moon_quarter_t):astro_moon_quarter_t;cdecl;external ;

  function Astronomy_SearchLunarEclipse(startTime:astro_time_t):astro_lunar_eclipse_t;cdecl;external;

  function Astronomy_NextLunarEclipse(prevEclipseTime:astro_time_t):astro_lunar_eclipse_t;cdecl;external;

  function Astronomy_SearchGlobalSolarEclipse(startTime:astro_time_t):astro_global_solar_eclipse_t;cdecl;external;

  function Astronomy_NextGlobalSolarEclipse(prevEclipseTime:astro_time_t):astro_global_solar_eclipse_t;cdecl;external;

  function Astronomy_SearchLocalSolarEclipse(startTime:astro_time_t; observer:astro_observer_t):astro_local_solar_eclipse_t;cdecl;external;

  function Astronomy_NextLocalSolarEclipse(prevEclipseTime:astro_time_t; observer:astro_observer_t):astro_local_solar_eclipse_t;cdecl;external;

  function Astronomy_SearchTransit(body:astro_body_t; startTime:astro_time_t):astro_transit_t;cdecl;external;

  function Astronomy_NextTransit(body:astro_body_t; prevTransitTime:astro_time_t):astro_transit_t;cdecl;external;

  function Astronomy_SearchMoonNode(startTime:astro_time_t):astro_node_event_t;cdecl;external;

  function Astronomy_NextMoonNode(prevNode:astro_node_event_t):astro_node_event_t;cdecl;external;

  function Astronomy_Search(func:astro_search_func_t; context:pointer; t1:astro_time_t; t2:astro_time_t; dt_tolerance_seconds:double):astro_search_result_t;cdecl;external;

  function Astronomy_SearchSunLongitude(targetLon:double; startTime:astro_time_t; limitDays:double):astro_search_result_t;cdecl;external;

  function Astronomy_SearchHourAngleEx(body:astro_body_t; observer:astro_observer_t; hourAngle:double; startTime:astro_time_t; direction:longint):astro_hour_angle_t;cdecl;external;

  function Astronomy_HourAngle(body:astro_body_t; var time:astro_time_t; observer:astro_observer_t):astro_func_result_t;cdecl;external;


  function Astronomy_SearchRiseSetEx(body:astro_body_t; observer:astro_observer_t; direction:astro_direction_t; startTime:astro_time_t; limitDays:double; 
             metersAboveGround:double):astro_search_result_t;cdecl;external ;

  function Astronomy_SearchAltitude(body:astro_body_t; observer:astro_observer_t; direction:astro_direction_t; startTime:astro_time_t; limitDays:double; 
             altitude:double):astro_search_result_t;cdecl;external;

  function Astronomy_Atmosphere(elevationMeters:double):astro_atmosphere_t;cdecl;external;

  function Astronomy_RotationAxis(body:astro_body_t; var time:astro_time_t):astro_axis_t;cdecl;external;

  function Astronomy_Seasons(year:longint):astro_seasons_t;cdecl;external;

  function Astronomy_Illumination(body:astro_body_t; time:astro_time_t):astro_illum_t;cdecl;external;

  function Astronomy_SearchPeakMagnitude(body:astro_body_t; startTime:astro_time_t):astro_illum_t;cdecl;external;

  function Astronomy_SearchLunarApsis(startTime:astro_time_t):astro_apsis_t;cdecl;external;

  function Astronomy_NextLunarApsis(apsis:astro_apsis_t):astro_apsis_t;cdecl;external;

  function Astronomy_SearchPlanetApsis(body:astro_body_t; startTime:astro_time_t):astro_apsis_t;cdecl;external;

  function Astronomy_NextPlanetApsis(body:astro_body_t; apsis:astro_apsis_t):astro_apsis_t;cdecl;external;

  function Astronomy_IdentityMatrix:astro_rotation_t;cdecl;external;

  function Astronomy_InverseRotation(rotation:astro_rotation_t):astro_rotation_t;cdecl;external;

  function Astronomy_CombineRotation(a:astro_rotation_t; b:astro_rotation_t):astro_rotation_t;cdecl;external;

  function Astronomy_Pivot(rotation:astro_rotation_t; axis:longint; angle:double):astro_rotation_t;cdecl;external;

  function Astronomy_VectorFromSphere(sphere:astro_spherical_t; time:astro_time_t):astro_vector_t;cdecl;external;

  function Astronomy_SphereFromVector(vector:astro_vector_t):astro_spherical_t;cdecl;external;

  function Astronomy_EquatorFromVector(vector:astro_vector_t):astro_equatorial_t;cdecl;external;

  function Astronomy_VectorFromHorizon(sphere:astro_spherical_t; time:astro_time_t; refraction:astro_refraction_t):astro_vector_t;cdecl;external;

  function Astronomy_HorizonFromVector(vector:astro_vector_t; refraction:astro_refraction_t):astro_spherical_t;cdecl;external;

  function Astronomy_RotateVector(rotation:astro_rotation_t; vector:astro_vector_t):astro_vector_t;cdecl;external;

  function Astronomy_RotateState(rotation:astro_rotation_t; state:astro_state_vector_t):astro_state_vector_t;cdecl;external;

  function Astronomy_Rotation_EQD_EQJ(var time:astro_time_t):astro_rotation_t;cdecl;external;

  function Astronomy_Rotation_EQD_ECL(var time:astro_time_t):astro_rotation_t;cdecl;external;

  function Astronomy_Rotation_EQD_ECT(var time:astro_time_t):astro_rotation_t;cdecl;external;

  function Astronomy_Rotation_EQD_HOR(var time:astro_time_t; observer:astro_observer_t):astro_rotation_t;cdecl;external ;

  function Astronomy_Rotation_EQJ_EQD(var time:astro_time_t):astro_rotation_t;cdecl;external;

  function Astronomy_Rotation_EQJ_ECT(var time:astro_time_t):astro_rotation_t;cdecl;external;

  function Astronomy_Rotation_EQJ_ECL:astro_rotation_t;cdecl;external;

  function Astronomy_Rotation_EQJ_HOR(var time:astro_time_t; observer:astro_observer_t):astro_rotation_t;cdecl;external;

  function Astronomy_Rotation_ECL_EQD(var time:astro_time_t):astro_rotation_t;cdecl;external;

  function Astronomy_Rotation_ECL_EQJ:astro_rotation_t;cdecl;external;

  function Astronomy_Rotation_ECL_HOR(var time:astro_time_t; observer:astro_observer_t):astro_rotation_t;cdecl;external;

  function Astronomy_Rotation_ECT_EQJ(var time:astro_time_t):astro_rotation_t;cdecl;external;

  function Astronomy_Rotation_ECT_EQD(var time:astro_time_t):astro_rotation_t;cdecl;external;

  function Astronomy_Rotation_HOR_EQD(var time:astro_time_t; observer:astro_observer_t):astro_rotation_t;cdecl;external;

  function Astronomy_Rotation_HOR_EQJ(var time:astro_time_t; observer:astro_observer_t):astro_rotation_t;cdecl;external;

  function Astronomy_Rotation_HOR_ECL(var time:astro_time_t; observer:astro_observer_t):astro_rotation_t;cdecl;external;

  function Astronomy_Rotation_EQJ_GAL:astro_rotation_t;cdecl;external;

  function Astronomy_Rotation_GAL_EQJ:astro_rotation_t;cdecl;external;

  function Astronomy_Refraction(refraction:astro_refraction_t; altitude:double):double;cdecl;external;

  function Astronomy_InverseRefraction(refraction:astro_refraction_t; bent_altitude:double):double;cdecl;external;

  function Astronomy_Constellation(ra:double; dec:double):astro_constellation_t;cdecl;external;


  type

    astro_position_func_t = function (context:pointer; time:astro_time_t):astro_vector_t;cdecl;



    type
	TCrepuscolo = (civildawn, civildusk, nauticaldawn, nauticaldusk, astronomicaldawn, astronomicaldusk);

    type
        TDatiLuna= record
        distanzakm:integer;
        diametrogradi:double;
        end;



  function Astronomy_CorrectLightTravel(context:pointer; func:astro_position_func_t; time:astro_time_t):astro_vector_t;cdecl;external;

  function Astronomy_BackdatePosition(time:astro_time_t; observerBody:astro_body_t; targetBody:astro_body_t; aberration:astro_aberration_t):astro_vector_t;cdecl;external ;

  function Astronomy_DefineStar(body:astro_body_t; ra:double; dec:double; distanceLightYears:double):astro_status_t;cdecl;external;


    //funzioni personali non di astronomy.h
  function AstroTimeToTDateTime(tempo:astro_time_t):TDateTime;
  function FaseLunare(tempo:TDateTime):double;
  function TDateTimeToAstroTime(data:TDateTime):astro_time_t;
  function IlluminazioneLuna(FaseLunare:double):double;
  function TrovaTramontoOggetto(oggetto:astro_body_t; lat:double; long:double; altezza: double; tempoinizio:TDateTime; giornilimite:Double):TDateTime;
  function TrovaSorgereOggetto(oggetto:astro_body_t; lat:double; long:double; altezza: double; tempoinizio:TDateTime; giornilimite:Double):TDateTime;
  function AltitudineOggetto(oggetto:astro_body_t; lat:double; long:double; altezza: double; tempo:TDateTime):double;

   //ancora incompleta continuare qua
  function Crepuscolo(lat, long, altezza, giornilimite:double; tempoinizio:TDateTime; tipocrepuscolo:TCrepuscolo):TDateTime;
  function DistanzaLuna(Tempo:TDateTime):TDatiLuna;
  function DistanzaOggetto(oggetto:astro_body_t; lat:double; long:double; altezza: double; tempo:TDateTime):double;
  function Illuminazione(oggetto:astro_body_t;Tempo:TDateTime):astro_illum_t;


implementation

 function Crepuscolo(lat, long, altezza, giornilimite:double; tempoinizio:TDateTime; tipocrepuscolo:TCrepuscolo):TDateTime; //tipocrepuscolo civildawn (alba), civildusk, nauticaldawn, nauticaldusk, astronomicaldawn, astronomicaldusk
 var
 Time:astro_time_t;
 location:astro_observer_t;
 TimeResult:astro_search_result_t;
 direzione:astro_direction_t;
 angolo:integer;
 begin
 Time:= TDateTimeToAstroTime(tempoinizio);
 location.height:=altezza;
 location.latitude:=lat;
 location.longitude:=long;
 case tipocrepuscolo of
 civildawn, civildusk: angolo:=-6;         //il crepuscolo civile ha angolo 6
 nauticaldawn, nauticaldusk: angolo:=-12;  //crepuscolo nautico
 astronomicaldawn, astronomicaldusk: angolo:=-18  //crepuscolo astronomico
 end;

 case tipocrepuscolo of        //decide in base al tipo di crepuscolo se bisogna calcolarlo all'alba o al tramonto
 civildawn, nauticaldawn, astronomicaldawn: direzione:=DIRECTION_SET;
 civildusk, nauticaldusk, astronomicaldusk: direzione:=DIRECTION_RISE;
 end;

 TimeResult:= Astronomy_SearchAltitude(BODY_SUN, location, direzione, Time, 1, angolo);
 Crepuscolo:=AstroTimeToTDateTime(TimeResult.time);
 end;




 function TrovaTramontoOggetto(oggetto:astro_body_t; lat:double; long:double; altezza: double; tempoinizio:TDateTime; giornilimite:Double):TDateTime;
 var
 Time:astro_time_t;
 location:astro_observer_t;
 TimeResult:astro_search_result_t;
 begin
 Time:= TDateTimeToAstroTime(LocalTimeToUniversal(tempoinizio));
 location.height:=altezza;
 location.latitude:=lat;
 location.longitude:=long;
 TimeResult:= Astronomy_SearchRiseSetEx(oggetto,location, DIRECTION_SET,Time, giornilimite, 0);
   { if TimeResult.status= ASTRO_SUCCESS then
 TrovaTramontoOggetto:=(AstroTimeToTDateTime(TimeResult.time))
 else raise Exception.Create('Set not found');  }

   try
   if TimeResult.status= ASTRO_SUCCESS then
   TrovaTramontoOggetto:=(AstroTimeToTDateTime(TimeResult.time))
   else raise Exception.Create('Set not Found');
  except
    on E: Exception do
    begin
      raise Exception.Create('Set not Found');
    end;
  end;


// else TrovaTramontoOggetto:=UniversalTimeToLocal(tempoinizio);
 end;

 function TrovaSorgereOggetto(oggetto:astro_body_t; lat:double; long:double; altezza: double; tempoinizio:TDateTime; giornilimite:Double):TDateTime;
 var
 Time:astro_time_t;
 location:astro_observer_t;
 TimeResult:astro_search_result_t;
 begin
 Time:= TDateTimeToAstroTime(LocalTimeToUniversal(tempoinizio));
 location.height:=altezza;
 location.latitude:=lat;
 location.longitude:=long;
 TimeResult:= Astronomy_SearchRiseSetEx(oggetto,location, DIRECTION_RISE,Time, giornilimite, 0);
 //TrovaSorgereOggetto:=AstroTimeToTDateTime(TimeResult.time);

  try
  if TimeResult.status= ASTRO_SUCCESS then
   TrovaSorgereOggetto:=(AstroTimeToTDateTime(TimeResult.time))
   else raise Exception.Create('Rise not Found');
  except
    on E: Exception do
    begin
      raise Exception.Create('Rise not Found');
    end;
  end;

 {
 if TimeResult.status= ASTRO_SUCCESS then
 TrovaSorgereOggetto:=(AstroTimeToTDateTime(TimeResult.time))
 else {TrovaSorgereOggetto:=tempoinizio; } raise Exception.Create('Rise not Found');    }
 end;


 function AltitudineOggetto(oggetto:astro_body_t; lat:double; long:double; altezza: double; tempo:TDateTime):double;
 var
 Time:astro_time_t;
 location:astro_observer_t;
 TimeResult:astro_search_result_t;
 CEquatoriali:astro_equatorial_t;
 CAltzimutali:astro_horizon_t;
 begin
 Time:= TDateTimeToAstroTime(tempo);
 location.height:=altezza;
 location.latitude:=lat;
 location.longitude:=long;

 CEquatoriali:=Astronomy_Equator(oggetto, Time, location, EQUATOR_OF_DATE, NO_ABERRATION);
 CAltzimutali:=Astronomy_Horizon(Time, location, CEquatoriali.ra, CEquatoriali.dec, NO_ABERRATION );

 result:=CAltzimutali.altitude;


 end;


 function DistanzaOggetto(oggetto:astro_body_t; lat:double; long:double; altezza: double; tempo:TDateTime):double;
 var
 Time:astro_time_t;
 location:astro_observer_t;
 TimeResult:astro_search_result_t;
 CEquatoriali:astro_equatorial_t;
 begin
 Time:= TDateTimeToAstroTime(tempo);
 location.height:=altezza;
 location.latitude:=lat;
 location.longitude:=long;

 CEquatoriali:=Astronomy_Equator(oggetto, Time, location, EQUATOR_OF_DATE, NO_ABERRATION);
 result:= CEquatoriali.dist;

 end;

function AstroTimeToTDateTime(tempo:astro_time_t):TDateTime;
var
 risultato:astro_utc_t;
begin
risultato:= Astronomy_UtcFromTime(tempo);
try
 AstroTimeToTDateTime:=UniversalTimeToLocal(EncodeDateTime(risultato.year, risultato.month, risultato.day, risultato.hour, risultato.minute, trunc(risultato.second), 0));
except
  on E:Exception do Exception.Create('Conversion Error');
end;


end;

function TDateTimeToAstroTime(data:TDateTime):astro_time_t;
begin
 TDateTimeToAstroTime:=Astronomy_MakeTime(YearOf(data), MonthOf(data), DayOf(data), HourOf(data), MinuteOf(data), SecondOf(data))
end;

function FaseLunare(tempo:TDateTime):double;
var
  angolo:astro_angle_result_t;
begin
   angolo:= Astronomy_MoonPhase(TDateTimeToAstroTime(tempo));
   FaseLunare:=angolo.angle;
end;

function IlluminazioneLuna(FaseLunare:double):double;
begin
   if FaseLunare<=180 then IlluminazioneLuna:=(FaseLunare/1.8);
   if FaseLunare>180 then IlluminazioneLuna:=(360-FaseLunare)/1.8;
end;


function DistanzaLuna(Tempo:TDateTime):TDatiLuna;
var
librazione:astro_libration_t;
begin
librazione:=Astronomy_Libration(TDateTimeToAstroTime(Tempo));

DistanzaLuna.distanzakm:=round(librazione.dist_km); //questa distanza corrisponde alla distanza centro centro luna terra ed è usata dalla nasa come distanza
DistanzaLuna.diametrogradi:=librazione.diam_deg;

end;

function Illuminazione(oggetto:astro_body_t;Tempo:TDateTime):astro_illum_t;
var
Time:astro_time_t;
begin
   Time:= TDateTimeToAstroTime(Tempo);
   result:=Astronomy_Illumination(oggetto, Time);
end;

end.
