module System.Console.Haskeline.Backend where

import System.Console.Haskeline.Term
import System.Console.Haskeline.Monads
import Control.Monad
import System.IO (stdin, hGetEcho, Handle)

#ifdef MINGW
import System.Console.Haskeline.Backend.Win32 as Win32
#else
import System.Console.Haskeline.Backend.Posix as Posix
#ifdef TERMINFO
import System.Console.Haskeline.Backend.Terminfo as Terminfo
#endif
import System.Console.Haskeline.Backend.DumbTerm as DumbTerm
#endif


defaultRunTerm :: IO RunTerm
defaultRunTerm :: IO RunTerm
defaultRunTerm = (IO Bool -> MaybeT IO Bool
forall a. IO a -> MaybeT IO a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (Handle -> IO Bool
hGetEcho Handle
stdin) MaybeT IO Bool -> (Bool -> MaybeT IO ()) -> MaybeT IO ()
forall a b. MaybeT IO a -> (a -> MaybeT IO b) -> MaybeT IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Bool -> MaybeT IO ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard MaybeT IO () -> MaybeT IO RunTerm -> MaybeT IO RunTerm
forall a b. MaybeT IO a -> MaybeT IO b -> MaybeT IO b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> MaybeT IO RunTerm
stdinTTY)
                    MaybeT IO RunTerm -> IO RunTerm -> IO RunTerm
forall (m :: * -> *) a. Monad m => MaybeT m a -> m a -> m a
`orElse` Handle -> IO RunTerm
fileHandleRunTerm Handle
stdin

terminalRunTerm :: IO RunTerm
terminalRunTerm :: IO RunTerm
terminalRunTerm = MaybeT IO RunTerm
directTTY MaybeT IO RunTerm -> IO RunTerm -> IO RunTerm
forall (m :: * -> *) a. Monad m => MaybeT m a -> m a -> m a
`orElse` Handle -> IO RunTerm
fileHandleRunTerm Handle
stdin

stdinTTY :: MaybeT IO RunTerm
#ifdef MINGW
stdinTTY = win32TermStdin
#else
stdinTTY :: MaybeT IO RunTerm
stdinTTY = MaybeT IO Handles
stdinTTYHandles MaybeT IO Handles
-> (Handles -> MaybeT IO RunTerm) -> MaybeT IO RunTerm
forall a b. MaybeT IO a -> (a -> MaybeT IO b) -> MaybeT IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Handles -> MaybeT IO RunTerm
runDraw
#endif

directTTY :: MaybeT IO RunTerm
#ifdef MINGW
directTTY = win32Term
#else
directTTY :: MaybeT IO RunTerm
directTTY = MaybeT IO Handles
ttyHandles MaybeT IO Handles
-> (Handles -> MaybeT IO RunTerm) -> MaybeT IO RunTerm
forall a b. MaybeT IO a -> (a -> MaybeT IO b) -> MaybeT IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Handles -> MaybeT IO RunTerm
runDraw
#endif


#ifndef MINGW
runDraw :: Handles -> MaybeT IO RunTerm
#ifndef TERMINFO
runDraw = runDumbTerm
#else
runDraw :: Handles -> MaybeT IO RunTerm
runDraw Handles
h = Handles -> MaybeT IO RunTerm
runTerminfoDraw Handles
h MaybeT IO RunTerm -> MaybeT IO RunTerm -> MaybeT IO RunTerm
forall a. MaybeT IO a -> MaybeT IO a -> MaybeT IO a
forall (m :: * -> *) a. MonadPlus m => m a -> m a -> m a
`mplus` Handles -> MaybeT IO RunTerm
runDumbTerm Handles
h
#endif
#endif

fileHandleRunTerm :: Handle -> IO RunTerm
#ifdef MINGW
fileHandleRunTerm = Win32.fileRunTerm
#else
fileHandleRunTerm :: Handle -> IO RunTerm
fileHandleRunTerm = Handle -> IO RunTerm
Posix.fileRunTerm
#endif