{-# LANGUAGE OverloadedStrings #-}
--------------------------------------------------------------------------------
-- |
-- Module      :  HGeometry.Miso.Svg
-- Copyright   :  (C) Frank Staals
-- License     :  see the LICENSE file
-- Maintainer  :  Frank Staals
--
-- Render geometric objects to Svg files through miso
--
--------------------------------------------------------------------------------
module HGeometry.Miso.Svg
  ( renderSvgToFile
  , renderAsSvgText, renderAsSvgByteString

  , withAts
  , Drawable(..)

  , dPoint
  , dLineSegment
  , dRectangle
  , dCircle
  , dDisk
  , dPolyLine
  , dSimplePolygon


  , SvgWriteAttributes(..)
  ) where

import Data.ByteString.Lazy qualified as ByteString
import Data.Text.Encoding.Error qualified as Text
import Data.Text.Lazy qualified as Text
import Data.Text.Lazy.Encoding qualified as Text
import HGeometry.Miso.Svg.Writer
import Miso qualified
import Miso.Html.Render qualified as Miso
import System.File.OsPath qualified as File
import System.OsPath

--------------------------------------------------------------------------------

-- | Given an file path, and a view whose root is an svg element,
-- render the output to the given file.
renderSvgToFile    :: OsPath -> Miso.View () () () action -> IO ()
renderSvgToFile :: forall action. OsPath -> View () () () action -> IO ()
renderSvgToFile OsPath
fp = OsPath -> ByteString -> IO ()
File.writeFile OsPath
fp (ByteString -> IO ())
-> (View () () () action -> ByteString)
-> View () () () action
-> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. View () () () action -> ByteString
forall action. View () () () action -> ByteString
renderAsSvgByteString

-- | Add the doctype
withDocType         :: ByteString.ByteString -> ByteString.ByteString
withDocType :: ByteString -> ByteString
withDocType ByteString
content = [ByteString] -> ByteString
forall a. Monoid a => [a] -> a
mconcat
  [ ByteString
"<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">"
  , ByteString
"<svg xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">"
  , ByteString
content
  , ByteString
"</svg>"
  ]


  -- "<svg>"

  --                    "</svg>"
  -- do
  --                       Svg.doctype_
  --                       Svg.with content
  --                            [ Lucid.makeAttribute "xmlns" "http://www.w3.org/2000/svg"
  --                            , Lucid.makeAttribute "xmlns:xlink" "http://www.w3.org/1999/xlink"
  --                            , Svg.version_ "1.1"
  --                            ]

-- | Given an View whose root is an svg element, renders the view to a
-- lazy Text
--
renderAsSvgText :: Miso.View () () () action -> Text.Text
renderAsSvgText :: forall action. View () () () action -> Text
renderAsSvgText = OnDecodeError -> ByteString -> Text
Text.decodeUtf8With OnDecodeError
Text.strictDecode (ByteString -> Text)
-> (View () () () action -> ByteString)
-> View () () () action
-> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. View () () () action -> ByteString
forall action. View () () () action -> ByteString
renderAsSvgByteString

-- | Given an View whose root is an svg element, renders the view to a
-- lazy ByteString.
--
renderAsSvgByteString :: Miso.View () () () action -> ByteString.ByteString
renderAsSvgByteString :: forall action. View () () () action -> ByteString
renderAsSvgByteString = ByteString -> ByteString
withDocType (ByteString -> ByteString)
-> (View () () () action -> ByteString)
-> View () () () action
-> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. View () () () action -> ByteString
forall a. ToHtml a => a -> ByteString
Miso.toHtml