module Rattletrap.PropertyValue where

import Rattletrap.Primitive

import qualified Data.Binary as Binary

data PropertyValue a
  = ArrayProperty (List (Dictionary a))
  -- ^ Yes, a list of dictionaries. No, it doesn't make sense. These usually
  -- only have one element.
  | BoolProperty Word8
  | ByteProperty Text
                 (Maybe Text)
  -- ^ This is a strange name for essentially a key-value pair.
  | FloatProperty Float32
  | IntProperty Int32
  | NameProperty Text
  -- ^ It's unclear how exactly this is different than a 'StrProperty'.
  | QWordProperty Word64
  | StrProperty Text
  deriving (Eq, Ord, Show)

getPropertyValue :: Binary.Get a -> Text -> Binary.Get (PropertyValue a)
getPropertyValue getProperty kind =
  case textToString kind of
    "ArrayProperty" -> do
      list <- getList (getDictionary getProperty)
      pure (ArrayProperty list)
    "BoolProperty" -> do
      word8 <- getWord8
      pure (BoolProperty word8)
    "ByteProperty" -> do
      k <- getText
      v <-
        if textToString k == "OnlinePlatform_Steam"
          then pure Nothing
          else do
            v <- getText
            pure (Just v)
      pure (ByteProperty k v)
    "FloatProperty" -> do
      float32 <- getFloat32
      pure (FloatProperty float32)
    "IntProperty" -> do
      int32 <- getInt32
      pure (IntProperty int32)
    "NameProperty" -> do
      text <- getText
      pure (NameProperty text)
    "QWordProperty" -> do
      word64 <- getWord64
      pure (QWordProperty word64)
    "StrProperty" -> do
      text <- getText
      pure (StrProperty text)
    _ -> fail ("don't know how to read property value " ++ show kind)

putPropertyValue :: (a -> Binary.Put) -> PropertyValue a -> Binary.Put
putPropertyValue putProperty value =
  case value of
    ArrayProperty list -> putList (putDictionary putProperty) list
    BoolProperty word8 -> putWord8 word8
    ByteProperty k mv -> do
      putText k
      case mv of
        Nothing -> pure ()
        Just v -> putText v
    FloatProperty float32 -> putFloat32 float32
    IntProperty int32 -> putInt32 int32
    NameProperty text -> putText text
    QWordProperty word64 -> putWord64 word64
    StrProperty text -> putText text