module FuzzyTimings.FuzzyTiming (FuzzyTiming(..), ftPlayCount, cropFuzzyTiming, TimesToPlay) where import FuzzyTimings.SlicedTime import FuzzyTimings.TimeSlice type TimesToPlay = Double -- | "Fuzzily" timed object that is to be scheduled a number of times within a period of time. data FuzzyTiming k = FuzzyTiming { ftId :: k, ftPlayTimes :: SlicedTime TimesToPlay, ftDuration :: Int } deriving (Show) instance (Eq k) => Eq (FuzzyTiming k) where ft1 == ft2 = ftId ft1 == ftId ft2 instance (Ord k) => Ord (FuzzyTiming k) where compare f1 f2 = compare (ftId f1) (ftId f2) ftPlayCount :: FuzzyTiming k -> Double ftPlayCount ft = sum [ tsValue ts | ts <- toTimeSlices $ ftPlayTimes ft ] cropFuzzyTiming :: SlicedTime () -> FuzzyTiming k -> FuzzyTiming k cropFuzzyTiming allowed ft = ft { ftPlayTimes = mapSlicedTime (intersectSlicedTime (ftPlayTimes ft) allowed) adjustTimesToPlay } where adjustTimesToPlay ts = Just $ ts { tsValue = (fromIntegral $ tsDuration ts) * totalTimesToPlay / (fromIntegral totalLength) } playTimeSlices = toTimeSlices $ ftPlayTimes ft totalTimesToPlay = sum $ map tsValue playTimeSlices totalLength = sum $ map tsDuration playTimeSlices