{-|
Module      : TikzStringDiagram
Description : Module for creating and printing string diagrams.
Copyright   : Anthony Wang, 2021
License     : MIT
Maintainer  : anthony.y.wang.math@gmail.com

@TikzStringDiagram@ is a module for defining 'TikzStringDiagram', the structure
containing the TikZ objects needed to create a string diagram.
A 'TikzStringDiagram' is an instance of 'ShowLatex', where
'showLatex' of a 'TikzStringDiagram' is the LaTeX code for rendering
the string diagram.
-}
module TikzStringDiagram where

import Prelude hiding (Functor)
import Data.Array
import Data.List
import Data.Maybe
import TikzObjects
import TwoCatOfCats
import Internal.FormattingData

-- | 'TikzStringDiagram' is a data structure containing the Tikz objects
-- needed to draw a string diagram.
data TikzStringDiagram = TikzStringDiagram
    { TikzStringDiagram -> Array (Int, Int) (Maybe TikzPathOperation)
tikzsd_array_of_coords :: !(Array (Int, Int) (Maybe TikzPathOperation))
        -- ^ the array of TikZ coordinate path operations used when placing functors
    , TikzStringDiagram -> Array (Int, Int) (Maybe TikzPathOperation)
tikzsd_array_of_tikz_nt_nodes :: !(Array (Int,Int) (Maybe TikzPathOperation))    
        -- ^ the array of TikZ node path operations, used to place the natural transformations
    , TikzStringDiagram -> [TikzPath]
tikzsd_functor_strings :: ![TikzPath]
        -- ^ a list of 'TikzPath's which draw the strings in the string diagram
    , TikzStringDiagram -> String
tikzsd_options :: !String
        -- ^ LaTeX code for options in the @tikzpicture@ environment
    }

-- | 'make_tikzsd' creates a 'TikzStringDiagram' from a 'NaturalTransformation',
-- a 'NatFormatting' which can be used to format the 'NaturalTransformation',
-- and a @String@ of LaTeX code for options in the @tikzpicture@ environment.
make_tikzsd :: NaturalTransformation -> NatFormatting -> String -> TikzStringDiagram
make_tikzsd :: NaturalTransformation
-> NatFormatting -> String -> TikzStringDiagram
make_tikzsd NaturalTransformation
nat NatFormatting
nf String
opts = Array (Int, Int) (Maybe TikzPathOperation)
-> Array (Int, Int) (Maybe TikzPathOperation)
-> [TikzPath]
-> String
-> TikzStringDiagram
TikzStringDiagram Array (Int, Int) (Maybe TikzPathOperation)
a Array (Int, Int) (Maybe TikzPathOperation)
b [TikzPath]
c String
opts
    where
        a :: Array (Int, Int) (Maybe TikzPathOperation)
a = NatFormatting -> Array (Int, Int) (Maybe TikzPathOperation)
array_of_tikz_coords NatFormatting
nf
        b :: Array (Int, Int) (Maybe TikzPathOperation)
b = NaturalTransformation
-> NatFormatting -> Array (Int, Int) (Maybe TikzPathOperation)
array_of_tikz_nt_nodes NaturalTransformation
nat NatFormatting
nf
        c :: [TikzPath]
c = (FunctorStringData -> TikzPath)
-> [FunctorStringData] -> [TikzPath]
forall a b. (a -> b) -> [a] -> [b]
map (NatFormatting -> FunctorStringData -> TikzPath
fsd_to_tikz_path NatFormatting
nf) ([FunctorStringData] -> [TikzPath])
-> [FunctorStringData] -> [TikzPath]
forall a b. (a -> b) -> a -> b
$ NaturalTransformation -> [FunctorStringData]
nt_to_functor_strings NaturalTransformation
nat

instance ShowLatex TikzStringDiagram where
    showLatex :: TikzStringDiagram -> String
showLatex (TikzStringDiagram Array (Int, Int) (Maybe TikzPathOperation)
cs Array (Int, Int) (Maybe TikzPathOperation)
ns [TikzPath]
fss String
opts) = [String] -> String
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [ String
"\\begin{tikzpicture}["
                                                     , String
"baseline=(current bounding box.center),"
                                                     , String
opts
                                                     , String
"]\n"
                                                     , String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate String
"\n" ([String] -> String) -> [String] -> String
forall a b. (a -> b) -> a -> b
$ (TikzPathOperation -> String) -> TikzPath -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (TikzPath -> String
forall a. ShowLatex a => a -> String
showLatex(TikzPath -> String)
-> (TikzPathOperation -> TikzPath) -> TikzPathOperation -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
.TikzPathOperation -> TikzPath
forall a. a -> [a]
singleton) (TikzPath -> [String]) -> TikzPath -> [String]
forall a b. (a -> b) -> a -> b
$ [Maybe TikzPathOperation] -> TikzPath
forall a. [Maybe a] -> [a]
catMaybes ([Maybe TikzPathOperation] -> TikzPath)
-> [Maybe TikzPathOperation] -> TikzPath
forall a b. (a -> b) -> a -> b
$ Array (Int, Int) (Maybe TikzPathOperation)
-> [Maybe TikzPathOperation]
forall i e. Array i e -> [e]
elems (Array (Int, Int) (Maybe TikzPathOperation)
 -> [Maybe TikzPathOperation])
-> Array (Int, Int) (Maybe TikzPathOperation)
-> [Maybe TikzPathOperation]
forall a b. (a -> b) -> a -> b
$ Array (Int, Int) (Maybe TikzPathOperation)
cs
                                                     , String
"\n\n"
                                                     , String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate String
"\n" ([String] -> String) -> [String] -> String
forall a b. (a -> b) -> a -> b
$ (TikzPathOperation -> String) -> TikzPath -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (TikzPath -> String
forall a. ShowLatex a => a -> String
showLatex(TikzPath -> String)
-> (TikzPathOperation -> TikzPath) -> TikzPathOperation -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
.TikzPathOperation -> TikzPath
forall a. a -> [a]
singleton) (TikzPath -> [String]) -> TikzPath -> [String]
forall a b. (a -> b) -> a -> b
$ [Maybe TikzPathOperation] -> TikzPath
forall a. [Maybe a] -> [a]
catMaybes ([Maybe TikzPathOperation] -> TikzPath)
-> [Maybe TikzPathOperation] -> TikzPath
forall a b. (a -> b) -> a -> b
$ Array (Int, Int) (Maybe TikzPathOperation)
-> [Maybe TikzPathOperation]
forall i e. Array i e -> [e]
elems (Array (Int, Int) (Maybe TikzPathOperation)
 -> [Maybe TikzPathOperation])
-> Array (Int, Int) (Maybe TikzPathOperation)
-> [Maybe TikzPathOperation]
forall a b. (a -> b) -> a -> b
$ Array (Int, Int) (Maybe TikzPathOperation)
ns
                                                     , String
"\n\n"
                                                     , String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate String
"\n" ([String] -> String) -> [String] -> String
forall a b. (a -> b) -> a -> b
$ (TikzPath -> String) -> [TikzPath] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map TikzPath -> String
forall a. ShowLatex a => a -> String
showLatex [TikzPath]
fss
                                                     , String
"\n"
                                                     , String
"\\end{tikzpicture}"]
        where singleton :: a -> [a]
singleton = forall a. a -> [a]
forall (m :: * -> *) a. Monad m => a -> m a
return :: a -> [a]