{-# LANGUAGE RankNTypes #-}

-- | Module to generate PNGs from shapefiles
module GIS.Graphics.PlotPNG where

import           Control.Lens                           hiding (lens)
import           Data.Semigroup
import           GIS.Graphics.Plot
import           GIS.Graphics.PlotSVG                   hiding (fileOptions)
import           GIS.Graphics.Types                     hiding (title)
import           GIS.Types
import           GIS.Utils
import           Graphics.Rendering.Chart.Backend.Cairo
import           Graphics.Rendering.Chart.Easy          hiding (lens)

-- | Default file options: PNG output and 1920x1080. To change the file size,
-- you can do e.g.
-- > fo_size .~ (640,480) $ fileOptions
fileOptions :: FileOptions
fileOptions = def { _fo_size = (1920, 1080) , _fo_format = PNG }

-- | Given a `Map` write it to file, where the format is determined by the
-- extension.
mkMap :: FilePath -> Map -> IO ()
mkMap filepath map' = case getExt filepath of
    "png" -> mkMapPng filepath map'
    "svg" -> mkMapSVG filepath map'
    _     -> error "file extension must be one of: .svg, .png"

-- | Given a `Map` write it to file, where the format is determined by the
-- extension.
mkLensMap :: (Show a) => String -> FilePath -> Lens' District a -> [District] -> IO ()
mkLensMap title filepath lens districts = case getExt filepath of
    "png" -> makeLensMapPng title filepath lens districts
    "svg" -> makeLensMapSVG title filepath lens districts
    _     -> error "file extension must be one of: .svg, .png"

-- | Given a `Map`, write it to file.
mkMapPng :: FilePath -> Map -> IO ()
mkMapPng path map' =
    renderableToFile fileOptions path (mkMapR map') >>
    putStrLn ("...output written to " <> path)

makeLensMapPng :: (Show a) => String -> FilePath -> Lens' District a -> [District] -> IO ()
makeLensMapPng title filepath lens districts =
    renderableToFile fileOptions filepath (mkRenderableLens lens districts title) >>
    putStrLn ("...output written to " <> filepath)