module Darcs.Patch.Progress
    ( progressRL
    , progressFL
    , progressRLShowTags
    ) where

import Darcs.Prelude

import System.IO.Unsafe ( unsafePerformIO )

import Darcs.Patch.Info ( justName, isTag )
import Darcs.Patch.PatchInfoAnd ( PatchInfoAnd, info )
import Darcs.Patch.Witnesses.Ordered ( FL(..), RL(..), lengthRL, lengthFL )

import Darcs.Util.Progress ( minlist, beginTedious, endTedious, progress,
                  progressKeepLatest, tediousSize, finishedOne )

startProgress :: a -> String -> Int -> a
startProgress :: forall a. a -> String -> Int -> a
startProgress a
x String
k Int
len = IO a -> a
forall a. IO a -> a
unsafePerformIO (IO a -> a) -> IO a -> a
forall a b. (a -> b) -> a -> b
$ do String -> IO ()
beginTedious String
k
                                             String -> Int -> IO ()
tediousSize String
k Int
len
                                             a -> IO a
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return a
x

-- | Evaluate an 'FL' list and report progress.
progressFL :: String -> FL a wX wY -> FL a wX wY
progressFL :: forall (a :: * -> * -> *) wX wY. String -> FL a wX wY -> FL a wX wY
progressFL String
_ FL a wX wY
NilFL = FL a wX wX
FL a wX wY
forall (a :: * -> * -> *) wX. FL a wX wX
NilFL
progressFL String
k xxs :: FL a wX wY
xxs@(a wX wY
x :>: FL a wY wY
xs) = if Int
xxsLen Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
minlist
                                  then FL a wX wY
xxs
                                  else a wX wY -> String -> Int -> a wX wY
forall a. a -> String -> Int -> a
startProgress a wX wY
x String
k Int
xxsLen a wX wY -> FL a wY wY -> FL a wX wY
forall (a :: * -> * -> *) wX wY wZ.
a wX wY -> FL a wY wZ -> FL a wX wZ
:>: FL a wY wY -> FL a wY wY
forall (a :: * -> * -> *) wX wY. FL a wX wY -> FL a wX wY
pl FL a wY wY
xs
  where
    xxsLen :: Int
xxsLen = FL a wX wY -> Int
forall (a :: * -> * -> *) wX wZ. FL a wX wZ -> Int
lengthFL FL a wX wY
xxs

    pl :: FL a wX wY -> FL a wX wY
    pl :: forall (a :: * -> * -> *) wX wY. FL a wX wY -> FL a wX wY
pl FL a wX wY
NilFL = FL a wX wX
FL a wX wY
forall (a :: * -> * -> *) wX. FL a wX wX
NilFL
    pl (a wX wY
y :>: FL a wY wY
NilFL) = IO (FL a wX wY) -> FL a wX wY
forall a. IO a -> a
unsafePerformIO (IO (FL a wX wY) -> FL a wX wY) -> IO (FL a wX wY) -> FL a wX wY
forall a b. (a -> b) -> a -> b
$ do String -> IO ()
endTedious String
k
                                            FL a wX wY -> IO (FL a wX wY)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (a wX wY
y a wX wY -> FL a wY wY -> FL a wX wY
forall (a :: * -> * -> *) wX wY wZ.
a wX wY -> FL a wY wZ -> FL a wX wZ
:>: FL a wY wY
FL a wY wY
forall (a :: * -> * -> *) wX. FL a wX wX
NilFL)
    pl (a wX wY
y :>: FL a wY wY
ys) = String -> a wX wY -> a wX wY
forall a. String -> a -> a
progress String
k a wX wY
y a wX wY -> FL a wY wY -> FL a wX wY
forall (a :: * -> * -> *) wX wY wZ.
a wX wY -> FL a wY wZ -> FL a wX wZ
:>: FL a wY wY -> FL a wY wY
forall (a :: * -> * -> *) wX wY. FL a wX wY -> FL a wX wY
pl FL a wY wY
ys

-- | Evaluate an 'RL' list and report progress.
progressRL :: String -> RL a wX wY -> RL a wX wY
progressRL :: forall (a :: * -> * -> *) wX wY. String -> RL a wX wY -> RL a wX wY
progressRL String
_ RL a wX wY
NilRL = RL a wX wX
RL a wX wY
forall (a :: * -> * -> *) wX. RL a wX wX
NilRL
progressRL String
k xxs :: RL a wX wY
xxs@(RL a wX wY
xs :<: a wY wY
x) =
    if Int
xxsLen Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
minlist
        then RL a wX wY
xxs
        else RL a wX wY -> RL a wX wY
forall (a :: * -> * -> *) wX wY. RL a wX wY -> RL a wX wY
pl RL a wX wY
xs RL a wX wY -> a wY wY -> RL a wX wY
forall (a :: * -> * -> *) wX wY wZ.
RL a wX wY -> a wY wZ -> RL a wX wZ
:<: a wY wY -> String -> Int -> a wY wY
forall a. a -> String -> Int -> a
startProgress a wY wY
x String
k Int
xxsLen
  where
    xxsLen :: Int
xxsLen = RL a wX wY -> Int
forall (a :: * -> * -> *) wX wZ. RL a wX wZ -> Int
lengthRL RL a wX wY
xxs
    pl :: RL a wX wY -> RL a wX wY
    pl :: forall (a :: * -> * -> *) wX wY. RL a wX wY -> RL a wX wY
pl RL a wX wY
NilRL = RL a wX wX
RL a wX wY
forall (a :: * -> * -> *) wX. RL a wX wX
NilRL
    pl (RL a wX wY
NilRL:<:a wY wY
y) = IO (RL a wX wY) -> RL a wX wY
forall a. IO a -> a
unsafePerformIO (IO (RL a wX wY) -> RL a wX wY) -> IO (RL a wX wY) -> RL a wX wY
forall a b. (a -> b) -> a -> b
$ do String -> IO ()
endTedious String
k
                                          RL a wX wY -> IO (RL a wX wY)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (RL a wX wX
forall (a :: * -> * -> *) wX. RL a wX wX
NilRLRL a wX wX -> a wX wY -> RL a wX wY
forall (a :: * -> * -> *) wX wY wZ.
RL a wX wY -> a wY wZ -> RL a wX wZ
:<:a wX wY
a wY wY
y)
    pl (RL a wX wY
ys:<:a wY wY
y) = RL a wX wY -> RL a wX wY
forall (a :: * -> * -> *) wX wY. RL a wX wY -> RL a wX wY
pl RL a wX wY
ys RL a wX wY -> a wY wY -> RL a wX wY
forall (a :: * -> * -> *) wX wY wZ.
RL a wX wY -> a wY wZ -> RL a wX wZ
:<: String -> a wY wY -> a wY wY
forall a. String -> a -> a
progress String
k a wY wY
y

-- | Evaluate an 'RL' list and report progress. In addition to printing
-- the number of patches we got, show the name of the last tag we got.
progressRLShowTags :: String -> RL (PatchInfoAnd p) wX wY
                   -> RL (PatchInfoAnd p) wX wY
progressRLShowTags :: forall (p :: * -> * -> *) wX wY.
String -> RL (PatchInfoAnd p) wX wY -> RL (PatchInfoAnd p) wX wY
progressRLShowTags String
_ RL (PatchInfoAnd p) wX wY
NilRL = RL (PatchInfoAnd p) wX wX
RL (PatchInfoAnd p) wX wY
forall (a :: * -> * -> *) wX. RL a wX wX
NilRL
progressRLShowTags String
k xxs :: RL (PatchInfoAnd p) wX wY
xxs@(RL (PatchInfoAnd p) wX wY
xs :<: PatchInfoAnd p wY wY
x) =
    if Int
xxsLen Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
minlist
        then RL (PatchInfoAnd p) wX wY
xxs
        else RL (PatchInfoAnd p) wX wY -> RL (PatchInfoAnd p) wX wY
forall (p :: * -> * -> *) wX wY.
RL (PatchInfoAnd p) wX wY -> RL (PatchInfoAnd p) wX wY
pl RL (PatchInfoAnd p) wX wY
xs RL (PatchInfoAnd p) wX wY
-> PatchInfoAnd p wY wY -> RL (PatchInfoAnd p) wX wY
forall (a :: * -> * -> *) wX wY wZ.
RL a wX wY -> a wY wZ -> RL a wX wZ
:<: PatchInfoAnd p wY wY -> String -> Int -> PatchInfoAnd p wY wY
forall a. a -> String -> Int -> a
startProgress PatchInfoAnd p wY wY
x String
k Int
xxsLen
  where
    xxsLen :: Int
xxsLen = RL (PatchInfoAnd p) wX wY -> Int
forall (a :: * -> * -> *) wX wZ. RL a wX wZ -> Int
lengthRL RL (PatchInfoAnd p) wX wY
xxs

    pl :: RL (PatchInfoAnd p) wX wY -> RL (PatchInfoAnd p) wX wY
    pl :: forall (p :: * -> * -> *) wX wY.
RL (PatchInfoAnd p) wX wY -> RL (PatchInfoAnd p) wX wY
pl RL (PatchInfoAnd p) wX wY
NilRL = RL (PatchInfoAnd p) wX wX
RL (PatchInfoAnd p) wX wY
forall (a :: * -> * -> *) wX. RL a wX wX
NilRL
    pl (RL (PatchInfoAnd p) wX wY
NilRL :<: PatchInfoAnd p wY wY
y) = IO (RL (PatchInfoAnd p) wX wY) -> RL (PatchInfoAnd p) wX wY
forall a. IO a -> a
unsafePerformIO (IO (RL (PatchInfoAnd p) wX wY) -> RL (PatchInfoAnd p) wX wY)
-> IO (RL (PatchInfoAnd p) wX wY) -> RL (PatchInfoAnd p) wX wY
forall a b. (a -> b) -> a -> b
$ do String -> IO ()
endTedious String
k
                                            RL (PatchInfoAnd p) wX wY -> IO (RL (PatchInfoAnd p) wX wY)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (RL (PatchInfoAnd p) wX wX
forall (a :: * -> * -> *) wX. RL a wX wX
NilRL RL (PatchInfoAnd p) wX wX
-> PatchInfoAnd p wX wY -> RL (PatchInfoAnd p) wX wY
forall (a :: * -> * -> *) wX wY wZ.
RL a wX wY -> a wY wZ -> RL a wX wZ
:<: PatchInfoAnd p wX wY
PatchInfoAnd p wY wY
y)
    pl (RL (PatchInfoAnd p) wX wY
ys :<: PatchInfoAnd p wY wY
y) =
        if PatchInfo -> Bool
isTag PatchInfo
iy
            then RL (PatchInfoAnd p) wX wY -> RL (PatchInfoAnd p) wX wY
forall (p :: * -> * -> *) wX wY.
RL (PatchInfoAnd p) wX wY -> RL (PatchInfoAnd p) wX wY
pl RL (PatchInfoAnd p) wX wY
ys RL (PatchInfoAnd p) wX wY
-> PatchInfoAnd p wY wY -> RL (PatchInfoAnd p) wX wY
forall (a :: * -> * -> *) wX wY wZ.
RL a wX wY -> a wY wZ -> RL a wX wZ
:<: String -> String -> PatchInfoAnd p wY wY -> PatchInfoAnd p wY wY
forall a. String -> String -> a -> a
finishedOne String
k (String
"back to "String -> String -> String
forall a. [a] -> [a] -> [a]
++ PatchInfo -> String
justName PatchInfo
iy) PatchInfoAnd p wY wY
y
            else RL (PatchInfoAnd p) wX wY -> RL (PatchInfoAnd p) wX wY
forall (p :: * -> * -> *) wX wY.
RL (PatchInfoAnd p) wX wY -> RL (PatchInfoAnd p) wX wY
pl RL (PatchInfoAnd p) wX wY
ys RL (PatchInfoAnd p) wX wY
-> PatchInfoAnd p wY wY -> RL (PatchInfoAnd p) wX wY
forall (a :: * -> * -> *) wX wY wZ.
RL a wX wY -> a wY wZ -> RL a wX wZ
:<: String -> PatchInfoAnd p wY wY -> PatchInfoAnd p wY wY
forall a. String -> a -> a
progressKeepLatest String
k PatchInfoAnd p wY wY
y
      where
        iy :: PatchInfo
iy = PatchInfoAnd p wY wY -> PatchInfo
forall (p :: * -> * -> *) wA wB. PatchInfoAndG p wA wB -> PatchInfo
info PatchInfoAnd p wY wY
y