-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | Amateur astronomical computations
--   
--   Amateur astronomical computations: rise and set times and azimuths,
--   coordinates, distances, angular sizes and other parameters of the Sun,
--   the Moon, planets and stars.
@package astro
@version 0.4.2.0


-- | Internal functions of Sun module. Exposed only for Unit Tests
module Data.Astro.Sun.SunInternals

-- | Solve Kepler's Equation: E - e * (sin E) = M It takes eccentricity,
--   mean anomaly in radians equals epsilon - omega (see
--   <tt>SunDetails</tt>). It returns E in radians.
solveKeplerEquation :: Double -> Double -> Double -> Double


-- | Gregorian Calendar was introduced by Pope Gregory XIII. He abolished
--   the days 1582-10-05 to 1582-10-14 inclusive to bring back civil and
--   tropical years back to line.
module Data.Astro.Time.GregorianCalendar

-- | Check Gregorian calendar leap year
isLeapYear :: Integer -> Bool

-- | Day Number in a year
dayNumber :: Day -> Int

-- | Get Easter date function uses absolutely crazy Butcher's algorithm
easterDayInYear :: Int -> Day
gregorianDateAdjustment :: Integer -> Int -> Int -> Int


-- | Utility functions.
module Data.Astro.Utils

-- | Convert From Fixed to Fractional
fromFixed :: (Fractional a, HasResolution b) => Fixed b -> a

-- | return the integral part of a number almost the same as truncate but
--   result type is Real
trunc :: RealFrac a => a -> a

-- | Almost the same the properFraction function but result type
fraction :: (RealFrac a, Num b) => a -> (b, a)

-- | Reduce to range from 0 to n
reduceToZeroRange :: RealFrac a => a -> a -> a

-- | Convert from degrees to radians
toRadians :: Floating a => a -> a

-- | Convert from radians to degrees
fromRadians :: Floating a => a -> a

-- | Round to a specified number of digits
roundToN :: RealFrac a => Int -> a -> a

-- | Length of a tropical year in days
tropicalYearLen :: Double


-- | Common Types are usfull across all subsystems like Time and
--   Coordinate.
--   
--   <h1>Examples</h1>
--   
--   <h2><i>Decimal hours and Decimal degrees</i></h2>
--   
--   <pre>
--   import Data.Astro.Types
--   
--   -- 10h 15m 19.7s
--   dh :: DecimalHours
--   dh = fromHMS 10 15 19.7
--   -- DH 10.255472222222222
--   
--   (h, m, s) = toHMS dh
--   -- (10,15,19.699999999999562)
--   
--   
--   -- 51°28′40″
--   dd :: DecimalDegrees
--   dd = fromDMS 51 28 40
--   -- DD 51.477777777777774
--   
--   (d, m, s) = toDMS dd
--   -- (51,28,39.999999999987494)
--   </pre>
--   
--   <h2><i>Geographic Coordinates</i></h2>
--   
--   <pre>
--   import Data.Astro.Types
--   
--   -- the Royal Observatory, Greenwich
--   ro :: GeographicCoordinates
--   ro = GeoC (fromDMS 51 28 40) (-(fromDMS 0 0 5))
--   -- GeoC {geoLatitude = DD 51.4778, geoLongitude = DD (-0.0014)}
--   </pre>
module Data.Astro.Types
newtype DecimalDegrees
DD :: Double -> DecimalDegrees
newtype DecimalHours
DH :: Double -> DecimalHours

-- | Geographic Coordinates
data GeographicCoordinates
GeoC :: DecimalDegrees -> DecimalDegrees -> GeographicCoordinates
[geoLatitude] :: GeographicCoordinates -> DecimalDegrees
[geoLongitude] :: GeographicCoordinates -> DecimalDegrees

-- | Astronomical Units, 1AU = 1.4960×1011 m (originally, the average
--   distance of Earth's aphelion and perihelion).
newtype AstronomicalUnits
AU :: Double -> AstronomicalUnits

-- | Light travel time of the distance in Astronomical Units
lightTravelTime :: AstronomicalUnits -> DecimalHours

-- | Convert from kilometers to Astronomical Units
kmToAU :: Double -> AstronomicalUnits

-- | Comvert from Astronomical Units to kilometers
auToKM :: AstronomicalUnits -> Double

-- | Convert decimal degrees to decimal hours
toDecimalHours :: DecimalDegrees -> DecimalHours

-- | Convert decimal hours to decimal degrees
fromDecimalHours :: DecimalHours -> DecimalDegrees

-- | Convert from DecimalDegrees to Radians
toRadians :: DecimalDegrees -> Double

-- | Convert from Radians to DecimalDegrees
fromRadians :: Double -> DecimalDegrees

-- | Convert Degrees, Minutes, Seconds to DecimalDegrees
fromDMS :: RealFrac a => Int -> Int -> a -> DecimalDegrees

-- | Convert DecimalDegrees to Degrees, Minutes, Seconds
toDMS :: (Integral b, Integral a) => DecimalDegrees -> (a, b, Double)

-- | Comvert Hours, Minutes, Seconds to DecimalHours
fromHMS :: RealFrac a => Int -> Int -> a -> DecimalHours

-- | Convert DecimalDegrees to Degrees, Minutes, Seconds
toHMS :: (Integral b, Integral a) => DecimalHours -> (a, b, Double)
instance GHC.Classes.Ord Data.Astro.Types.AstronomicalUnits
instance GHC.Classes.Eq Data.Astro.Types.AstronomicalUnits
instance GHC.Show.Show Data.Astro.Types.AstronomicalUnits
instance GHC.Classes.Eq Data.Astro.Types.GeographicCoordinates
instance GHC.Show.Show Data.Astro.Types.GeographicCoordinates
instance GHC.Classes.Ord Data.Astro.Types.DecimalHours
instance GHC.Classes.Eq Data.Astro.Types.DecimalHours
instance GHC.Show.Show Data.Astro.Types.DecimalHours
instance GHC.Classes.Ord Data.Astro.Types.DecimalDegrees
instance GHC.Classes.Eq Data.Astro.Types.DecimalDegrees
instance GHC.Show.Show Data.Astro.Types.DecimalDegrees
instance GHC.Num.Num Data.Astro.Types.AstronomicalUnits
instance GHC.Real.Real Data.Astro.Types.AstronomicalUnits
instance GHC.Real.Fractional Data.Astro.Types.AstronomicalUnits
instance GHC.Real.RealFrac Data.Astro.Types.AstronomicalUnits
instance GHC.Num.Num Data.Astro.Types.DecimalHours
instance GHC.Real.Real Data.Astro.Types.DecimalHours
instance GHC.Real.Fractional Data.Astro.Types.DecimalHours
instance GHC.Real.RealFrac Data.Astro.Types.DecimalHours
instance GHC.Num.Num Data.Astro.Types.DecimalDegrees
instance GHC.Real.Real Data.Astro.Types.DecimalDegrees
instance GHC.Real.Fractional Data.Astro.Types.DecimalDegrees
instance GHC.Real.RealFrac Data.Astro.Types.DecimalDegrees


-- | Julian date is the continuous count of days since noon on January 1,
--   4713 BC, the beginning of the Julian Period.
--   
--   <h1>Examples</h1>
--   
--   <h2><i>JulianDate</i></h2>
--   
--   <pre>
--   import Data.Astro.Time.JulianDate
--   
--   -- 2017-06-25 9:29:00 (GMT)
--   jd :: JulianDate
--   jd = fromYMDHMS 2017 6 25 9 29 0
--   -- JD 2457929.895138889
--   </pre>
--   
--   <h2><i>LocalCiviTime and LocalCivilDate</i></h2>
--   
--   <pre>
--   import Data.Astro.Time.JulianDate
--   import Data.Astro.Types
--   
--   -- 2017-06-25 10:29:00 +0100 (BST)
--   lct :: LocalCivilTime
--   lct = lctFromYMDHMS (DH 1) 2017 6 25 10 29 0
--   -- 2017-06-25 10:29:00.0000 +1.0
--   
--   lctJD :: JulianDate
--   lctJD = lctUniversalTime lct
--   -- JD 2457929.895138889
--   
--   lctTZ :: DecimalHours
--   lctTZ = lctTimeZone lct
--   -- DH 1.0
--   
--   lcd :: LocalCivilDate
--   lcd = lcdFromYMD (DH 1) 2017 6 25
--   
--   lcdJD :: JulianDate
--   lcdJD = lcdDate lcd
--   -- JD 2457929.5
--   
--   lcdTZ :: DecimalHours
--   lcdTZ = lcdTimeZone lcd
--   -- DH 1.0
--   </pre>
module Data.Astro.Time.JulianDate

-- | A number of days since noon of 1 January 4713 BC
newtype JulianDate
JD :: TimeBaseType -> JulianDate

-- | Beginning of the Julian Period
julianStartDateTime :: JulianDate

-- | Represents Local Civil Time
data LocalCivilTime
LCT :: DecimalHours -> JulianDate -> LocalCivilTime
[lctTimeZone] :: LocalCivilTime -> DecimalHours
[lctUniversalTime] :: LocalCivilTime -> JulianDate

-- | Local Civil Date, used for time conversions when base date is needed
data LocalCivilDate
LCD :: DecimalHours -> JulianDate -> LocalCivilDate
[lcdTimeZone] :: LocalCivilDate -> DecimalHours
[lcdDate] :: LocalCivilDate -> JulianDate
type TimeBaseType = Double

-- | Return number of days since the first argument till the second one
numberOfDays :: JulianDate -> JulianDate -> TimeBaseType

-- | Return number of years since the first argument till the second one
numberOfYears :: JulianDate -> JulianDate -> TimeBaseType

-- | Return number of centuries since the first argument till the second
--   one
numberOfCenturies :: JulianDate -> JulianDate -> TimeBaseType

-- | add Decimal Hours
addHours :: DecimalHours -> JulianDate -> JulianDate

-- | Create Julian Date. It takes year, month [1..12], Day [1..31].
fromYMD :: Integer -> Int -> Int -> JulianDate

-- | Create Julian Date. It takes year, month [1..12], Day [1..31], hours,
--   minutes, seconds.
fromYMDHMS :: Integer -> Int -> Int -> Int -> Int -> TimeBaseType -> JulianDate

-- | It returns year, month [1..12], Day [1..31], hours, minutes, seconds.
toYMDHMS :: JulianDate -> (Integer, Int, Int, Int, Int, TimeBaseType)

-- | Get Day of the Week 0 is for Sunday, 1 for manday and 6 for Saturday
dayOfWeek :: JulianDate -> Int

-- | Extract Day and Time parts of Date
splitToDayAndTime :: JulianDate -> (JulianDate, JulianDate)

-- | Create LocalCivilTime from tize zone, local year, local month, local
--   day, local hours, local minutes and local secunds.
lctFromYMDHMS :: DecimalHours -> Integer -> Int -> Int -> Int -> Int -> TimeBaseType -> LocalCivilTime

-- | Get from LocalCivilTime local year, local month, local day, local
--   hours, local minutes and local secunds.
lctToYMDHMS :: LocalCivilTime -> (Integer, Int, Int, Int, Int, TimeBaseType)
lcdFromYMD :: DecimalHours -> Integer -> Int -> Int -> LocalCivilDate

-- | Print local civil time in machine readable format
printLctHs :: LocalCivilTime -> String
instance GHC.Classes.Eq Data.Astro.Time.JulianDate.LocalCivilDate
instance GHC.Classes.Eq Data.Astro.Time.JulianDate.LocalCivilTime
instance GHC.Classes.Eq Data.Astro.Time.JulianDate.JulianDate
instance GHC.Show.Show Data.Astro.Time.JulianDate.JulianDate
instance GHC.Show.Show Data.Astro.Time.JulianDate.LocalCivilTime
instance GHC.Num.Num Data.Astro.Time.JulianDate.JulianDate


-- | Definitions of well-known astronomical epochs.
module Data.Astro.Time.Epoch

-- | Epoch B1900.0, 1900 January 0.8135
b1900 :: JulianDate

-- | Epoch B1950.0, January 0.9235
b1950 :: JulianDate

-- | Epoch J1900.0 1900 January 0.5
j1900 :: JulianDate

-- | Epoch J2000.0, 12h on 1 January 2000
j2000 :: JulianDate

-- | Epoch J2050.0, 12h on 1 January 2000
j2050 :: JulianDate

-- | The Sun's and planets reference Epoch J2010.0 (2010 January 0.0)
j2010 :: JulianDate


-- | According to the Sidereal Clock any observed star returns to the same
--   position in the sky every 24 hours.
--   
--   Each sidereal day is shorter than the solar day, 24 hours of sidereal
--   time corresponding to 23:56:04.0916 of solar time.
module Data.Astro.Time.Sidereal

-- | Greenwich Sidereal Time GST can be in range [-12h, 36h] carrying out a
--   day correction
data GreenwichSiderealTime

-- | Local Sidereal Time
data LocalSiderealTime

-- | Convert Decimal Hours to Greenwich Sidereal Time
dhToGST :: DecimalHours -> GreenwichSiderealTime

-- | Convert Decimal Hours to Local Sidereal Time
dhToLST :: DecimalHours -> LocalSiderealTime

-- | Convert Greenwich Sidereal Time to Decimal Hours
gstToDH :: GreenwichSiderealTime -> DecimalHours

-- | Convert Local Sidereal Time to Decimal Hours
lstToDH :: LocalSiderealTime -> DecimalHours

-- | Comvert Hours, Minutes, Seconds to Greenwich Sidereal Time
hmsToGST :: Int -> Int -> TimeBaseType -> GreenwichSiderealTime

-- | Comvert Hours, Minutes, Seconds to Local Sidereal Time
hmsToLST :: Int -> Int -> TimeBaseType -> LocalSiderealTime

-- | Convert from Universal Time (UT) to Greenwich Sidereal Time (GST)
utToGST :: JulianDate -> GreenwichSiderealTime

-- | Convert from Greenwich Sidereal Time (GST) to Universal Time (UT). It
--   takes GST and Greenwich Date, returns JulianDate. Because the sidereal
--   day is shorter than the solar day (see comment to the module). In case
--   of such ambiguity the early time will be returned. You can easily
--   check the ambiguity: if time is equal or less 00:03:56 you can get the
--   second time by adding 23:56:04
gstToUT :: JulianDate -> GreenwichSiderealTime -> JulianDate

-- | Convert Greenwich Sidereal Time to Local Sidereal Time. It takes GST
--   and longitude in decimal degrees
gstToLST :: DecimalDegrees -> GreenwichSiderealTime -> LocalSiderealTime

-- | Convert Local Sidereal Time to Greenwich Sidereal Time It takes LST
--   and longitude in decimal degrees
lstToGST :: DecimalDegrees -> LocalSiderealTime -> GreenwichSiderealTime

-- | Convert Local Sidereal Time to Greenwich Sidereal Time with Day
--   Correction. It takes LST and longitude in decimal degrees
lstToGSTwDC :: DecimalDegrees -> LocalSiderealTime -> GreenwichSiderealTime
instance GHC.Classes.Eq Data.Astro.Time.Sidereal.LocalSiderealTime
instance GHC.Show.Show Data.Astro.Time.Sidereal.LocalSiderealTime
instance GHC.Classes.Eq Data.Astro.Time.Sidereal.GreenwichSiderealTime
instance GHC.Show.Show Data.Astro.Time.Sidereal.GreenwichSiderealTime


-- | Root Time module
module Data.Astro.Time

-- | Universal Time to Local Sidereal Time. It takes longitude in decimal
--   degrees and local civil time
utToLST :: DecimalDegrees -> JulianDate -> LocalSiderealTime

-- | Local Civil Time to Local Sidereal Time. It takes longitude in decimal
--   degrees and local civil time
lctToLST :: DecimalDegrees -> LocalCivilTime -> LocalSiderealTime

-- | Local Sidereal Time to Local Civil Time. It takes longitude in decimal
--   degrees, local civil date and local sidereal time
lstToLCT :: DecimalDegrees -> LocalCivilDate -> LocalSiderealTime -> LocalCivilTime


-- | Planet Details.
module Data.Astro.Planet.PlanetDetails

-- | Planets of the Solar System
data Planet
Mercury :: Planet
Venus :: Planet
Earth :: Planet
Mars :: Planet
Jupiter :: Planet
Saturn :: Planet
Uranus :: Planet
Neptune :: Planet

-- | Details of the planetary orbit at the epoch
data PlanetDetails
PlanetDetails :: Planet -> JulianDate -> Double -> DecimalDegrees -> DecimalDegrees -> Double -> AstronomicalUnits -> DecimalDegrees -> DecimalDegrees -> DecimalDegrees -> PlanetDetails
[pdPlanet] :: PlanetDetails -> Planet
[pdEpoch] :: PlanetDetails -> JulianDate

-- | Orbital period in tropical years
[pdTp] :: PlanetDetails -> Double

-- | Longitude at the Epoch
[pdEpsilon] :: PlanetDetails -> DecimalDegrees

-- | Longitude of the perihelion
[pdOmegaBar] :: PlanetDetails -> DecimalDegrees

-- | Eccentricity of the orbit
[pdE] :: PlanetDetails -> Double

-- | Semi-major axis of the orbit in AU
[pdAlpha] :: PlanetDetails -> AstronomicalUnits

-- | Orbital inclination
[pdI] :: PlanetDetails -> DecimalDegrees

-- | Longitude of the ascending node
[pdBigOmega] :: PlanetDetails -> DecimalDegrees

-- | Angular diameter at 1 AU
[pdBigTheta] :: PlanetDetails -> DecimalDegrees

-- | PlanetDetails at the reference Epoch J2010.0
j2010PlanetDetails :: Planet -> PlanetDetails

-- | Return True if the planet is inner (its orbit lies inside the Earth's
--   orbit)
isInnerPlanet :: PlanetDetails -> Bool
instance GHC.Classes.Eq Data.Astro.Planet.PlanetDetails.PlanetDetails
instance GHC.Show.Show Data.Astro.Planet.PlanetDetails.PlanetDetails
instance GHC.Classes.Eq Data.Astro.Planet.PlanetDetails.Planet
instance GHC.Show.Show Data.Astro.Planet.PlanetDetails.Planet


-- | Moon Details.
module Data.Astro.Moon.MoonDetails

-- | Details of the Moon's orbit at the epoch
data MoonDetails
MoonDetails :: JulianDate -> DecimalDegrees -> DecimalDegrees -> DecimalDegrees -> DecimalDegrees -> Double -> Double -> DecimalDegrees -> DecimalDegrees -> MoonDetails

-- | the epoch
[mdEpoch] :: MoonDetails -> JulianDate

-- | mean longitude at the epoch
[mdL] :: MoonDetails -> DecimalDegrees

-- | mean longitude of the perigee at the epoch
[mdP] :: MoonDetails -> DecimalDegrees

-- | mean longitude of the node at the epoch
[mdN] :: MoonDetails -> DecimalDegrees

-- | inclination of the orbit
[mdI] :: MoonDetails -> DecimalDegrees

-- | eccentricity of the orbit
[mdE] :: MoonDetails -> Double

-- | semi-major axis of the orbit
[mdA] :: MoonDetails -> Double

-- | angular diameter at the distance <a>mdA</a> from the Earth
[mdBigTheta] :: MoonDetails -> DecimalDegrees

-- | parallax at distance <a>mdA</a> from the Earth
[mdPi] :: MoonDetails -> DecimalDegrees

-- | Moon distance units, 1 MDU = semi-major axis of the Moon's orbit
newtype MoonDistanceUnits
MDU :: Double -> MoonDistanceUnits
j2010MoonDetails :: MoonDetails

-- | Convert MoonDistanceUnits to km
mduToKm :: MoonDistanceUnits -> Double
instance GHC.Show.Show Data.Astro.Moon.MoonDetails.MoonDistanceUnits
instance GHC.Show.Show Data.Astro.Moon.MoonDetails.MoonDetails


-- | Conversion functions between datetime types defined in Data.Time and
--   Data.Astro.Time modules.
module Data.Astro.Time.Conv

-- | Convert ZonedTime to LocalCivilTime
zonedTimeToLCT :: ZonedTime -> LocalCivilTime

-- | Convert ZonedTime to LocalCivilDate
zonedTimeToLCD :: ZonedTime -> LocalCivilDate

-- | Convert LocalCivilTime to ZonedTime
lctToZonedTime :: LocalCivilTime -> ZonedTime


-- | See <a>Data.Astro.Types</a> module for Georgraphic Coordinates.
--   
--   <h1>Celestial Coordinate Systems</h1>
--   
--   <h2><i>Horizon coordinates</i></h2>
--   
--   <ul>
--   <li><b>altitude, α</b> - <i>'how far up'</i> angle from the horizontal
--   plane in degrees</li>
--   <li><b>azimuth, Α</b> - <i>'how far round'</i> agle from the north
--   direction in degrees to the east</li>
--   </ul>
--   
--   <h2><i>Equatorial coordinates</i></h2>
--   
--   Accoring to the equatorial coordinates system stars move westwards
--   along the circles centered in the north selestial pole, making the
--   full cicrle in 24 hours of sidereal time (see
--   <a>Data.Astro.Time.Sidereal</a>).
--   
--   <ul>
--   <li><b>declination, δ</b> - <i>'how far up'</i> angle from the
--   quatorial plane;</li>
--   <li><b>right ascension, α</b> - <i>'how far round'</i> angle from the
--   <i>vernal equinox</i> to the east; <b><i>or</i></b></li>
--   <li><b>hour angle</b> - <i>'how far round'</i> angle from the meridian
--   to the west</li>
--   </ul>
--   
--   <h2><i>Ecliptic Coordinate</i></h2>
--   
--   Accoring to the ecliptic coordinates system the Sun moves eastwards
--   along the trace of th ecliptic. The Sun's ecplitic latitude is always
--   0.
--   
--   <ul>
--   <li><b>ecliptic latitude, β</b> - <i>'how far up'</i> angle from the
--   ecliptic</li>
--   <li><b>ecliptic longitude, λ</b> - <i>'how far round'</i> angle from
--   the <i>vernal equinox</i> to the east</li>
--   </ul>
--   
--   <h2><i>Galactic Coordinates</i></h2>
--   
--   <ul>
--   <li><b>galactic latitute, b</b> - <i>'how far up'</i> angle from the
--   plane of the Galaxy</li>
--   <li><b>galactiv longitude, l</b> - - <i>'how far round'</i> angle from
--   the direction the Sun - the centre of the Galaxy</li>
--   </ul>
--   
--   <h2><i>Terms</i></h2>
--   
--   <ul>
--   <li><b>ecliptic</b> - the plane containing the Earth's orbit around
--   the Sun</li>
--   <li><b>vernal equinox</b>, ♈ - fixed direction lies along the line of
--   the intersection of the equatorial plane and the ecliptic</li>
--   <li><b>obliquity of the ecliptic, β</b> - the angle between the plane
--   of the Earth's equator and the ecliptic</li>
--   <li><b>north selestial pole, P</b> - the point on the selestial
--   sphere, right above the Earth's North Pole</li>
--   </ul>
--   
--   <h1>Examples</h1>
--   
--   <h2><i>Horizontal Coordinate System</i></h2>
--   
--   <pre>
--   import Data.Astro.Coordinate
--   import Data.Astro.Types
--   
--   hc :: HorizonCoordinates
--   hc = HC (DD 30.5) (DD 180)
--   -- HC {hAltitude = DD 30.0, hAzimuth = DD 180.0}
--   </pre>
--   
--   <h2><i>Equatorial Coordinate System</i></h2>
--   
--   <pre>
--   import Data.Astro.Coordinate
--   import Data.Astro.Types
--   
--   ec1 :: EquatorialCoordinates1
--   ec1 = EC1 (DD 71.7) (DH 8)
--   -- EC1 {e1Declination = DD 71.7, e1RightAscension = DH 8.0}
--   
--   ec2 :: EquatorialCoordinates2
--   ec2 = EC1 (DD 77.7) (DH 11)
--   -- EC2 {e2Declination = DD 77.7, e2HoursAngle = DH 11.0}
--   </pre>
--   
--   <h2><i>Transformations</i></h2>
--   
--   <pre>
--   import Data.Astro.Time.JulianDate
--   import Data.Astro.Coordinate
--   import Data.Astro.Types
--   
--   ro :: GeographicCoordinates
--   ro = GeoC (fromDMS 51 28 40) (-(fromDMS 0 0 5))
--   
--   dt :: LocalCivilTime
--   dt = lctFromYMDHMS (DH 1) 2017 6 25 10 29 0
--   
--   sunHC :: HorizonCoordinates
--   sunHC = HC (fromDMS 49 18 21.77) (fromDMS 118 55 19.53)
--   -- HC {hAltitude = DD 49.30604722222222, hAzimuth = DD 118.92209166666666}
--   
--   sunEC2 :: EquatorialCoordinates2
--   sunEC2 = horizonToEquatorial (geoLatitude ro) sunHC
--   -- EC2 {e2Declination = DD 23.378295912623855, e2HoursAngle = DH 21.437117068873537}
--   
--   sunEC1 :: EquatorialCoordinates1
--   sunEC1 = EC1 (e2Declination sunEC2) (haToRA (e2HoursAngle sunEC2) (geoLongitude ro) (lctUniversalTime dt))
--   -- EC1 {e1Declination = DD 23.378295912623855, e1RightAscension = DH 6.29383725890224}
--   
--   
--   sunEC2' :: EquatorialCoordinates2
--   sunEC2' = EC2 (e1Declination sunEC1) (raToHA (e1RightAscension sunEC1) (geoLongitude ro) (lctUniversalTime dt))
--   -- EC2 {e2Declination = DD 23.378295912623855, e2HoursAngle = DH 21.437117068873537}
--   
--   sunHC' :: HorizonCoordinates
--   sunHC' = equatorialToHorizon (geoLatitude ro) sunEC2'
--   -- HC {hAltitude = DD 49.30604722222222, hAzimuth = DD 118.92209166666666}
--   </pre>
--   
--   <h3><i>Function-shortcuts</i></h3>
--   
--   <pre>
--   import Data.Astro.Time.JulianDate
--   import Data.Astro.Coordinate
--   import Data.Astro.Types
--   
--   ro :: GeographicCoordinates
--   ro = GeoC (fromDMS 51 28 40) (-(fromDMS 0 0 5))
--   
--   dt :: LocalCivilTime
--   dt = lctFromYMDHMS (DH 1) 2017 6 25 10 29 0
--   
--   sunHC :: HorizonCoordinates
--   sunHC = HC (fromDMS 49 18 21.77) (fromDMS 118 55 19.53)
--   -- HC {hAltitude = DD 49.30604722222222, hAzimuth = DD 118.92209166666666}
--   
--   sunEC1 :: EquatorialCoordinates1
--   sunEC1 = hcToEC1 ro (lctUniversalTime dt) sunHC
--   -- EC1 {e1Declination = DD 23.378295912623855, e1RightAscension = DH 6.29383725890224}
--   
--   sunHC' :: HorizonCoordinates
--   sunHC' = ec1ToHC ro (lctUniversalTime dt) sunEC1
--   -- HC {hAltitude = DD 49.30604722222222, hAzimuth = DD 118.92209166666666}
--   </pre>
module Data.Astro.Coordinate
newtype DecimalDegrees
DD :: Double -> DecimalDegrees
newtype DecimalHours
DH :: Double -> DecimalHours

-- | Horizon Coordinates, for details see the module's description
data HorizonCoordinates
HC :: DecimalDegrees -> DecimalDegrees -> HorizonCoordinates

-- | alpha
[hAltitude] :: HorizonCoordinates -> DecimalDegrees

-- | big alpha
[hAzimuth] :: HorizonCoordinates -> DecimalDegrees

-- | Equatorial Coordinates, defines fixed position in the sky
data EquatorialCoordinates1
EC1 :: DecimalDegrees -> DecimalHours -> EquatorialCoordinates1

-- | delta
[e1Declination] :: EquatorialCoordinates1 -> DecimalDegrees

-- | alpha
[e1RightAscension] :: EquatorialCoordinates1 -> DecimalHours

-- | Equatorial Coordinates
data EquatorialCoordinates2
EC2 :: DecimalDegrees -> DecimalHours -> EquatorialCoordinates2

-- | delta
[e2Declination] :: EquatorialCoordinates2 -> DecimalDegrees

-- | H
[e2HoursAngle] :: EquatorialCoordinates2 -> DecimalHours

-- | Ecliptic Coordinates
data EclipticCoordinates
EcC :: DecimalDegrees -> DecimalDegrees -> EclipticCoordinates

-- | beta
[ecLatitude] :: EclipticCoordinates -> DecimalDegrees

-- | lambda
[ecLongitude] :: EclipticCoordinates -> DecimalDegrees

-- | Galactic Coordinates
data GalacticCoordinates
GC :: DecimalDegrees -> DecimalDegrees -> GalacticCoordinates

-- | b
[gLatitude] :: GalacticCoordinates -> DecimalDegrees

-- | l
[gLongitude] :: GalacticCoordinates -> DecimalDegrees

-- | Convert Right Ascension to Hour Angle for specified longitude and
--   Universal Time
raToHA :: DecimalHours -> DecimalDegrees -> JulianDate -> DecimalHours

-- | Convert Hour Angle to Right Ascension for specified longitude and
--   Universal Time
haToRA :: DecimalHours -> DecimalDegrees -> JulianDate -> DecimalHours

-- | Convert Equatorial Coordinates to Horizon Coordinates. It takes a
--   latitude of the observer and <a>EquatorialCoordinates2</a>. If you
--   need to convert <a>EquatorialCoordinates1</a> you may use
--   <tt>raToHa</tt> function to obtain <a>EquatorialCoordinates2</a> or
--   just use function-shortcut <a>ec1ToHC</a> straightaway. The functions
--   returns <a>HorizonCoordinates</a>.
equatorialToHorizon :: DecimalDegrees -> EquatorialCoordinates2 -> HorizonCoordinates

-- | Convert Horizon Coordinates to Equatorial Coordinates. It takes a
--   latitude of the observer and <a>HorizonCoordinates</a>. The functions
--   returns <a>EquatorialCoordinates2</a>. If you need to obtain
--   <a>EquatorialCoordinates1</a> you may use <tt>haToRa</tt> function, or
--   function-shortcut <a>hcToEC1</a>.
horizonToEquatorial :: DecimalDegrees -> HorizonCoordinates -> EquatorialCoordinates2

-- | Convert Equatorial Coordinates (Type 1) to Horizon Coordinates. This
--   is function shortcut - tt combines <a>equatorialToHorizon</a> and
--   <a>raToHA</a>. It takes geographic coordinates of the observer,
--   universal time and equatorial coordinates.
ec1ToHC :: GeographicCoordinates -> JulianDate -> EquatorialCoordinates1 -> HorizonCoordinates

-- | Convert Horizon Coordinates to Equatorial Coordinates (Type 1). This
--   is function shortcut - tt combines <a>horizonToEquatorial</a> and
--   <a>haToRA</a>. It takes geographic coordinates of the observer,
--   universal time and horizon coordinates.
hcToEC1 :: GeographicCoordinates -> JulianDate -> HorizonCoordinates -> EquatorialCoordinates1

-- | Function converts Equatorial Coordinates To Horizon Coordinates and
--   vice versa It takes a latitide of the observer as a first parameter
--   and a pair of 'how far up' and 'how far round' coordinates as a second
--   parameter. It returns a pair of 'how far up' and 'how far round'
--   coordinates.
ecHCConv :: DecimalDegrees -> (DecimalDegrees, DecimalDegrees) -> (DecimalDegrees, DecimalDegrees)

-- | Calculate the obliquity of the ecpliptic on JulianDate
obliquity :: JulianDate -> DecimalDegrees

-- | Converts Ecliptic Coordinates on specified Julian Date to Equatorial
--   Coordinates
eclipticToEquatorial :: EclipticCoordinates -> JulianDate -> EquatorialCoordinates1

-- | Converts Equatorial Coordinates to Ecliptic Coordinates on specified
--   Julian Date
equatorialToEcliptic :: EquatorialCoordinates1 -> JulianDate -> EclipticCoordinates

-- | Convert Galactic Coordinates Equatorial Coordinates
galacticToEquatorial :: GalacticCoordinates -> EquatorialCoordinates1

-- | Convert Equatorial Coordinates to Galactic Coordinates
equatorialToGalactic :: EquatorialCoordinates1 -> GalacticCoordinates
instance GHC.Classes.Eq Data.Astro.Coordinate.GalacticCoordinates
instance GHC.Show.Show Data.Astro.Coordinate.GalacticCoordinates
instance GHC.Classes.Eq Data.Astro.Coordinate.EclipticCoordinates
instance GHC.Show.Show Data.Astro.Coordinate.EclipticCoordinates
instance GHC.Classes.Eq Data.Astro.Coordinate.EquatorialCoordinates2
instance GHC.Show.Show Data.Astro.Coordinate.EquatorialCoordinates2
instance GHC.Classes.Eq Data.Astro.Coordinate.EquatorialCoordinates1
instance GHC.Show.Show Data.Astro.Coordinate.EquatorialCoordinates1
instance GHC.Classes.Eq Data.Astro.Coordinate.HorizonCoordinates
instance GHC.Show.Show Data.Astro.Coordinate.HorizonCoordinates


-- | Stars.
--   
--   <h1>Examples</h1>
--   
--   <h2><i>Location</i></h2>
--   
--   <pre>
--   import Data.Astro.Time.JulianDate
--   import Data.Astro.Coordinate
--   import Data.Astro.Types
--   import Data.Astro.Star
--   
--   
--   ro :: GeographicCoordinates
--   ro = GeoC (fromDMS 51 28 40) (-(fromDMS 0 0 5))
--   
--   dt :: LocalCivilTime
--   dt = lctFromYMDHMS (DH 1) 2017 6 25 10 29 0
--   
--   -- Calculate location of Betelgeuse
--   
--   betelgeuseEC1 :: EquatorialCoordinates1
--   betelgeuseEC1 = starCoordinates Betelgeuse
--   -- EC1 {e1Declination = DD 7.407064, e1RightAscension = DH 5.919529}
--   
--   betelgeuseHC :: HorizonCoordinates
--   betelgeuseHC = ec1ToHC ro (lctUniversalTime dt) betelgeuseEC1
--   -- HC {hAltitude = DD 38.30483892505852, hAzimuth = DD 136.75755644642248}
--   </pre>
--   
--   <h2><i>Rise and Set</i></h2>
--   
--   <pre>
--   import Data.Astro.Time.JulianDate
--   import Data.Astro.Coordinate
--   import Data.Astro.Types
--   import Data.Astro.Effects
--   import Data.Astro.CelestialObject.RiseSet
--   import Data.Astro.Star
--   
--   
--   ro :: GeographicCoordinates
--   ro = GeoC (fromDMS 51 28 40) (-(fromDMS 0 0 5))
--   
--   today :: LocalCivilDate
--   today = lcdFromYMD (DH 1) 2017 6 25
--   
--   -- Calculate location of Betelgeuse
--   
--   rigelEC1 :: EquatorialCoordinates1
--   rigelEC1 = starCoordinates Rigel
--   
--   verticalShift :: DecimalDegrees
--   verticalShift = refract (DD 0) 12 1012
--   -- DD 0.5660098245614035
--   
--   rigelRiseSet :: RiseSetLCT
--   rigelRiseSet = riseAndSetLCT ro today verticalShift rigelEC1
--   -- RiseSet (2017-06-25 06:38:18.4713 +1.0,DD 102.51249855335433) (2017-06-25 17:20:33.4902 +1.0,DD 257.48750144664564)
--   </pre>
module Data.Astro.Star

-- | Some of the stars
data Star
Polaris :: Star
AlphaCrucis :: Star
Sirius :: Star
Betelgeuse :: Star
Rigel :: Star
Vega :: Star
Antares :: Star
Canopus :: Star
Pleiades :: Star

-- | Returns Equatorial Coordinates for the given star
starCoordinates :: Star -> EquatorialCoordinates1
instance GHC.Classes.Eq Data.Astro.Star.Star
instance GHC.Show.Show Data.Astro.Star.Star


-- | Planet mechanics.
module Data.Astro.Planet.PlanetMechanics

-- | Calculate the planet mean anomaly.
planetMeanAnomaly :: PlanetDetails -> JulianDate -> DecimalDegrees

-- | Calculate the planet true anomaly using approximate method
planetTrueAnomaly1 :: PlanetDetails -> JulianDate -> DecimalDegrees

-- | Calculate Heliocentric Radius Vector. It takes Planet Details and true
--   anomaly.
planetHeliocentricRadiusVector :: PlanetDetails -> DecimalDegrees -> AstronomicalUnits

-- | Calculate Heliocentric Longitude. It takes Planet Details and true
--   anomaly.
planetHeliocentricLongitude :: PlanetDetails -> DecimalDegrees -> DecimalDegrees

-- | Calculate Heliocentric Latitude. It takes Planet Details and
--   heliocentric longitude.
planetHeliocentricLatitude :: PlanetDetails -> DecimalDegrees -> DecimalDegrees

-- | Calculate Heliocentric Radius Vector projected to the ecliptic. It
--   takes Planet Details, planetHeliocentric latitude and Radius Vector
planetProjectedRadiusVector :: PlanetDetails -> DecimalDegrees -> AstronomicalUnits -> AstronomicalUnits

-- | Calculate Heliocentric Longitude projected to the ecliptic. It takes
--   Planet Details and Heliocentric Longitude
planetProjectedLongitude :: PlanetDetails -> DecimalDegrees -> DecimalDegrees

-- | Calculate Ecliptic Longitude. It takes planet projected longitude,
--   planet projected radius vector the Earth's longitude and radius
--   vector.
planetEclipticLongitude :: PlanetDetails -> DecimalDegrees -> AstronomicalUnits -> DecimalDegrees -> AstronomicalUnits -> DecimalDegrees

-- | Calculate ecliptic Latitude. It takes the planet's: heliocentric
--   latitude, projected heliocentric longutide, projected heliocentric
--   longitude; the Earth's: heliocentric longitede and heliocentric radius
--   vector. Also it takes the planet's ecliptic longitude.
planetEclipticLatitude :: DecimalDegrees -> DecimalDegrees -> AstronomicalUnits -> DecimalDegrees -> AstronomicalUnits -> DecimalDegrees -> DecimalDegrees

-- | Calculate the planet's postion at the given date. It takes a function
--   to calculate true anomaly, planet details of the planet, planet
--   details of the Earth and JulianDate.
planetPosition :: (PlanetDetails -> JulianDate -> DecimalDegrees) -> PlanetDetails -> PlanetDetails -> JulianDate -> EquatorialCoordinates1

-- | Calculate the planet's postion at the given date using the approximate
--   algoruthm. It takes a function to calculate true anomaly, planet
--   details of the planet, planet details of the Earth and JulianDate.
planetPosition1 :: PlanetDetails -> PlanetDetails -> JulianDate -> EquatorialCoordinates1

-- | Calculates the distance betweeth the planet and the Earth at the given
--   date. It takes the planet's detail, the Earth's details and the julian
--   date.
planetDistance1 :: PlanetDetails -> PlanetDetails -> JulianDate -> AstronomicalUnits

-- | Calculates the planet's angular diameter for the given distance.
planetAngularDiameter :: PlanetDetails -> AstronomicalUnits -> DecimalDegrees

-- | Calculate the planet's phase at the given phase. Phase is a fraction
--   of the visible disc that is illuminated. It takes the planet's
--   details, the Earth's details and the julian date. Returns fraction
--   values from 0 to 1.
planetPhase1 :: PlanetDetails -> PlanetDetails -> JulianDate -> Double

-- | Calculates pertubations for the planet at the given julian date.
--   Returns a value that should be added to the mean longitude (planet
--   heliocentric longitude).
planetPertubations :: Planet -> JulianDate -> DecimalDegrees

-- | Calculate the planet's position-angle of the bright limb. It takes the
--   planet's coordinates and the Sun's coordinates. Position-angle is the
--   angle of the midpoint of the illuminated limb measured eastwards from
--   the north point of the disk.
planetBrightLimbPositionAngle :: EquatorialCoordinates1 -> EquatorialCoordinates1 -> DecimalDegrees


-- | Planet calculations.
--   
--   <h1>Example</h1>
--   
--   <h3><i>Initialisation</i></h3>
--   
--   <pre>
--   import Data.Astro.Time.JulianDate
--   import Data.Astro.Coordinate
--   import Data.Astro.Types
--   import Data.Astro.Effects
--   import Data.Astro.CelestialObject.RiseSet
--   import Data.Astro.Planet
--   
--   ro :: GeographicCoordinates
--   ro = GeoC (fromDMS 51 28 40) (-(fromDMS 0 0 5))
--   
--   dt :: LocalCivilTime
--   dt = lctFromYMDHMS (DH 1) 2017 6 25 10 29 0
--   
--   today :: LocalCivilDate
--   today = lcdFromYMD (DH 1) 2017 6 25
--   
--   jupiterDetails :: PlanetDetails
--   jupiterDetails = j2010PlanetDetails Jupiter
--   
--   earthDetails :: PlanetDetails
--   earthDetails = j2010PlanetDetails Earth
--   
--   jupiterPosition :: JulianDate -&gt; EquatorialCoordinates1
--   jupiterPosition = planetPosition planetTrueAnomaly1 jupiterDetails earthDetails
--   </pre>
--   
--   <h3><i>Calcaulate Coordinates</i></h3>
--   
--   <pre>
--   jupiterEC1 :: EquatorialCoordinates1
--   jupiterEC1 = jupiterPosition (lctUniversalTime dt)
--   -- EC1 {e1Declination = DD (-4.104626810672402), e1RightAscension = DH 12.863365504382228}
--   
--   jupiterHC :: HorizonCoordinates
--   jupiterHC = ec1ToHC ro (lctUniversalTime dt) jupiterEC1
--   -- HC {hAltitude = DD (-30.67914598469227), hAzimuth = DD 52.29376845044007}
--   </pre>
--   
--   <h3><i>Calculate Distance</i></h3>
--   
--   <pre>
--   jupiterDistance :: AstronomicalUnits
--   jupiterDistance = planetDistance1 jupiterDetails earthDetails (lctUniversalTime dt)
--   -- AU 5.193435872521039
--   </pre>
--   
--   <h3><i>Calculate Angular Size</i></h3>
--   
--   <pre>
--   jupiterAngularSize :: DecimalDegrees
--   jupiterAngularSize = planetAngularDiameter jupiterDetails jupiterDistance
--   -- DD 1.052289877865987e-2
--   
--   toDMS jupiterAngularSize
--   -- (0,0,37.88243560317554)
--   </pre>
--   
--   <h3><i>Calculate Rise and Set</i></h3>
--   
--   <pre>
--   verticalShift :: DecimalDegrees
--   verticalShift = refract (DD 0) 12 1012
--   -- DD 0.5660098245614035
--   
--   jupiterRiseSet :: RiseSetMB
--   jupiterRiseSet = riseAndSet2 0.000001 jupiterPosition ro verticalShift today
--   -- RiseSet
--   --    (Just (2017-06-25 13:53:27.3109 +1.0,DD 95.88943953535569))
--   --    (Just (2017-06-25 01:21:23.5835 +1.0,DD 264.1289033612776))
--   </pre>
module Data.Astro.Planet

-- | Planets of the Solar System
data Planet
Mercury :: Planet
Venus :: Planet
Earth :: Planet
Mars :: Planet
Jupiter :: Planet
Saturn :: Planet
Uranus :: Planet
Neptune :: Planet

-- | Details of the planetary orbit at the epoch
data PlanetDetails
PlanetDetails :: Planet -> JulianDate -> Double -> DecimalDegrees -> DecimalDegrees -> Double -> AstronomicalUnits -> DecimalDegrees -> DecimalDegrees -> DecimalDegrees -> PlanetDetails
[pdPlanet] :: PlanetDetails -> Planet
[pdEpoch] :: PlanetDetails -> JulianDate

-- | Orbital period in tropical years
[pdTp] :: PlanetDetails -> Double

-- | Longitude at the Epoch
[pdEpsilon] :: PlanetDetails -> DecimalDegrees

-- | Longitude of the perihelion
[pdOmegaBar] :: PlanetDetails -> DecimalDegrees

-- | Eccentricity of the orbit
[pdE] :: PlanetDetails -> Double

-- | Semi-major axis of the orbit in AU
[pdAlpha] :: PlanetDetails -> AstronomicalUnits

-- | Orbital inclination
[pdI] :: PlanetDetails -> DecimalDegrees

-- | Longitude of the ascending node
[pdBigOmega] :: PlanetDetails -> DecimalDegrees

-- | Angular diameter at 1 AU
[pdBigTheta] :: PlanetDetails -> DecimalDegrees

-- | PlanetDetails at the reference Epoch J2010.0
j2010PlanetDetails :: Planet -> PlanetDetails

-- | Calculate the planet true anomaly using approximate method
planetTrueAnomaly1 :: PlanetDetails -> JulianDate -> DecimalDegrees

-- | Calculate the planet's postion at the given date. It takes a function
--   to calculate true anomaly, planet details of the planet, planet
--   details of the Earth and JulianDate.
planetPosition :: (PlanetDetails -> JulianDate -> DecimalDegrees) -> PlanetDetails -> PlanetDetails -> JulianDate -> EquatorialCoordinates1

-- | Calculate the planet's postion at the given date using the approximate
--   algoruthm. It takes a function to calculate true anomaly, planet
--   details of the planet, planet details of the Earth and JulianDate.
planetPosition1 :: PlanetDetails -> PlanetDetails -> JulianDate -> EquatorialCoordinates1

-- | Calculates the distance betweeth the planet and the Earth at the given
--   date. It takes the planet's detail, the Earth's details and the julian
--   date.
planetDistance1 :: PlanetDetails -> PlanetDetails -> JulianDate -> AstronomicalUnits

-- | Calculates the planet's angular diameter for the given distance.
planetAngularDiameter :: PlanetDetails -> AstronomicalUnits -> DecimalDegrees

-- | Calculate the planet's phase at the given phase. Phase is a fraction
--   of the visible disc that is illuminated. It takes the planet's
--   details, the Earth's details and the julian date. Returns fraction
--   values from 0 to 1.
planetPhase1 :: PlanetDetails -> PlanetDetails -> JulianDate -> Double

-- | Calculate the planet's position-angle of the bright limb. It takes the
--   planet's coordinates and the Sun's coordinates. Position-angle is the
--   angle of the midpoint of the illuminated limb measured eastwards from
--   the north point of the disk.
planetBrightLimbPositionAngle :: EquatorialCoordinates1 -> EquatorialCoordinates1 -> DecimalDegrees


-- | Calculation effects of geocentric parallax.
module Data.Astro.Effects.Parallax

-- | It takes latitude of the observer and height above sea-level of the
--   observer measured in metres Returns palallax quantities (p*(sin phi'),
--   p*(cos phi')), where phi' is the geocentric latitude and p is the
--   distance of the obserbve from the centre of the Earth.
parallaxQuantities :: DecimalDegrees -> Double -> (Double, Double)

-- | Calculate the apparent position of the celestial object (the Sun or a
--   planet). It takes geocraphic coordinates of the observer and height
--   above sea-level of the observer measured in metres, distance from the
--   celestial object to the Earth measured in AU, the Universal Time and
--   geocentric equatorial coordinates. It returns adjusted equatorial
--   coordinates.
parallax :: GeographicCoordinates -> Double -> AstronomicalUnits -> JulianDate -> EquatorialCoordinates1 -> EquatorialCoordinates1


-- | Physical effects which influence on accuracy of astronomical
--   calculations.
module Data.Astro.Effects

-- | Calculate the atmospheric refraction angle. It takes the observed
--   altitude (of Horizon Coordinates), temperature in degrees centigrade
--   and barometric pressure in millibars. The average sea level
--   atmospheric pressure is 1013 millibars.
refract :: DecimalDegrees -> Double -> Double -> DecimalDegrees

-- | Epoch Enumeration. See also <a>Data.Astro.Time.JulianDate</a> module.
data AstronomyEpoch

-- | Epoch B1900.0
B1900 :: AstronomyEpoch

-- | Epoch B1950.0
B1950 :: AstronomyEpoch

-- | Epoch J2000.0
J2000 :: AstronomyEpoch

-- | Epoch J2050.0
J2050 :: AstronomyEpoch

-- | Low-precision method to calculate luni-solar precession. It takes
--   Epoch, Equatorial Coordinates those correct at the given epoch, Julian
--   Date of the observation. It returns corrected Equatorial Coordinates.
precession1 :: AstronomyEpoch -> EquatorialCoordinates1 -> JulianDate -> EquatorialCoordinates1

-- | Rigorous method to calculate luni-solar precession. It takes julian
--   date at whose the coordinates are correct, Equatorial Coordinates,
--   Julian Date of the observation. It returns corrected Equatorial
--   Coordinates.
precession2 :: JulianDate -> EquatorialCoordinates1 -> JulianDate -> EquatorialCoordinates1

-- | Calculates the nutation on the ecliptic longitude at the given
--   JulianDate
nutationLongitude :: JulianDate -> DecimalDegrees

-- | Calculates the nutation on the obliquity of the ecliptic at the given
--   JulianDate
nutationObliquity :: JulianDate -> DecimalDegrees

-- | Includes aberration effect. It takes true Ecliptic Coordinates, the
--   Sun's longitude at the given Julian Day (the third parameter). Returns
--   apparent ecliptic coordinates. The Sun's longitude can be calculated
--   using <tt>sunEclipticLongitude1</tt> or <tt>sunEclipticLongitude2</tt>
--   of <a>Data.Astro.Sun</a> module.
includeAberration :: EclipticCoordinates -> JulianDate -> DecimalDegrees -> EclipticCoordinates

-- | Calculate the apparent position of the celestial object (the Sun or a
--   planet). It takes geocraphic coordinates of the observer and height
--   above sea-level of the observer measured in metres, distance from the
--   celestial object to the Earth measured in AU, the Universal Time and
--   geocentric equatorial coordinates. It returns adjusted equatorial
--   coordinates.
parallax :: GeographicCoordinates -> Double -> AstronomicalUnits -> JulianDate -> EquatorialCoordinates1 -> EquatorialCoordinates1


-- | Computations characteristics of selestial objects.
module Data.Astro.CelestialObject

-- | Calculate angle between two celestial objects whose coordinates
--   specified in Equatorial Coordinate System.
angleEquatorial :: EquatorialCoordinates1 -> EquatorialCoordinates1 -> DecimalDegrees

-- | Calculate angle between two celestial objects whose coordinates
--   specified in Ecliptic Coordinate System.
angleEcliptic :: EclipticCoordinates -> EclipticCoordinates -> DecimalDegrees


-- | Computations rise and set of selestial objects.
--   
--   <h1>Examples</h1>
--   
--   <h2><i>Stars</i></h2>
--   
--   See <a>Data.Astro.Star</a> module for example.
--   
--   <h2><i>Planets</i></h2>
--   
--   See <a>Data.Astro.Planet</a> module for example.
module Data.Astro.CelestialObject.RiseSet

-- | Some Info of Rise and Set of a celestial object
data RiseSet a

-- | Some Info of Rise and Set of the celestial object
RiseSet :: a -> a -> RiseSet a

-- | The celestial object is always above the horizon
Circumpolar :: RiseSet a

-- | The celestial object is always below the horizon
NeverRises :: RiseSet a

-- | Rise or Set time and azimuth
type RSInfo a = (a, DecimalDegrees)

-- | LST (Local Sidereal Time) and Azimuth of Rise and Set
type RiseSetLST = RiseSet (RSInfo LocalSiderealTime)

-- | Local Civil Time and Azimuth of Rise and Set
type RiseSetLCT = RiseSet (RSInfo LocalCivilTime)

-- | The optional Rise And optinal Set Information (LocalCivilTime and
--   Azimuth)
type RiseSetMB = RiseSet (Maybe (RSInfo LocalCivilTime))

-- | Calculate rise and set local sidereal time of a celestial object. It
--   takes the equatorial coordinates of the celestial object, vertical
--   shift and the latitude of the observation. To calculate <i>vertical
--   shift</i> for stars use function <tt>refract</tt> from
--   <a>Data.Astro.Effects</a>. In most cases you can assume that
--   <i>vertical shift</i> equals 0.566569 (34 arcmins ~ 'refract (DD 0) 12
--   1012').
riseAndSet :: EquatorialCoordinates1 -> DecimalDegrees -> DecimalDegrees -> RiseSetLST

-- | Calculate rise and set local sidereal time of a celestial object that
--   changes its equatorial coordinates during the day (the Sun, the Moon,
--   planets). It takes epsilon, the function that returns equatorial
--   coordinates of the celestial object for a given julian date, vertical
--   shift and the latitude of the observation. To calculate <i>vertical
--   shift</i> for stars use function <tt>refract</tt> from
--   <a>Data.Astro.Effects</a>. In most cases you can assume that
--   <i>vertical shift</i> equals 0.566569 (34 arcmins ~ 'refract (DD 0) 12
--   1012').
riseAndSet2 :: DecimalHours -> (JulianDate -> EquatorialCoordinates1) -> GeographicCoordinates -> DecimalDegrees -> LocalCivilDate -> RiseSetMB

-- | Calculates set and rise of the celestial object It takes geographic
--   coordinates of the observer, local civil date, vertical shift and
--   equatorial coordinates of the celestial object.
riseAndSetLCT :: GeographicCoordinates -> LocalCivilDate -> DecimalDegrees -> EquatorialCoordinates1 -> RiseSetLCT

-- | Converts Rise and Set in Local Sidereal Time to Rise and Set in Local
--   Civil Time. It takes longutude of the observer and local civil date.
--   To calculate <i>vertical shift</i> for stars use function
--   <tt>refract</tt> from <a>Data.Astro.Effects</a>. In most cases you can
--   assume that <i>vertical shift</i> equals 0.566569 (34 arcmins ~
--   'refract (DD 0) 12 1012').
toRiseSetLCT :: DecimalDegrees -> LocalCivilDate -> RiseSetLST -> RiseSetLCT
instance GHC.Classes.Eq a => GHC.Classes.Eq (Data.Astro.CelestialObject.RiseSet.RiseSet a)
instance GHC.Show.Show a => GHC.Show.Show (Data.Astro.CelestialObject.RiseSet.RiseSet a)


-- | <h1>Calculation characteristics of the Sun.</h1>
--   
--   <h2><i>Terms</i></h2>
--   
--   <ul>
--   <li><b>perihelion</b> - minimal distance from the Sun to the
--   planet</li>
--   <li><b>aphelion</b> - maximal distance from the Sun to the planet</li>
--   <li><b>perigee</b> - minimal distance from the Sun to the Earth</li>
--   <li><b>apogee</b> - maximal distance from the Sun to the Earth</li>
--   </ul>
--   
--   <h1>Example</h1>
--   
--   <pre>
--   import Data.Astro.Time.JulianDate
--   import Data.Astro.Coordinate
--   import Data.Astro.Types
--   import Data.Astro.Sun
--   
--   ro :: GeographicCoordinates
--   ro = GeoC (fromDMS 51 28 40) (-(fromDMS 0 0 5))
--   
--   dt :: LocalCivilTime
--   dt = lctFromYMDHMS (DH 1) 2017 6 25 10 29 0
--   
--   today :: LocalCivilDate
--   today = lcdFromYMD (DH 1) 2017 6 25
--   
--   jd :: JulianDate
--   jd = lctUniversalTime dt
--   
--   verticalShift :: DecimalDegrees
--   verticalShift = refract (DD 0) 12 1012
--   
--   -- distance from the Earth to the Sun in kilometres
--   distance :: Double
--   distance = sunDistance jd
--   -- 1.5206375976421073e8
--   
--   -- Angular Size
--   angularSize :: DecimalDegrees
--   angularSize = sunAngularSize jd
--   -- DD 0.5244849215333616
--   
--   -- The Sun's coordinates
--   ec1 :: EquatorialCoordinates1
--   ec1 = sunPosition2 jd
--   -- EC1 {e1Declination = DD 23.37339098989099, e1RightAscension = DH 6.29262026252748}
--   
--   hc :: HorizonCoordinates
--   hc = ec1ToHC ro jd ec1
--   -- HC {hAltitude = DD 49.312050979507404, hAzimuth = DD 118.94723825710143}
--   
--   
--   -- Rise and Set
--   riseSet :: RiseSetMB
--   riseSet = sunRiseAndSet ro 0.833333 today
--   -- RiseSet
--   --    (Just (2017-06-25 04:44:04.3304 +1.0,DD 49.043237261724215))
--   --    (Just (2017-06-25 21:21:14.4565 +1.0,DD 310.91655607595595))
--   </pre>
module Data.Astro.Sun

-- | Details of the Sun's apparent orbit at the given epoch
data SunDetails
SunDetails :: JulianDate -> DecimalDegrees -> DecimalDegrees -> Double -> SunDetails

-- | Epoch
[sdEpoch] :: SunDetails -> JulianDate

-- | Ecliptic longitude at the Epoch
[sdEpsilon] :: SunDetails -> DecimalDegrees

-- | Ecliptic longitude of perigee at the Epoch
[sdOmega] :: SunDetails -> DecimalDegrees

-- | Eccentricity of the orbit at the Epoch
[sdE] :: SunDetails -> Double

-- | Some Info of Rise and Set of a celestial object
data RiseSet a

-- | Some Info of Rise and Set of the celestial object
RiseSet :: a -> a -> RiseSet a

-- | The celestial object is always above the horizon
Circumpolar :: RiseSet a

-- | The celestial object is always below the horizon
NeverRises :: RiseSet a

-- | Calculate SunDetails for the given JulianDate.
sunDetails :: JulianDate -> SunDetails

-- | SunDetails at the Sun's reference Epoch J2010.0
j2010SunDetails :: SunDetails

-- | Calculate mean anomaly using the second 'more accurate' method
sunMeanAnomaly2 :: SunDetails -> DecimalDegrees

-- | Calculate the ecliptic longitude of the Sun with the given SunDetails
--   at the given JulianDate
sunEclipticLongitude1 :: SunDetails -> JulianDate -> DecimalDegrees

-- | Calculate the ecliptic longitude of the Sun
sunEclipticLongitude2 :: SunDetails -> DecimalDegrees

-- | Calculate Equatorial Coordinates of the Sun with the given SunDetails
--   at the given JulianDate. It is recommended to use
--   <a>j2010SunDetails</a> as a first parameter.
sunPosition1 :: SunDetails -> JulianDate -> EquatorialCoordinates1

-- | More accurate method to calculate position of the Sun
sunPosition2 :: JulianDate -> EquatorialCoordinates1

-- | Calculate Sun-Earth distance.
sunDistance :: JulianDate -> Double

-- | Calculate the Sun's angular size (i.e. its angular diameter).
sunAngularSize :: JulianDate -> DecimalDegrees

-- | Calculatesthe Sun's rise and set It takes coordinates of the observer,
--   local civil date, vertical shift (good value is 0.833333). It returns
--   Nothing if fails to calculate rise and/or set. It should be accurate
--   to within a minute of time.
sunRiseAndSet :: GeographicCoordinates -> DecimalDegrees -> LocalCivilDate -> RiseSetMB

-- | Calculates discrepancy between the mean solar time and real solar time
--   at the given date.
equationOfTime :: JulianDate -> DecimalHours

-- | Calculates the angle between the lines of sight to the Sun and to a
--   celestial object specified by the given coordinates at the given
--   Universal Time.
solarElongation :: EquatorialCoordinates1 -> JulianDate -> DecimalDegrees
instance GHC.Show.Show Data.Astro.Sun.SunDetails


-- | Calculation characteristics of the Moon.
--   
--   <h1>Example</h1>
--   
--   <pre>
--   import Data.Astro.Time.JulianDate
--   import Data.Astro.Coordinate
--   import Data.Astro.Types
--   import Data.Astro.Effects
--   import Data.Astro.CelestialObject.RiseSet
--   import Data.Astro.Moon
--   
--   ro :: GeographicCoordinates
--   ro = GeoC (fromDMS 51 28 40) (-(fromDMS 0 0 5))
--   
--   dt :: LocalCivilTime
--   dt = lctFromYMDHMS (DH 1) 2017 6 25 10 29 0
--   
--   today :: LocalCivilDate
--   today = lcdFromYMD (DH 1) 2017 6 25
--   
--   jd :: JulianDate
--   jd = lctUniversalTime dt
--   
--   -- distance from the Earth to the Moon in kilometres
--   mdu :: MoonDistanceUnits
--   mdu = moonDistance1 j2010MoonDetails jd
--   -- MDU 0.9550170577020396
--   
--   distance :: Double
--   distance = mduToKm mdu
--   -- 367109.51199772174
--   
--   -- Angular Size
--   angularSize :: DecimalDegrees
--   angularSize = moonAngularSize mdu
--   -- DD 0.5425033990980761
--   
--   -- The Moon's coordinates
--   position :: JulianDate -&gt; EquatorialCoordinates1
--   position = moonPosition1 j2010MoonDetails
--   
--   ec1 :: EquatorialCoordinates1
--   ec1 = position jd
--   -- EC1 {e1Declination = DD 18.706180658927323, e1RightAscension = DH 7.56710547682055}
--   
--   hc :: HorizonCoordinates
--   hc = ec1ToHC ro jd ec1
--   -- HC {hAltitude = DD 34.57694951316064, hAzimuth = DD 103.91119101451832}
--   
--   -- Rise and Set
--   riseSet :: RiseSetMB
--   riseSet = riseAndSet2 0.000001 position ro verticalShift today
--   -- RiseSet
--   --    (Just (2017-06-25 06:22:51.4858 +1.0,DD 57.81458864497365))
--   --    (Just (2017-06-25 22:28:20.3023 +1.0,DD 300.4168238905249))
--   
--   -- Phase
--   phase :: Double
--   phase = moonPhase j2010MoonDetails jd
--   -- 2.4716141948212922e-2
--   
--   
--   sunEC1 :: EquatorialCoordinates1
--   sunEC1 = sunPosition2 jd
--   -- EC1 {e1Declination = DD 23.37339098989099, e1RightAscension = DH 6.29262026252748}
--   
--   limbAngle :: DecimalDegrees
--   limbAngle = moonBrightLimbPositionAngle ec1 sunEC1
--   -- DD 287.9869373767473
--   </pre>
module Data.Astro.Moon

-- | Calculate Equatorial Coordinates of the Moon with the given
--   MoonDetails and at the given JulianDate. It is recommended to use
--   <a>j2010MoonDetails</a> as a first parameter.
moonPosition1 :: MoonDetails -> JulianDate -> EquatorialCoordinates1

-- | Calculate Equatorial Coordinates of the Moon with the given
--   MoonDetails, distance to the Moon, geographic coordinates of the
--   onserver, height above sea-level of the observer measured in metres
--   (20 is a good reasonable value for the height) and at the given
--   JulianDate. It is recommended to use <a>j2010MoonDetails</a> as a
--   first parameter, to obtain the distance to the Moon you can use
--   <a>moonDistance1</a> function. <a>moonPosition2</a> takes into account
--   parallax effect.
moonPosition2 :: MoonDetails -> MoonDistanceUnits -> GeographicCoordinates -> Double -> JulianDate -> EquatorialCoordinates1

-- | Calculates the Moon's Distance at the given julian date. Returns
--   distance to the Moon moonDistance1 :: JulianDate -&gt;
--   MoonDistanceUnits you can use <a>mduToKm</a> (defined in
--   <a>Data.Astro.Moon.MoonDetails</a>) to convert result to kilometers
moonDistance1 :: MoonDetails -> JulianDate -> MoonDistanceUnits

-- | Calculate the Moon's angular size at the given distance.
moonAngularSize :: MoonDistanceUnits -> DecimalDegrees

-- | Calculates the Moon's horizontal parallax at the given distance.
moonHorizontalParallax :: MoonDistanceUnits -> DecimalDegrees

-- | Calculates the Moon's phase (the area of the visible segment expressed
--   as a fraction of the whole disk) at the given universal time.
moonPhase :: MoonDetails -> JulianDate -> Double

-- | Calculate the Moon's position-angle of the bright limb. It takes the
--   Moon's coordinates and the Sun's coordinates. Position-angle is the
--   angle of the midpoint of the illuminated limb measured eastwards from
--   the north point of the disk.
moonBrightLimbPositionAngle :: EquatorialCoordinates1 -> EquatorialCoordinates1 -> DecimalDegrees
