    {-# 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 :: 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 4)

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

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

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

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

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

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

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

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

    -- | Cubic Bezier curve (absolute)
    cA :: RealFloat a =>  a -> a -> a -> a -> a -> a -> Text
    cA :: a -> a -> a -> a -> a -> a -> Text
    cA c1x :: a
    c1x c1y :: a
    c1y c2x :: a
    c2x c2y :: a
    c2y x :: a
    x y :: a
    y = [Text] -> Text
    T.concat
      [ "C ", a -> Text
    forall a. RealFloat a => a -> Text
    toText a
    c1x, ",", a -> Text
    forall a. RealFloat a => a -> Text
    toText a
    c1y, " ", a -> Text
    forall a. RealFloat a => a -> Text
    toText a
    c2x, ","
      , a -> Text
    forall a. RealFloat a => a -> Text
    toText a
    c2y, " ", a -> Text
    forall a. RealFloat a => a -> Text
    toText a
    x, " ", 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 :: a -> a -> a -> a -> a -> a -> Text
    cR dc1x :: a
    dc1x dc1y :: a
    dc1y dc2x :: a
    dc2x dc2y :: a
    dc2y dx :: a
    dx dy :: a
    dy = [Text] -> Text
    T.concat
      [ "c ", a -> Text
    forall a. RealFloat a => a -> Text
    toText a
    dc1x, ",", a -> Text
    forall a. RealFloat a => a -> Text
    toText a
    dc1y, " ", a -> Text
    forall a. RealFloat a => a -> Text
    toText a
    dc2x
      , ",", a -> Text
    forall a. RealFloat a => a -> Text
    toText a
    dc2y, " ", a -> Text
    forall a. RealFloat a => a -> Text
    toText a
    dx, " ", 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 :: a -> a -> a -> a -> Text
    sA c2x :: a
    c2x c2y :: a
    c2y x :: a
    x y :: a
    y = [Text] -> Text
    T.concat
      ["S ", a -> Text
    forall a. RealFloat a => a -> Text
    toText a
    c2x, ",", a -> Text
    forall a. RealFloat a => a -> Text
    toText a
    c2y, " ", a -> Text
    forall a. RealFloat a => a -> Text
    toText a
    x, ",", a -> Text
    forall a. RealFloat a => a -> Text
    toText a
    y, " "]

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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