module Sound.MED.Raw.MMD1Block where

import qualified Sound.MED.Raw.BlockInfo as BlockInfo
import Sound.MED.Raw.BlockInfo(BlockInfo)
import qualified Sound.MED.Raw.MMD1NoteData as MMD1NoteData
import Sound.MED.Raw.MMD1NoteData(MMD1NoteData)

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

data MMD1Block = MMD1Block
  { MMD1Block -> UWORD
numtracks :: UWORD
  , MMD1Block -> UWORD
lines     :: UWORD -- NOTE: actual number of lines is one greater
  , MMD1Block -> Maybe BlockInfo
info      :: Maybe BlockInfo
  , MMD1Block -> [[MMD1NoteData]]
notedata  :: [ [ MMD1NoteData ] ]
  }
  deriving (Int -> MMD1Block -> ShowS
[MMD1Block] -> ShowS
MMD1Block -> String
(Int -> MMD1Block -> ShowS)
-> (MMD1Block -> String)
-> ([MMD1Block] -> ShowS)
-> Show MMD1Block
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [MMD1Block] -> ShowS
$cshowList :: [MMD1Block] -> ShowS
show :: MMD1Block -> String
$cshow :: MMD1Block -> String
showsPrec :: Int -> MMD1Block -> ShowS
$cshowsPrec :: Int -> MMD1Block -> ShowS
Show)

{-# SPECIALISE peek :: PTR -> StorableReader MMD1Block #-}
{-# SPECIALISE peek :: PTR -> ByteStringReader MMD1Block #-}
peek :: (Reader m) => PTR -> m MMD1Block
peek :: PTR -> m MMD1Block
peek PTR
p = do
  UWORD
numtracks'    <- Peek m UWORD
forall (m :: * -> *). Reader m => Peek m UWORD
peekUWORD (PTR
p PTR -> PTR -> PTR
forall a. Num a => a -> a -> a
+ PTR
0)
  UWORD
lines'        <- Peek m UWORD
forall (m :: * -> *). Reader m => Peek m UWORD
peekUWORD (PTR
p PTR -> PTR -> PTR
forall a. Num a => a -> a -> a
+ PTR
2)
  PTR
info'''       <- Peek m PTR
forall (m :: * -> *). Reader m => Peek m PTR
peekPTR   (PTR
p PTR -> PTR -> PTR
forall a. Num a => a -> a -> a
+ PTR
4)
  Maybe BlockInfo
info'         <- UWORD -> UWORD -> PTR -> m BlockInfo
forall (m :: * -> *).
Reader m =>
UWORD -> UWORD -> PTR -> m BlockInfo
BlockInfo.peek UWORD
numtracks' (UWORD
lines'UWORD -> UWORD -> UWORD
forall a. Num a => a -> a -> a
+UWORD
1) (PTR -> m BlockInfo) -> PTR -> m (Maybe BlockInfo)
forall (m :: * -> *) a.
Monad m =>
(PTR -> m a) -> PTR -> m (Maybe a)
$? PTR
info'''
  [MMD1NoteData]
notedata''    <- (PTR -> m MMD1NoteData) -> [PTR] -> m [MMD1NoteData]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM PTR -> m MMD1NoteData
forall (m :: * -> *). Reader m => PTR -> m MMD1NoteData
MMD1NoteData.peek ([PTR] -> m [MMD1NoteData]) -> [PTR] -> m [MMD1NoteData]
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
pPTR -> PTR -> PTR
forall a. Num a => a -> a -> a
+PTR
8) PTR
4 UWORD
numtracks' (UWORD
lines'UWORD -> UWORD -> UWORD
forall a. Num a => a -> a -> a
+UWORD
1)
  let notedata' :: [[MMD1NoteData]]
notedata' =  UWORD -> [MMD1NoteData] -> [[MMD1NoteData]]
forall i a. Integral i => i -> [a] -> [[a]]
chunk UWORD
numtracks' [MMD1NoteData]
notedata''
  MMD1Block -> m MMD1Block
forall (m :: * -> *) a. Monad m => a -> m a
return (MMD1Block -> m MMD1Block) -> MMD1Block -> m MMD1Block
forall a b. (a -> b) -> a -> b
$ UWORD -> UWORD -> Maybe BlockInfo -> [[MMD1NoteData]] -> MMD1Block
MMD1Block
    UWORD
numtracks' UWORD
lines' Maybe BlockInfo
info' [[MMD1NoteData]]
notedata'