{-# LANGUAGE OverloadedStrings, GeneralizedNewtypeDeriving #-}
module Clay.Transform
(

-- * The transform propery.

  Transformation
, transform
, transforms
, TransformStyle
, transformStyle
, flat
, preserve3d
, TransformBox
, transformBox
, transformContentBox
, transformBorderBox
, fillBox
, strokeBox
, viewBox
, transformOrigin

-- * Translating.

, translate
, translateX, translateY, translateZ
, translate3d

-- * Scaling.

, scale
, scaleX, scaleY, scaleZ
, scale3d

-- * Rotating.

, rotate
, rotateX, rotateY, rotateZ
, rotate3d

-- * Skewing.

, skew
, skewX, skewY

-- * Custom 3D transformations.

, perspective
, matrix
, matrix3d 
)
where

import Prelude hiding (Left, Right)

import Clay.Property
import Clay.Stylesheet
import Clay.Size
import Clay.Common

newtype Transformation = Transformation Value
  deriving (Transformation -> Value
(Transformation -> Value) -> Val Transformation
forall a. (a -> Value) -> Val a
$cvalue :: Transformation -> Value
value :: Transformation -> Value
Val, Transformation
Transformation -> None Transformation
forall a. a -> None a
$cnone :: Transformation
none :: Transformation
None)

transform :: Transformation -> Css
transform :: Transformation -> Css
transform = Prefixed -> Transformation -> Css
forall a. Val a => Prefixed -> a -> Css
prefixed (Prefixed
browsers Prefixed -> Prefixed -> Prefixed
forall a. Semigroup a => a -> a -> a
<> Prefixed
"transform")

transforms :: [Transformation] -> Css
transforms :: [Transformation] -> Css
transforms [Transformation]
xs = Prefixed -> Value -> Css
forall a. Val a => Prefixed -> a -> Css
prefixed (Prefixed
browsers Prefixed -> Prefixed -> Prefixed
forall a. Semigroup a => a -> a -> a
<> Prefixed
"transform") ([Transformation] -> Value
forall a. Val a => [a] -> Value
noCommas [Transformation]
xs)

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

newtype TransformStyle = TransformStyle Value
  deriving (TransformStyle -> Value
(TransformStyle -> Value) -> Val TransformStyle
forall a. (a -> Value) -> Val a
$cvalue :: TransformStyle -> Value
value :: TransformStyle -> Value
Val, TransformStyle
TransformStyle -> Inherit TransformStyle
forall a. a -> Inherit a
$cinherit :: TransformStyle
inherit :: TransformStyle
Inherit, TransformStyle
TransformStyle -> Initial TransformStyle
forall a. a -> Initial a
$cinitial :: TransformStyle
initial :: TransformStyle
Initial, TransformStyle
TransformStyle -> Unset TransformStyle
forall a. a -> Unset a
$cunset :: TransformStyle
unset :: TransformStyle
Unset)

transformStyle :: TransformStyle -> Css
transformStyle :: TransformStyle -> Css
transformStyle = Prefixed -> TransformStyle -> Css
forall a. Val a => Prefixed -> a -> Css
prefixed (Prefixed
browsers Prefixed -> Prefixed -> Prefixed
forall a. Semigroup a => a -> a -> a
<> Prefixed
"transform-style")

flat, preserve3d :: TransformStyle
flat :: TransformStyle
flat = Value -> TransformStyle
TransformStyle Value
"flat"
preserve3d :: TransformStyle
preserve3d = Value -> TransformStyle
TransformStyle Value
"preserve-3d"

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

newtype TransformBox = TransformBox Value
  deriving (TransformBox -> Value
(TransformBox -> Value) -> Val TransformBox
forall a. (a -> Value) -> Val a
$cvalue :: TransformBox -> Value
value :: TransformBox -> Value
Val, TransformBox
TransformBox -> Inherit TransformBox
forall a. a -> Inherit a
$cinherit :: TransformBox
inherit :: TransformBox
Inherit, TransformBox
TransformBox -> Initial TransformBox
forall a. a -> Initial a
$cinitial :: TransformBox
initial :: TransformBox
Initial, TransformBox
TransformBox -> Unset TransformBox
forall a. a -> Unset a
$cunset :: TransformBox
unset :: TransformBox
Unset)

transformBox :: TransformBox -> Css
transformBox :: TransformBox -> Css
transformBox = Prefixed -> TransformBox -> Css
forall a. Val a => Prefixed -> a -> Css
prefixed (Prefixed
browsers Prefixed -> Prefixed -> Prefixed
forall a. Semigroup a => a -> a -> a
<> Prefixed
"transform-box")

transformContentBox, transformBorderBox, fillBox, strokeBox, viewBox :: TransformBox
transformContentBox :: TransformBox
transformContentBox = Value -> TransformBox
TransformBox Value
"contentBox"
transformBorderBox :: TransformBox
transformBorderBox = Value -> TransformBox
TransformBox Value
"borderBox"
fillBox :: TransformBox
fillBox = Value -> TransformBox
TransformBox Value
"fillBox"
strokeBox :: TransformBox
strokeBox = Value -> TransformBox
TransformBox Value
"strokeBox"
viewBox :: TransformBox
viewBox = Value -> TransformBox
TransformBox Value
"viewBox"

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

transformOrigin :: [Size a] -> Css
transformOrigin :: forall a. [Size a] -> Css
transformOrigin = Prefixed -> Value -> Css
forall a. Val a => Prefixed -> a -> Css
prefixed (Prefixed
browsers Prefixed -> Prefixed -> Prefixed
forall a. Semigroup a => a -> a -> a
<> Prefixed
"transform-origin") (Value -> Css) -> ([Size a] -> Value) -> [Size a] -> Css
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Size a] -> Value
forall a. Val a => [a] -> Value
noCommas

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

scale :: Number -> Number -> Transformation
scale :: Number -> Number -> Transformation
scale Number
x Number
y = Value -> Transformation
Transformation (Value
"scale(" Value -> Value -> Value
forall a. Semigroup a => a -> a -> a
<> [Number] -> Value
forall a. Val a => a -> Value
value [Number
x, Number
y] Value -> Value -> Value
forall a. Semigroup a => a -> a -> a
<> Value
")")

scaleX, scaleY, scaleZ :: Number -> Transformation

scaleX :: Number -> Transformation
scaleX Number
x = Value -> Transformation
Transformation (Value
"scaleX(" Value -> Value -> Value
forall a. Semigroup a => a -> a -> a
<> Number -> Value
forall a. Val a => a -> Value
value Number
x Value -> Value -> Value
forall a. Semigroup a => a -> a -> a
<> Value
")")
scaleY :: Number -> Transformation
scaleY Number
y = Value -> Transformation
Transformation (Value
"scaleY(" Value -> Value -> Value
forall a. Semigroup a => a -> a -> a
<> Number -> Value
forall a. Val a => a -> Value
value Number
y Value -> Value -> Value
forall a. Semigroup a => a -> a -> a
<> Value
")")
scaleZ :: Number -> Transformation
scaleZ Number
z = Value -> Transformation
Transformation (Value
"scaleZ(" Value -> Value -> Value
forall a. Semigroup a => a -> a -> a
<> Number -> Value
forall a. Val a => a -> Value
value Number
z Value -> Value -> Value
forall a. Semigroup a => a -> a -> a
<> Value
")")

scale3d :: Number -> Number -> Number -> Transformation
scale3d :: Number -> Number -> Number -> Transformation
scale3d Number
x Number
y Number
z = Value -> Transformation
Transformation (Value
"scale3d(" Value -> Value -> Value
forall a. Semigroup a => a -> a -> a
<> [Number] -> Value
forall a. Val a => a -> Value
value [Number
x, Number
y, Number
z] Value -> Value -> Value
forall a. Semigroup a => a -> a -> a
<> Value
")")

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

rotate :: Angle a -> Transformation
rotate :: forall a. Angle a -> Transformation
rotate Angle a
x = Value -> Transformation
Transformation (Value
"rotate(" Value -> Value -> Value
forall a. Semigroup a => a -> a -> a
<> Angle a -> Value
forall a. Val a => a -> Value
value Angle a
x Value -> Value -> Value
forall a. Semigroup a => a -> a -> a
<> Value
")")

rotateX, rotateY, rotateZ :: Angle a -> Transformation

rotateX :: forall a. Angle a -> Transformation
rotateX Angle a
x = Value -> Transformation
Transformation (Value
"rotateX(" Value -> Value -> Value
forall a. Semigroup a => a -> a -> a
<> Angle a -> Value
forall a. Val a => a -> Value
value Angle a
x Value -> Value -> Value
forall a. Semigroup a => a -> a -> a
<> Value
")")
rotateY :: forall a. Angle a -> Transformation
rotateY Angle a
y = Value -> Transformation
Transformation (Value
"rotateY(" Value -> Value -> Value
forall a. Semigroup a => a -> a -> a
<> Angle a -> Value
forall a. Val a => a -> Value
value Angle a
y Value -> Value -> Value
forall a. Semigroup a => a -> a -> a
<> Value
")")
rotateZ :: forall a. Angle a -> Transformation
rotateZ Angle a
z = Value -> Transformation
Transformation (Value
"rotateZ(" Value -> Value -> Value
forall a. Semigroup a => a -> a -> a
<> Angle a -> Value
forall a. Val a => a -> Value
value Angle a
z Value -> Value -> Value
forall a. Semigroup a => a -> a -> a
<> Value
")")

rotate3d :: Number -> Number -> Number -> Angle a -> Transformation
rotate3d :: forall a. Number -> Number -> Number -> Angle a -> Transformation
rotate3d Number
x Number
y Number
z Angle a
a = Value -> Transformation
Transformation (Value
"rotate3d(" Value -> Value -> Value
forall a. Semigroup a => a -> a -> a
<> [Value] -> Value
forall a. Val a => a -> Value
value [Number -> Value
forall a. Val a => a -> Value
value Number
x, Number -> Value
forall a. Val a => a -> Value
value Number
y, Number -> Value
forall a. Val a => a -> Value
value Number
z, Angle a -> Value
forall a. Val a => a -> Value
value Angle a
a] Value -> Value -> Value
forall a. Semigroup a => a -> a -> a
<> Value
")")

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

translate :: Size a -> Size b -> Transformation
translate :: forall a b. Size a -> Size b -> Transformation
translate Size a
x Size b
y = Value -> Transformation
Transformation (Value
"translate(" Value -> Value -> Value
forall a. Semigroup a => a -> a -> a
<> [Value] -> Value
forall a. Val a => a -> Value
value [Size a -> Value
forall a. Val a => a -> Value
value Size a
x, Size b -> Value
forall a. Val a => a -> Value
value Size b
y] Value -> Value -> Value
forall a. Semigroup a => a -> a -> a
<> Value
")")

translateX, translateY :: Size LengthUnit -> Transformation
translateZ :: Size LengthUnit -> Transformation

translateX :: Size LengthUnit -> Transformation
translateX Size LengthUnit
x = Value -> Transformation
Transformation (Value
"translateX(" Value -> Value -> Value
forall a. Semigroup a => a -> a -> a
<> Size LengthUnit -> Value
forall a. Val a => a -> Value
value Size LengthUnit
x Value -> Value -> Value
forall a. Semigroup a => a -> a -> a
<> Value
")")
translateY :: Size LengthUnit -> Transformation
translateY Size LengthUnit
y = Value -> Transformation
Transformation (Value
"translateY(" Value -> Value -> Value
forall a. Semigroup a => a -> a -> a
<> Size LengthUnit -> Value
forall a. Val a => a -> Value
value Size LengthUnit
y Value -> Value -> Value
forall a. Semigroup a => a -> a -> a
<> Value
")")
translateZ :: Size LengthUnit -> Transformation
translateZ Size LengthUnit
z = Value -> Transformation
Transformation (Value
"translateZ(" Value -> Value -> Value
forall a. Semigroup a => a -> a -> a
<> Size LengthUnit -> Value
forall a. Val a => a -> Value
value Size LengthUnit
z Value -> Value -> Value
forall a. Semigroup a => a -> a -> a
<> Value
")")

translate3d :: Size a -> Size b -> Size LengthUnit -> Transformation
translate3d :: forall a b. Size a -> Size b -> Size LengthUnit -> Transformation
translate3d Size a
x Size b
y Size LengthUnit
z = Value -> Transformation
Transformation (Value
"translate3d(" Value -> Value -> Value
forall a. Semigroup a => a -> a -> a
<> [Value] -> Value
forall a. Val a => a -> Value
value [Size a -> Value
forall a. Val a => a -> Value
value Size a
x, Size b -> Value
forall a. Val a => a -> Value
value Size b
y, Size LengthUnit -> Value
forall a. Val a => a -> Value
value Size LengthUnit
z] Value -> Value -> Value
forall a. Semigroup a => a -> a -> a
<> Value
")")

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

skew :: Angle a -> Angle a -> Transformation
skew :: forall a. Angle a -> Angle a -> Transformation
skew Angle a
x Angle a
y = Value -> Transformation
Transformation (Value
"skew(" Value -> Value -> Value
forall a. Semigroup a => a -> a -> a
<> [Angle a] -> Value
forall a. Val a => a -> Value
value [Angle a
x, Angle a
y] Value -> Value -> Value
forall a. Semigroup a => a -> a -> a
<> Value
")")

skewX, skewY :: Angle a -> Transformation

skewX :: forall a. Angle a -> Transformation
skewX Angle a
x = Value -> Transformation
Transformation (Value
"skewX(" Value -> Value -> Value
forall a. Semigroup a => a -> a -> a
<> Angle a -> Value
forall a. Val a => a -> Value
value Angle a
x Value -> Value -> Value
forall a. Semigroup a => a -> a -> a
<> Value
")")
skewY :: forall a. Angle a -> Transformation
skewY Angle a
y = Value -> Transformation
Transformation (Value
"skewY(" Value -> Value -> Value
forall a. Semigroup a => a -> a -> a
<> Angle a -> Value
forall a. Val a => a -> Value
value Angle a
y Value -> Value -> Value
forall a. Semigroup a => a -> a -> a
<> Value
")")

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

perspective :: Number -> Transformation
perspective :: Number -> Transformation
perspective Number
p = Value -> Transformation
Transformation (Value
"perspective(" Value -> Value -> Value
forall a. Semigroup a => a -> a -> a
<> Number -> Value
forall a. Val a => a -> Value
value Number
p Value -> Value -> Value
forall a. Semigroup a => a -> a -> a
<> Value
")")

matrix :: Number -> Number -> Number -> Number -> Number -> Number -> Transformation
matrix :: Number
-> Number -> Number -> Number -> Number -> Number -> Transformation
matrix Number
u Number
v Number
w Number
x Number
y Number
z = Value -> Transformation
Transformation (Value
"matrix(" Value -> Value -> Value
forall a. Semigroup a => a -> a -> a
<> [Number] -> Value
forall a. Val a => a -> Value
value [ Number
u, Number
v, Number
w, Number
x, Number
y, Number
z ] Value -> Value -> Value
forall a. Semigroup a => a -> a -> a
<> Value
")")

matrix3d :: Number -> Number -> Number -> Number 
         -> Number -> Number -> Number -> Number
         -> Number -> Number -> Number -> Number
         -> Number -> Number -> Number -> Number
         -> Transformation
matrix3d :: Number
-> Number
-> Number
-> Number
-> Number
-> Number
-> Number
-> Number
-> Number
-> Number
-> Number
-> Number
-> Number
-> Number
-> Number
-> Number
-> Transformation
matrix3d Number
w0 Number
x0 Number
y0 Number
z0
         Number
w1 Number
x1 Number
y1 Number
z1
         Number
w2 Number
x2 Number
y2 Number
z2
         Number
w3 Number
x3 Number
y3 Number
z3 =
  Value -> Transformation
Transformation (Value
"matrix3d(" Value -> Value -> Value
forall a. Semigroup a => a -> a -> a
<> [Number] -> Value
forall a. Val a => a -> Value
value
       [ Number
w0, Number
x0, Number
y0, Number
z0
       , Number
w1, Number
x1, Number
y1, Number
z1
       , Number
w2, Number
x2, Number
y2, Number
z2
       , Number
w3, Number
x3, Number
y3, Number
z3
       ] Value -> Value -> Value
forall a. Semigroup a => a -> a -> a
<> Value
")")