module Point exposing(Pos, Point, decoder, downsample, duration, subseq)

import Json.Decode as D

type alias Pos =
    { lat : Float
    , lon : Float
    , ele : Maybe Float
    }


type alias Point =
    { time : Float
    , pos : Pos
    , cadence : Maybe Int
    , power : Maybe Int
    , heartRate : Maybe Int
    }

posDecoder : D.Decoder Pos
posDecoder = D.map3 Pos
             (D.field "lat" D.float)
             (D.field "lon" D.float)
             (D.field "ele" (D.maybe D.float))


decoder : D.Decoder Point
decoder = D.map5 Point
          (D.field "time" D.float)
          (D.field "pos" posDecoder)
          (D.field "cadence" (D.maybe D.int))
          (D.field "power" (D.maybe D.int))
          (D.field "heartRate" (D.maybe D.int))


last x xs =
    case xs of
        [] -> x
        (x_::xs_) -> last x_ xs_

tracef x = Debug.log (String.fromFloat x) x

-- divide the points into n equal time buckets and return the first
-- point in each
downsample n points =
    let
        nextpoint step prev points_ =
            case points_ of
                (next::rest) ->
                    if next.time - prev.time > step
                    then prev :: (nextpoint step next rest)
                    else nextpoint step prev rest
                _ -> [prev]
    in
        case points of
            (first::rest) ->
                let step = (duration points) / (toFloat n)
                in nextpoint step first rest
            [] -> []

duration points =
    case points of
        (p::ps) -> (last p ps).time - p.time
        _ -> 0

subseq points start dur =
    case points of
        [] -> []
        (p::ps) ->
            if p.time < start
            then subseq ps start dur
            else if p.time >= (start + dur)
                 then []
                 else p::(subseq ps start dur)
