module Data.Geo.Haversine(
                           haversine
                         ) where

import Data.Geo.Sphere
import Data.Geo.Coord
import Data.Geo.Radians
import Data.Geo.Accessor.Lat
import Data.Geo.Accessor.Lon
import Data.Geo.Accessor.Value

haversine :: Sphere -> Coord -> Coord -> Double
haversine s start end = let lat1 = lat start
                            lat2 = lat end
                            dlat = (toRadians (lat1 - lat2)) / 2
                            dlon = (toRadians (lon start - lon end)) / 2
                            cosr = cos . toRadians
                            square x = x * x
                            a = square (sin dlat) + cosr lat1 * cosr lat2 * square (sin (dlon))
                            c = 2 * atan2 (sqrt a) (sqrt (1 - a))
                        in value s * c