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