main = do
  args <- getArgs
  setDBUp

  case args of
    ["add"]        -> insert =<< create =<< nextId
    "edit" : ids   -> do
              max <- liftM fromJust maxId
              let ids' = if null ids then [max] else map read ids
              mCards <- mapM get ids'

              forM_ (catMaybes mCards) $
                        \ card -> update card =<< edit card
    ["export"]     -> mapM_ export =<< cards
    ["info"]       -> putDBInfo
    ["list"]       -> mapM_ put =<< cards
    "pick": _      -> do
              (opts, ids) <- parseOpt allOptions $ tail args

              if optAll opts
                then do
                  dueCards <- filterM isDue =<< randomCards

                  forM_ dueCards $
                            \ card -> do
                              isOk <- ask card

                              (=<<) (update card)
                                      (if isOk
                                         then promote card
                                         else demote card)
                else do
                  mFirst <- first =<< randomCards
                  let ids' = map read ids
                  mCards <- mapM get ids'
                  let mCards' = if null mCards then [mFirst] else mCards

                  forM_ (catMaybes mCards') $
                            \ card -> do
                              isOk <- ask card

                              (=<<) (update card)
                                      (if isOk
                                         then promote card
                                         else demote card)
    "remove" : ids -> if null ids
                        then delete =<< liftM fromJust maxId
                        else mapM_ (delete . read) ids
    _              -> putStrLn ("Argument has to be either add, " ++
                                "edit [ids...], export, info, list, " ++
                                "pick [ids...|-a|--all] or remove [ids...].")
main = do
  args <- getArgs
  setDBUp

  case args of
    ["add"]        -> insert =<< create =<< nextId
    "edit" : ids   -> do
              max <- liftM fromJust maxId
              let ids' = if null ids then [max] else map read ids
              mCards <- mapM get ids'

              forM_ (catMaybes mCards) $
                        \ card -> update card =<< edit card
    ["export"]     -> mapM_ export =<< cards
    ["info"]       -> putDBInfo
    ["list"]       -> mapM_ put =<< cards
    "pick": _      -> do
              (opts, ids) <- parseOpt allOptions $ tail args

              if optAll opts
                then do
                  dueCards <- filterM isDue =<< randomCards

                  forM_ dueCards $
                            \ card -> do
                              isOk <- ask card

                              (=<<) (update card)
                                      (if isOk
                                         then promote card
                                         else demote card)
                else do
                  mFirst <- first =<< randomCards
                  let ids' = map read ids
                  mCards <- mapM get ids'
                  let mCards' = if null mCards then [mFirst] else mCards

                  forM_ (catMaybes mCards') $
                            \ card -> do
                              isOk <- ask card

                              (=<<) (update card)
                                      (if isOk
                                         then promote card
                                         else demote card)
    "remove" : ids -> if null ids
                        then delete =<< liftM fromJust maxId
                        else mapM_ (delete . read) ids
    _              -> putStrLn ("Argument has to be either add, " ++
                                "edit [ids...], export, info, list, " ++
                                "pick [ids...|-a|--all] or remove [ids...].")
main = do
  args <- getArgs
  setDBUp

  case args of
    ["add"]        -> insert =<< create =<< nextId
    "edit" : ids   -> do
              max <- liftM fromJust maxId
              let ids' = if null ids then [max] else map read ids
              mCards <- mapM get ids'

              forM_ (catMaybes mCards) $
                        \ card -> update card =<< edit card
    ["export"]     -> mapM_ export =<< cards
    ["info"]       -> putDBInfo
    ["list"]       -> mapM_ put =<< cards
    "pick": _      -> do
              (opts, ids) <- parseOpt allOptions $ tail args

              if optAll opts
                then do
                  dueCards <- filterM isDue =<< randomCards

                  forM_ dueCards $
                            \ card -> do
                              isOk <- ask card

                              (=<<) (update card)
                                      (if isOk
                                         then promote card
                                         else demote card)
                else do
                  mFirst <- first =<< randomCards
                  let ids' = map read ids
                  mCards <- mapM get ids'
                  let mCards' = if null mCards then [mFirst] else mCards

                  forM_ (catMaybes mCards') $
                            \ card -> do
                              isOk <- ask card

                              (=<<) (update card)
                                      (if isOk
                                         then promote card
                                         else demote card)
    "remove" : ids -> if null ids
                        then delete =<< liftM fromJust maxId
                        else mapM_ (delete . read) ids
    _              -> putStrLn ("Argument has to be either add, " ++
                                "edit [ids...], export, info, list, " ++
                                "pick [ids...|-a|--all] or remove [ids...].")