module Diagrams.Backend.Rasterific.Text
  ( texterific'
  , texterific
  , fromFontStyle
  , textBoundingBox
  ) where
import           Graphics.Text.TrueType    hiding (BoundingBox)
import           Diagrams.Prelude
import           Diagrams.TwoD.Text        hiding (Font)
import           Data.FileEmbed            (embedDir)
import           Data.ByteString           (ByteString)
import           Data.ByteString.Lazy      (fromStrict)
textBoundingBox :: RealFloat n => Font -> PointSize -> String -> BoundingBox V2 n
textBoundingBox f p s = fromCorners
                        (mkP2 (2*r2f _xMin bb)              (r2f _yMin bb))
                        (mkP2 (r2f _xMax bb + r2f _xMin bb) (r2f _yMax bb))
  where
    r2f = fmap realToFrac
    bb = stringBoundingBox f 96 p s
texterific' :: (TypeableFloat n, Renderable (Text n) b)
            => FontSlant -> FontWeight -> String -> QDiagram b V2 n Any
texterific' fs fw s = recommendFillColor black . fontSizeL 1
                    . fontSlant fs . fontWeight fw
                    $ mkQD (Prim $ Text mempty BaselineText s)
                           (getEnvelope bb)
                           (getTrace bb)
                           mempty
                           (getQuery bb)
  where
    bb = textBoundingBox fnt (PointSize 1) s
    fnt = fromFontStyle fs fw
texterific :: (TypeableFloat n, Renderable (Text n) b) => String -> QDiagram b V2 n Any
texterific s = texterific' FontSlantNormal FontWeightNormal s
fromFontStyle :: FontSlant -> FontWeight -> Font
fromFontStyle FontSlantItalic  FontWeightBold   = openSansBoldItalic
fromFontStyle FontSlantOblique FontWeightBold   = openSansBoldItalic
fromFontStyle FontSlantNormal  FontWeightBold   = openSansBold
fromFontStyle FontSlantItalic  FontWeightNormal = openSansItalic
fromFontStyle FontSlantOblique FontWeightNormal = openSansItalic
fromFontStyle _                _                = openSansRegular
fonts :: [(FilePath,ByteString)]
fonts = $(embedDir "fonts")
staticFont :: String -> Font
staticFont nm = case lookup nm fonts of
   Nothing -> error ("Font not found: " ++ nm)
   Just f  -> case decodeFont (fromStrict f) of
                Right r -> r
                Left e  -> error e
openSansRegular :: Font
openSansRegular = staticFont "OpenSans-Regular.ttf"
openSansBold :: Font
openSansBold = staticFont "OpenSans-Bold.ttf"
openSansItalic :: Font
openSansItalic = staticFont "OpenSans-Italic.ttf"
openSansBoldItalic :: Font
openSansBoldItalic = staticFont "OpenSans-BoldItalic.ttf"