import { EventDef } from './event-def' ; import { EventInstance , createEventInstance } from './event-instance' ; import { DateRange } from '../datelib/date-range' ; import { DateEnv } from '../datelib/env' ; import { Duration } from '../datelib/duration' ; import { DateMarker , startOfDay } from '../datelib/marker' ; import { EventStore } from './event-store' ; import { CalendarContext } from '../CalendarContext' ; import { filterHash } from '../util/object' ; import { EventRefined } from './event-parse' ; export interface ParsedRecurring < RecurringData > { typeData : RecurringData ; allDayGuess : boolean | null ; duration : Duration | null ; } export interface RecurringType < RecurringData > { parse : ( refined : EventRefined , dateEnv : DateEnv ) => ParsedRecurring < RecurringData > | null ; expand : ( typeData : any , framingRange : DateRange , dateEnv : DateEnv ) => DateMarker [ ] ; } export function parseRecurring ( refined , defaultAllDay , dateEnv , recurringTypes ) { for ( let i = 0 ; i < recurringTypes . length ; i += 1 ) { let parsed = recurringTypes [ i ] . parse ( refined , dateEnv ) ; if ( parsed ) { let { allDay } = refined ; if ( allDay == null ) { allDay = defaultAllDay ; if ( allDay == null ) { allDay = parsed . allDayGuess ; if ( allDay == null ) { allDay = false ; } } } return { allDay , duration : parsed . duration , typeData : parsed . typeData , typeId : i , } ; } } return null ; } export function expandRecurring ( eventStore , framingRange , context ) { let { dateEnv , pluginHooks , options } = context ; let { defs , instances } = eventStore ; instances = filterHash ( instances , ( instance ) => ! defs [ instance . defId ] . recurringDef ) ; for ( let defId in defs ) { let def = defs [ defId ] ; if ( def . recurringDef ) { let { duration } = def . recurringDef ; if ( ! duration ) { duration = def . allDay ? options . defaultAllDayEventDuration : options . defaultTimedEventDuration ; } let starts = expandRecurringRanges ( def , duration , framingRange , dateEnv , pluginHooks . recurringTypes ) ; for ( let start of starts ) { let instance = createEventInstance ( defId , { start , end : dateEnv . add ( start , duration ) , } ) ; instances [ instance . instanceId ] = instance ; } } } return { defs , instances } ; } function expandRecurringRanges ( eventDef , duration , framingRange , dateEnv , recurringTypes ) { let typeDef = recurringTypes [ eventDef . recurringDef . typeId ] ; let markers = typeDef . expand ( eventDef . recurringDef . typeData , { start : dateEnv . subtract ( framingRange . start , duration ) , end : framingRange . end , } , dateEnv ) ; if ( eventDef . allDay ) { markers = markers . map ( startOfDay ) ; } return markers ; }