content: module Unused.CLI.ProgressIndicator.Internal
      ( start
      , stop
      , increment
      , printPrefix
      ) where
  
  import qualified Control.Concurrent as CC
  import qualified Control.Monad as M
  import qualified System.ProgressBar as PB
  import Unused.CLI.ProgressIndicator.Types (ProgressIndicator(..))
  import Unused.CLI.Util
  
  start :: ProgressIndicator -> Int -> IO (CC.ThreadId, ProgressIndicator)
  start s@Spinner {} _ = do
      tid <- CC.forkIO $ runSpinner 0 s
      return (tid, s {sThreadId = Just tid})
  start ProgressBar {} i = do
      (ref, tid) <- buildProgressBar $ toInteger i
      return (tid, ProgressBar (Just ref) (Just tid))
  
  stop :: ProgressIndicator -> IO ()
  stop ProgressBar {pbThreadId = Just tid} = CC.killThread tid
  stop Spinner {sThreadId = Just tid} = CC.killThread tid
  stop _ = return ()
  
  increment :: ProgressIndicator -> IO ()
  increment ProgressBar {pbProgressRef = Just ref} = PB.incProgress ref 1
  increment _ = return ()
  
  printPrefix :: ProgressIndicator -> IO ()
  printPrefix ProgressBar {} = putStr "\n\n"
  printPrefix Spinner {} = putStr " "
  
  runSpinner :: Int -> ProgressIndicator -> IO ()
  runSpinner i s@Spinner {sDelay = delay, sSnapshots = snapshots, sColors = colors, sLength = length'} =
      M.forever $ do
          setSGR [SetColor Foreground Dull currentColor]
          putStr currentSnapshot
          cursorBackward 1
          CC.threadDelay delay
          runSpinner (i + 1) s
    where
      currentSnapshot = snapshots !! (i `mod` snapshotLength)
      currentColor = colors !! (i `div` snapshotLength)
      snapshotLength = length'
  runSpinner _ _ = return ()
  
  buildProgressBar :: Integer -> IO (PB.ProgressRef, CC.ThreadId)
  buildProgressBar = PB.startProgress (PB.msg message) PB.percentage progressBarWidth
    where
      message = "Working"
      progressBarWidth = 60
  