module Tart.Format.V1
  ( version1Format
  , encodeVersion1
  )
where

import qualified Data.Binary as B
import qualified Data.Text as T

import Tart.Canvas
import Tart.Format.Types

data TartFileDataV1 =
    TartFileDataV1 { TartFileDataV1 -> [CanvasData]
tartFileDataV1CanvasData  :: [CanvasData]
                   , TartFileDataV1 -> [Text]
tartFileDataV1CanvasNames :: [T.Text]
                   , TartFileDataV1 -> [Int]
tartFileDataV1CanvasOrder :: [Int]
                   }

encodeVersion1 :: TartFile -> B.Put
encodeVersion1 :: TartFile -> Put
encodeVersion1 = TartFileDataV1 -> Put
forall t. Binary t => t -> Put
B.put (TartFileDataV1 -> Put)
-> (TartFile -> TartFileDataV1) -> TartFile -> Put
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TartFile -> TartFileDataV1
tartFileToDataV1

version1Format :: TartFileFormat
version1Format :: TartFileFormat
version1Format =
    Get TartFileDataV1
-> (TartFileDataV1 -> IO (Either String TartFile))
-> TartFileFormat
forall a.
Get a -> (a -> IO (Either String TartFile)) -> TartFileFormat
BinaryFormatVersion Get TartFileDataV1
forall t. Binary t => Get t
B.get TartFileDataV1 -> IO (Either String TartFile)
tartFileFromDataV1

instance B.Binary TartFileDataV1 where
    put :: TartFileDataV1 -> Put
put TartFileDataV1
d = do
        [CanvasData] -> Put
forall t. Binary t => t -> Put
B.put ([CanvasData] -> Put) -> [CanvasData] -> Put
forall a b. (a -> b) -> a -> b
$ TartFileDataV1 -> [CanvasData]
tartFileDataV1CanvasData TartFileDataV1
d
        [String] -> Put
forall t. Binary t => t -> Put
B.put ([String] -> Put) -> [String] -> Put
forall a b. (a -> b) -> a -> b
$ Text -> String
T.unpack (Text -> String) -> [Text] -> [String]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> TartFileDataV1 -> [Text]
tartFileDataV1CanvasNames TartFileDataV1
d
        [Int] -> Put
forall t. Binary t => t -> Put
B.put ([Int] -> Put) -> [Int] -> Put
forall a b. (a -> b) -> a -> b
$ TartFileDataV1 -> [Int]
tartFileDataV1CanvasOrder TartFileDataV1
d
    get :: Get TartFileDataV1
get = do
        [CanvasData] -> [Text] -> [Int] -> TartFileDataV1
TartFileDataV1 ([CanvasData] -> [Text] -> [Int] -> TartFileDataV1)
-> Get [CanvasData] -> Get ([Text] -> [Int] -> TartFileDataV1)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get [CanvasData]
forall t. Binary t => Get t
B.get
                       Get ([Text] -> [Int] -> TartFileDataV1)
-> Get [Text] -> Get ([Int] -> TartFileDataV1)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ((String -> Text) -> [String] -> [Text]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap String -> Text
T.pack ([String] -> [Text]) -> Get [String] -> Get [Text]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get [String]
forall t. Binary t => Get t
B.get)
                       Get ([Int] -> TartFileDataV1) -> Get [Int] -> Get TartFileDataV1
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Get [Int]
forall t. Binary t => Get t
B.get

tartFileToDataV1 :: TartFile -> TartFileDataV1
tartFileToDataV1 :: TartFile -> TartFileDataV1
tartFileToDataV1 TartFile
tf =
    [CanvasData] -> [Text] -> [Int] -> TartFileDataV1
TartFileDataV1 (Canvas -> CanvasData
canvasToData (Canvas -> CanvasData) -> [Canvas] -> [CanvasData]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> TartFile -> [Canvas]
tartFileCanvasList TartFile
tf)
                   (TartFile -> [Text]
tartFileCanvasNames TartFile
tf)
                   (TartFile -> [Int]
tartFileCanvasOrder TartFile
tf)

tartFileFromDataV1 :: TartFileDataV1 -> IO (Either String TartFile)
tartFileFromDataV1 :: TartFileDataV1 -> IO (Either String TartFile)
tartFileFromDataV1 TartFileDataV1
d = do
    let loadCanvases :: [CanvasData] -> IO (Either String [Canvas])
loadCanvases [] = Either String [Canvas] -> IO (Either String [Canvas])
forall (m :: * -> *) a. Monad m => a -> m a
return (Either String [Canvas] -> IO (Either String [Canvas]))
-> Either String [Canvas] -> IO (Either String [Canvas])
forall a b. (a -> b) -> a -> b
$ [Canvas] -> Either String [Canvas]
forall a b. b -> Either a b
Right []
        loadCanvases (CanvasData
cd:[CanvasData]
cds) = do
            Either String Canvas
result <- CanvasData -> IO (Either String Canvas)
canvasFromData CanvasData
cd
            case Either String Canvas
result of
                Left String
e -> Either String [Canvas] -> IO (Either String [Canvas])
forall (m :: * -> *) a. Monad m => a -> m a
return (Either String [Canvas] -> IO (Either String [Canvas]))
-> Either String [Canvas] -> IO (Either String [Canvas])
forall a b. (a -> b) -> a -> b
$ String -> Either String [Canvas]
forall a b. a -> Either a b
Left String
e
                Right Canvas
c -> do
                    Either String [Canvas]
rest <- [CanvasData] -> IO (Either String [Canvas])
loadCanvases [CanvasData]
cds
                    case Either String [Canvas]
rest of
                        Left String
e -> Either String [Canvas] -> IO (Either String [Canvas])
forall (m :: * -> *) a. Monad m => a -> m a
return (Either String [Canvas] -> IO (Either String [Canvas]))
-> Either String [Canvas] -> IO (Either String [Canvas])
forall a b. (a -> b) -> a -> b
$ String -> Either String [Canvas]
forall a b. a -> Either a b
Left String
e
                        Right [Canvas]
cs -> Either String [Canvas] -> IO (Either String [Canvas])
forall (m :: * -> *) a. Monad m => a -> m a
return (Either String [Canvas] -> IO (Either String [Canvas]))
-> Either String [Canvas] -> IO (Either String [Canvas])
forall a b. (a -> b) -> a -> b
$ [Canvas] -> Either String [Canvas]
forall a b. b -> Either a b
Right ([Canvas] -> Either String [Canvas])
-> [Canvas] -> Either String [Canvas]
forall a b. (a -> b) -> a -> b
$ Canvas
c Canvas -> [Canvas] -> [Canvas]
forall a. a -> [a] -> [a]
: [Canvas]
cs

    Either String [Canvas]
result <- [CanvasData] -> IO (Either String [Canvas])
loadCanvases (TartFileDataV1 -> [CanvasData]
tartFileDataV1CanvasData TartFileDataV1
d)
    case Either String [Canvas]
result of
        Left String
s -> Either String TartFile -> IO (Either String TartFile)
forall (m :: * -> *) a. Monad m => a -> m a
return (Either String TartFile -> IO (Either String TartFile))
-> Either String TartFile -> IO (Either String TartFile)
forall a b. (a -> b) -> a -> b
$ String -> Either String TartFile
forall a b. a -> Either a b
Left String
s
        Right [Canvas]
cs -> Either String TartFile -> IO (Either String TartFile)
forall (m :: * -> *) a. Monad m => a -> m a
return (Either String TartFile -> IO (Either String TartFile))
-> Either String TartFile -> IO (Either String TartFile)
forall a b. (a -> b) -> a -> b
$ TartFile -> Either String TartFile
forall a b. b -> Either a b
Right (TartFile -> Either String TartFile)
-> TartFile -> Either String TartFile
forall a b. (a -> b) -> a -> b
$ [Canvas] -> [Text] -> [Int] -> TartFile
TartFile [Canvas]
cs (TartFileDataV1 -> [Text]
tartFileDataV1CanvasNames TartFileDataV1
d)
                                                 (TartFileDataV1 -> [Int]
tartFileDataV1CanvasOrder TartFileDataV1
d)