{-# LANGUAGE FlexibleContexts  #-}
{-# LANGUAGE OverloadedStrings #-}

-------------------------------------------------------------------------------
-- |
-- Module      :  Lucid.Svg.Path
-- Copyright   :  (c) 2015 Jeffrey Rosenbluth
-- License     :  BSD-style (see LICENSE)
-- Maintainer  :  jeffrey.rosenbluth@gmail.com
--
-- Utility functions to help create SVG path attributes,
-- and transforms.
--
-------------------------------------------------------------------------------

module Lucid.Svg.Path where

import           Data.Text                        (Text)
import qualified Data.Text                        as T
import           Data.Text.Lazy                   (toStrict)
import           Data.Text.Lazy.Builder           (toLazyText)
import           Data.Text.Lazy.Builder.RealFloat

-- | Convert a number to Text.
toText :: RealFloat a => a -> Text
toText :: forall a. RealFloat a => a -> Text
toText = Text -> Text
toStrict forall b c a. (b -> c) -> (a -> b) -> a -> c
. Builder -> Text
toLazyText forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. RealFloat a => FPFormat -> Maybe Int -> a -> Builder
formatRealFloat FPFormat
Fixed (forall a. a -> Maybe a
Just Int
4)

-- | moveto (absolute)
mA :: RealFloat a =>  a -> a -> Text
mA :: forall a. RealFloat a => a -> a -> Text
mA a
x a
y = [Text] -> Text
T.concat [Text
"M " ,forall a. RealFloat a => a -> Text
toText a
x, Text
",", forall a. RealFloat a => a -> Text
toText a
y, Text
" "]

-- | moveto (relative)
mR :: RealFloat a =>  a -> a -> Text
mR :: forall a. RealFloat a => a -> a -> Text
mR a
dx a
dy = [Text] -> Text
T.concat [Text
"m ", forall a. RealFloat a => a -> Text
toText a
dx, Text
",", forall a. RealFloat a => a -> Text
toText a
dy, Text
" "]

-- | lineto (absolute)
lA :: RealFloat a =>  a -> a -> Text
lA :: forall a. RealFloat a => a -> a -> Text
lA a
x a
y = [Text] -> Text
T.concat [Text
"L ", forall a. RealFloat a => a -> Text
toText a
x, Text
",", forall a. RealFloat a => a -> Text
toText a
y, Text
" "]

-- | lineto (relative)
lR :: RealFloat a =>  a -> a -> Text
lR :: forall a. RealFloat a => a -> a -> Text
lR a
dx a
dy = [Text] -> Text
T.concat [Text
"l ", forall a. RealFloat a => a -> Text
toText a
dx, Text
",", forall a. RealFloat a => a -> Text
toText a
dy, Text
" "]

-- | horizontal lineto (absolute)
hA :: RealFloat a =>  a -> Text
hA :: forall a. RealFloat a => a -> Text
hA a
x = [Text] -> Text
T.concat [Text
"H ", forall a. RealFloat a => a -> Text
toText a
x, Text
" "]

-- | horizontal lineto (relative)
hR :: RealFloat a =>  a -> Text
hR :: forall a. RealFloat a => a -> Text
hR a
dx = [Text] -> Text
T.concat [Text
"h ", forall a. RealFloat a => a -> Text
toText a
dx, Text
" "]

-- | vertical lineto (absolute)
vA :: RealFloat a =>  a -> Text
vA :: forall a. RealFloat a => a -> Text
vA a
y = [Text] -> Text
T.concat [Text
"V ", forall a. RealFloat a => a -> Text
toText a
y, Text
" "]

-- | vertical lineto (relative)
vR :: RealFloat a =>  a -> Text
vR :: forall a. RealFloat a => a -> Text
vR a
dy = [Text] -> Text
T.concat [Text
"v ", forall a. RealFloat a => a -> Text
toText a
dy, Text
" "]

-- | Cubic Bezier curve (absolute)
cA :: RealFloat a =>  a -> a -> a -> a -> a -> a -> Text
cA :: forall a. RealFloat a => a -> a -> a -> a -> a -> a -> Text
cA a
c1x a
c1y a
c2x a
c2y a
x a
y = [Text] -> Text
T.concat
  [ Text
"C ", forall a. RealFloat a => a -> Text
toText a
c1x, Text
",", forall a. RealFloat a => a -> Text
toText a
c1y, Text
" ", forall a. RealFloat a => a -> Text
toText a
c2x, Text
","
  , forall a. RealFloat a => a -> Text
toText a
c2y, Text
" ", forall a. RealFloat a => a -> Text
toText a
x, Text
" ", forall a. RealFloat a => a -> Text
toText a
y]

-- | Cubic Bezier curve (relative)
cR :: RealFloat a =>  a -> a -> a -> a -> a -> a -> Text
cR :: forall a. RealFloat a => a -> a -> a -> a -> a -> a -> Text
cR a
dc1x a
dc1y a
dc2x a
dc2y a
dx a
dy = [Text] -> Text
T.concat
  [ Text
"c ", forall a. RealFloat a => a -> Text
toText a
dc1x, Text
",", forall a. RealFloat a => a -> Text
toText a
dc1y, Text
" ", forall a. RealFloat a => a -> Text
toText a
dc2x
  , Text
",", forall a. RealFloat a => a -> Text
toText a
dc2y, Text
" ", forall a. RealFloat a => a -> Text
toText a
dx, Text
" ", forall a. RealFloat a => a -> Text
toText a
dy]

-- | Smooth Cubic Bezier curve (absolute)
sA :: RealFloat a =>  a -> a -> a -> a -> Text
sA :: forall a. RealFloat a => a -> a -> a -> a -> Text
sA a
c2x a
c2y a
x a
y = [Text] -> Text
T.concat
  [Text
"S ", forall a. RealFloat a => a -> Text
toText a
c2x, Text
",", forall a. RealFloat a => a -> Text
toText a
c2y, Text
" ", forall a. RealFloat a => a -> Text
toText a
x, Text
",", forall a. RealFloat a => a -> Text
toText a
y, Text
" "]

-- | Smooth Cubic Bezier curve (relative)
sR :: RealFloat a =>  a -> a -> a -> a -> Text
sR :: forall a. RealFloat a => a -> a -> a -> a -> Text
sR a
dc2x a
dc2y a
dx a
dy = [Text] -> Text
T.concat
  [Text
"s ", forall a. RealFloat a => a -> Text
toText a
dc2x, Text
",", forall a. RealFloat a => a -> Text
toText a
dc2y, Text
" ", forall a. RealFloat a => a -> Text
toText a
dx, Text
",", forall a. RealFloat a => a -> Text
toText a
dy, Text
" "]

-- | Quadratic Bezier curve (absolute)
qA :: RealFloat a =>  a -> a -> a -> a -> Text
qA :: forall a. RealFloat a => a -> a -> a -> a -> Text
qA a
cx a
cy a
x a
y = [Text] -> Text
T.concat
  [Text
"Q ", forall a. RealFloat a => a -> Text
toText a
cx, Text
",", forall a. RealFloat a => a -> Text
toText a
cy, Text
" ", forall a. RealFloat a => a -> Text
toText a
x, Text
",", forall a. RealFloat a => a -> Text
toText a
y, Text
" "]

-- | Quadratic Bezier curve (relative)
qR :: RealFloat a =>  a -> a -> a -> a -> Text
qR :: forall a. RealFloat a => a -> a -> a -> a -> Text
qR a
dcx a
dcy a
dx a
dy = [Text] -> Text
T.concat
  [Text
"q ", forall a. RealFloat a => a -> Text
toText a
dcx, Text
",", forall a. RealFloat a => a -> Text
toText a
dcy, Text
" ", forall a. RealFloat a => a -> Text
toText a
dx, Text
",", forall a. RealFloat a => a -> Text
toText a
dy, Text
" " ]

-- | Smooth Quadratic Bezier curve (absolute)
tA  :: RealFloat a =>  a -> a -> Text
tA :: forall a. RealFloat a => a -> a -> Text
tA a
x a
y = [Text] -> Text
T.concat [Text
"T ", Text
" ", forall a. RealFloat a => a -> Text
toText a
x, Text
",", forall a. RealFloat a => a -> Text
toText a
y, Text
" "]

-- | Smooth Quadratic Bezier curve (relative)
tR :: RealFloat a =>  a -> a -> Text
tR :: forall a. RealFloat a => a -> a -> Text
tR a
x a
y = [Text] -> Text
T.concat [ Text
"t ", forall a. RealFloat a => a -> Text
toText a
x, Text
",", forall a. RealFloat a => a -> Text
toText a
y, Text
" "]

-- | Arc (absolute)
aA :: RealFloat a =>  a -> a -> a -> a -> a -> a -> a -> Text
aA :: forall a. RealFloat a => a -> a -> a -> a -> a -> a -> a -> Text
aA a
rx a
ry a
xrot a
largeFlag a
sweepFlag a
x a
y = [Text] -> Text
T.concat
  [ Text
"A ", forall a. RealFloat a => a -> Text
toText a
rx, Text
",", forall a. RealFloat a => a -> Text
toText a
ry, Text
" ", forall a. RealFloat a => a -> Text
toText a
xrot, Text
" ", forall a. RealFloat a => a -> Text
toText a
largeFlag
  , Text
" ", forall a. RealFloat a => a -> Text
toText a
sweepFlag, Text
" ", forall a. RealFloat a => a -> Text
toText a
x, Text
" ", forall a. RealFloat a => a -> Text
toText a
y, Text
" "]

-- | Arc (relative)
aR :: RealFloat a =>  a -> a -> a -> a -> a -> a -> a -> Text
aR :: forall a. RealFloat a => a -> a -> a -> a -> a -> a -> a -> Text
aR a
rx a
ry a
xrot a
largeFlag a
sweepFlag a
x a
y = [Text] -> Text
T.concat
  [ Text
"a ", forall a. RealFloat a => a -> Text
toText a
rx, Text
",", forall a. RealFloat a => a -> Text
toText a
ry, Text
" ", forall a. RealFloat a => a -> Text
toText a
xrot, Text
" ", forall a. RealFloat a => a -> Text
toText a
largeFlag
  , Text
" ", forall a. RealFloat a => a -> Text
toText a
sweepFlag, Text
" ", forall a. RealFloat a => a -> Text
toText a
x, Text
" ", forall a. RealFloat a => a -> Text
toText a
y, Text
" "]

-- | closepath
z :: Text
z :: Text
z = Text
"Z"

-- | SVG Transform components
-- | Specifies a translation by @x@ and @y@
translate :: RealFloat a =>  a -> a -> Text
translate :: forall a. RealFloat a => a -> a -> Text
translate a
x a
y = [Text] -> Text
T.concat [Text
"translate(", forall a. RealFloat a => a -> Text
toText a
x, Text
" ", forall a. RealFloat a => a -> Text
toText a
y, Text
")"]

-- | Specifies a scale operation by @x@ and @y@
scale :: RealFloat a =>  a -> a -> Text
scale :: forall a. RealFloat a => a -> a -> Text
scale a
x a
y = [Text] -> Text
T.concat [Text
"scale(", forall a. RealFloat a => a -> Text
toText a
x, Text
" ", forall a. RealFloat a => a -> Text
toText a
y, Text
")"]

-- | Specifies a rotation by @rotate-angle@ degrees
rotate :: RealFloat a =>  a -> Text
rotate :: forall a. RealFloat a => a -> Text
rotate a
angle = [Text] -> Text
T.concat [Text
"rotate(", forall a. RealFloat a => a -> Text
toText a
angle, Text
")"]

-- | Specifies a rotation by @rotate-angle@ degrees about the given time @rx,ry@
rotateAround :: RealFloat a =>  a -> a -> a -> Text
rotateAround :: forall a. RealFloat a => a -> a -> a -> Text
rotateAround a
angle a
rx a
ry = [Text] -> Text
T.concat
  [Text
"rotate(", forall a. RealFloat a => a -> Text
toText a
angle, Text
",", forall a. RealFloat a => a -> Text
toText a
rx, Text
",", forall a. RealFloat a => a -> Text
toText a
ry, Text
")"]

-- | Skew tansformation along x-axis
skewX :: RealFloat a =>  a -> Text
skewX :: forall a. RealFloat a => a -> Text
skewX a
angle = [Text] -> Text
T.concat [Text
"skewX(", forall a. RealFloat a => a -> Text
toText a
angle, Text
")"]

-- | Skew tansformation along y-axis
skewY :: RealFloat a =>  a -> Text
skewY :: forall a. RealFloat a => a -> Text
skewY a
angle = [Text] -> Text
T.concat [Text
"skewY(", forall a. RealFloat a => a -> Text
toText a
angle, Text
")"]

-- | Specifies a transform in the form of a transformation matrix
matrix :: RealFloat a =>  a -> a -> a -> a -> a -> a -> Text
matrix :: forall a. RealFloat a => a -> a -> a -> a -> a -> a -> Text
matrix a
a a
b a
c a
d a
e a
f =  [Text] -> Text
T.concat
  [ Text
"matrix(", forall a. RealFloat a => a -> Text
toText a
a, Text
",", forall a. RealFloat a => a -> Text
toText a
b, Text
",",  forall a. RealFloat a => a -> Text
toText a
c
  , Text
",",  forall a. RealFloat a => a -> Text
toText a
d, Text
",", forall a. RealFloat a => a -> Text
toText a
e, Text
",",  forall a. RealFloat a => a -> Text
toText a
f, Text
")"]