    -- | Basic types used by this library.
    {-# LANGUAGE RankNTypes #-}
    {-# OPTIONS_GHC -fno-warn-orphans #-}
    module Brick.Types
      ( -- * The Widget type
        Widget(..)

        -- * Location types and lenses
      , Location(..)
      , locL
      , TerminalLocation(..)
      , CursorLocation(..)
      , cursorLocationL
      , cursorLocationNameL

      -- * Viewports
      , Viewport(..)
      , ViewportType(..)
      , vpSize
      , vpTop
      , vpLeft
      , vpContentSize
      , VScrollBarOrientation(..)
      , HScrollBarOrientation(..)
      , VScrollbarRenderer(..)
      , HScrollbarRenderer(..)
      , ClickableScrollbarElement(..)

      -- * Event-handling types and functions
      , EventM
      , BrickEvent(..)
      , nestEventM
      , nestEventM'

      -- * Rendering infrastructure
      , RenderM
      , getContext

      -- ** The rendering context
      , Context(ctxAttrName, availWidth, availHeight, windowWidth, windowHeight, ctxBorderStyle, ctxAttrMap, ctxDynBorders)
      , attrL
      , availWidthL
      , availHeightL
      , windowWidthL
      , windowHeightL
      , ctxVScrollBarOrientationL
      , ctxVScrollBarRendererL
      , ctxHScrollBarOrientationL
      , ctxHScrollBarRendererL
      , ctxAttrMapL
      , ctxAttrNameL
      , ctxBorderStyleL
      , ctxDynBordersL

      -- ** Rendering results
      , Result(..)
      , emptyResult
      , lookupAttrName
      , Extent(..)

      -- ** Rendering result lenses
      , imageL
      , cursorsL
      , visibilityRequestsL
      , extentsL

      -- ** Visibility requests
      , VisibilityRequest(..)
      , vrPositionL
      , vrSizeL

      -- * Making lenses
      , suffixLenses
      , suffixLensesWith

      -- * Dynamic borders
      , bordersL
      , DynBorder(..)
      , dbStyleL, dbAttrL, dbSegmentsL
      , BorderSegment(..)
      , bsAcceptL, bsOfferL, bsDrawL
      , Edges(..)
      , eTopL, eBottomL, eRightL, eLeftL

      -- * Miscellaneous
      , Size(..)
      , Direction(..)

      -- * Renderer internals (for benchmarking)
      , RenderState

      -- * Re-exports for convenience
      , get
      , gets
      , put
      , modify
      , zoom
      )
    where

    import Lens.Micro (_1, _2, to, (^.))
    import Lens.Micro.Type (Getting)
    import Lens.Micro.Mtl (zoom)
    #if !MIN_VERSION_base(4,13,0)
    import Control.Monad.Fail (MonadFail)
    #endif
    import Control.Monad.State.Strict
    import Control.Monad.Reader
    import Graphics.Vty (Attr)

    import Brick.Types.TH
    import Brick.Types.Internal
    import Brick.Types.EventM
    import Brick.AttrMap (AttrName, attrMapLookup)

    -- | Given a state value and an 'EventM' that mutates that state, run
    -- the specified action and return resulting modified state.
    nestEventM' :: a
               -- ^ The initial state to use in the nested action.
                -> EventM n a b
                -- ^ The action to run.
                -> EventM n s a
    nestEventM' :: forall a n b s. a -> EventM n a b -> EventM n s a
    nestEventM' a
    s EventM n a b
    act = (a, b) -> a
    forall a b. (a, b) -> a
    fst ((a, b) -> a) -> EventM n s (a, b) -> EventM n s a
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> a -> EventM n a b -> EventM n s (a, b)
    forall a n b s. a -> EventM n a b -> EventM n s (a, b)
    nestEventM a
    s EventM n a b
    act

    -- | Given a state value and an 'EventM' that mutates that state, run
    -- the specified action and return both the resulting modified state and
    -- the result of the action itself.
    nestEventM :: a
               -- ^ The initial state to use in the nested action.
               -> EventM n a b
               -- ^ The action to run.
               -> EventM n s (a, b)
    nestEventM :: forall a n b s. a -> EventM n a b -> EventM n s (a, b)
    nestEventM a
    s' EventM n a b
    act = do
        ro <- ReaderT
      (EventRO n) (StateT s (StateT (EventState n) IO)) (EventRO n)
    -> EventM n s (EventRO n)
    forall n s a.
    ReaderT (EventRO n) (StateT s (StateT (EventState n) IO)) a
    -> EventM n s a
    EventM ReaderT
      (EventRO n) (StateT s (StateT (EventState n) IO)) (EventRO n)
    forall r (m :: * -> *). MonadReader r m => m r
    ask
        es <- EventM $ lift $ lift get
        vtyCtx <- getVtyContext
        let stInner = ES { nextAction :: NextAction
    nextAction = NextAction
    Continue
                         , esScrollRequests :: [(n, ScrollRequest)]
    esScrollRequests = EventState n -> [(n, ScrollRequest)]
    forall n. EventState n -> [(n, ScrollRequest)]
    esScrollRequests EventState n
    es
                         , cacheInvalidateRequests :: Set (CacheInvalidateRequest n)
    cacheInvalidateRequests = EventState n -> Set (CacheInvalidateRequest n)
    forall n. EventState n -> Set (CacheInvalidateRequest n)
    cacheInvalidateRequests EventState n
    es
                         , requestedVisibleNames :: Set n
    requestedVisibleNames = EventState n -> Set n
    forall n. EventState n -> Set n
    requestedVisibleNames EventState n
    es
                         , vtyContext :: VtyContext
    vtyContext = VtyContext
    vtyCtx
                         }
        ((actResult, newSt), stInnerFinal) <- liftIO $ runStateT (runStateT (runReaderT (runEventM act) ro) s') stInner

        EventM $ lift $ lift $ modify $
            \EventState n
    st -> EventState n
    st { nextAction = nextAction stInnerFinal
                      , esScrollRequests = esScrollRequests stInnerFinal
                      , cacheInvalidateRequests = cacheInvalidateRequests stInnerFinal
                      , requestedVisibleNames = requestedVisibleNames stInnerFinal
                      , vtyContext = vtyContext stInnerFinal
                      }
        return (newSt, actResult)

    -- | The rendering context's current drawing attribute.
    attrL :: forall r n. Getting r (Context n) Attr
    attrL :: forall r n. Getting r (Context n) Attr
    attrL = (Context n -> Attr) -> SimpleGetter (Context n) Attr
    forall s a. (s -> a) -> SimpleGetter s a
    to (\Context n
    c -> AttrName -> AttrMap -> Attr
    attrMapLookup (Context n
    cContext n -> Getting AttrName (Context n) AttrName -> AttrName
    forall s a. s -> Getting a s a -> a
    ^.Getting AttrName (Context n) AttrName
    forall n (f :: * -> *).
    Functor f =>
    (AttrName -> f AttrName) -> Context n -> f (Context n)
    ctxAttrNameL) (Context n
    cContext n -> Getting AttrMap (Context n) AttrMap -> AttrMap
    forall s a. s -> Getting a s a -> a
    ^.Getting AttrMap (Context n) AttrMap
    forall n (f :: * -> *).
    Functor f =>
    (AttrMap -> f AttrMap) -> Context n -> f (Context n)
    ctxAttrMapL))

    instance TerminalLocation (CursorLocation n) where
        locationColumnL :: Lens' (CursorLocation n) Int
    locationColumnL = (Location -> f Location)
    -> CursorLocation n -> f (CursorLocation n)
    forall n (f :: * -> *).
    Functor f =>
    (Location -> f Location)
    -> CursorLocation n -> f (CursorLocation n)
    cursorLocationL((Location -> f Location)
     -> CursorLocation n -> f (CursorLocation n))
    -> ((Int -> f Int) -> Location -> f Location)
    -> (Int -> f Int)
    -> CursorLocation n
    -> f (CursorLocation n)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    .(Int -> f Int) -> Location -> f Location
    forall s t a b. Field1 s t a b => Lens s t a b
    Lens Location Location Int Int
    _1
        locationColumn :: CursorLocation n -> Int
    locationColumn = Location -> Int
    forall a. TerminalLocation a => a -> Int
    locationColumn (Location -> Int)
    -> (CursorLocation n -> Location) -> CursorLocation n -> Int
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . CursorLocation n -> Location
    forall n. CursorLocation n -> Location
    cursorLocation
        locationRowL :: Lens' (CursorLocation n) Int
    locationRowL = (Location -> f Location)
    -> CursorLocation n -> f (CursorLocation n)
    forall n (f :: * -> *).
    Functor f =>
    (Location -> f Location)
    -> CursorLocation n -> f (CursorLocation n)
    cursorLocationL((Location -> f Location)
     -> CursorLocation n -> f (CursorLocation n))
    -> ((Int -> f Int) -> Location -> f Location)
    -> (Int -> f Int)
    -> CursorLocation n
    -> f (CursorLocation n)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    .(Int -> f Int) -> Location -> f Location
    forall s t a b. Field2 s t a b => Lens s t a b
    Lens Location Location Int Int
    _2
        locationRow :: CursorLocation n -> Int
    locationRow = Location -> Int
    forall a. TerminalLocation a => a -> Int
    locationRow (Location -> Int)
    -> (CursorLocation n -> Location) -> CursorLocation n -> Int
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . CursorLocation n -> Location
    forall n. CursorLocation n -> Location
    cursorLocation

    -- | Given an attribute name, obtain the attribute for the attribute
    -- name by consulting the context's attribute map.
    lookupAttrName :: AttrName -> RenderM n Attr
    lookupAttrName :: forall n. AttrName -> RenderM n Attr
    lookupAttrName AttrName
    n = do
        c <- RenderM n (Context n)
    forall n. RenderM n (Context n)
    getContext
        return $ attrMapLookup n (c^.ctxAttrMapL)