#if INTERACTIVE
#r "WindowsBase"
#r "PresentationCore"
#else
module Heatmap
#endif
open System.Windows.Media
open System

let colorIntensity (v:float) min max (colorRange:Color seq) =
    if v < min || v > max then failwithf "value %0.3f should be between min (%0.3f) and max (%0.3f)" v min max
    let nV = if max=min then 1.f else (v - min) / (max - min) |> float32 // between 0..1
    let steps = colorRange |> Seq.length
    let step = 1.f / float32 steps
    let minV = nV - step
    let maxV = nV + step
    let (<->) x (a,b) = x>=a && x<=b //between operator
    seq {for i in 0..steps -> (float32 i) * step} 
    |> Seq.windowed 2 
    |> Seq.map(fun r -> r.[0],r.[1])
    |> Seq.map(fun (a,b) ->
        if nV <-> (a,b) then abs((a-b)/2.0f-nV)
        elif minV <-> (a,b) then step-(nV-b)
        elif maxV <-> (a,b) then step-(a-nV)
        else 0.0f)
    |> Seq.zip colorRange 
    |> Seq.map (fun (c,s) -> s,Color.FromScRgb(1.f, c.ScR*s, c.ScG*s, c.ScB*s))
    |> Seq.filter (fun (a,c) -> a>0.f)
    |> Seq.map (fun (_,c)-> c.Clamp(); c)
    |> Seq.fold (+) (Color.FromScRgb(1.f,0.f,0.f,0.f))
(*
colorIntensity 0.1 0. 1. [Colors.Blue;Colors.LightGreen;Colors.Yellow;Colors.Red]
*)