module Sound.MED.Raw.MMD0 where

import qualified Sound.MED.Raw.MMD0Song as MMD0Song
import Sound.MED.Raw.MMD0Song(MMD0Song)
import qualified Sound.MED.Raw.MMD0Block as MMD0Block
import Sound.MED.Raw.MMD0Block(MMD0Block)
import qualified Sound.MED.Raw.InstrHdr as InstrHdr
import Sound.MED.Raw.InstrHdr(InstrHdr)
import qualified Sound.MED.Raw.MMD0exp as MMD0exp
import Sound.MED.Raw.MMD0exp(MMD0exp)
import Sound.MED.Basic.Amiga

data MMD0 = MMD0
  { id          :: ULONG
  , modlen      :: ULONG
  , song        :: MMD0Song
  , psecnum     :: UWORD
  , pseq        :: UWORD
  , blockarr    :: [ MMD0Block ]
  , mmdflags    :: UBYTE
  , reserved1   :: UBYTE
  , reserved2   :: UBYTE
  , reserved3   :: UBYTE
  , smplarr     :: [ Maybe InstrHdr ]
  , reserved4   :: ULONG
  , expdata     :: Maybe MMD0exp
  , reserved5   :: ULONG
  , pstate      :: UWORD
  , pblock      :: UWORD
  , pline       :: UWORD
  , pseqnum     :: UWORD
  , actplayline :: WORD
  , counter     :: UBYTE
  , extra_songs :: UBYTE
  }
  deriving (Show)

peek :: MEM -> PTR -> IO MMD0
peek m p = do
  id'          <- peekULONG m (p + 0)
  modlen'      <- peekULONG m (p + 4)
  song''       <- peekPTR   m (p + 8)
  song'        <- MMD0Song.peek m song''
  psecnum'     <- peekUWORD m (p + 12)
  pseq'        <- peekUWORD m (p + 14)
  blockarr'''  <- peekPTR   m (p + 16)
  blockarr''   <- mapM (peekPTR m) $ pointerRangeGen blockarr''' 4 (MMD0Song.numblocks song')
  blockarr'    <- mapM (MMD0Block.peek m) blockarr''
  mmdflags'    <- peekUBYTE m (p + 20)
  reserved1'   <- peekUBYTE m (p + 21)
  reserved2'   <- peekUBYTE m (p + 22)
  reserved3'   <- peekUBYTE m (p + 23)
  smplarr'''   <- peekPTR   m (p + 24)
  smplarr''    <- mapM (peekPTR m) $ pointerRangeGenCheck smplarr''' 4 (MMD0Song.numsamples song')
  smplarr'     <- mapM (InstrHdr.peek m $?) smplarr''
  reserved4'   <- peekULONG m (p + 28)
  expdata'''   <- peekPTR   m (p + 32)
  expdata'     <- MMD0exp.peek m $? expdata'''
  reserved5'   <- peekULONG m (p + 36)
  pstate'      <- peekUWORD m (p + 40)
  pblock'      <- peekUWORD m (p + 42)
  pline'       <- peekUWORD m (p + 44)
  pseqnum'     <- peekUWORD m (p + 46)
  actplayline' <- peekWORD  m (p + 48)
  counter'     <- peekUBYTE m (p + 50)
  extra_songs' <- peekUBYTE m (p + 51)
  return $ MMD0
    id' modlen' song' psecnum' pseq' blockarr' mmdflags'
    reserved1' reserved2' reserved3' smplarr' reserved4'
    expdata' reserved5' pstate' pblock' pline' pseqnum'
    actplayline' counter' extra_songs'