/*
 * Copyright (C) 2021 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.android.calendar

import android.provider.CalendarContract.EXTRA_EVENT_BEGIN_TIME
import android.provider.CalendarContract.EXTRA_EVENT_END_TIME
import android.provider.CalendarContract.Attendees.ATTENDEE_STATUS
import android.content.ComponentName
import android.content.ContentUris
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.provider.CalendarContract.Attendees
import android.provider.CalendarContract.Events
import android.text.format.Time
import android.util.Log
import android.util.Pair
import java.lang.ref.WeakReference
import java.util.LinkedHashMap
import java.util.LinkedList
import java.util.WeakHashMap

class CalendarController private constructor(context: Context?) {
    private var mContext: Context? = null

    // This uses a LinkedHashMap so that we can replace fragments based on the
    // view id they are being expanded into since we can't guarantee a reference
    // to the handler will be findable
    private val eventHandlers: LinkedHashMap<Int, EventHandler> =
        LinkedHashMap<Int, EventHandler>(5)
    private val mToBeRemovedEventHandlers: LinkedList<Int> = LinkedList<Int>()
    private val mToBeAddedEventHandlers: LinkedHashMap<Int, EventHandler> =
        LinkedHashMap<Int, EventHandler>()
    private var mFirstEventHandler: Pair<Int, EventHandler>? = null
    private var mToBeAddedFirstEventHandler: Pair<Int, EventHandler>? = null

    @Volatile
    private var mDispatchInProgressCounter = 0
    private val filters: WeakHashMap<Object, Long> = WeakHashMap<Object, Long>(1)

    // Forces the viewType. Should only be used for initialization.
    var viewType = -1
    private var mDetailViewType = -1
    var previousViewType = -1
        private set

    // The last event ID the edit view was launched with
    var eventId: Long = -1
    private val mTime: Time? = Time()

    // The last set of date flags sent with
    var dateFlags: Long = 0
        private set
    private val mUpdateTimezone: Runnable = object : Runnable {
        @Override
        override fun run() {
            mTime?.switchTimezone(Utils.getTimeZone(mContext, this))
        }
    }

    /**
     * One of the event types that are sent to or from the controller
     */
    interface EventType {
        companion object {
            // Simple view of an event
            const val VIEW_EVENT = 1L shl 1

            // Full detail view in read only mode
            const val VIEW_EVENT_DETAILS = 1L shl 2

            // full detail view in edit mode
            const val EDIT_EVENT = 1L shl 3
            const val GO_TO = 1L shl 5
            const val EVENTS_CHANGED = 1L shl 7
            const val USER_HOME = 1L shl 9

            // date range has changed, update the title
            const val UPDATE_TITLE = 1L shl 10
        }
    }

    /**
     * One of the Agenda/Day/Week/Month view types
     */
    interface ViewType {
        companion object {
            const val DETAIL = -1
            const val CURRENT = 0
            const val AGENDA = 1
            const val DAY = 2
            const val WEEK = 3
            const val MONTH = 4
            const val EDIT = 5
            const val MAX_VALUE = 5
        }
    }

    class EventInfo {
        @JvmField var eventType: Long = 0 // one of the EventType
        @JvmField var viewType = 0 // one of the ViewType
        @JvmField var id: Long = 0 // event id
        @JvmField var selectedTime: Time? = null // the selected time in focus

        // Event start and end times.  All-day events are represented in:
        // - local time for GO_TO commands
        // - UTC time for VIEW_EVENT and other event-related commands
        @JvmField var startTime: Time? = null
        @JvmField var endTime: Time? = null
        @JvmField var x = 0 // x coordinate in the activity space
        @JvmField var y = 0 // y coordinate in the activity space
        @JvmField var query: String? = null // query for a user search
        @JvmField var componentName: ComponentName? = null // used in combination with query
        @JvmField var eventTitle: String? = null
        @JvmField var calendarId: Long = 0

        /**
         * For EventType.VIEW_EVENT:
         * It is the default attendee response and an all day event indicator.
         * Set to Attendees.ATTENDEE_STATUS_NONE, Attendees.ATTENDEE_STATUS_ACCEPTED,
         * Attendees.ATTENDEE_STATUS_DECLINED, or Attendees.ATTENDEE_STATUS_TENTATIVE.
         * To signal the event is an all-day event, "or" ALL_DAY_MASK with the response.
         * Alternatively, use buildViewExtraLong(), getResponse(), and isAllDay().
         *
         *
         * For EventType.GO_TO:
         * Set to [.EXTRA_GOTO_TIME] to go to the specified date/time.
         * Set to [.EXTRA_GOTO_DATE] to consider the date but ignore the time.
         * Set to [.EXTRA_GOTO_BACK_TO_PREVIOUS] if back should bring back previous view.
         * Set to [.EXTRA_GOTO_TODAY] if this is a user request to go to the current time.
         *
         *
         * For EventType.UPDATE_TITLE:
         * Set formatting flags for Utils.formatDateRange
         */
        @JvmField var extraLong: Long = 0
        val isAllDay: Boolean
            get() {
                if (eventType != EventType.VIEW_EVENT) {
                    Log.wtf(TAG, "illegal call to isAllDay , wrong event type $eventType")
                    return false
                }
                return if (extraLong and ALL_DAY_MASK != 0L) true else false
            }
        val response: Int
            get() {
                if (eventType != EventType.VIEW_EVENT) {
                    Log.wtf(TAG, "illegal call to getResponse , wrong event type $eventType")
                    return Attendees.ATTENDEE_STATUS_NONE
                }
                val response = (extraLong and ATTENTEE_STATUS_MASK).toInt()
                when (response) {
                    ATTENDEE_STATUS_NONE_MASK -> return Attendees.ATTENDEE_STATUS_NONE
                    ATTENDEE_STATUS_ACCEPTED_MASK -> return Attendees.ATTENDEE_STATUS_ACCEPTED
                    ATTENDEE_STATUS_DECLINED_MASK -> return Attendees.ATTENDEE_STATUS_DECLINED
                    ATTENDEE_STATUS_TENTATIVE_MASK -> return Attendees.ATTENDEE_STATUS_TENTATIVE
                    else -> Log.wtf(TAG, "Unknown attendee response $response")
                }
                return ATTENDEE_STATUS_NONE_MASK
            }

        companion object {
            private const val ATTENTEE_STATUS_MASK: Long = 0xFF
            private const val ALL_DAY_MASK: Long = 0x100
            private const val ATTENDEE_STATUS_NONE_MASK = 0x01
            private const val ATTENDEE_STATUS_ACCEPTED_MASK = 0x02
            private const val ATTENDEE_STATUS_DECLINED_MASK = 0x04
            private const val ATTENDEE_STATUS_TENTATIVE_MASK = 0x08

            // Used to build the extra long for a VIEW event.
            @JvmStatic fun buildViewExtraLong(response: Int, allDay: Boolean): Long {
                var extra = if (allDay) ALL_DAY_MASK else 0
                extra = when (response) {
                    Attendees.ATTENDEE_STATUS_NONE -> extra or
                            ATTENDEE_STATUS_NONE_MASK.toLong()
                    Attendees.ATTENDEE_STATUS_ACCEPTED -> extra or
                            ATTENDEE_STATUS_ACCEPTED_MASK.toLong()
                    Attendees.ATTENDEE_STATUS_DECLINED -> extra or
                            ATTENDEE_STATUS_DECLINED_MASK.toLong()
                    Attendees.ATTENDEE_STATUS_TENTATIVE -> extra or
                            ATTENDEE_STATUS_TENTATIVE_MASK.toLong()
                    else -> {
                        Log.wtf(
                                TAG,
                                "Unknown attendee response $response"
                        )
                        extra or ATTENDEE_STATUS_NONE_MASK.toLong()
                    }
                }
                return extra
            }
        }
    }

    interface EventHandler {
        val supportedEventTypes: Long
        fun handleEvent(event: EventInfo?)

        /**
         * This notifies the handler that the database has changed and it should
         * update its view.
         */
        fun eventsChanged()
    }

    fun sendEventRelatedEvent(
        sender: Object?,
        eventType: Long,
        eventId: Long,
        startMillis: Long,
        endMillis: Long,
        x: Int,
        y: Int,
        selectedMillis: Long
    ) {
        // TODO: pass the real allDay status or at least a status that says we don't know the
        // status and have the receiver query the data.
        // The current use of this method for VIEW_EVENT is by the day view to show an EventInfo
        // so currently the missing allDay status has no effect.
        sendEventRelatedEventWithExtra(
                sender, eventType, eventId, startMillis, endMillis, x, y,
                EventInfo.buildViewExtraLong(Attendees.ATTENDEE_STATUS_NONE, false),
                selectedMillis
        )
    }

    /**
     * Helper for sending New/View/Edit/Delete events
     *
     * @param sender object of the caller
     * @param eventType one of [EventType]
     * @param eventId event id
     * @param startMillis start time
     * @param endMillis end time
     * @param x x coordinate in the activity space
     * @param y y coordinate in the activity space
     * @param extraLong default response value for the "simple event view" and all day indication.
     * Use Attendees.ATTENDEE_STATUS_NONE for no response.
     * @param selectedMillis The time to specify as selected
     */
    fun sendEventRelatedEventWithExtra(
        sender: Object?,
        eventType: Long,
        eventId: Long,
        startMillis: Long,
        endMillis: Long,
        x: Int,
        y: Int,
        extraLong: Long,
        selectedMillis: Long
    ) {
        sendEventRelatedEventWithExtraWithTitleWithCalendarId(
                sender, eventType, eventId,
                startMillis, endMillis, x, y, extraLong, selectedMillis, null, -1
        )
    }

    /**
     * Helper for sending New/View/Edit/Delete events
     *
     * @param sender object of the caller
     * @param eventType one of [EventType]
     * @param eventId event id
     * @param startMillis start time
     * @param endMillis end time
     * @param x x coordinate in the activity space
     * @param y y coordinate in the activity space
     * @param extraLong default response value for the "simple event view" and all day indication.
     * Use Attendees.ATTENDEE_STATUS_NONE for no response.
     * @param selectedMillis The time to specify as selected
     * @param title The title of the event
     * @param calendarId The id of the calendar which the event belongs to
     */
    fun sendEventRelatedEventWithExtraWithTitleWithCalendarId(
        sender: Object?,
        eventType: Long,
        eventId: Long,
        startMillis: Long,
        endMillis: Long,
        x: Int,
        y: Int,
        extraLong: Long,
        selectedMillis: Long,
        title: String?,
        calendarId: Long
    ) {
        val info = EventInfo()
        info.eventType = eventType
        if (eventType == EventType.VIEW_EVENT_DETAILS) {
            info.viewType = ViewType.CURRENT
        }
        info.id = eventId
        info.startTime = Time(Utils.getTimeZone(mContext, mUpdateTimezone))
        (info.startTime as Time).set(startMillis)
        if (selectedMillis != -1L) {
            info.selectedTime = Time(Utils.getTimeZone(mContext, mUpdateTimezone))
            (info.selectedTime as Time).set(selectedMillis)
        } else {
            info.selectedTime = info.startTime
        }
        info.endTime = Time(Utils.getTimeZone(mContext, mUpdateTimezone))
        (info.endTime as Time).set(endMillis)
        info.x = x
        info.y = y
        info.extraLong = extraLong
        info.eventTitle = title
        info.calendarId = calendarId
        this.sendEvent(sender, info)
    }

    /**
     * Helper for sending non-calendar-event events
     *
     * @param sender object of the caller
     * @param eventType one of [EventType]
     * @param start start time
     * @param end end time
     * @param eventId event id
     * @param viewType [ViewType]
     */
    fun sendEvent(
        sender: Object?,
        eventType: Long,
        start: Time?,
        end: Time?,
        eventId: Long,
        viewType: Int
    ) {
        sendEvent(
                sender, eventType, start, end, start, eventId, viewType, EXTRA_GOTO_TIME, null,
                null
        )
    }

    /**
     * sendEvent() variant with extraLong, search query, and search component name.
     */
    fun sendEvent(
        sender: Object?,
        eventType: Long,
        start: Time?,
        end: Time?,
        eventId: Long,
        viewType: Int,
        extraLong: Long,
        query: String?,
        componentName: ComponentName?
    ) {
        sendEvent(
                sender, eventType, start, end, start, eventId, viewType, extraLong, query,
                componentName
        )
    }

    fun sendEvent(
        sender: Object?,
        eventType: Long,
        start: Time?,
        end: Time?,
        selected: Time?,
        eventId: Long,
        viewType: Int,
        extraLong: Long,
        query: String?,
        componentName: ComponentName?
    ) {
        val info = EventInfo()
        info.eventType = eventType
        info.startTime = start
        info.selectedTime = selected
        info.endTime = end
        info.id = eventId
        info.viewType = viewType
        info.query = query
        info.componentName = componentName
        info.extraLong = extraLong
        this.sendEvent(sender, info)
    }

    fun sendEvent(sender: Object?, event: EventInfo) {
        // TODO Throw exception on invalid events
        if (DEBUG) {
            Log.d(TAG, eventInfoToString(event))
        }
        val filteredTypes: Long? = filters.get(sender)
        if (filteredTypes != null && filteredTypes.toLong() and event.eventType != 0L) {
            // Suppress event per filter
            if (DEBUG) {
                Log.d(TAG, "Event suppressed")
            }
            return
        }
        previousViewType = viewType

        // Fix up view if not specified
        if (event.viewType == ViewType.DETAIL) {
            event.viewType = mDetailViewType
            viewType = mDetailViewType
        } else if (event.viewType == ViewType.CURRENT) {
            event.viewType = viewType
        } else if (event.viewType != ViewType.EDIT) {
            viewType = event.viewType
            if (event.viewType == ViewType.AGENDA || event.viewType == ViewType.DAY ||
                    Utils.getAllowWeekForDetailView() && event.viewType == ViewType.WEEK) {
                mDetailViewType = viewType
            }
        }
        if (DEBUG) {
            Log.d(TAG, "vvvvvvvvvvvvvvv")
            Log.d(
                    TAG,
                    "Start  " + if (event.startTime == null) "null" else event.startTime.toString()
            )
            Log.d(TAG, "End    " + if (event.endTime == null) "null" else event.endTime.toString())
            Log.d(
                    TAG,
                    "Select " + if (event.selectedTime == null) "null"
                    else event.selectedTime.toString()
            )
            Log.d(TAG, "mTime  " + if (mTime == null) "null" else mTime.toString())
        }
        var startMillis: Long = 0
        val temp = event.startTime
        if (temp != null) {
            startMillis = (event.startTime as Time).toMillis(false)
        }

        // Set mTime if selectedTime is set
        val temp1 = event.selectedTime
        if (temp1 != null && temp1?.toMillis(false) != 0L) {
            mTime?.set(event.selectedTime)
        } else {
            if (startMillis != 0L) {
                // selectedTime is not set so set mTime to startTime iff it is not
                // within start and end times
                val mtimeMillis: Long = mTime?.toMillis(false) as Long
                val temp2 = event.endTime
                if (mtimeMillis < startMillis ||
                        temp2 != null && mtimeMillis > temp2.toMillis(false)) {
                    mTime?.set(event.startTime)
                }
            }
            event.selectedTime = mTime
        }
        // Store the formatting flags if this is an update to the title
        if (event.eventType == EventType.UPDATE_TITLE) {
            dateFlags = event.extraLong
        }

        // Fix up start time if not specified
        if (startMillis == 0L) {
            event.startTime = mTime
        }
        if (DEBUG) {
            Log.d(
                    TAG,
                    "Start  " + if (event.startTime == null) "null" else
                        event.startTime.toString()
            )
            Log.d(TAG, "End    " + if (event.endTime == null) "null" else
                event.endTime.toString())
            Log.d(
                    TAG,
                    "Select " + if (event.selectedTime == null) "null" else
                        event.selectedTime.toString()
            )
            Log.d(TAG, "mTime  " + if (mTime == null) "null" else mTime.toString())
            Log.d(TAG, "^^^^^^^^^^^^^^^")
        }

        // Store the eventId if we're entering edit event
        if ((event.eventType and EventType.VIEW_EVENT_DETAILS) != 0L) {
            if (event.id > 0) {
                eventId = event.id
            } else {
                eventId = -1
            }
        }
        var handled = false
        synchronized(this) {
            mDispatchInProgressCounter++
            if (DEBUG) {
                Log.d(
                        TAG,
                        "sendEvent: Dispatching to " + eventHandlers.size.toString() + " handlers"
                )
            }
            // Dispatch to event handler(s)
            val temp3 = mFirstEventHandler
            if (temp3 != null) {
                // Handle the 'first' one before handling the others
                val handler: EventHandler? = mFirstEventHandler?.second
                if (handler != null && handler.supportedEventTypes and event.eventType != 0L &&
                        !mToBeRemovedEventHandlers.contains(mFirstEventHandler?.first)) {
                    handler.handleEvent(event)
                    handled = true
                }
            }
            val handlers: MutableIterator<MutableMap.MutableEntry<Int,
                CalendarController.EventHandler>> = eventHandlers.entries.iterator()
            while (handlers.hasNext()) {
                val entry: MutableMap.MutableEntry<Int,
                    CalendarController.EventHandler> = handlers.next()
                val key: Int = entry.key.toInt()
                val temp4 = mFirstEventHandler
                if (temp4 != null && key.toInt() == temp4.first.toInt()) {
                    // If this was the 'first' handler it was already handled
                    continue
                }
                val eventHandler: EventHandler = entry.value
                if (eventHandler != null &&
                    eventHandler.supportedEventTypes and event.eventType != 0L) {
                    if (mToBeRemovedEventHandlers.contains(key)) {
                        continue
                    }
                    eventHandler.handleEvent(event)
                    handled = true
                }
            }
            mDispatchInProgressCounter--
            if (mDispatchInProgressCounter == 0) {

                // Deregister removed handlers
                if (mToBeRemovedEventHandlers.size > 0) {
                    for (zombie in mToBeRemovedEventHandlers) {
                        eventHandlers.remove(zombie)
                        val temp5 = mFirstEventHandler
                        if (temp5 != null && zombie.equals(temp5.first)) {
                            mFirstEventHandler = null
                        }
                    }
                    mToBeRemovedEventHandlers.clear()
                }
                // Add new handlers
                if (mToBeAddedFirstEventHandler != null) {
                    mFirstEventHandler = mToBeAddedFirstEventHandler
                    mToBeAddedFirstEventHandler = null
                }
                if (mToBeAddedEventHandlers.size > 0) {
                    for (food in mToBeAddedEventHandlers.entries) {
                        eventHandlers.put(food.key, food.value)
                    }
                }
            }
        }
    }

    /**
     * Adds or updates an event handler. This uses a LinkedHashMap so that we can
     * replace fragments based on the view id they are being expanded into.
     *
     * @param key The view id or placeholder for this handler
     * @param eventHandler Typically a fragment or activity in the calendar app
     */
    fun registerEventHandler(key: Int, eventHandler: EventHandler?) {
        synchronized(this) {
            if (mDispatchInProgressCounter > 0) {
                mToBeAddedEventHandlers.put(key,
                        eventHandler as CalendarController.EventHandler)
            } else {
                eventHandlers.put(key, eventHandler as CalendarController.EventHandler)
            }
        }
    }

    fun registerFirstEventHandler(key: Int, eventHandler: EventHandler?) {
        synchronized(this) {
            registerEventHandler(key, eventHandler)
            if (mDispatchInProgressCounter > 0) {
                mToBeAddedFirstEventHandler = Pair<Int, EventHandler>(key, eventHandler)
            } else {
                mFirstEventHandler = Pair<Int, EventHandler>(key, eventHandler)
            }
        }
    }

    fun deregisterEventHandler(key: Int) {
        synchronized(this) {
            if (mDispatchInProgressCounter > 0) {
                // To avoid ConcurrencyException, stash away the event handler for now.
                mToBeRemovedEventHandlers.add(key)
            } else {
                eventHandlers.remove(key)
                val temp6 = mFirstEventHandler
                if (temp6 != null && temp6.first == key) {
                    mFirstEventHandler = null
                } else {}
            }
        }
    }

    fun deregisterAllEventHandlers() {
        synchronized(this) {
            if (mDispatchInProgressCounter > 0) {
                // To avoid ConcurrencyException, stash away the event handler for now.
                mToBeRemovedEventHandlers.addAll(eventHandlers.keys)
            } else {
                eventHandlers.clear()
                mFirstEventHandler = null
            }
        }
    }

    // FRAG_TODO doesn't work yet
    fun filterBroadcasts(sender: Object?, eventTypes: Long) {
        filters.put(sender, eventTypes)
    }
    /**
     * @return the time that this controller is currently pointed at
     */
    /**
     * Set the time this controller is currently pointed at
     *
     * @param millisTime Time since epoch in millis
     */
    var time: Long?
        get() = mTime?.toMillis(false)
        set(millisTime) {
            mTime?.set(millisTime as Long)
        }

    fun launchViewEvent(eventId: Long, startMillis: Long, endMillis: Long, response: Int) {
        val intent = Intent(Intent.ACTION_VIEW)
        val eventUri: Uri = ContentUris.withAppendedId(Events.CONTENT_URI, eventId)
        intent.setData(eventUri)
        intent.setClass(mContext as Context, AllInOneActivity::class.java)
        intent.putExtra(EXTRA_EVENT_BEGIN_TIME, startMillis)
        intent.putExtra(EXTRA_EVENT_END_TIME, endMillis)
        intent.putExtra(ATTENDEE_STATUS, response)
        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
        mContext?.startActivity(intent)
    }

    private fun eventInfoToString(eventInfo: EventInfo): String {
        var tmp = "Unknown"
        val builder = StringBuilder()
        if (eventInfo.eventType and EventType.GO_TO != 0L) {
            tmp = "Go to time/event"
        } else if (eventInfo.eventType and EventType.VIEW_EVENT != 0L) {
            tmp = "View event"
        } else if (eventInfo.eventType and EventType.VIEW_EVENT_DETAILS != 0L) {
            tmp = "View details"
        } else if (eventInfo.eventType and EventType.EVENTS_CHANGED != 0L) {
            tmp = "Refresh events"
        } else if (eventInfo.eventType and EventType.USER_HOME != 0L) {
            tmp = "Gone home"
        } else if (eventInfo.eventType and EventType.UPDATE_TITLE != 0L) {
            tmp = "Update title"
        }
        builder.append(tmp)
        builder.append(": id=")
        builder.append(eventInfo.id)
        builder.append(", selected=")
        builder.append(eventInfo.selectedTime)
        builder.append(", start=")
        builder.append(eventInfo.startTime)
        builder.append(", end=")
        builder.append(eventInfo.endTime)
        builder.append(", viewType=")
        builder.append(eventInfo.viewType)
        builder.append(", x=")
        builder.append(eventInfo.x)
        builder.append(", y=")
        builder.append(eventInfo.y)
        return builder.toString()
    }

    companion object {
        private const val DEBUG = false
        private const val TAG = "CalendarController"
        const val EVENT_EDIT_ON_LAUNCH = "editMode"
        const val MIN_CALENDAR_YEAR = 1970
        const val MAX_CALENDAR_YEAR = 2036
        const val MIN_CALENDAR_WEEK = 0
        const val MAX_CALENDAR_WEEK = 3497 // weeks between 1/1/1970 and 1/1/2037
        private val instances: WeakHashMap<Context, WeakReference<CalendarController>> =
                WeakHashMap<Context, WeakReference<CalendarController>>()

        /**
         * Pass to the ExtraLong parameter for EventType.GO_TO to signal the time
         * can be ignored
         */
        const val EXTRA_GOTO_DATE: Long = 1
        const val EXTRA_GOTO_TIME: Long = 2
        const val EXTRA_GOTO_BACK_TO_PREVIOUS: Long = 4
        const val EXTRA_GOTO_TODAY: Long = 8

        /**
         * Creates and/or returns an instance of CalendarController associated with
         * the supplied context. It is best to pass in the current Activity.
         *
         * @param context The activity if at all possible.
         */
        @JvmStatic fun getInstance(context: Context?): CalendarController? {
            synchronized(instances) {
                var controller: CalendarController? = null
                val weakController: WeakReference<CalendarController>? = instances.get(context)
                if (weakController != null) {
                    controller = weakController.get()
                }
                if (controller == null) {
                    controller = CalendarController(context)
                    instances.put(context, WeakReference(controller))
                }
                return controller
            }
        }

        /**
         * Removes an instance when it is no longer needed. This should be called in
         * an activity's onDestroy method.
         *
         * @param context The activity used to create the controller
         */
        @JvmStatic fun removeInstance(context: Context?) {
            instances.remove(context)
        }
    }

    init {
        mContext = context
        mUpdateTimezone.run()
        mTime?.setToNow()
        mDetailViewType = Utils.getSharedPreference(
                mContext,
                GeneralPreferences.KEY_DETAILED_VIEW,
                GeneralPreferences.DEFAULT_DETAILED_VIEW
        )
    }
}