{-# LANGUAGE
    OverloadedStrings
  , FlexibleInstances
  , GeneralizedNewtypeDeriving
  #-}
module Clay.Gradient
(
-- * Color ramp type.

  Ramp

-- * Linear gradients.

, linearGradient
, hGradient
, vGradient

-- * Radial gradients.

, Radial
, circle, ellipse
, circular, elliptical

, Extend
, closestSide, closestCorner, farthestSide, farthestCorner

, radialGradient

-- * Repeating gradients.

, repeatingLinearGradient
, hRepeatingGradient
, vRepeatingGradient
, repeatingRadialGradient

)
where

import Clay.Color
import Clay.Common
import Clay.Property
import Clay.Size
import Clay.Background

type Ramp = [(Color, Size Percentage)]

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

linearGradient :: Direction -> Ramp -> BackgroundImage
linearGradient :: Direction -> Ramp -> BackgroundImage
linearGradient Direction
d Ramp
xs = Value -> BackgroundImage
forall a. Other a => Value -> a
other (Value -> BackgroundImage) -> Value -> BackgroundImage
forall a b. (a -> b) -> a -> b
$ Prefixed -> Value
Value (Prefixed -> Value) -> Prefixed -> Value
forall a b. (a -> b) -> a -> b
$
  let Value Prefixed
v = Value
"linear-gradient(" Value -> Value -> Value
forall a. Semigroup a => a -> a -> a
<> Direction -> Value
forall a. Val a => a -> Value
value Direction
d Value -> Value -> Value
forall a. Semigroup a => a -> a -> a
<> Value
"," Value -> Value -> Value
forall a. Semigroup a => a -> a -> a
<> Ramp -> Value
ramp Ramp
xs Value -> Value -> Value
forall a. Semigroup a => a -> a -> a
<> Value
")"
   in Prefixed
browsers Prefixed -> Prefixed -> Prefixed
forall a. Semigroup a => a -> a -> a
<> Prefixed
v

hGradient, vGradient :: Color -> Color -> BackgroundImage

hGradient :: Color -> Color -> BackgroundImage
hGradient = (Ramp -> BackgroundImage) -> Color -> Color -> BackgroundImage
shortcut (Direction -> Ramp -> BackgroundImage
linearGradient (Side -> Direction
straight Side
sideLeft))
vGradient :: Color -> Color -> BackgroundImage
vGradient = (Ramp -> BackgroundImage) -> Color -> Color -> BackgroundImage
shortcut (Direction -> Ramp -> BackgroundImage
linearGradient (Side -> Direction
straight Side
sideTop ))

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

repeatingLinearGradient :: Direction -> Ramp -> BackgroundImage
repeatingLinearGradient :: Direction -> Ramp -> BackgroundImage
repeatingLinearGradient Direction
d Ramp
xs = Value -> BackgroundImage
forall a. Other a => Value -> a
other (Value -> BackgroundImage) -> Value -> BackgroundImage
forall a b. (a -> b) -> a -> b
$ Prefixed -> Value
Value (Prefixed -> Value) -> Prefixed -> Value
forall a b. (a -> b) -> a -> b
$
  let Value Prefixed
v = Value
"repeating-linear-gradient(" Value -> Value -> Value
forall a. Semigroup a => a -> a -> a
<> Direction -> Value
forall a. Val a => a -> Value
value Direction
d Value -> Value -> Value
forall a. Semigroup a => a -> a -> a
<> Value
"," Value -> Value -> Value
forall a. Semigroup a => a -> a -> a
<> Ramp -> Value
ramp Ramp
xs Value -> Value -> Value
forall a. Semigroup a => a -> a -> a
<> Value
")"
   in Prefixed
browsers Prefixed -> Prefixed -> Prefixed
forall a. Semigroup a => a -> a -> a
<> Prefixed
v

hRepeatingGradient, vRepeatingGradient :: Color -> Color -> BackgroundImage

hRepeatingGradient :: Color -> Color -> BackgroundImage
hRepeatingGradient = (Ramp -> BackgroundImage) -> Color -> Color -> BackgroundImage
shortcut (Direction -> Ramp -> BackgroundImage
repeatingLinearGradient (Side -> Direction
straight Side
sideLeft))
vRepeatingGradient :: Color -> Color -> BackgroundImage
vRepeatingGradient = (Ramp -> BackgroundImage) -> Color -> Color -> BackgroundImage
shortcut (Direction -> Ramp -> BackgroundImage
repeatingLinearGradient (Side -> Direction
straight Side
sideTop ))

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

newtype Radial = Radial Value
  deriving (Radial -> Value
(Radial -> Value) -> Val Radial
forall a. (a -> Value) -> Val a
value :: Radial -> Value
$cvalue :: Radial -> Value
Val, Value -> Radial
(Value -> Radial) -> Other Radial
forall a. (Value -> a) -> Other a
other :: Value -> Radial
$cother :: Value -> Radial
Other)

circle :: Extend -> Radial
circle :: Extend -> Radial
circle Extend
ext = Value -> Radial
Radial (Value
"circle " Value -> Value -> Value
forall a. Semigroup a => a -> a -> a
<> Extend -> Value
forall a. Val a => a -> Value
value Extend
ext)

ellipse :: Extend -> Radial
ellipse :: Extend -> Radial
ellipse Extend
ext = Value -> Radial
Radial (Value
"ellipse " Value -> Value -> Value
forall a. Semigroup a => a -> a -> a
<> Extend -> Value
forall a. Val a => a -> Value
value Extend
ext)

circular :: Size LengthUnit -> Radial
circular :: Size LengthUnit -> Radial
circular Size LengthUnit
radius = Value -> Radial
Radial ((Size LengthUnit, Size LengthUnit) -> Value
forall a. Val a => a -> Value
value (Size LengthUnit
radius, Size LengthUnit
radius))

elliptical :: Size a -> Size a -> Radial
elliptical :: Size a -> Size a -> Radial
elliptical Size a
radx Size a
rady = Value -> Radial
Radial ((Size a, Size a) -> Value
forall a. Val a => a -> Value
value (Size a
radx, Size a
rady))

newtype Extend = Extend Value
  deriving (Extend -> Value
(Extend -> Value) -> Val Extend
forall a. (a -> Value) -> Val a
value :: Extend -> Value
$cvalue :: Extend -> Value
Val, Value -> Extend
(Value -> Extend) -> Other Extend
forall a. (Value -> a) -> Other a
other :: Value -> Extend
$cother :: Value -> Extend
Other)

closestSide, closestCorner, farthestSide, farthestCorner :: Extend

closestSide :: Extend
closestSide    = Value -> Extend
Extend Value
"closest-side"
closestCorner :: Extend
closestCorner  = Value -> Extend
Extend Value
"closest-corner"
farthestSide :: Extend
farthestSide   = Value -> Extend
Extend Value
"farthest-side"
farthestCorner :: Extend
farthestCorner = Value -> Extend
Extend Value
"farthest-corner"

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

radialGradient :: Loc l => l -> Radial -> Ramp -> BackgroundImage
radialGradient :: l -> Radial -> Ramp -> BackgroundImage
radialGradient l
d Radial
r Ramp
xs = Value -> BackgroundImage
forall a. Other a => Value -> a
other (Value -> BackgroundImage) -> Value -> BackgroundImage
forall a b. (a -> b) -> a -> b
$ Prefixed -> Value
Value (Prefixed -> Value) -> Prefixed -> Value
forall a b. (a -> b) -> a -> b
$
  let Value Prefixed
v = Value
"radial-gradient(" Value -> Value -> Value
forall a. Semigroup a => a -> a -> a
<> [Value] -> Value
forall a. Val a => a -> Value
value [l -> Value
forall a. Val a => a -> Value
value l
d, Radial -> Value
forall a. Val a => a -> Value
value Radial
r, Ramp -> Value
ramp Ramp
xs] Value -> Value -> Value
forall a. Semigroup a => a -> a -> a
<> Value
")"
   in Prefixed
browsers Prefixed -> Prefixed -> Prefixed
forall a. Semigroup a => a -> a -> a
<> Prefixed
v

repeatingRadialGradient :: Loc l => l -> Radial -> Ramp -> BackgroundImage
repeatingRadialGradient :: l -> Radial -> Ramp -> BackgroundImage
repeatingRadialGradient l
d Radial
r Ramp
xs = Value -> BackgroundImage
forall a. Other a => Value -> a
other (Value -> BackgroundImage) -> Value -> BackgroundImage
forall a b. (a -> b) -> a -> b
$ Prefixed -> Value
Value (Prefixed -> Value) -> Prefixed -> Value
forall a b. (a -> b) -> a -> b
$
  let Value Prefixed
v = Value
"repeating-radial-gradient(" Value -> Value -> Value
forall a. Semigroup a => a -> a -> a
<> [Value] -> Value
forall a. Val a => a -> Value
value [l -> Value
forall a. Val a => a -> Value
value l
d, Radial -> Value
forall a. Val a => a -> Value
value Radial
r, Ramp -> Value
ramp Ramp
xs] Value -> Value -> Value
forall a. Semigroup a => a -> a -> a
<> Value
")"
   in Prefixed
browsers Prefixed -> Prefixed -> Prefixed
forall a. Semigroup a => a -> a -> a
<> Prefixed
v

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

ramp :: Ramp -> Value
ramp :: Ramp -> Value
ramp Ramp
xs = [Value] -> Value
forall a. Val a => a -> Value
value (((Color, Size Percentage) -> Value) -> Ramp -> [Value]
forall a b. (a -> b) -> [a] -> [b]
map (\(Color
a, Size Percentage
b) -> (Value, Value) -> Value
forall a. Val a => a -> Value
value (Color -> Value
forall a. Val a => a -> Value
value Color
a, Size Percentage -> Value
forall a. Val a => a -> Value
value Size Percentage
b)) Ramp
xs)

shortcut :: (Ramp -> BackgroundImage) -> Color -> Color -> BackgroundImage
shortcut :: (Ramp -> BackgroundImage) -> Color -> Color -> BackgroundImage
shortcut Ramp -> BackgroundImage
g Color
f Color
t = Ramp -> BackgroundImage
g [(Color
f, (Double -> Size Percentage
pct Double
0)), (Color
t, (Double -> Size Percentage
pct Double
100))]