import { startOfDay , addDays , DateMarker } from '../datelib/marker' ; import { Duration , subtractDurations } from '../datelib/duration' ; import { arrayToHash } from '../util/object' ; import { RecurringType } from './recurring-event' ; import { EventRefined } from './event-parse' ; import { DateRange , intersectRanges } from '../datelib/date-range' ; import { DateEnv } from '../datelib/env' ; import { createPlugin } from '../plugin-system' ; import { SIMPLE_RECURRING_REFINERS } from './recurring-event-simple-refiners' ; import './recurring-event-simple-declare' ; interface SimpleRecurringData { daysOfWeek : number [ ] | null ; startTime : Duration | null ; endTime : Duration | null ; startRecur : DateMarker | null ; endRecur : DateMarker | null ; } let recurring = { parse ( refined , dateEnv ) { if ( refined . daysOfWeek || refined . startTime || refined . endTime || refined . startRecur || refined . endRecur ) { let recurringData = { daysOfWeek : refined . daysOfWeek || null , startTime : refined . startTime || null , endTime : refined . endTime || null , startRecur : refined . startRecur ? dateEnv . createMarker ( refined . startRecur ) : null , endRecur : refined . endRecur ? dateEnv . createMarker ( refined . endRecur ) : null , } ; let duration ; if ( refined . duration ) { duration = refined . duration ; } if ( ! duration && refined . startTime && refined . endTime ) { duration = subtractDurations ( refined . endTime , refined . startTime ) ; } return { allDayGuess : Boolean ( ! refined . startTime && ! refined . endTime ) , duration , typeData : recurringData , } ; } return null ; } , expand ( typeData , framingRange , dateEnv ) { let clippedFramingRange = intersectRanges ( framingRange , { start : typeData . startRecur , end : typeData . endRecur } ) ; if ( clippedFramingRange ) { return expandRanges ( typeData . daysOfWeek , typeData . startTime , clippedFramingRange , dateEnv ) ; } return [ ] ; } , } ; export const simpleRecurringEventsPlugin = createPlugin ( { recurringTypes : [ recurring ] , eventRefiners : SIMPLE_RECURRING_REFINERS , } ) ; function expandRanges ( daysOfWeek , startTime , framingRange , dateEnv ) { let dowHash = daysOfWeek ? arrayToHash ( daysOfWeek ) : null ; let dayMarker = startOfDay ( framingRange . start ) ; let endMarker = framingRange . end ; let instanceStarts = [ ] ; while ( dayMarker < endMarker ) { let instanceStart ; if ( ! dowHash || dowHash [ dayMarker . getUTCDay ( ) ] ) { if ( startTime ) { instanceStart = dateEnv . add ( dayMarker , startTime ) ; } else { instanceStart = dayMarker ; } instanceStarts . push ( instanceStart ) ; } dayMarker = addDays ( dayMarker , 1 ) ; } return instanceStarts ; }