module JSDOM.EventTargetClosures
  ( EventName(..)
  , SaferEventListener(..)
  , eventNameString
  , unsafeEventName
  , unsafeEventNameAsync
  , eventListenerNew
  , eventListenerNewSync
  , eventListenerNewAsync
  , eventListenerRelease) where

import Control.Applicative ((<$>))
import JSDOM.Types
import Language.Javascript.JSaddle as JSaddle (function, asyncFunction, JSM, Function(..), freeFunction)

data EventName t e = EventNameSyncDefault DOMString | EventNameAsyncDefault DOMString

eventNameString :: EventName t e -> DOMString
eventNameString :: EventName t e -> DOMString
eventNameString (EventNameSyncDefault DOMString
s) = DOMString
s
eventNameString (EventNameAsyncDefault DOMString
s) = DOMString
s

newtype SaferEventListener t e = SaferEventListener JSaddle.Function

instance ToJSVal (SaferEventListener t e) where
    toJSVal :: SaferEventListener t e -> JSM JSVal
toJSVal (SaferEventListener Function
l) = Function -> JSM JSVal
forall a. ToJSVal a => a -> JSM JSVal
toJSVal Function
l
    {-# INLINE toJSVal #-}

--instance FromJSVal (SaferEventListener t e) where
--    fromJSVal l = fmap SaferEventListener <$> fromJSVal l
--    {-# INLINE fromJSVal #-}

unsafeEventName :: DOMString -> EventName t e
unsafeEventName :: DOMString -> EventName t e
unsafeEventName = DOMString -> EventName t e
forall t e. DOMString -> EventName t e
EventNameSyncDefault

unsafeEventNameAsync :: DOMString -> EventName t e
unsafeEventNameAsync :: DOMString -> EventName t e
unsafeEventNameAsync = DOMString -> EventName t e
forall t e. DOMString -> EventName t e
EventNameAsyncDefault

eventListenerNew :: (IsEvent e) => (e -> JSM ()) -> JSM (SaferEventListener t e)
eventListenerNew :: (e -> JSM ()) -> JSM (SaferEventListener t e)
eventListenerNew e -> JSM ()
callback = Function -> SaferEventListener t e
forall t e. Function -> SaferEventListener t e
SaferEventListener (Function -> SaferEventListener t e)
-> JSM Function -> JSM (SaferEventListener t e)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> JSCallAsFunction -> JSM Function
function (\JSVal
_ JSVal
_ [JSVal
e] -> JSVal -> JSM e
forall a. FromJSVal a => JSVal -> JSM a
fromJSValUnchecked JSVal
e JSM e -> (e -> JSM ()) -> JSM ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= e -> JSM ()
callback)

eventListenerNewSync :: (IsEvent e) => (e -> JSM ()) -> JSM (SaferEventListener t e)
eventListenerNewSync :: (e -> JSM ()) -> JSM (SaferEventListener t e)
eventListenerNewSync e -> JSM ()
callback = Function -> SaferEventListener t e
forall t e. Function -> SaferEventListener t e
SaferEventListener (Function -> SaferEventListener t e)
-> JSM Function -> JSM (SaferEventListener t e)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> JSCallAsFunction -> JSM Function
function (\JSVal
_ JSVal
_ [JSVal
e] -> JSVal -> JSM e
forall a. FromJSVal a => JSVal -> JSM a
fromJSValUnchecked JSVal
e JSM e -> (e -> JSM ()) -> JSM ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= e -> JSM ()
callback)

eventListenerNewAsync :: (IsEvent e) => (e -> JSM ()) -> JSM (SaferEventListener t e)
eventListenerNewAsync :: (e -> JSM ()) -> JSM (SaferEventListener t e)
eventListenerNewAsync e -> JSM ()
callback = Function -> SaferEventListener t e
forall t e. Function -> SaferEventListener t e
SaferEventListener (Function -> SaferEventListener t e)
-> JSM Function -> JSM (SaferEventListener t e)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> JSCallAsFunction -> JSM Function
asyncFunction (\JSVal
_ JSVal
_ [JSVal
e] -> JSVal -> JSM e
forall a. FromJSVal a => JSVal -> JSM a
fromJSValUnchecked JSVal
e JSM e -> (e -> JSM ()) -> JSM ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= e -> JSM ()
callback)

eventListenerRelease :: SaferEventListener t e -> JSM ()
eventListenerRelease :: SaferEventListener t e -> JSM ()
eventListenerRelease (SaferEventListener Function
f) = Function -> JSM ()
freeFunction Function
f