module Data.Analysis.Fulcrum.Pretty
  ( showResults
  ) where

import           Data.List (nub, intersperse)
import           Data.Map.Strict (Map)
import qualified Data.Map.Strict as M

import Data.Analysis.Fulcrum.Analysis

-- | Produce a pretty, tabular representation of the results of a 'Plan'
showResults :: Show a => Result a -> String
showResults = showTable . tabulate

tabulate :: Show a => Result a -> [[String]]
tabulate res =
  [ [""] ++ map absShowS cols ] ++
  [ absShowS r :
    [ maybe "" show $ M.lookup (c,r) res
    | c <- cols
    ]
  | r <- rows
  ]
  where rows = nub $ map snd $ M.keys res
        cols = nub $ map fst $ M.keys res

rowJoin :: [String] -> String
rowJoin = concat . intersperse " | "

showTable :: [[String]] -> String
showTable tab = unlines $ map rowJoin $ map padRow tab
  where sizes = [ maximum (map (length . (!! n)) tab)
                | n <- [0..(length (head tab))-1]
                ]
        pad len str =
          let diff = len - length str
            in str ++ (take diff $ repeat ' ')
        padRow = zipWith pad sizes
