content: -- |This module provides infrastructure for widgets that need to
  -- produce events and provide event handler registration
  -- functionality.
  module Graphics.Vty.Widgets.Events
      ( Handlers
      , Handler
      , newHandlers
      , addHandler
      , fireEvent
      )
  where
  
  import Control.Monad
  import Data.IORef
  
  -- |The type of event handlers which take a parameter of type 'a'.
  type Handler a = a -> IO ()
  
  -- |The type of event handler collections of parameter type 'a'.
  newtype Handlers a = Handlers (IORef [Handler a])
  
  -- |Given an event handler collection projection combinator, a target,
  -- and a handler, add the handler to the target's event handler
  -- collection.
  addHandler :: (w -> IO (Handlers a)) -> w -> Handler a -> IO ()
  addHandler getRef w handler = do
    (Handlers r) <- getRef w
    modifyIORef r $ \s -> s ++ [handler]
  
  -- |Fire an event by extracting an event handler collection from a
  -- target and invoking all of its handlers with the specified
  -- parameter value.
  fireEvent :: w -> (w -> IO (Handlers a)) -> a -> IO ()
  fireEvent w getRef ev = do
    (Handlers r) <- getRef w
    handlers <- readIORef r
    forM_ handlers $ \handler ->
        handler ev
  
  -- |Create a new event handler collection.
  newHandlers :: IO (Handlers a)
  newHandlers = do
    r <- newIORef []
    return $ Handlers r
  