type step = Prepare | Work | Rest | End let prettyPrint step = match step with | Prepare -> "Prepare" | Work -> "Work" | Rest -> "Rest" | End -> "End" type state = { step : step; remaining : int; tabata : int; cycle : int } let getAt (config : Config.config) elapsed = let cycleDuration = config.work + config.rest in let tabataDuration = config.prepare + (config.cycles * cycleDuration) in if elapsed >= tabataDuration * config.tabatas then { step = End; remaining = 0; tabata = config.tabatas; cycle = config.cycles; } else let currentTabataElapsed = elapsed mod tabataDuration in let step, remaining = if currentTabataElapsed < config.prepare then (Prepare, config.prepare - currentTabataElapsed) else let currentCycleElapsed = (currentTabataElapsed - config.prepare) mod cycleDuration in if currentCycleElapsed < config.work then (Work, config.work - currentCycleElapsed) else (Rest, config.work + config.rest - currentCycleElapsed) in let tabata = (elapsed / tabataDuration) + 1 in let cycle = if currentTabataElapsed < config.prepare then 1 else ((currentTabataElapsed - config.prepare) / cycleDuration) + 1 in { step; remaining; tabata; cycle }