<commit_before>import * as $ from 'jquery'
import * as moment from 'moment'
import { capitaliseFirstLetter, debounce } from './util'
import { globalDefaults, englishDefaults, rtlDefaults } from './options'
import Iterator from './common/Iterator'
import GlobalEmitter from './common/GlobalEmitter'
import { default as EmitterMixin, EmitterInterface } from './common/EmitterMixin'
import { default as ListenerMixin, ListenerInterface } from './common/ListenerMixin'
import Toolbar from './Toolbar'
import OptionsManager from './OptionsManager'
import ViewSpecManager from './ViewSpecManager'
import View from './View'
import Theme from './theme/Theme'
import Constraints from './Constraints'
import { getMomentLocaleData } from './locale'
import momentExt from './moment-ext'
import UnzonedRange from './models/UnzonedRange'
import ComponentFootprint from './models/ComponentFootprint'
import EventDateProfile from './models/event/EventDateProfile'
import EventManager from './models/EventManager'
import BusinessHourGenerator from './models/BusinessHourGenerator'
import EventSourceParser from './models/event-source/EventSourceParser'
import EventDefParser from './models/event/EventDefParser'
import SingleEventDef from './models/event/SingleEventDef'
import EventDefMutation from './models/event/EventDefMutation'
import EventSource from './models/event-source/EventSource'
import { getThemeSystemClass } from './theme/ThemeRegistry'
import { RangeInput, MomentInput, OptionsInput, EventObjectInput, EventSourceInput } from './types/input-types'


export default class Calendar {

  // not for internal use. use options module directly instead.
  static defaults: any = globalDefaults
  static englishDefaults: any = englishDefaults
  static rtlDefaults: any = rtlDefaults

  on: EmitterInterface['on']
  one: EmitterInterface['one']
  off: EmitterInterface['off']
  trigger: EmitterInterface['trigger']
  triggerWith: EmitterInterface['triggerWith']
  hasHandlers: EmitterInterface['hasHandlers']
  listenTo: ListenerInterface['listenTo']
  stopListeningTo: ListenerInterface['stopListeningTo']

  view: View // current View object
  viewsByType: { [viewName: string]: View } // holds all instantiated view instances, current or not
  currentDate: moment.Moment // unzoned moment. private (public API should use getDate instead)
  theme: Theme
  eventManager: EventManager
  constraints: Constraints
  optionsManager: OptionsManager
  viewSpecManager: ViewSpecManager
  businessHourGenerator: BusinessHourGenerator
  loadingLevel: number = 0 // number of simultaneous loading tasks

  defaultAllDayEventDuration: moment.Duration
  defaultTimedEventDuration: moment.Duration
  localeData: object

  el: JQuery
  contentEl: JQuery
  suggestedViewHeight: number
  ignoreUpdateViewSize: number = 0
  freezeContentHeightDepth: number = 0
  windowResizeProxy: any

  header: Toolbar
  footer: Toolbar
  toolbarsManager: Iterator


  constructor(el: JQuery, overrides: OptionsInput) {

    // declare the current calendar instance relies on GlobalEmitter. needed for garbage collection.
    // unneeded() is called in destroy.
    GlobalEmitter.needed()

    this.el = el
    this.viewsByType = {}

    this.optionsManager = new OptionsManager(this, overrides)
    this.viewSpecManager = new ViewSpecManager(this.optionsManager, this)
    this.initMomentInternals() // needs to happen after options hash initialized
    this.initCurrentDate()
    this.initEventManager()
    this.constraints = new Constraints(this.eventManager, this)

    this.constructed()
  }


  constructed() {
    // useful for monkeypatching. used?
  }


  getView(): View {
    return this.view
  }


  publiclyTrigger(name: string, triggerInfo) {
    let optHandler = this.opt(name)
    let context
    let args

    if ($.isPlainObject(triggerInfo)) {
      context = triggerInfo.context
      args = triggerInfo.args
    } else if ($.isArray(triggerInfo)) {
      args = triggerInfo
    }

    if (context == null) {
      context = this.el[0] // fallback context
    }

    if (!args) {
      args = []
    }

    this.triggerWith(name, context, args) // Emitter's method

    if (optHandler) {
      return optHandler.apply(context, args)
    }
  }


  hasPublicHandlers(name: string): boolean {
    return this.hasHandlers(name) ||
      this.opt(name) // handler specified in options
  }


  // Options Public API
  // -----------------------------------------------------------------------------------------------------------------


  // public getter/setter
  option(name: string | object, value?) {
    let newOptionHash

    if (typeof name === 'string') {
      if (value === undefined) { // getter
        return this.optionsManager.get(name)
      } else { // setter for individual option
        newOptionHash = {}
        newOptionHash[name] = value
        this.optionsManager.add(newOptionHash)
      }
    } else if (typeof name === 'object') { // compound setter with object input
      this.optionsManager.add(name)
    }
  }


  // private getter
  opt(name: string) {
    return this.optionsManager.get(name)
  }


  // View
  // -----------------------------------------------------------------------------------------------------------------


  // Given a view name for a custom view or a standard view, creates a ready-to-go View object
  instantiateView(viewType: string): View {
    let spec = this.viewSpecManager.getViewSpec(viewType)

    return new spec['class'](this, spec)
  }


  // Returns a boolean about whether the view is okay to instantiate at some point
  isValidViewType(viewType: string): boolean {
    return Boolean(this.viewSpecManager.getViewSpec(viewType))
  }


  changeView(viewName: string, dateOrRange: RangeInput | MomentInput) {

    if (dateOrRange) {
      if ((dateOrRange as RangeInput).start && (dateOrRange as RangeInput).end) { // a range
        this.optionsManager.recordOverrides({ // will not rerender<commit_msg>add informative error message about view not existing<commit_after>import * as $ from 'jquery'
import * as moment from 'moment'
import { capitaliseFirstLetter, debounce } from './util'
import { globalDefaults, englishDefaults, rtlDefaults } from './options'
import Iterator from './common/Iterator'
import GlobalEmitter from './common/GlobalEmitter'
import { default as EmitterMixin, EmitterInterface } from './common/EmitterMixin'
import { default as ListenerMixin, ListenerInterface } from './common/ListenerMixin'
import Toolbar from './Toolbar'
import OptionsManager from './OptionsManager'
import ViewSpecManager from './ViewSpecManager'
import View from './View'
import Theme from './theme/Theme'
import Constraints from './Constraints'
import { getMomentLocaleData } from './locale'
import momentExt from './moment-ext'
import UnzonedRange from './models/UnzonedRange'
import ComponentFootprint from './models/ComponentFootprint'
import EventDateProfile from './models/event/EventDateProfile'
import EventManager from './models/EventManager'
import BusinessHourGenerator from './models/BusinessHourGenerator'
import EventSourceParser from './models/event-source/EventSourceParser'
import EventDefParser from './models/event/EventDefParser'
import SingleEventDef from './models/event/SingleEventDef'
import EventDefMutation from './models/event/EventDefMutation'
import EventSource from './models/event-source/EventSource'
import { getThemeSystemClass } from './theme/ThemeRegistry'
import { RangeInput, MomentInput, OptionsInput, EventObjectInput, EventSourceInput } from './types/input-types'


export default class Calendar {

  // not for internal use. use options module directly instead.
  static defaults: any = globalDefaults
  static englishDefaults: any = englishDefaults
  static rtlDefaults: any = rtlDefaults

  on: EmitterInterface['on']
  one: EmitterInterface['one']
  off: EmitterInterface['off']
  trigger: EmitterInterface['trigger']
  triggerWith: EmitterInterface['triggerWith']
  hasHandlers: EmitterInterface['hasHandlers']
  listenTo: ListenerInterface['listenTo']
  stopListeningTo: ListenerInterface['stopListeningTo']

  view: View // current View object
  viewsByType: { [viewName: string]: View } // holds all instantiated view instances, current or not
  currentDate: moment.Moment // unzoned moment. private (public API should use getDate instead)
  theme: Theme
  eventManager: EventManager
  constraints: Constraints
  optionsManager: OptionsManager
  viewSpecManager: ViewSpecManager
  businessHourGenerator: BusinessHourGenerator
  loadingLevel: number = 0 // number of simultaneous loading tasks

  defaultAllDayEventDuration: moment.Duration
  defaultTimedEventDuration: moment.Duration
  localeData: object

  el: JQuery
  contentEl: JQuery
  suggestedViewHeight: number
  ignoreUpdateViewSize: number = 0
  freezeContentHeightDepth: number = 0
  windowResizeProxy: any

  header: Toolbar
  footer: Toolbar
  toolbarsManager: Iterator


  constructor(el: JQuery, overrides: OptionsInput) {

    // declare the current calendar instance relies on GlobalEmitter. needed for garbage collection.
    // unneeded() is called in destroy.
    GlobalEmitter.needed()

    this.el = el
    this.viewsByType = {}

    this.optionsManager = new OptionsManager(this, overrides)
    this.viewSpecManager = new ViewSpecManager(this.optionsManager, this)
    this.initMomentInternals() // needs to happen after options hash initialized
    this.initCurrentDate()
    this.initEventManager()
    this.constraints = new Constraints(this.eventManager, this)

    this.constructed()
  }


  constructed() {
    // useful for monkeypatching. used?
  }


  getView(): View {
    return this.view
  }


  publiclyTrigger(name: string, triggerInfo) {
    let optHandler = this.opt(name)
    let context
    let args

    if ($.isPlainObject(triggerInfo)) {
      context = triggerInfo.context
      args = triggerInfo.args
    } else if ($.isArray(triggerInfo)) {
      args = triggerInfo
    }

    if (context == null) {
      context = this.el[0] // fallback context
    }

    if (!args) {
      args = []
    }

    this.triggerWith(name, context, args) // Emitter's method

    if (optHandler) {
      return optHandler.apply(context, args)
    }
  }


  hasPublicHandlers(name: string): boolean {
    return this.hasHandlers(name) ||
      this.opt(name) // handler specified in options
  }


  // Options Public API
  // -----------------------------------------------------------------------------------------------------------------


  // public getter/setter
  option(name: string | object, value?) {
    let newOptionHash

    if (typeof name === 'string') {
      if (value === undefined) { // getter
        return this.optionsManager.get(name)
      } else { // setter for individual option
        newOptionHash = {}
        newOptionHash[name] = value
        this.optionsManager.add(newOptionHash)
      }
    } else if (typeof name === 'object') { // compound setter with object input
      this.optionsManager.add(name)
    }
  }


  // private getter
  opt(name: string) {
    return this.optionsManager.get(name)
  }


  // View
  // -----------------------------------------------------------------------------------------------------------------


  // Given a view name for a custom view or a standard view, creates a ready-to-go View object
  instantiateView(viewType: string): View {
    let spec = this.viewSpecManager.getViewSpec(viewType)

    if (!spec) {
      throw new Error(`View type "${viewType}" is not valid`)
    }

    return new spec['class'](this, spec)
  }


  // Returns a boolean about whether the view is okay to instantiate at some point
  isValidViewType(viewType: string): boolean {
    return Boolean(this.viewSpecManager.getViewSpec(viewType))
  }


  changeView(viewName: string, dateOrRange: RangeInput | MomentInput) {

    if (dateOrRange) {
      if ((dateOrRange as RangeInput).start && (dateOrRange as RangeInput).end) { // a range
        this.optionsManager.recordOverrides({ // will not rerender
{'fraction_non_alphanumeric': 0.13198138297872342, 'fraction_numerical': 0.0006648936170212766, 'mean_word_length': 3.2088142707240292, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1496117', 'n_tokens_mistral': 3302, 'n_tokens_neox': 3161, 'n_words': 942}