module DSL.Common where
data Dir = Hori | Vert deriving (Eq, Show)
type ArtStrs = [String]
type ArtSize = (Int, Int)
type Sem = (ArtSize, ArtStrs)
frameSem :: Sem -> Sem
frameSem ((rows, cols), ss) = ((rows + 2, cols + 2), topbot : map f ss ++ [topbot])
where topbot = '+' : replicate cols '-' ++ "+"
f s = '|':s++"|"
textSem :: Dir -> String -> Sem
textSem Hori s = embed [s]
textSem Vert s = embed (map (:[]) s)
-- Invariant: all string in ss must have the same length (or perhaps the first is longest)
embed :: ArtStrs -> Sem
embed ss = ((rows, cols), ss)
where rows = length ss
cols | rows == 0 = 0
| otherwise = length (head ss)
aboveSem :: Sem -> Sem -> Sem
aboveSem ((arows, acols), a) ((brows, bcols), b) = ((arows+brows, maxcols), extend maxcols (a ++ b))
where maxcols = max acols bcols
extend :: Int -> ArtStrs -> ArtStrs
extend n = map (extOne n)
extOne :: Int -> String -> String
extOne n xs = take n (xs ++ repeat ' ')
besideSem :: Sem -> Sem -> Sem
besideSem ((arows, acols), a) ((brows, bcols), b) =
((maxrows, acols + bcols), zipWith (++) (fillIn (maxrows, acols) a)
(fillIn (maxrows, bcols) b))
where maxrows = max arows brows
-- make sure all lines lengths match and column lenghts match
fillIn :: ArtSize -> ArtStrs -> ArtStrs
fillIn (rows, cols) ss = extend cols rowsDone
where rowsDone :: ArtStrs
rowsDone = take rows (ss ++ repeat [])
spaceSem :: ArtSize -> Sem
spaceSem shape = (shape, fillIn shape [])
----------------------------------------------------------------
-- Not asked for in the exam:
lineSem :: Int -> Dir -> Sem
lineSem n Hori = embed [replicate n '-']
lineSem n Vert = embed (replicate n "|")
emptySem :: Sem
emptySem = ((0, 0), [])