module JSDOM.Custom.Geolocation (
    module Generated
  , getCurrentPosition'
  , getCurrentPosition
) where

import Data.Maybe (fromJust)

import Control.Monad.IO.Class (MonadIO(..))
import Control.Concurrent.MVar (takeMVar, putMVar, newEmptyMVar)

import JSDOM.Types

import JSDOM.Custom.PositionError (throwPositionException)

import JSDOM.Generated.PositionCallback
       (newPositionCallback)
import JSDOM.Generated.PositionErrorCallback
       (newPositionErrorCallback)

import JSDOM.Generated.Geolocation as Generated hiding (getCurrentPosition)
import qualified
       JSDOM.Generated.Geolocation as Generated
       (getCurrentPosition)

-- | <https://developer.mozilla.org/en-US/docs/Web/API/Geolocation.getCurrentPosition Mozilla Geolocation.getCurrentPosition documentation>
getCurrentPosition' :: MonadDOM m => Geolocation -> Maybe PositionOptions -> m (Either PositionError Geoposition)
getCurrentPosition' :: forall (m :: * -> *).
MonadDOM m =>
Geolocation
-> Maybe PositionOptions -> m (Either PositionError Geoposition)
getCurrentPosition' Geolocation
self Maybe PositionOptions
options = do
    MVar (Either PositionError Geoposition)
result <- IO (MVar (Either PositionError Geoposition))
-> m (MVar (Either PositionError Geoposition))
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO IO (MVar (Either PositionError Geoposition))
forall a. IO (MVar a)
newEmptyMVar
    JSM PositionCallback
-> (PositionCallback -> JSM (Either PositionError Geoposition))
-> m (Either PositionError Geoposition)
forall (m :: * -> *) c a.
(MonadDOM m, Coercible c Function) =>
JSM c -> (c -> JSM a) -> m a
withCallback ((Geoposition -> JSM ()) -> JSM PositionCallback
forall (m :: * -> *).
MonadDOM m =>
(Geoposition -> JSM ()) -> m PositionCallback
newPositionCallback (IO () -> JSM ()
forall a. IO a -> JSM a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> JSM ())
-> (Geoposition -> IO ()) -> Geoposition -> JSM ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MVar (Either PositionError Geoposition)
-> Either PositionError Geoposition -> IO ()
forall a. MVar a -> a -> IO ()
putMVar MVar (Either PositionError Geoposition)
result (Either PositionError Geoposition -> IO ())
-> (Geoposition -> Either PositionError Geoposition)
-> Geoposition
-> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Geoposition -> Either PositionError Geoposition
forall a b. b -> Either a b
Right)) ((PositionCallback -> JSM (Either PositionError Geoposition))
 -> m (Either PositionError Geoposition))
-> (PositionCallback -> JSM (Either PositionError Geoposition))
-> m (Either PositionError Geoposition)
forall a b. (a -> b) -> a -> b
$ \PositionCallback
success ->
        JSM PositionErrorCallback
-> (PositionErrorCallback
    -> JSM (Either PositionError Geoposition))
-> JSM (Either PositionError Geoposition)
forall (m :: * -> *) c a.
(MonadDOM m, Coercible c Function) =>
JSM c -> (c -> JSM a) -> m a
withCallback ((PositionError -> JSM ()) -> JSM PositionErrorCallback
forall (m :: * -> *).
MonadDOM m =>
(PositionError -> JSM ()) -> m PositionErrorCallback
newPositionErrorCallback (IO () -> JSM ()
forall a. IO a -> JSM a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> JSM ())
-> (PositionError -> IO ()) -> PositionError -> JSM ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. MVar (Either PositionError Geoposition)
-> Either PositionError Geoposition -> IO ()
forall a. MVar a -> a -> IO ()
putMVar MVar (Either PositionError Geoposition)
result (Either PositionError Geoposition -> IO ())
-> (PositionError -> Either PositionError Geoposition)
-> PositionError
-> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PositionError -> Either PositionError Geoposition
forall a b. a -> Either a b
Left)) ((PositionErrorCallback -> JSM (Either PositionError Geoposition))
 -> JSM (Either PositionError Geoposition))
-> (PositionErrorCallback
    -> JSM (Either PositionError Geoposition))
-> JSM (Either PositionError Geoposition)
forall a b. (a -> b) -> a -> b
$ \PositionErrorCallback
error -> do
            Geolocation
-> PositionCallback
-> Maybe PositionErrorCallback
-> Maybe PositionOptions
-> JSM ()
forall (m :: * -> *).
MonadDOM m =>
Geolocation
-> PositionCallback
-> Maybe PositionErrorCallback
-> Maybe PositionOptions
-> m ()
Generated.getCurrentPosition Geolocation
self PositionCallback
success (PositionErrorCallback -> Maybe PositionErrorCallback
forall a. a -> Maybe a
Just PositionErrorCallback
error) Maybe PositionOptions
options
            IO (Either PositionError Geoposition)
-> JSM (Either PositionError Geoposition)
forall a. IO a -> JSM a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (Either PositionError Geoposition)
 -> JSM (Either PositionError Geoposition))
-> IO (Either PositionError Geoposition)
-> JSM (Either PositionError Geoposition)
forall a b. (a -> b) -> a -> b
$ MVar (Either PositionError Geoposition)
-> IO (Either PositionError Geoposition)
forall a. MVar a -> IO a
takeMVar MVar (Either PositionError Geoposition)
result

-- | <https://developer.mozilla.org/en-US/docs/Web/API/Geolocation.getCurrentPosition Mozilla Geolocation.getCurrentPosition documentation>
getCurrentPosition :: MonadDOM m => Geolocation -> Maybe PositionOptions -> m Geoposition
getCurrentPosition :: forall (m :: * -> *).
MonadDOM m =>
Geolocation -> Maybe PositionOptions -> m Geoposition
getCurrentPosition Geolocation
self Maybe PositionOptions
options =
    Geolocation
-> Maybe PositionOptions -> m (Either PositionError Geoposition)
forall (m :: * -> *).
MonadDOM m =>
Geolocation
-> Maybe PositionOptions -> m (Either PositionError Geoposition)
getCurrentPosition' Geolocation
self Maybe PositionOptions
options m (Either PositionError Geoposition)
-> (Either PositionError Geoposition -> m Geoposition)
-> m Geoposition
forall a b. m a -> (a -> m b) -> m b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (PositionError -> m Geoposition)
-> (Geoposition -> m Geoposition)
-> Either PositionError Geoposition
-> m Geoposition
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either PositionError -> m Geoposition
forall (m :: * -> *) a. MonadDOM m => PositionError -> m a
throwPositionException Geoposition -> m Geoposition
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return