-- | Shared visual helpers for the Fractal Fair Haskell examples.
--
-- Keep the mathematical rule in each chapter file; keep repeated
-- `diagrams` plumbing here.  The result is deliberately "executable
-- pseudocode": a fractal module says what points/segments exist, then
-- hands those values to one small renderer.
module FractalFairHelpers
  ( oceanGradient, fireGradient, greenGradient
  , gradientPath, gradientSegments
  ) where

import Diagrams.Prelude
import Diagrams.Backend.SVG.CmdLine

oceanGradient, fireGradient, greenGradient :: Double -> Colour Double
oceanGradient t = blend t (sRGB24 0x03 0x04 0x5e) (sRGB24 0xca 0xf0 0xf8)
fireGradient  t = blend t (sRGB24 0x0b 0x00 0x33) (sRGB24 0xfc 0xfd 0xbf)
greenGradient t = blend t (sRGB24 0xe5 0xf5 0xe0) (sRGB24 0x00 0x44 0x1b)

-- | Draw consecutive points with a traversal-order colour gradient.
gradientPath :: (Double -> Colour Double) -> Double -> [P2 Double] -> Diagram B
gradientPath palette width pts = gradientSegments palette width (zip pts (tail pts))

-- | Draw independent segments with a traversal-order colour gradient.
gradientSegments :: (Double -> Colour Double) -> Double
                 -> [(P2 Double, P2 Double)] -> Diagram B
gradientSegments palette width segs = mconcat
  [ fromVertices [p, q] # lc (palette (fromIntegral i / fromIntegral denom)) # lw width
  | (i, (p, q)) <- zip [0 :: Int ..] segs
  ]
  where denom = max 1 (length segs - 1)
