module Rattletrap.Decode.Quaternion
  ( decodeQuaternionBits
  )
where

import Rattletrap.Decode.Common
import Rattletrap.Decode.CompressedWord
import Rattletrap.Type.CompressedWord
import Rattletrap.Type.Quaternion

decodeQuaternionBits :: DecodeBits Quaternion
decodeQuaternionBits :: DecodeBits Quaternion
decodeQuaternionBits =
  Component -> Double -> Double -> Double -> Quaternion
toQuaternion (Component -> Double -> Double -> Double -> Quaternion)
-> BitGet Component
-> BitGet (Double -> Double -> Double -> Quaternion)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> BitGet Component
decodeComponent BitGet (Double -> Double -> Double -> Quaternion)
-> BitGet Double -> BitGet (Double -> Double -> Quaternion)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> BitGet Double
decodePart BitGet (Double -> Double -> Quaternion)
-> BitGet Double -> BitGet (Double -> Quaternion)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> BitGet Double
decodePart BitGet (Double -> Quaternion)
-> BitGet Double -> DecodeBits Quaternion
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> BitGet Double
decodePart

decodeComponent :: DecodeBits Component
decodeComponent :: BitGet Component
decodeComponent = do
  CompressedWord
x <- Word -> DecodeBits CompressedWord
decodeCompressedWordBits Word
3
  case CompressedWord -> Word
compressedWordValue CompressedWord
x of
    Word
0 -> Component -> BitGet Component
forall (f :: * -> *) a. Applicative f => a -> f a
pure Component
ComponentX
    Word
1 -> Component -> BitGet Component
forall (f :: * -> *) a. Applicative f => a -> f a
pure Component
ComponentY
    Word
2 -> Component -> BitGet Component
forall (f :: * -> *) a. Applicative f => a -> f a
pure Component
ComponentZ
    Word
3 -> Component -> BitGet Component
forall (f :: * -> *) a. Applicative f => a -> f a
pure Component
ComponentW
    Word
y -> String -> BitGet Component
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String
"[RT08] invalid component: " String -> String -> String
forall a. Semigroup a => a -> a -> a
<> Word -> String
forall a. Show a => a -> String
show Word
y)

decodePart :: DecodeBits Double
decodePart :: BitGet Double
decodePart = CompressedWord -> Double
decompressPart (CompressedWord -> Double)
-> DecodeBits CompressedWord -> BitGet Double
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Word -> DecodeBits CompressedWord
decodeCompressedWordBits Word
maxCompressedValue