module Sound.MED.Raw.BlockCmdPageTable where

import qualified Sound.MED.Raw.CmdPageData as CmdPageData
import Sound.MED.Raw.CmdPageData(CmdPageData)

import Sound.MED.Basic.Amiga
import Sound.MED.Basic.Utility

import Control.Monad (liftM)

data BlockCmdPageTable = BlockCmdPageTable
  { BlockCmdPageTable -> UWORD
num_pages :: UWORD
  , BlockCmdPageTable -> UWORD
reserved  :: UWORD
  , BlockCmdPageTable -> [Maybe [[CmdPageData]]]
pages     :: [ Maybe [ [ CmdPageData ] ] ]
  }
  deriving (Int -> BlockCmdPageTable -> ShowS
[BlockCmdPageTable] -> ShowS
BlockCmdPageTable -> String
(Int -> BlockCmdPageTable -> ShowS)
-> (BlockCmdPageTable -> String)
-> ([BlockCmdPageTable] -> ShowS)
-> Show BlockCmdPageTable
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [BlockCmdPageTable] -> ShowS
$cshowList :: [BlockCmdPageTable] -> ShowS
show :: BlockCmdPageTable -> String
$cshow :: BlockCmdPageTable -> String
showsPrec :: Int -> BlockCmdPageTable -> ShowS
$cshowsPrec :: Int -> BlockCmdPageTable -> ShowS
Show)

{-# SPECIALISE peek :: UWORD -> UWORD -> PTR -> StorableReader BlockCmdPageTable #-}
{-# SPECIALISE peek :: UWORD -> UWORD -> PTR -> ByteStringReader BlockCmdPageTable #-}
peek :: (Reader m) => UWORD -> UWORD -> PTR -> m BlockCmdPageTable
peek :: UWORD -> UWORD -> PTR -> m BlockCmdPageTable
peek UWORD
tracks UWORD
numlines PTR
p = do
  UWORD
num_pages' <- Peek m UWORD
forall (m :: * -> *). Reader m => Peek m UWORD
peekUWORD PTR
p
  UWORD
reserved'  <- Peek m UWORD
forall (m :: * -> *). Reader m => Peek m UWORD
peekUWORD (PTR
pPTR -> PTR -> PTR
forall a. Num a => a -> a -> a
+PTR
2)
  [PTR]
pages''    <- (PTR -> m PTR) -> [PTR] -> m [PTR]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM PTR -> m PTR
forall (m :: * -> *). Reader m => Peek m PTR
peekPTR ([PTR] -> m [PTR]) -> [PTR] -> m [PTR]
forall a b. (a -> b) -> a -> b
$ PTR -> PTR -> UWORD -> [PTR]
forall i. Integral i => PTR -> PTR -> i -> [PTR]
pointerRangeGen (PTR
pPTR -> PTR -> PTR
forall a. Num a => a -> a -> a
+PTR
4) PTR
4 UWORD
num_pages'
  [Maybe [[CmdPageData]]]
pages'     <- (PTR -> m (Maybe [[CmdPageData]]))
-> [PTR] -> m [Maybe [[CmdPageData]]]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (UWORD -> UWORD -> PTR -> m (Maybe [[CmdPageData]])
forall (m :: * -> *).
Reader m =>
UWORD -> UWORD -> PTR -> m (Maybe [[CmdPageData]])
peekPage UWORD
tracks UWORD
numlines) [PTR]
pages''
  BlockCmdPageTable -> m BlockCmdPageTable
forall (m :: * -> *) a. Monad m => a -> m a
return (BlockCmdPageTable -> m BlockCmdPageTable)
-> BlockCmdPageTable -> m BlockCmdPageTable
forall a b. (a -> b) -> a -> b
$ UWORD -> UWORD -> [Maybe [[CmdPageData]]] -> BlockCmdPageTable
BlockCmdPageTable
    UWORD
num_pages' UWORD
reserved' [Maybe [[CmdPageData]]]
pages'

peekPage ::
  (Reader m) => UWORD -> UWORD -> PTR -> m (Maybe [ [ CmdPageData ] ])
peekPage :: UWORD -> UWORD -> PTR -> m (Maybe [[CmdPageData]])
peekPage UWORD
tracks UWORD
numlines PTR
p =
  Bool -> m [[CmdPageData]] -> m (Maybe [[CmdPageData]])
forall (m :: * -> *) a. Monad m => Bool -> m a -> m (Maybe a)
skipIf (PTR
p PTR -> PTR -> Bool
forall a. Eq a => a -> a -> Bool
== PTR
0) (m [[CmdPageData]] -> m (Maybe [[CmdPageData]]))
-> m [[CmdPageData]] -> m (Maybe [[CmdPageData]])
forall a b. (a -> b) -> a -> b
$ ([CmdPageData] -> [[CmdPageData]])
-> m [CmdPageData] -> m [[CmdPageData]]
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM (UWORD -> [CmdPageData] -> [[CmdPageData]]
forall i a. Integral i => i -> [a] -> [[a]]
chunk UWORD
tracks) (m [CmdPageData] -> m [[CmdPageData]])
-> m [CmdPageData] -> m [[CmdPageData]]
forall a b. (a -> b) -> a -> b
$
    (PTR -> m CmdPageData) -> [PTR] -> m [CmdPageData]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM PTR -> m CmdPageData
forall (m :: * -> *). Reader m => PTR -> m CmdPageData
CmdPageData.peek ([PTR] -> m [CmdPageData]) -> [PTR] -> m [CmdPageData]
forall a b. (a -> b) -> a -> b
$ PTR -> PTR -> UWORD -> UWORD -> [PTR]
forall i j.
(Integral i, Integral j) =>
PTR -> PTR -> i -> j -> [PTR]
pointerRangeGen2 PTR
p PTR
2 UWORD
tracks UWORD
numlines