{-# LINE 1 "src/Foreign/SweEphe4.hsc" #-}
{-# LANGUAGE CPP, ForeignFunctionInterface #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
-- |
-- Module: Foreign.SweEphe4
--
-- Exposes functions to interact with the "ephe4" format of pre-calculated
-- ephemeris. 

module Foreign.SweEphe4 where

import Foreign
import Foreign.C.Types
import Foreign.C.String




-- | "placalc" style enum of precalculate-able bodies. 
-- All are provided for convenience, but take note that
-- only planets up to 'lastPlanet' are guaranteed to be present
-- via this FFI in any files produced via the bundled source.
newtype PlacalcPlanet = PlacalcPlanet
  { PlacalcPlanet -> CInt
unPlacalcPlanet :: CInt } deriving (PlacalcPlanet -> PlacalcPlanet -> Bool
(PlacalcPlanet -> PlacalcPlanet -> Bool)
-> (PlacalcPlanet -> PlacalcPlanet -> Bool) -> Eq PlacalcPlanet
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: PlacalcPlanet -> PlacalcPlanet -> Bool
$c/= :: PlacalcPlanet -> PlacalcPlanet -> Bool
== :: PlacalcPlanet -> PlacalcPlanet -> Bool
$c== :: PlacalcPlanet -> PlacalcPlanet -> Bool
Eq, Int -> PlacalcPlanet -> ShowS
[PlacalcPlanet] -> ShowS
PlacalcPlanet -> String
(Int -> PlacalcPlanet -> ShowS)
-> (PlacalcPlanet -> String)
-> ([PlacalcPlanet] -> ShowS)
-> Show PlacalcPlanet
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [PlacalcPlanet] -> ShowS
$cshowList :: [PlacalcPlanet] -> ShowS
show :: PlacalcPlanet -> String
$cshow :: PlacalcPlanet -> String
showsPrec :: Int -> PlacalcPlanet -> ShowS
$cshowsPrec :: Int -> PlacalcPlanet -> ShowS
Show, Int -> PlacalcPlanet
PlacalcPlanet -> Int
PlacalcPlanet -> [PlacalcPlanet]
PlacalcPlanet -> PlacalcPlanet
PlacalcPlanet -> PlacalcPlanet -> [PlacalcPlanet]
PlacalcPlanet -> PlacalcPlanet -> PlacalcPlanet -> [PlacalcPlanet]
(PlacalcPlanet -> PlacalcPlanet)
-> (PlacalcPlanet -> PlacalcPlanet)
-> (Int -> PlacalcPlanet)
-> (PlacalcPlanet -> Int)
-> (PlacalcPlanet -> [PlacalcPlanet])
-> (PlacalcPlanet -> PlacalcPlanet -> [PlacalcPlanet])
-> (PlacalcPlanet -> PlacalcPlanet -> [PlacalcPlanet])
-> (PlacalcPlanet
    -> PlacalcPlanet -> PlacalcPlanet -> [PlacalcPlanet])
-> Enum PlacalcPlanet
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
enumFromThenTo :: PlacalcPlanet -> PlacalcPlanet -> PlacalcPlanet -> [PlacalcPlanet]
$cenumFromThenTo :: PlacalcPlanet -> PlacalcPlanet -> PlacalcPlanet -> [PlacalcPlanet]
enumFromTo :: PlacalcPlanet -> PlacalcPlanet -> [PlacalcPlanet]
$cenumFromTo :: PlacalcPlanet -> PlacalcPlanet -> [PlacalcPlanet]
enumFromThen :: PlacalcPlanet -> PlacalcPlanet -> [PlacalcPlanet]
$cenumFromThen :: PlacalcPlanet -> PlacalcPlanet -> [PlacalcPlanet]
enumFrom :: PlacalcPlanet -> [PlacalcPlanet]
$cenumFrom :: PlacalcPlanet -> [PlacalcPlanet]
fromEnum :: PlacalcPlanet -> Int
$cfromEnum :: PlacalcPlanet -> Int
toEnum :: Int -> PlacalcPlanet
$ctoEnum :: Int -> PlacalcPlanet
pred :: PlacalcPlanet -> PlacalcPlanet
$cpred :: PlacalcPlanet -> PlacalcPlanet
succ :: PlacalcPlanet -> PlacalcPlanet
$csucc :: PlacalcPlanet -> PlacalcPlanet
Enum)

pSun  :: PlacalcPlanet
pSun :: PlacalcPlanet
pSun  = CInt -> PlacalcPlanet
PlacalcPlanet CInt
0
pMoon  :: PlacalcPlanet
pMoon :: PlacalcPlanet
pMoon  = CInt -> PlacalcPlanet
PlacalcPlanet CInt
1
pMercury  :: PlacalcPlanet
pMercury :: PlacalcPlanet
pMercury  = CInt -> PlacalcPlanet
PlacalcPlanet CInt
2
pVenus  :: PlacalcPlanet
pVenus :: PlacalcPlanet
pVenus  = CInt -> PlacalcPlanet
PlacalcPlanet CInt
3
pMars  :: PlacalcPlanet
pMars :: PlacalcPlanet
pMars  = CInt -> PlacalcPlanet
PlacalcPlanet CInt
4
pJupiter  :: PlacalcPlanet
pJupiter :: PlacalcPlanet
pJupiter  = CInt -> PlacalcPlanet
PlacalcPlanet CInt
5
pSaturn  :: PlacalcPlanet
pSaturn :: PlacalcPlanet
pSaturn  = CInt -> PlacalcPlanet
PlacalcPlanet CInt
6
pUranus  :: PlacalcPlanet
pUranus :: PlacalcPlanet
pUranus  = CInt -> PlacalcPlanet
PlacalcPlanet CInt
7
pNeptune  :: PlacalcPlanet
pNeptune :: PlacalcPlanet
pNeptune  = CInt -> PlacalcPlanet
PlacalcPlanet CInt
8
pPluto  :: PlacalcPlanet
pPluto :: PlacalcPlanet
pPluto  = CInt -> PlacalcPlanet
PlacalcPlanet CInt
9
pMeanNode  :: PlacalcPlanet
pMeanNode :: PlacalcPlanet
pMeanNode  = CInt -> PlacalcPlanet
PlacalcPlanet CInt
10
pTrueNode  :: PlacalcPlanet
pTrueNode :: PlacalcPlanet
pTrueNode  = CInt -> PlacalcPlanet
PlacalcPlanet CInt
11
pChiron  :: PlacalcPlanet
pChiron :: PlacalcPlanet
pChiron  = CInt -> PlacalcPlanet
PlacalcPlanet CInt
12
pLilith  :: PlacalcPlanet
pLilith :: PlacalcPlanet
pLilith  = CInt -> PlacalcPlanet
PlacalcPlanet CInt
13
pCeres  :: PlacalcPlanet
pCeres :: PlacalcPlanet
pCeres  = PlacalcPlanet 14
pPallas  :: PlacalcPlanet
pPallas :: PlacalcPlanet
pPallas  = PlacalcPlanet 15
pJuno  :: PlacalcPlanet
pJuno :: PlacalcPlanet
pJuno  = PlacalcPlanet 16
pVesta  :: PlacalcPlanet
pVesta :: PlacalcPlanet
pVesta  = PlacalcPlanet 17
pHeliocentricEarth  :: PlacalcPlanet
pHeliocentricEarth :: PlacalcPlanet
pHeliocentricEarth  = CInt -> PlacalcPlanet
PlacalcPlanet CInt
18
pParsFortunae  :: PlacalcPlanet
pParsFortunae :: PlacalcPlanet
pParsFortunae  = CInt -> PlacalcPlanet
PlacalcPlanet CInt
19

{-# LINE 47 "src/Foreign/SweEphe4.hsc" #-}

-- | Options for requesting pre-calculated ephemeris;
-- Unless the use case calls for it, it's cheap and fast to just
-- `includeAll` (which should evaluate to @0@.)
newtype PlanetListFlag = PlanetListFlag
  { unPlanetListFlag :: CInt } deriving (Eq, Show)

includeAllPlanets  :: PlanetListFlag
includeAllPlanets  = PlanetListFlag 16383
includeEcliptic  :: PlanetListFlag
includeEcliptic  = PlanetListFlag 16384
includeNutation  :: PlanetListFlag
includeNutation  = PlanetListFlag 32768
includeAll  :: PlanetListFlag
includeAll  = PlanetListFlag 65535

{-# LINE 60 "src/Foreign/SweEphe4.hsc" #-}

-- | Lengths and indices for pre-calculated ephemeris.
-- They're only true for a file **created by the same
-- code in use**. Memory corruption can occur if reading
-- a file created with fewer or more planets/bodies, or
-- in an incompatible architecture!
newtype EpheConst = EpheConst
  { unEpheConst :: CInt } deriving (Eq, Show)

-- These are also "planet flags," but it felt weird to
-- present them as options, when they're more like
numberOfFactors, numberOfPlanets, eclipticIndex, nutationIndex :: EpheConst
numberOfFactors :: EpheConst
numberOfFactors = CInt -> EpheConst
EpheConst CInt
16
{-# LINE 73 "src/Foreign/SweEphe4.hsc" #-}
numberOfPlanets = EpheConst 14
{-# LINE 74 "src/Foreign/SweEphe4.hsc" #-}
eclipticIndex = EpheConst 14
{-# LINE 75 "src/Foreign/SweEphe4.hsc" #-}
nutationIndex = EpheConst 15
{-# LINE 76 "src/Foreign/SweEphe4.hsc" #-}

-- | Convenience helper to turn an 'EpheConst'
-- into an int for indexed access.
constToIndex :: EpheConst -> Int
constToIndex :: EpheConst -> Int
constToIndex = CInt -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (CInt -> Int) -> (EpheConst -> CInt) -> EpheConst -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. EpheConst -> CInt
unEpheConst 

-- | The last planet that the current pre-calculated
-- files will contain, if produced with the same sources
-- in `csrc`. 
-- You'll have to edit the C source
-- and compile, then run the `swegen` target to re-produce
-- files with more or fewer planets
lastPlanet :: PlacalcPlanet
lastPlanet :: PlacalcPlanet
lastPlanet = CInt -> PlacalcPlanet
PlacalcPlanet (CInt -> PlacalcPlanet)
-> (EpheConst -> CInt) -> EpheConst -> PlacalcPlanet
forall b c a. (b -> c) -> (a -> b) -> a -> c
. EpheConst -> CInt
unEpheConst (EpheConst -> PlacalcPlanet) -> EpheConst -> PlacalcPlanet
forall a b. (a -> b) -> a -> b
$ EpheConst
numberOfPlanets

-- | Options for additional computations when reading.
-- The authors recommend to always `includeSpeed`, since
-- it's a negligible overhead and can be useful.
-- If `mustUseStoredEphe` is not set, reading dates outside
-- of the precalculated range won't fail, and instead fall back
-- to the more expensive @swecalc@ -- which can still fail
-- if requesting a body that the current swiss ephemeris mode
-- is unable to calculate (e.g. requesting Chiron when no
-- asteroid data is present.)
newtype EpheCalcFlag = EpheCalcFlag
  { EpheCalcFlag -> CInt
unEpheCalcFlag :: CInt } deriving (EpheCalcFlag -> EpheCalcFlag -> Bool
(EpheCalcFlag -> EpheCalcFlag -> Bool)
-> (EpheCalcFlag -> EpheCalcFlag -> Bool) -> Eq EpheCalcFlag
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: EpheCalcFlag -> EpheCalcFlag -> Bool
$c/= :: EpheCalcFlag -> EpheCalcFlag -> Bool
== :: EpheCalcFlag -> EpheCalcFlag -> Bool
$c== :: EpheCalcFlag -> EpheCalcFlag -> Bool
Eq, Int -> EpheCalcFlag -> ShowS
[EpheCalcFlag] -> ShowS
EpheCalcFlag -> String
(Int -> EpheCalcFlag -> ShowS)
-> (EpheCalcFlag -> String)
-> ([EpheCalcFlag] -> ShowS)
-> Show EpheCalcFlag
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [EpheCalcFlag] -> ShowS
$cshowList :: [EpheCalcFlag] -> ShowS
show :: EpheCalcFlag -> String
$cshow :: EpheCalcFlag -> String
showsPrec :: Int -> EpheCalcFlag -> ShowS
$cshowsPrec :: Int -> EpheCalcFlag -> ShowS
Show)

includeSpeed  :: EpheCalcFlag
includeSpeed :: EpheCalcFlag
includeSpeed  = CInt -> EpheCalcFlag
EpheCalcFlag CInt
16
mustUseStoredEphe  :: EpheCalcFlag
mustUseStoredEphe :: EpheCalcFlag
mustUseStoredEphe  = CInt -> EpheCalcFlag
EpheCalcFlag CInt
256

{-# LINE 107 "src/Foreign/SweEphe4.hsc" #-}


-- | Set the base pre-calculated ephemeris path. This function is
-- called automatically by the read functions and will either
-- default to the environment variable @EP4_PATH@, or the library's
-- current hardcoded path; if unable to set environment variables reliably,
-- use this function. Otherwise it's an unnecessary complication outside of
-- testing.
foreign import ccall unsafe "configurable_sweephe4.h ephe4_set_ephe_path"
  c_ephe4_set_ephe_path :: CString -> IO ()

-- | Obtain an array of doubles containing all requested planets, ecliptic,
-- nutation, and their speeds.   
foreign import ccall unsafe "configurable_sweephe4.h dephread2"
  c_dephread2 :: CDouble
              -- ^ @jd@ (julian date)
              -> PlanetListFlag
              -- ^ @plalist@ -- bitwise flag for the position data to include
              -> EpheCalcFlag
              -- ^ @flag@ -- bitwise flag for the additional options
              -> CString
              -- ^ @char* errtext@ -- at least 256 characters for error message
              -> IO (Ptr CDouble)
              -- ^ array of the calculated data

-- | Write one block of 10,000 day ephemeris to disk. Both valid base
-- paths for ephe4 stored ephemeris, and base ephemeris, should be set.
foreign import ccall unsafe "configurable_sweephe4.h ephe4_write_file"
  c_ephe4_write_file :: CInt
                     -- ^ @fnr@: three-digit prefix of the starting day
                     -> CString
                     -- ^ @errtext@: error/warning message
                     -> IO CInt
                     -- ^ error code.