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

    -------------------------------------------------------------------------------
    -- |
    -- Module      :  Graphics.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 Graphics.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 (Text -> Text) -> (a -> Text) -> a -> Text
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Builder -> Text
    toLazyText (Builder -> Text) -> (a -> Builder) -> a -> Text
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . FPFormat -> Maybe Int -> a -> Builder
    forall a. RealFloat a => FPFormat -> Maybe Int -> a -> Builder
    formatRealFloat FPFormat
    Fixed (Int -> Maybe Int
    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 " ,a -> Text
    forall a. RealFloat a => a -> Text
    toText a
    x, Text
    ",", a -> 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 ", a -> Text
    forall a. RealFloat a => a -> Text
    toText a
    dx, Text
    ",", a -> 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 ", a -> Text
    forall a. RealFloat a => a -> Text
    toText a
    x, Text
    ",", a -> 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 ", a -> Text
    forall a. RealFloat a => a -> Text
    toText a
    dx, Text
    ",", a -> 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 ", a -> Text
    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 ", a -> Text
    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 ", a -> Text
    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 ", a -> Text
    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 ", a -> Text
    forall a. RealFloat a => a -> Text
    toText a
    c1x, Text
    ",", a -> Text
    forall a. RealFloat a => a -> Text
    toText a
    c1y, Text
    " ", a -> Text
    forall a. RealFloat a => a -> Text
    toText a
    c2x, Text
    ","
      , a -> Text
    forall a. RealFloat a => a -> Text
    toText a
    c2y, Text
    " ", a -> Text
    forall a. RealFloat a => a -> Text
    toText a
    x, Text
    " ", a -> 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 ", a -> Text
    forall a. RealFloat a => a -> Text
    toText a
    dc1x, Text
    ",", a -> Text
    forall a. RealFloat a => a -> Text
    toText a
    dc1y, Text
    " ", a -> Text
    forall a. RealFloat a => a -> Text
    toText a
    dc2x
      , Text
    ",", a -> Text
    forall a. RealFloat a => a -> Text
    toText a
    dc2y, Text
    " ", a -> Text
    forall a. RealFloat a => a -> Text
    toText a
    dx, Text
    " ", a -> 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 ", a -> Text
    forall a. RealFloat a => a -> Text
    toText a
    c2x, Text
    ",", a -> Text
    forall a. RealFloat a => a -> Text
    toText a
    c2y, Text
    " ", a -> Text
    forall a. RealFloat a => a -> Text
    toText a
    x, Text
    ",", a -> 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 ", a -> Text
    forall a. RealFloat a => a -> Text
    toText a
    dc2x, Text
    ",", a -> Text
    forall a. RealFloat a => a -> Text
    toText a
    dc2y, Text
    " ", a -> Text
    forall a. RealFloat a => a -> Text
    toText a
    dx, Text
    ",", a -> 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 ", a -> Text
    forall a. RealFloat a => a -> Text
    toText a
    cx, Text
    ",", a -> Text
    forall a. RealFloat a => a -> Text
    toText a
    cy, Text
    " ", a -> Text
    forall a. RealFloat a => a -> Text
    toText a
    x, Text
    ",", a -> 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 ", a -> Text
    forall a. RealFloat a => a -> Text
    toText a
    dcx, Text
    ",", a -> Text
    forall a. RealFloat a => a -> Text
    toText a
    dcy, Text
    " ", a -> Text
    forall a. RealFloat a => a -> Text
    toText a
    dx, Text
    ",", a -> 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
    " ", a -> Text
    forall a. RealFloat a => a -> Text
    toText a
    x, Text
    ",", a -> 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 ", a -> Text
    forall a. RealFloat a => a -> Text
    toText a
    x, Text
    ",", a -> 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 ", a -> Text
    forall a. RealFloat a => a -> Text
    toText a
    rx, Text
    ",", a -> Text
    forall a. RealFloat a => a -> Text
    toText a
    ry, Text
    " ", a -> Text
    forall a. RealFloat a => a -> Text
    toText a
    xrot, Text
    " ", a -> Text
    forall a. RealFloat a => a -> Text
    toText a
    largeFlag
      , Text
    " ", a -> Text
    forall a. RealFloat a => a -> Text
    toText a
    sweepFlag, Text
    " ", a -> Text
    forall a. RealFloat a => a -> Text
    toText a
    x, Text
    " ", a -> 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 ", a -> Text
    forall a. RealFloat a => a -> Text
    toText a
    rx, Text
    ",", a -> Text
    forall a. RealFloat a => a -> Text
    toText a
    ry, Text
    " ", a -> Text
    forall a. RealFloat a => a -> Text
    toText a
    xrot, Text
    " ", a -> Text
    forall a. RealFloat a => a -> Text
    toText a
    largeFlag
      , Text
    " ", a -> Text
    forall a. RealFloat a => a -> Text
    toText a
    sweepFlag, Text
    " ", a -> Text
    forall a. RealFloat a => a -> Text
    toText a
    x, Text
    " ", a -> 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(", a -> Text
    forall a. RealFloat a => a -> Text
    toText a
    x, Text
    " ", a -> 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(", a -> Text
    forall a. RealFloat a => a -> Text
    toText a
    x, Text
    " ", a -> 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(", a -> Text
    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(", a -> Text
    forall a. RealFloat a => a -> Text
    toText a
    angle, Text
    ",", a -> Text
    forall a. RealFloat a => a -> Text
    toText a
    rx, Text
    ",", a -> 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(", a -> Text
    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(", a -> Text
    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(", a -> Text
    forall a. RealFloat a => a -> Text
    toText a
    a, Text
    ",", a -> Text
    forall a. RealFloat a => a -> Text
    toText a
    b, Text
    ",",  a -> Text
    forall a. RealFloat a => a -> Text
    toText a
    c
      , Text
    ",",  a -> Text
    forall a. RealFloat a => a -> Text
    toText a
    d, Text
    ",", a -> Text
    forall a. RealFloat a => a -> Text
    toText a
    e, Text
    ",",  a -> Text
    forall a. RealFloat a => a -> Text
    toText a
    f, Text
    ")"]