\begin{code}
module Event (
 module Event,
 module Listener,
 Event,Wire(..),neverE,
 mapE,filterE,mapMaybeE,withTimeE,afterTimeE,withIOE,mapEs,fromListE,
 traceE,mergeE,arrayE,alarmE,
 onceE,scanlE,distinctEWith,accumE,accumIOE,withElemE,switcherE,manyE,
 onceE',scanlE',distinctEWith',accumE',accumIOE',withElemE',switcherE',manyE',
 switcherL,

 addWeakListener,addListener,
 addListenerE,newWire,primNewWire,neverTermE

) where
import EventPrim
import WirePrim
import BaseTypes
import Listener

infixl 1 `bindOneE`,`bindManyE`,`bindOneE'`,`bindManyE'`
infixl 2 .|.

-- Binary event modifiers.  Left associative for cascading.
infixl 3 ==>, -=>, `withElemE_`, `suchThat`, `suchThat_`

\end{code}

-------------- non-primitives --------------

\begin{code}

-- infix map operators
(==>) :: Event a -> (a -> b) -> Event b
ev ==> f = mapE f ev

(-=>) :: Event a -> b -> Event b
ev -=> x  =  ev ==> const x

-- A synonym for merge
(.|.) :: Event a -> Event a -> Event a
e1 .|. e2 = mergeE e1 e2

-- List version of .|.

anyE :: [Event a] -> Event a
anyE = cache . foldr (mergeE) neverE

-- get the time

withTimeE_ :: Event a -> Event Time
withTimeE_ e = withTimeE e ==> snd

-- Filter out event occurrences whose data doesn't satisfy a condition.

isJustE :: Event (Maybe a) -> Event a
isJustE ev = mapMaybeE id ev 

-- Equivalent of filterE but with alternative ordering for arguments
suchThat :: Event a -> (a -> Bool) -> Event a
ev `suchThat` pred = filterE pred ev

suchThat_ :: Event a -> (a -> Bool) -> Event ()
ev `suchThat_` pred = ev `suchThat` pred -=> ()

-- lookup values from a table
assocE :: Eq key => Event key -> [(key,a)] -> Event a
assocE e pairs = mapMaybeE (flip lookup pairs) e

\end{code}

IO based functions
\begin{code}
-- filter out duplicate occurrences
distinctE :: Eq a => Event a -> IO (Event a)
distinctE = distinctEWith (==) (const False)

-- associate list with event occurrences
withElemE_ :: Event a -> [b] -> IO (Event b)
e `withElemE_` l = fmap (mapE snd) $ e `withElemE` l 

-- get only previous occurrences

withPrevE :: Event a -> a -> IO (Event (a,a))
e `withPrevE` a0 = scanlE (\(older,old) new -> (old,new))
                          (error "withPrevE: no prev", a0)
                          e

withPrevE_ :: Event a -> a -> IO (Event a)
e `withPrevE_` a0 = fmap (mapE snd) $ e `withPrevE` a0 
\end{code}

Monad like implementations on events

\begin{code}
bindOneE' :: Event a -> (a -> Event b) -> Event b
bindOneE' ev f = neverE `switcherE'` mapE f ev

bindManyE' :: Event a -> (a -> Event b) -> Event b
bindManyE' ev f = neverE `manyE'` mapE f ev

bindOneE :: Event a -> (a -> Event b) -> IO (Event b)
bindOneE ev f = neverE `switcherE` mapE f ev

bindManyE :: Event a -> (a -> Event b) -> IO (Event b)
bindManyE ev f = neverE `manyE` mapE f ev
\end{code}



