-- |
-- Module:     Control.Wire.Trans.Exhibit
-- Copyright:  (c) 2011 Ertugrul Soeylemez
-- License:    BSD3
-- Maintainer: Ertugrul Soeylemez <es@ertes.de>
--
-- Wire transformers for handling inhibited signals.

module Control.Wire.Trans.Exhibit
    ( -- * Exhibition
      event,
      exhibit
    )
    where

import Control.Arrow
import Control.Wire.Types


-- | Produces 'Just', whenever the argument wire produces, otherwise
-- 'Nothing'.
--
-- * Depends: like argument wire.

event :: Arrow (>~) => Wire e (>~) a b -> Wire e (>~) a (Maybe b)
event (WPure f) =
    mkPure $ \(f -> (mx, w)) ->
        (Right $ either (const Nothing) Just mx, event w)
event (WGen c) =
    mkGen $ proc x' -> do
        (mx, w) <- c -< x'
        returnA -< (Right $ either (const Nothing) Just mx, event w)


-- | Produces 'Right', whenever the argument wire produces, otherwise
-- 'Left' with the inhibition value.
--
-- * Depends: like argument wire.

exhibit :: Arrow (>~) => Wire e (>~) a b -> Wire e (>~) a (Either e b)
exhibit (WPure f) =
    mkPure $ \(f -> (mx, w)) ->
        (Right mx, exhibit w)
exhibit (WGen c) =
    mkGen $ proc x' -> do
        (mx, w) <- c -< x'
        returnA -< (Right mx, exhibit w)