module Rattletrap.Encode.Quaternion
  ( putQuaternion
  )
where

import Rattletrap.Encode.CompressedWord
import Rattletrap.Type.CompressedWord
import Rattletrap.Type.Quaternion

import qualified Data.Binary.Bits.Put as BinaryBits

putQuaternion :: Quaternion -> BinaryBits.BitPut ()
putQuaternion :: Quaternion -> BitPut ()
putQuaternion Quaternion
q = do
  let c :: Component
c = Quaternion -> Component
maxComponent Quaternion
q
  Component -> BitPut ()
putComponent Component
c
  case Component
c of
    Component
ComponentX -> Double -> Double -> Double -> BitPut ()
putParts (Quaternion -> Double
quaternionY Quaternion
q) (Quaternion -> Double
quaternionZ Quaternion
q) (Quaternion -> Double
quaternionW Quaternion
q)
    Component
ComponentY -> Double -> Double -> Double -> BitPut ()
putParts (Quaternion -> Double
quaternionX Quaternion
q) (Quaternion -> Double
quaternionZ Quaternion
q) (Quaternion -> Double
quaternionW Quaternion
q)
    Component
ComponentZ -> Double -> Double -> Double -> BitPut ()
putParts (Quaternion -> Double
quaternionX Quaternion
q) (Quaternion -> Double
quaternionY Quaternion
q) (Quaternion -> Double
quaternionW Quaternion
q)
    Component
ComponentW -> Double -> Double -> Double -> BitPut ()
putParts (Quaternion -> Double
quaternionX Quaternion
q) (Quaternion -> Double
quaternionY Quaternion
q) (Quaternion -> Double
quaternionZ Quaternion
q)

putComponent :: Component -> BinaryBits.BitPut ()
putComponent :: Component -> BitPut ()
putComponent Component
component = CompressedWord -> BitPut ()
putCompressedWord
  (Word -> Word -> CompressedWord
CompressedWord
    Word
3
    (case Component
component of
      Component
ComponentX -> Word
0
      Component
ComponentY -> Word
1
      Component
ComponentZ -> Word
2
      Component
ComponentW -> Word
3
    )
  )

putParts :: Double -> Double -> Double -> BinaryBits.BitPut ()
putParts :: Double -> Double -> Double -> BitPut ()
putParts Double
a Double
b Double
c = do
  Double -> BitPut ()
putPart Double
a
  Double -> BitPut ()
putPart Double
b
  Double -> BitPut ()
putPart Double
c

putPart :: Double -> BinaryBits.BitPut ()
putPart :: Double -> BitPut ()
putPart = CompressedWord -> BitPut ()
putCompressedWord (CompressedWord -> BitPut ())
-> (Double -> CompressedWord) -> Double -> BitPut ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Double -> CompressedWord
compressPart