module Codec.Tiled.Layer.Data where

import Control.Applicative ((<|>))
import Data.Aeson (FromJSON(..), ToJSON(..), withArray, withText)
import Data.Text (Text)
import Data.Vector.Storable qualified as Storable
import GHC.Generics (Generic)

import Data.Tiled.GID (GID)

data LayerData
  = Base64 Text
  | GIDs (Storable.Vector GID)
  deriving (LayerData -> LayerData -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: LayerData -> LayerData -> Bool
$c/= :: LayerData -> LayerData -> Bool
== :: LayerData -> LayerData -> Bool
$c== :: LayerData -> LayerData -> Bool
Eq, Int -> LayerData -> ShowS
[LayerData] -> ShowS
LayerData -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [LayerData] -> ShowS
$cshowList :: [LayerData] -> ShowS
show :: LayerData -> String
$cshow :: LayerData -> String
showsPrec :: Int -> LayerData -> ShowS
$cshowsPrec :: Int -> LayerData -> ShowS
Show, forall x. Rep LayerData x -> LayerData
forall x. LayerData -> Rep LayerData x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep LayerData x -> LayerData
$cfrom :: forall x. LayerData -> Rep LayerData x
Generic)

instance FromJSON LayerData where
  parseJSON :: Value -> Parser LayerData
parseJSON Value
v = Value -> Parser LayerData
encoded Value
v forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Value -> Parser LayerData
csv Value
v
    where
      encoded :: Value -> Parser LayerData
encoded =
        forall a. String -> (Text -> Parser a) -> Value -> Parser a
withText String
"Base64" forall a b. (a -> b) -> a -> b
$
          forall (f :: * -> *) a. Applicative f => a -> f a
pure forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> LayerData
Base64

      csv :: Value -> Parser LayerData
csv =
        forall a. String -> (Array -> Parser a) -> Value -> Parser a
withArray String
"GIDs" forall a b. (a -> b) -> a -> b
$
          forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Vector GID -> LayerData
GIDs forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (v :: * -> *) a (w :: * -> *).
(Vector v a, Vector w a) =>
v a -> w a
Storable.convert) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse forall a. FromJSON a => Value -> Parser a
parseJSON

instance ToJSON LayerData where
  toJSON :: LayerData -> Value
toJSON = \case
    Base64 Text
text ->
      forall a. ToJSON a => a -> Value
toJSON Text
text
    GIDs Vector GID
ints ->
      forall a. ToJSON a => a -> Value
toJSON Vector GID
ints