module Game.LambdaHack.Common.LQueue
( LQueue
, newLQueue, nullLQueue, lengthLQueue, tryReadLQueue, writeLQueue
, trimLQueue, dropStartLQueue, lastLQueue, toListLQueue
) where
import Data.Maybe
type LQueue a = ([a], [a])
newLQueue :: LQueue a
newLQueue = ([], [])
nullLQueue :: LQueue a -> Bool
nullLQueue (rs, ws) = null rs && null ws
lengthLQueue :: LQueue a -> Int
lengthLQueue (rs, ws) = length rs + length ws
tryReadLQueue :: LQueue a -> Maybe (a, LQueue a)
tryReadLQueue (r : rs, ws) = Just (r, (rs, ws))
tryReadLQueue ([], []) = Nothing
tryReadLQueue ([], ws) = tryReadLQueue (reverse ws, [])
writeLQueue :: LQueue a -> a -> LQueue a
writeLQueue (rs, ws) w = (rs, w : ws)
trimLQueue :: LQueue (Maybe a) -> LQueue (Maybe a)
trimLQueue (rs, ws) =
let trim (_, w:_) = ([w], [])
trim ([], []) = ([], [])
trim (rsj, []) = ([last rsj], [])
in trim (filter isJust rs, filter isJust ws)
dropStartLQueue :: LQueue (Maybe a) -> LQueue (Maybe a)
dropStartLQueue (rs, ws) =
let dq = (dropWhile isNothing $ dropWhile isJust $ rs ++ reverse ws, [])
in if nullLQueue dq then trimLQueue (rs, ws) else dq
lastLQueue :: LQueue (Maybe a) -> Maybe a
lastLQueue (rs, ws) =
let lst (_, w:_) = Just w
lst ([], []) = Nothing
lst (rsj, []) = Just $ last rsj
in lst (catMaybes rs, catMaybes ws)
toListLQueue :: LQueue a -> [a]
toListLQueue (rs, ws) = rs ++ reverse ws