-- |
-- = A Module for ASCII Pictures.
module Picture where

-- | The height of a picture.
type Height  = Int
-- | The width of a picture.
type Width   = Int
-- | A picture consists of a list of rows.
type Picture = (Height, Width, [[Char]])

-- | Compute the height of a picture.
height :: Picture -> Height
height (h, _, _) = h

-- | Compute the width of a picture.
width :: Picture -> Width
width (_, w, _) = w

-- | A single character \"pixel\".
pixel :: Char -> Picture
pixel c = (1, 1, [[c]])

-- | A single line picture.
row :: String -> Picture
row r = (1, length r, [r])

-- | A blank picture of given dimensions.
blank :: Height -> Width -> Picture
blank h w = (h, w, blanks)
  where
    blanks = replicate h (replicate w ' ')

-- | Put two pictures above each other.
above :: Picture -> Picture -> Picture
(h, w, css) `above` (h', w', css')
  | w == w'   = (h + h', w, css ++ css')
  | otherwise = error "above: different widths"

-- | Stack a list of pictures above each other.
stack :: [Picture] -> Picture
stack = foldr1 above

-- | Put two pictures beside each other.
beside :: Picture -> Picture -> Picture
(h, w, css) `beside` (h', w', css')
  | h == h'   = (h, w + w', zipWith (++) css css')
  | otherwise = error "beside: different heights"

-- | Spread a list of pictures beside each other.
spread :: [Picture] -> Picture
spread = foldr1 beside

-- | Tile a list of lists of pictures.
tile :: [[Picture]] -> Picture
tile = stack . map spread

-- | Turn a picture into a 'String'.
showPic :: Picture -> String
showPic (_, _, css) = unlines css