module FuzzyTimings.Schedule (scheduleTimings) where
import FuzzyTimings.TimingBuckets
import FuzzyTimings.TimeSlice
import FuzzyTimings.SlicedTime
import FuzzyTimings.AccTiming
import FuzzyTimings.FuzzyTiming
import qualified Data.Map as Map
import System.Random
import Data.List
scheduleTimings :: Show k => SlicedTime (FuzzyCountMap k) -> IO [AccTiming k]
scheduleTimings st = do
accTimings <- mapM scheduleSlice $ toTimeSlices st
return $ concat accTimings
scheduleSlice :: Show k => TimeSlice (FuzzyCountMap k) -> IO [AccTiming k]
scheduleSlice ts = do
print instanceRanges
instances <- mapM rndInstancePos instanceRanges
return [ AccTiming (ftId ft) (addSecs pos (tsStart ts)) (ftDuration ft)
| (ft,pos) <- schedule instances ]
where
schedule instances = let
sortedInstances = sortBy (\(_,pos1) (_,pos2) -> compare pos1 pos2)
instances
in scheduleInstances 0 [ (ft,pos i (length instances))
| ((ft,_), i) <- zip sortedInstances [0..] ]
instanceRanges = [ (ft,pos (i1) ttp, (pos (i1) ttp + pos i ttp) `div` 2)
| (ft,ttp) <- fts, i <- [1..ttp] ]
pos i ttp = (tsDuration ts * i) `div` ttp
fts = [ (ft,floor ttp) | (ft,ttp) <- Map.toList (tsValue ts) ]
rndInstancePos (ft,start,end) = do
pos <- randomRIO (start,end)
return (ft,pos)
scheduleInstances :: Int -> [(FuzzyTiming k, Int)] -> [(FuzzyTiming k, Int)]
scheduleInstances now ((ft,pos):xs)
| now > pos = (ft,now):scheduleInstances (now+ftDuration ft) xs
| otherwise = (ft,pos):scheduleInstances (pos+ftDuration ft) xs
scheduleInstances _ [] = []