-- This file is part of Intricacy -- Copyright (C) 2013 Martin Bays -- -- This program is free software: you can redistribute it and/or modify -- it under the terms of version 3 of the GNU General Public License as -- published by the Free Software Foundation, or any later version. -- -- You should have received a copy of the GNU General Public License -- along with this program. If not, see http://www.gnu.org/licenses/. module Init where import Control.Applicative import Control.Monad import Control.Monad.Trans import Control.Monad.Trans.Maybe import Control.Monad.Trans.State import Data.Maybe import System.Exit import System.Environment import System.Directory import System.FilePath import System.Console.GetOpt import Lock import MainState import Interact import Util data Opt = LockSize Int | ForceCurses | Help deriving (Eq, Ord, Show) options = [ Option ['c'] ["curses"] (NoArg ForceCurses) "force curses UI" , Option ['s'] ["locksize"] (ReqArg (LockSize . read) "SIZE") "locksize" , Option ['h'] ["help"] (NoArg Help) "show usage information" ] usage :: String usage = usageInfo header options where header = "Usage: intricacy [OPTION...] [file]" parseArgs :: [String] -> IO ([Opt],[String]) parseArgs argv = case getOpt Permute options argv of (o,n,[]) -> return (o,n) (_,_,errs) -> ioError (userError (concat errs ++ usage)) setup :: IO (Maybe Lock,[Opt],Maybe String) setup = do argv <- getArgs (opts,args) <- parseArgs argv when (Help `elem` opts) $ putStr usage >> exitSuccess let size = fromMaybe 8 $ listToMaybe [ size | LockSize size <- opts ] curDir <- getCurrentDirectory (fromJust <$>) $ runMaybeT $ msum [ do path <- liftMaybe ((curDir ) <$> listToMaybe args) msum [ do lock <- reframe.fst <$> MaybeT (readLock path) return (Just lock,opts,Just path) , return (Just $ baseLock size, opts, Just path) ] , return (Nothing,opts,Nothing) ] main' :: (UIMonad s, UIMonad c) => Maybe (s MainState -> IO (Maybe MainState)) -> Maybe (c MainState -> IO (Maybe MainState)) -> IO () main' msdlUI mcursesUI = do (mlock,opts,mpath) <- setup initMState <- case mlock of Nothing -> initMetaState Just lock -> return $ newEditState lock Nothing mpath void $ runMaybeT $ msum [ do finalState <- msum [ do guard $ ForceCurses `notElem` opts sdlUI <- liftMaybe $ msdlUI MaybeT $ sdlUI $ interactUI `execStateT` initMState , do cursesUI <- liftMaybe $ mcursesUI MaybeT $ cursesUI $ interactUI `execStateT` initMState ] when (isNothing mlock) $ lift $ writeMetaState finalState lift $ exitSuccess , lift exitFailure ]