module Rattletrap.Encode.Content
  ( putContent
  )
where

import Rattletrap.Encode.Cache
import Rattletrap.Encode.ClassMapping
import Rattletrap.Encode.Frame
import Rattletrap.Encode.KeyFrame
import Rattletrap.Encode.List
import Rattletrap.Encode.Mark
import Rattletrap.Encode.Message
import Rattletrap.Encode.Str
import Rattletrap.Encode.Word32le
import Rattletrap.Type.Content
import Rattletrap.Type.Word32le
import Rattletrap.Utility.Bytes

import qualified Data.Binary as Binary
import qualified Data.Binary.Bits.Put as BinaryBits
import qualified Data.Binary.Put as Binary
import qualified Data.ByteString.Lazy as LazyBytes

putContent :: Content -> Binary.Put
putContent :: Content -> Put
putContent Content
content = do
  (Str -> Put) -> List Str -> Put
forall a. (a -> Put) -> List a -> Put
putList Str -> Put
putText (Content -> List Str
contentLevels Content
content)
  (KeyFrame -> Put) -> List KeyFrame -> Put
forall a. (a -> Put) -> List a -> Put
putList KeyFrame -> Put
putKeyFrame (Content -> List KeyFrame
contentKeyFrames Content
content)
  let streamSize :: Word32le
streamSize = Content -> Word32le
contentStreamSize Content
content
  Word32le -> Put
putWord32 Word32le
streamSize
  let
    stream :: ByteString
stream = ByteString -> ByteString
LazyBytes.toStrict
      (Put -> ByteString
Binary.runPut (BitPut () -> Put
BinaryBits.runBitPut ([Frame] -> BitPut ()
putFrames (Content -> [Frame]
contentFrames Content
content)))
      )
  ByteString -> Put
Binary.putByteString
    (ByteString -> ByteString
reverseBytes (Word32 -> ByteString -> ByteString
forall a. Integral a => a -> ByteString -> ByteString
padBytes (Word32le -> Word32
word32leValue Word32le
streamSize) ByteString
stream))
  (Message -> Put) -> List Message -> Put
forall a. (a -> Put) -> List a -> Put
putList Message -> Put
putMessage (Content -> List Message
contentMessages Content
content)
  (Mark -> Put) -> List Mark -> Put
forall a. (a -> Put) -> List a -> Put
putList Mark -> Put
putMark (Content -> List Mark
contentMarks Content
content)
  (Str -> Put) -> List Str -> Put
forall a. (a -> Put) -> List a -> Put
putList Str -> Put
putText (Content -> List Str
contentPackages Content
content)
  (Str -> Put) -> List Str -> Put
forall a. (a -> Put) -> List a -> Put
putList Str -> Put
putText (Content -> List Str
contentObjects Content
content)
  (Str -> Put) -> List Str -> Put
forall a. (a -> Put) -> List a -> Put
putList Str -> Put
putText (Content -> List Str
contentNames Content
content)
  (ClassMapping -> Put) -> List ClassMapping -> Put
forall a. (a -> Put) -> List a -> Put
putList ClassMapping -> Put
putClassMapping (Content -> List ClassMapping
contentClassMappings Content
content)
  (Cache -> Put) -> List Cache -> Put
forall a. (a -> Put) -> List a -> Put
putList Cache -> Put
putCache (Content -> List Cache
contentCaches Content
content)
  (Word8 -> Put) -> [Word8] -> Put
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ Word8 -> Put
Binary.putWord8 (Content -> [Word8]
contentUnknown Content
content)