module FMP.Matrix (
matrix, matrixAlign, matrixSepBy, matrixAlignSepBy,
rowAlign, columnAlign, rowAlignSepBy, columnAlignSepBy,
cell, cell'
) where
import FMP.Types
import FMP.Picture
data Cell = Cell Dir Picture
deriving Show
cell :: IsPicture a => a -> Cell
cell = cell' C
cell' :: IsPicture a => Dir -> a -> Cell
cell' d p = Cell d (toPicture p)
matrix :: IsPicture a => [[a]] -> Picture
matrix m = matrixSepBy 16 16 m
matrixSepBy :: IsPicture a => Numeric -> Numeric -> [[a]]
-> Picture
matrixSepBy sepH sepV m = matrixAlignSepBy sepH sepV (map (map cell) m)
matrixAlign :: [[Cell]] -> Picture
matrixAlign = matrixAlignSepBy 16 16
matrixAlignSepBy :: Numeric -> Numeric -> [[Cell]] -> Picture
matrixAlignSepBy _ _ [] = empty
matrixAlignSepBy sepH sepV cs = overlay (equations colWidths
:equations rowHeights
:equations ofsHs
:equations ofsVs
:[equations placements])
(map ((\(Cell _ p) -> p).snd) nps)
where
origin = ref "X"
maxH, maxV, ofsH ,ofsV :: Int -> Numeric
maxH i = var (i*4)
maxV i = var (i*4+1)
ofsH i = var (i*4+2)
ofsV i = var (i*4+3)
nps = number (0, 0, 0::Int) cs
nH = maximum [length c | c <- cs]
nV = length cs
rowHeights = [ maxV i .= maximum' [height n
| ((_, x, n), _) <- nps, i == x]
| i <- [0..nV1]]
colWidths = [ maxH i .= maximum' [width n
| ((y, _, n), _) <- nps, i == y]
| i <- [0..nH1]]
ofsHs = [ ofsH 0 .= xpart origin]
++ [ ofsH i .= ofsH (i1) + maxH (i1) + sepH
| i <- [1..nH]]
ofsVs = [ ofsV 0 .= ypart origin]
++ [ ofsV i .= ofsV (i1) maxV (i1) sepV
| i <- [1..nV]]
placements = [
ref (n <+ d) .= case d of
C -> vec (ofsH x + maxH x / 2,
ofsV (y+1) + maxV y / 2)
N -> vec (ofsH x + maxH x / 2, ofsV y sepV)
NE-> vec (ofsH (x+1) sepH, ofsV y sepV)
E -> vec (ofsH (x+1) sepH,
ofsV (y+1) + maxV y / 2)
SE-> vec (ofsH (x+1) sepH, ofsV (y+1))
S -> vec (ofsH x + maxH x / 2, ofsV (y+1))
SW-> vec (ofsH x, ofsV (y+1))
W -> vec (ofsH x, ofsV (y+1) + maxV y / 2)
NW-> vec (ofsH x, ofsV y sepV)
| ((x, y, n), Cell d _) <- nps]
number (x, y, n) ((Cell d p:cs):rs)
= ((x, y, n),Cell d p):number (x+1, y, n+1) (cs:rs)
number (_, y, n) ([]:rs)= number (0, y+1, n) rs
number _ _ = []
rowAlign :: [Cell] -> Picture
rowAlign = rowAlignSepBy 0
columnAlign :: [Cell] -> Picture
columnAlign = columnAlignSepBy 0
rowAlignSepBy :: Numeric -> [Cell] -> Picture
rowAlignSepBy hSep ps = matrixAlignSepBy hSep 0 [ps]
columnAlignSepBy :: Numeric -> [Cell] -> Picture
columnAlignSepBy vSep ps = matrixAlignSepBy 0 vSep (map (\x->[x]) ps)