{-# LANGUAGE RecordWildCards, CPP #-}
-- | This module provides a function to build an 'Output' for Unix
-- terminal devices.
--
-- This module is exposed for testing purposes only; applications should
-- never need to import this directly.
module Graphics.Vty.Platform.Unix.Output
  ( buildOutput
  )
where

import Graphics.Vty.Config
import Graphics.Vty.Output

import Graphics.Vty.Platform.Unix.Settings
import Graphics.Vty.Platform.Unix.Output.Color (detectColorMode)
import Graphics.Vty.Platform.Unix.Output.XTermColor as XTermColor
import Graphics.Vty.Platform.Unix.Output.TerminfoBased as TerminfoBased

import Data.List (isPrefixOf)

#if !MIN_VERSION_base(4,11,0)
import Data.Monoid ((<>))
#endif

-- | Returns an 'Output' for the terminal specified in 'UnixSettings'.
--
-- The specific output implementation chosen is based
-- on the @TERM@ environment variable and ultimately
-- uses @Graphics.Vty.Platform.Unix.Output.XTermColor@
-- for terminals that look @xterm@-like or
-- @Graphics.Vty.Platform.Unix.Output.TerminfoBased@ as a fallback
-- otherwise.
--
-- * If @TERM@ starts with @xterm@, @screen@, @rxvt@, or @tmux@, this
--   will the @xterm@-based implementation.
-- * Otherwise this will use the 'TerminfoBased' implementation.
buildOutput :: VtyUserConfig -> UnixSettings -> IO Output
buildOutput :: VtyUserConfig -> UnixSettings -> IO Output
buildOutput VtyUserConfig
config UnixSettings
settings = do
    let termName :: String
termName = UnixSettings -> String
settingTermName UnixSettings
settings
        fd :: Fd
fd = UnixSettings -> Fd
settingOutputFd UnixSettings
settings

    ColorMode
colorMode <- case VtyUserConfig -> Maybe ColorMode
configPreferredColorMode VtyUserConfig
config of
        Maybe ColorMode
Nothing -> String -> IO ColorMode
detectColorMode String
termName
        Just ColorMode
m -> forall (m :: * -> *) a. Monad m => a -> m a
return ColorMode
m

    Output
t <- if String -> Bool
isXtermLike String
termName
         then forall (m :: * -> *).
(Applicative m, MonadIO m) =>
String -> Fd -> ColorMode -> m Output
XTermColor.reserveTerminal String
termName Fd
fd ColorMode
colorMode
         -- Not an xterm-like terminal. try for generic terminfo.
         else String -> Fd -> ColorMode -> IO Output
TerminfoBased.reserveTerminal String
termName Fd
fd ColorMode
colorMode

    forall (m :: * -> *) a. Monad m => a -> m a
return Output
t

isXtermLike :: String -> Bool
isXtermLike :: String -> Bool
isXtermLike String
termName =
    forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (forall a. Eq a => [a] -> [a] -> Bool
`isPrefixOf` String
termName) [String]
xtermLikeTerminalNamePrefixes

xtermLikeTerminalNamePrefixes :: [String]
xtermLikeTerminalNamePrefixes :: [String]
xtermLikeTerminalNamePrefixes =
    [ String
"xterm"
    , String
"screen"
    , String
"tmux"
    , String
"rxvt"
    ]