/*
 * 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.animation.Animator
import android.animation.AnimatorListenerAdapter
import android.animation.ObjectAnimator
import android.animation.ValueAnimator
import android.app.Service
import android.content.Context
import android.content.res.Resources
import android.content.res.TypedArray
import android.graphics.Canvas
import android.graphics.Paint
import android.graphics.Paint.Align
import android.graphics.Paint.Style
import android.graphics.Rect
import android.graphics.Typeface
import android.graphics.drawable.Drawable
import android.os.Handler
import android.provider.CalendarContract.Attendees
import android.provider.CalendarContract.Calendars
import android.text.Layout.Alignment
import android.text.SpannableStringBuilder
import android.text.StaticLayout
import android.text.TextPaint
import android.text.format.DateFormat
import android.text.format.DateUtils
import android.text.format.Time
import android.text.style.StyleSpan
import android.util.Log
import android.view.ContextMenu
import android.view.ContextMenu.ContextMenuInfo
import android.view.GestureDetector
import android.view.KeyEvent
import android.view.LayoutInflater
import android.view.MenuItem
import android.view.MotionEvent
import android.view.ScaleGestureDetector
import android.view.View
import android.view.ViewConfiguration
import android.view.ViewGroup
import android.view.ViewGroup.LayoutParams
import android.view.WindowManager
import android.view.accessibility.AccessibilityEvent
import android.view.accessibility.AccessibilityManager
import android.view.animation.AccelerateDecelerateInterpolator
import android.view.animation.Animation
import android.view.animation.Interpolator
import android.view.animation.TranslateAnimation
import android.widget.EdgeEffect
import android.widget.OverScroller
import android.widget.PopupWindow
import android.widget.ViewSwitcher
import com.android.calendar.CalendarController.EventType
import com.android.calendar.CalendarController.ViewType
import java.util.ArrayList
import java.util.Arrays
import java.util.Calendar
import java.util.Formatter
import java.util.Locale
import java.util.regex.Matcher
import java.util.regex.Pattern

/**
 * View for multi-day view. So far only 1 and 7 day have been tested.
 */
class DayView(
    context: Context?,
    controller: CalendarController?,
    viewSwitcher: ViewSwitcher?,
    eventLoader: EventLoader?,
    numDays: Int
) : View(context), View.OnCreateContextMenuListener, ScaleGestureDetector.OnScaleGestureListener,
    View.OnClickListener, View.OnLongClickListener {
    private var mOnFlingCalled = false
    private var mStartingScroll = false
    protected var mPaused = true
    private var mHandler: Handler? = null

    /**
     * ID of the last event which was displayed with the toast popup.
     *
     * This is used to prevent popping up multiple quick views for the same event, especially
     * during calendar syncs. This becomes valid when an event is selected, either by default
     * on starting calendar or by scrolling to an event. It becomes invalid when the user
     * explicitly scrolls to an empty time slot, changes views, or deletes the event.
     */
    private var mLastPopupEventID: Long
    protected var mContext: Context? = null
    private val mContinueScroll: ContinueScroll = ContinueScroll()

    // Make this visible within the package for more informative debugging
    var mBaseDate: Time? = null
    private var mCurrentTime: Time? = null
    private val mUpdateCurrentTime: UpdateCurrentTime = UpdateCurrentTime()
    private var mTodayJulianDay = 0
    private val mBold: Typeface = Typeface.DEFAULT_BOLD
    private var mFirstJulianDay = 0
    private var mLoadedFirstJulianDay = -1
    private var mLastJulianDay = 0
    private var mMonthLength = 0
    private var mFirstVisibleDate = 0
    private var mFirstVisibleDayOfWeek = 0
    private var mEarliestStartHour: IntArray? = null // indexed by the week day offset
    private var mHasAllDayEvent: BooleanArray? = null // indexed by the week day offset
    private var mEventCountTemplate: String? = null
    private var mClickedEvent: Event? = null // The event the user clicked on
    private var mSavedClickedEvent: Event? = null
    private var mClickedYLocation = 0
    private var mDownTouchTime: Long = 0
    private var mEventsAlpha = 255
    private var mEventsCrossFadeAnimation: ObjectAnimator? = null
    private val mTZUpdater: Runnable = object : Runnable {
        @Override
        override fun run() {
            val tz: String? = Utils.getTimeZone(mContext, this)
            mBaseDate!!.timezone = tz
            mBaseDate?.normalize(true)
            mCurrentTime?.switchTimezone(tz)
            invalidate()
        }
    }

    // Sets the "clicked" color from the clicked event
    private val mSetClick: Runnable = object : Runnable {
        @Override
        override fun run() {
            mClickedEvent = mSavedClickedEvent
            mSavedClickedEvent = null
            this@DayView.invalidate()
        }
    }

    // Clears the "clicked" color from the clicked event and launch the event
    private val mClearClick: Runnable = object : Runnable {
        @Override
        override fun run() {
            if (mClickedEvent != null) {
                mController?.sendEventRelatedEvent(
                    this as Object?, EventType.VIEW_EVENT, mClickedEvent!!.id,
                    mClickedEvent!!.startMillis, mClickedEvent!!.endMillis,
                    this@DayView.getWidth() / 2, mClickedYLocation,
                    selectedTimeInMillis
                )
            }
            mClickedEvent = null
            this@DayView.invalidate()
        }
    }
    private val mTodayAnimatorListener: TodayAnimatorListener = TodayAnimatorListener()

    internal inner class TodayAnimatorListener : AnimatorListenerAdapter() {
        @Volatile
        private var mAnimator: Animator? = null

        @Volatile
        private var mFadingIn = false
        @Override
        override fun onAnimationEnd(animation: Animator) {
            synchronized(this) {
                if (mAnimator !== animation) {
                    animation.removeAllListeners()
                    animation.cancel()
                    return
                }
                if (mFadingIn) {
                    if (mTodayAnimator != null) {
                        mTodayAnimator?.removeAllListeners()
                        mTodayAnimator?.cancel()
                    }
                    mTodayAnimator = ObjectAnimator
                        .ofInt(this@DayView, "animateTodayAlpha", 255, 0)
                    mAnimator = mTodayAnimator
                    mFadingIn = false
                    mTodayAnimator?.addListener(this)
                    mTodayAnimator?.setDuration(600)
                    mTodayAnimator?.start()
                } else {
                    mAnimateToday = false
                    mAnimateTodayAlpha = 0
                    mAnimator?.removeAllListeners()
                    mAnimator = null
                    mTodayAnimator = null
                    invalidate()
                }
            }
        }

        fun setAnimator(animation: Animator?) {
            mAnimator = animation
        }

        fun setFadingIn(fadingIn: Boolean) {
            mFadingIn = fadingIn
        }
    }

    var mAnimatorListener: AnimatorListenerAdapter = object : AnimatorListenerAdapter() {
        @Override
        override fun onAnimationStart(animation: Animator?) {
            mScrolling = true
        }

        @Override
        override fun onAnimationCancel(animation: Animator?) {
            mScrolling = false
        }

        @Override
        override fun onAnimationEnd(animation: Animator?) {
            mScrolling = false
            resetSelectedHour()
            invalidate()
        }
    }

    /**
     * This variable helps to avoid unnecessarily reloading events by keeping
     * track of the start millis parameter used for the most recent loading
     * of events.  If the next reload matches this, then the events are not
     * reloaded.  To force a reload, set this to zero (this is set to zero
     * in the method clearCachedEvents()).
     */
    private var mLastReloadMillis: Long = 0
    private var mEvents: ArrayList<Event> = ArrayList<Event>()
    private var mAllDayEvents: ArrayList<Event>? = ArrayList<Event>()
    private var mLayouts: Array<StaticLayout?>? = null
    private var mAllDayLayouts: Array<StaticLayout?>? = null
    private var mSelectionDay = 0 // Julian day
    private var mSelectionHour = 0
    var mSelectionAllday = false

    // Current selection info for accessibility
    private var mSelectionDayForAccessibility = 0 // Julian day
    private var mSelectionHourForAccessibility = 0
    private var mSelectedEventForAccessibility: Event? = null

    // Last selection info for accessibility
    private var mLastSelectionDayForAccessibility = 0
    private var mLastSelectionHourForAccessibility = 0
    private var mLastSelectedEventForAccessibility: Event? = null

    /** Width of a day or non-conflicting event  */
    private var mCellWidth = 0

    // Pre-allocate these objects and re-use them
    private val mRect: Rect = Rect()
    private val mDestRect: Rect = Rect()
    private val mSelectionRect: Rect = Rect()

    // This encloses the more allDay events icon
    private val mExpandAllDayRect: Rect = Rect()

    // TODO Clean up paint usage
    private val mPaint: Paint = Paint()
    private val mEventTextPaint: Paint = Paint()
    private val mSelectionPaint: Paint = Paint()
    private var mLines: FloatArray = emptyArray<Float>().toFloatArray()
    private var mFirstDayOfWeek = 0 // First day of the week
    private var mPopup: PopupWindow? = null
    private var mPopupView: View? = null
    private val mDismissPopup: DismissPopup = DismissPopup()
    private var mRemeasure = true
    private val mEventLoader: EventLoader
    protected val mEventGeometry: EventGeometry
    private var mAnimationDistance = 0f
    private var mViewStartX = 0
    private var mViewStartY = 0
    private var mMaxViewStartY = 0
    private var mViewHeight = 0
    private var mViewWidth = 0
    private var mGridAreaHeight = -1
    private var mScrollStartY = 0
    private var mPreviousDirection = 0

    /**
     * Vertical distance or span between the two touch points at the start of a
     * scaling gesture
     */
    private var mStartingSpanY = 0f

    /** Height of 1 hour in pixels at the start of a scaling gesture  */
    private var mCellHeightBeforeScaleGesture = 0

    /** The hour at the center two touch points  */
    private var mGestureCenterHour = 0f
    private var mRecalCenterHour = false

    /**
     * Flag to decide whether to handle the up event. Cases where up events
     * should be ignored are 1) right after a scale gesture and 2) finger was
     * down before app launch
     */
    private var mHandleActionUp = true
    private var mHoursTextHeight = 0

    /**
     * The height of the area used for allday events
     */
    private var mAlldayHeight = 0

    /**
     * The height of the allday event area used during animation
     */
    private var mAnimateDayHeight = 0

    /**
     * The height of an individual allday event during animation
     */
    private var mAnimateDayEventHeight = MIN_UNEXPANDED_ALLDAY_EVENT_HEIGHT.toInt()

    /**
     * Max of all day events in a given day in this view.
     */
    private var mMaxAlldayEvents = 0

    /**
     * A count of the number of allday events that were not drawn for each day
     */
    private var mSkippedAlldayEvents: IntArray? = null

    /**
     * The number of allDay events at which point we start hiding allDay events.
     */
    private var mMaxUnexpandedAlldayEventCount = 4
    protected var mNumDays = 7
    private var mNumHours = 10

    /** Width of the time line (list of hours) to the left.  */
    private var mHoursWidth = 0
    private var mDateStrWidth = 0

    /** Top of the scrollable region i.e. below date labels and all day events  */
    private var mFirstCell = 0

    /** First fully visible hour  */
    private var mFirstHour = -1

    /** Distance between the mFirstCell and the top of first fully visible hour.  */
    private var mFirstHourOffset = 0
    private var mHourStrs: Array<String>? = null
    private var mDayStrs: Array<String?>? = null
    private var mDayStrs2Letter: Array<String?>? = null
    private var mIs24HourFormat = false
    private val mSelectedEvents: ArrayList<Event> = ArrayList<Event>()
    private var mComputeSelectedEvents = false
    private var mUpdateToast = false
    private var mSelectedEvent: Event? = null
    private var mPrevSelectedEvent: Event? = null
    private val mPrevBox: Rect = Rect()
    protected val mResources: Resources
    protected val mCurrentTimeLine: Drawable
    protected val mCurrentTimeAnimateLine: Drawable
    protected val mTodayHeaderDrawable: Drawable
    protected val mExpandAlldayDrawable: Drawable
    protected val mCollapseAlldayDrawable: Drawable
    protected var mAcceptedOrTentativeEventBoxDrawable: Drawable
    private var mAmString: String? = null
    private var mPmString: String? = null
    var mScaleGestureDetector: ScaleGestureDetector
    private var mTouchMode = TOUCH_MODE_INITIAL_STATE
    private var mSelectionMode = SELECTION_HIDDEN
    private var mScrolling = false

    // Pixels scrolled
    private var mInitialScrollX = 0f
    private var mInitialScrollY = 0f
    private var mAnimateToday = false
    private var mAnimateTodayAlpha = 0

    // Animates the height of the allday region
    var mAlldayAnimator: ObjectAnimator? = null

    // Animates the height of events in the allday region
    var mAlldayEventAnimator: ObjectAnimator? = null

    // Animates the transparency of the more events text
    var mMoreAlldayEventsAnimator: ObjectAnimator? = null

    // Animates the current time marker when Today is pressed
    var mTodayAnimator: ObjectAnimator? = null

    // whether or not an event is stopping because it was cancelled
    private var mCancellingAnimations = false

    // tracks whether a touch originated in the allday area
    private var mTouchStartedInAlldayArea = false
    private val mController: CalendarController
    private val mViewSwitcher: ViewSwitcher
    private val mGestureDetector: GestureDetector
    private val mScroller: OverScroller
    private val mEdgeEffectTop: EdgeEffect
    private val mEdgeEffectBottom: EdgeEffect
    private var mCallEdgeEffectOnAbsorb = false
    private val OVERFLING_DISTANCE: Int
    private var mLastVelocity = 0f
    private val mHScrollInterpolator: ScrollInterpolator
    private var mAccessibilityMgr: AccessibilityManager? = null
    private var mIsAccessibilityEnabled = false
    private var mTouchExplorationEnabled = false
    private val mNewEventHintString: String
    @Override
    protected override fun onAttachedToWindow() {
        if (mHandler == null) {
            mHandler = getHandler()
            mHandler?.post(mUpdateCurrentTime)
        }
    }

    private fun init(context: Context) {
        setFocusable(true)

        // Allow focus in touch mode so that we can do keyboard shortcuts
        // even after we've entered touch mode.
        setFocusableInTouchMode(true)
        setClickable(true)
        setOnCreateContextMenuListener(this)
        mFirstDayOfWeek = Utils.getFirstDayOfWeek(context)
        mCurrentTime = Time(Utils.getTimeZone(context, mTZUpdater))
        val currentTime: Long = System.currentTimeMillis()
        mCurrentTime?.set(currentTime)
        mTodayJulianDay = Time.getJulianDay(currentTime, mCurrentTime!!.gmtoff)
        mWeek_saturdayColor = mResources.getColor(R.color.week_saturday)
        mWeek_sundayColor = mResources.getColor(R.color.week_sunday)
        mCalendarDateBannerTextColor = mResources.getColor(R.color.calendar_date_banner_text_color)
        mFutureBgColorRes = mResources.getColor(R.color.calendar_future_bg_color)
        mBgColor = mResources.getColor(R.color.calendar_hour_background)
        mCalendarAmPmLabel = mResources.getColor(R.color.calendar_ampm_label)
        mCalendarGridAreaSelected = mResources.getColor(R.color.calendar_grid_area_selected)
        mCalendarGridLineInnerHorizontalColor = mResources
            .getColor(R.color.calendar_grid_line_inner_horizontal_color)
        mCalendarGridLineInnerVerticalColor = mResources
            .getColor(R.color.calendar_grid_line_inner_vertical_color)
        mCalendarHourLabelColor = mResources.getColor(R.color.calendar_hour_label)
        mEventTextColor = mResources.getColor(R.color.calendar_event_text_color)
        mMoreEventsTextColor = mResources.getColor(R.color.month_event_other_color)
        mEventTextPaint.setTextSize(EVENT_TEXT_FONT_SIZE)
        mEventTextPaint.setTextAlign(Paint.Align.LEFT)
        mEventTextPaint.setAntiAlias(true)
        val gridLineColor: Int = mResources.getColor(R.color.calendar_grid_line_highlight_color)
        var p: Paint = mSelectionPaint
        p.setColor(gridLineColor)
        p.setStyle(Style.FILL)
        p.setAntiAlias(false)
        p = mPaint
        p.setAntiAlias(true)

        // Allocate space for 2 weeks worth of weekday names so that we can
        // easily start the week display at any week day.
        mDayStrs = arrayOfNulls(14)

        // Also create an array of 2-letter abbreviations.
        mDayStrs2Letter = arrayOfNulls(14)
        for (i in Calendar.SUNDAY..Calendar.SATURDAY) {
            val index: Int = i - Calendar.SUNDAY
            // e.g. Tue for Tuesday
            mDayStrs!![index] = DateUtils.getDayOfWeekString(i, DateUtils.LENGTH_MEDIUM)
                .toUpperCase()
            mDayStrs!![index + 7] = mDayStrs!![index]
            // e.g. Tu for Tuesday
            mDayStrs2Letter!![index] = DateUtils.getDayOfWeekString(i, DateUtils.LENGTH_SHORT)
                .toUpperCase()

            // If we don't have 2-letter day strings, fall back to 1-letter.
            if (mDayStrs2Letter!![index]!!.equals(mDayStrs!![index])) {
                mDayStrs2Letter!![index] = DateUtils.getDayOfWeekString(i,
                DateUtils.LENGTH_SHORTEST)
            }
            mDayStrs2Letter!![index + 7] = mDayStrs2Letter!![index]
        }

        // Figure out how much space we need for the 3-letter abbrev names
        // in the worst case.
        p.setTextSize(DATE_HEADER_FONT_SIZE)
        p.setTypeface(mBold)
        val dateStrs = arrayOf<String?>(" 28", " 30")
        mDateStrWidth = computeMaxStringWidth(0, dateStrs, p)
        p.setTextSize(DAY_HEADER_FONT_SIZE)
        mDateStrWidth += computeMaxStringWidth(0, mDayStrs as Array<String?>, p)
        p.setTextSize(HOURS_TEXT_SIZE)
        p.setTypeface(null)
        handleOnResume()
        mAmString = DateUtils.getAMPMString(Calendar.AM).toUpperCase()
        mPmString = DateUtils.getAMPMString(Calendar.PM).toUpperCase()
        val ampm = arrayOf(mAmString, mPmString)
        p.setTextSize(AMPM_TEXT_SIZE)
        mHoursWidth = Math.max(
            HOURS_MARGIN, computeMaxStringWidth(mHoursWidth, ampm, p) +
                HOURS_RIGHT_MARGIN
        )
        mHoursWidth = Math.max(MIN_HOURS_WIDTH, mHoursWidth)
        val inflater: LayoutInflater
        inflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
        mPopupView = inflater.inflate(R.layout.bubble_event, null)
        mPopupView?.setLayoutParams(
            LayoutParams(
                ViewGroup.LayoutParams.MATCH_PARENT,
                ViewGroup.LayoutParams.WRAP_CONTENT
            )
        )
        mPopup = PopupWindow(context)
        mPopup?.setContentView(mPopupView)
        val dialogTheme: Resources.Theme = getResources().newTheme()
        dialogTheme.applyStyle(android.R.style.Theme_Dialog, true)
        val ta: TypedArray = dialogTheme.obtainStyledAttributes(
            intArrayOf(
                android.R.attr.windowBackground
            )
        )
        mPopup?.setBackgroundDrawable(ta.getDrawable(0))
        ta.recycle()

        // Enable touching the popup window
        mPopupView?.setOnClickListener(this)
        // Catch long clicks for creating a new event
        setOnLongClickListener(this)
        mBaseDate = Time(Utils.getTimeZone(context, mTZUpdater))
        val millis: Long = System.currentTimeMillis()
        mBaseDate?.set(millis)
        mEarliestStartHour = IntArray(mNumDays)
        mHasAllDayEvent = BooleanArray(mNumDays)

        // mLines is the array of points used with Canvas.drawLines() in
        // drawGridBackground() and drawAllDayEvents().  Its size depends
        // on the max number of lines that can ever be drawn by any single
        // drawLines() call in either of those methods.
        val maxGridLines = (24 + 1 + // max horizontal lines we might draw
            (mNumDays + 1)) // max vertical lines we might draw
        mLines = FloatArray(maxGridLines * 4)
    }

    /**
     * This is called when the popup window is pressed.
     */
    override fun onClick(v: View) {
        if (v === mPopupView) {
            // Pretend it was a trackball click because that will always
            // jump to the "View event" screen.
            switchViews(true /* trackball */)
        }
    }

    fun handleOnResume() {
        initAccessibilityVariables()
        if (Utils.getSharedPreference(mContext, OtherPreferences.KEY_OTHER_1, false)) {
            mFutureBgColor = 0
        } else {
            mFutureBgColor = mFutureBgColorRes
        }
        mIs24HourFormat = DateFormat.is24HourFormat(mContext)
        mHourStrs = if (mIs24HourFormat) CalendarData.s24Hours else CalendarData.s12HoursNoAmPm
        mFirstDayOfWeek = Utils.getFirstDayOfWeek(mContext)
        mLastSelectionDayForAccessibility = 0
        mLastSelectionHourForAccessibility = 0
        mLastSelectedEventForAccessibility = null
        mSelectionMode = SELECTION_HIDDEN
    }

    private fun initAccessibilityVariables() {
        mAccessibilityMgr = mContext
            ?.getSystemService(Service.ACCESSIBILITY_SERVICE) as AccessibilityManager
        mIsAccessibilityEnabled = mAccessibilityMgr != null && mAccessibilityMgr!!.isEnabled()
        mTouchExplorationEnabled = isTouchExplorationEnabled
    } /* ignore isDst */ // We ignore the "isDst" field because we want normalize() to figure
    // out the correct DST value and not adjust the selected time based
    // on the current setting of DST.
    /**
     * Returns the start of the selected time in milliseconds since the epoch.
     *
     * @return selected time in UTC milliseconds since the epoch.
     */
    val selectedTimeInMillis: Long
        get() {
            val time = Time(mBaseDate)
            time.setJulianDay(mSelectionDay)
            time.hour = mSelectionHour

            // We ignore the "isDst" field because we want normalize() to figure
            // out the correct DST value and not adjust the selected time based
            // on the current setting of DST.
            return time.normalize(true /* ignore isDst */)
        } /* ignore isDst */

    // We ignore the "isDst" field because we want normalize() to figure
    // out the correct DST value and not adjust the selected time based
    // on the current setting of DST.
    val selectedTime: Time
        get() {
            val time = Time(mBaseDate)
            time.setJulianDay(mSelectionDay)
            time.hour = mSelectionHour

            // We ignore the "isDst" field because we want normalize() to figure
            // out the correct DST value and not adjust the selected time based
            // on the current setting of DST.
            time.normalize(true /* ignore isDst */)
            return time
        } /* ignore isDst */

    // We ignore the "isDst" field because we want normalize() to figure
    // out the correct DST value and not adjust the selected time based
    // on the current setting of DST.
    val selectedTimeForAccessibility: Time
        get() {
            val time = Time(mBaseDate)
            time.setJulianDay(mSelectionDayForAccessibility)
            time.hour = mSelectionHourForAccessibility

            // We ignore the "isDst" field because we want normalize() to figure
            // out the correct DST value and not adjust the selected time based
            // on the current setting of DST.
            time.normalize(true /* ignore isDst */)
            return time
        }

    /**
     * Returns the start of the selected time in minutes since midnight,
     * local time.  The derived class must ensure that this is consistent
     * with the return value from getSelectedTimeInMillis().
     */
    val selectedMinutesSinceMidnight: Int
        get() = mSelectionHour * MINUTES_PER_HOUR
    var firstVisibleHour: Int
        get() = mFirstHour
        set(firstHour) {
            mFirstHour = firstHour
            mFirstHourOffset = 0
        }

    fun setSelected(time: Time?, ignoreTime: Boolean, animateToday: Boolean) {
        mBaseDate?.set(time)
        setSelectedHour(mBaseDate!!.hour)
        setSelectedEvent(null)
        mPrevSelectedEvent = null
        val millis: Long = mBaseDate!!.toMillis(false /* use isDst */)
        setSelectedDay(Time.getJulianDay(millis, mBaseDate!!.gmtoff))
        mSelectedEvents.clear()
        mComputeSelectedEvents = true
        var gotoY: Int = Integer.MIN_VALUE
        if (!ignoreTime && mGridAreaHeight != -1) {
            var lastHour = 0
            if (mBaseDate!!.hour < mFirstHour) {
                // Above visible region
                gotoY = mBaseDate!!.hour * (mCellHeight + HOUR_GAP)
            } else {
                lastHour = ((mGridAreaHeight - mFirstHourOffset) / (mCellHeight + HOUR_GAP) +
                    mFirstHour)
                if (mBaseDate!!.hour >= lastHour) {
                    // Below visible region

                    // target hour + 1 (to give it room to see the event) -
                    // grid height (to get the y of the top of the visible
                    // region)
                    gotoY = ((mBaseDate!!.hour + 1 + mBaseDate!!.minute / 60.0f) *
                        (mCellHeight + HOUR_GAP) - mGridAreaHeight).toInt()
                }
            }
            if (DEBUG) {
                Log.e(
                    TAG, "Go " + gotoY + " 1st " + mFirstHour + ":" + mFirstHourOffset + "CH " +
                        (mCellHeight + HOUR_GAP) + " lh " + lastHour + " gh " + mGridAreaHeight +
                        " ymax " + mMaxViewStartY
                )
            }
            if (gotoY > mMaxViewStartY) {
                gotoY = mMaxViewStartY
            } else if (gotoY < 0 && gotoY != Integer.MIN_VALUE) {
                gotoY = 0
            }
        }
        recalc()
        mRemeasure = true
        invalidate()
        var delayAnimateToday = false
        if (gotoY != Integer.MIN_VALUE) {
            val scrollAnim: ValueAnimator =
                ObjectAnimator.ofInt(this, "viewStartY", mViewStartY, gotoY)
            scrollAnim.setDuration(GOTO_SCROLL_DURATION.toLong())
            scrollAnim.setInterpolator(AccelerateDecelerateInterpolator())
            scrollAnim.addListener(mAnimatorListener)
            scrollAnim.start()
            delayAnimateToday = true
        }
        if (animateToday) {
            synchronized(mTodayAnimatorListener) {
                if (mTodayAnimator != null) {
                    mTodayAnimator?.removeAllListeners()
                    mTodayAnimator?.cancel()
                }
                mTodayAnimator = ObjectAnimator.ofInt(
                    this, "animateTodayAlpha",
                    mAnimateTodayAlpha, 255
                )
                mAnimateToday = true
                mTodayAnimatorListener.setFadingIn(true)
                mTodayAnimatorListener.setAnimator(mTodayAnimator)
                mTodayAnimator?.addListener(mTodayAnimatorListener)
                mTodayAnimator?.setDuration(150)
                if (delayAnimateToday) {
                    mTodayAnimator?.setStartDelay(GOTO_SCROLL_DURATION.toLong())
                }
                mTodayAnimator?.start()
            }
        }
        sendAccessibilityEventAsNeeded(false)
    }

    // Called from animation framework via reflection. Do not remove
    fun setViewStartY(viewStartY: Int) {
        var viewStartY = viewStartY
        if (viewStartY > mMaxViewStartY) {
            viewStartY = mMaxViewStartY
        }
        mViewStartY = viewStartY
        computeFirstHour()
        invalidate()
    }

    fun setAnimateTodayAlpha(todayAlpha: Int) {
        mAnimateTodayAlpha = todayAlpha
        invalidate()
    } /* ignore isDst */

    fun getSelectedDay(): Time {
        val time = Time(mBaseDate)
        time.setJulianDay(mSelectionDay)
        time.hour = mSelectionHour

        // We ignore the "isDst" field because we want normalize() to figure
        // out the correct DST value and not adjust the selected time based
        // on the current setting of DST.
        time.normalize(true /* ignore isDst */)
        return time
    }

    fun updateTitle() {
        val start = Time(mBaseDate)
        start.normalize(true)
        val end = Time(start)
        end.monthDay += mNumDays - 1
        // Move it forward one minute so the formatter doesn't lose a day
        end.minute += 1
        end.normalize(true)
        var formatFlags: Long = DateUtils.FORMAT_SHOW_DATE.toLong() or
            DateUtils.FORMAT_SHOW_YEAR.toLong()
        if (mNumDays != 1) {
            // Don't show day of the month if for multi-day view
            formatFlags = formatFlags or DateUtils.FORMAT_NO_MONTH_DAY.toLong()

            // Abbreviate the month if showing multiple months
            if (start.month !== end.month) {
                formatFlags = formatFlags or DateUtils.FORMAT_ABBREV_MONTH.toLong()
            }
        }
        mController.sendEvent(
            this as Object?, EventType.UPDATE_TITLE, start, end, null, -1, ViewType.CURRENT,
            formatFlags, null, null
        )
    }

    /**
     * return a negative number if "time" is comes before the visible time
     * range, a positive number if "time" is after the visible time range, and 0
     * if it is in the visible time range.
     */
    fun compareToVisibleTimeRange(time: Time): Int {
        val savedHour: Int = mBaseDate!!.hour
        val savedMinute: Int = mBaseDate!!.minute
        val savedSec: Int = mBaseDate!!.second
        mBaseDate!!.hour = 0
        mBaseDate!!.minute = 0
        mBaseDate!!.second = 0
        if (DEBUG) {
            Log.d(TAG, "Begin " + mBaseDate.toString())
            Log.d(TAG, "Diff  " + time.toString())
        }

        // Compare beginning of range
        var diff: Int = Time.compare(time, mBaseDate)
        if (diff > 0) {
            // Compare end of range
            mBaseDate!!.monthDay += mNumDays
            mBaseDate?.normalize(true)
            diff = Time.compare(time, mBaseDate)
            if (DEBUG) Log.d(TAG, "End   " + mBaseDate.toString())
            mBaseDate!!.monthDay -= mNumDays
            mBaseDate?.normalize(true)
            if (diff < 0) {
                // in visible time
                diff = 0
            } else if (diff == 0) {
                // Midnight of following day
                diff = 1
            }
        }
        if (DEBUG) Log.d(TAG, "Diff: $diff")
        mBaseDate!!.hour = savedHour
        mBaseDate!!.minute = savedMinute
        mBaseDate!!.second = savedSec
        return diff
    }

    private fun recalc() {
        // Set the base date to the beginning of the week if we are displaying
        // 7 days at a time.
        if (mNumDays == 7) {
            adjustToBeginningOfWeek(mBaseDate)
        }
        val start: Long = mBaseDate!!.toMillis(false /* use isDst */)
        mFirstJulianDay = Time.getJulianDay(start, mBaseDate!!.gmtoff)
        mLastJulianDay = mFirstJulianDay + mNumDays - 1
        mMonthLength = mBaseDate!!.getActualMaximum(Time.MONTH_DAY)
        mFirstVisibleDate = mBaseDate!!.monthDay
        mFirstVisibleDayOfWeek = mBaseDate!!.weekDay
    }

    private fun adjustToBeginningOfWeek(time: Time?) {
        val dayOfWeek: Int = time!!.weekDay
        var diff = dayOfWeek - mFirstDayOfWeek
        if (diff != 0) {
            if (diff < 0) {
                diff += 7
            }
            time!!.monthDay -= diff
            time?.normalize(true /* ignore isDst */)
        }
    }

    @Override
    protected override fun onSizeChanged(width: Int, height: Int, oldw: Int, oldh: Int) {
        mViewWidth = width
        mViewHeight = height
        mEdgeEffectTop.setSize(mViewWidth, mViewHeight)
        mEdgeEffectBottom.setSize(mViewWidth, mViewHeight)
        val gridAreaWidth = width - mHoursWidth
        mCellWidth = (gridAreaWidth - mNumDays * DAY_GAP) / mNumDays

        // This would be about 1 day worth in a 7 day view
        mHorizontalSnapBackThreshold = width / 7
        val p = Paint()
        p.setTextSize(HOURS_TEXT_SIZE)
        mHoursTextHeight = Math.abs(p.ascent()).toInt()
        remeasure(width, height)
    }

    /**
     * Measures the space needed for various parts of the view after
     * loading new events.  This can change if there are all-day events.
     */
    private fun remeasure(width: Int, height: Int) {
        // Shrink to fit available space but make sure we can display at least two events
        MAX_UNEXPANDED_ALLDAY_HEIGHT = (MIN_UNEXPANDED_ALLDAY_EVENT_HEIGHT * 4).toInt()
        MAX_UNEXPANDED_ALLDAY_HEIGHT = Math.min(MAX_UNEXPANDED_ALLDAY_HEIGHT, height / 6)
        MAX_UNEXPANDED_ALLDAY_HEIGHT = Math.max(
            MAX_UNEXPANDED_ALLDAY_HEIGHT,
            MIN_UNEXPANDED_ALLDAY_EVENT_HEIGHT.toInt() * 2
        )
        mMaxUnexpandedAlldayEventCount =
            (MAX_UNEXPANDED_ALLDAY_HEIGHT / MIN_UNEXPANDED_ALLDAY_EVENT_HEIGHT).toInt()

        // First, clear the array of earliest start times, and the array
        // indicating presence of an all-day event.
        for (day in 0 until mNumDays) {
            mEarliestStartHour!![day] = 25 // some big number
            mHasAllDayEvent!![day] = false
        }
        val maxAllDayEvents = mMaxAlldayEvents

        // The min is where 24 hours cover the entire visible area
        mMinCellHeight = Math.max((height - DAY_HEADER_HEIGHT) / 24, MIN_EVENT_HEIGHT.toInt())
        if (mCellHeight < mMinCellHeight) {
            mCellHeight = mMinCellHeight
        }

        // Calculate mAllDayHeight
        mFirstCell = DAY_HEADER_HEIGHT
        var allDayHeight = 0
        if (maxAllDayEvents > 0) {
            val maxAllAllDayHeight = height - DAY_HEADER_HEIGHT - MIN_HOURS_HEIGHT
            // If there is at most one all-day event per day, then use less
            // space (but more than the space for a single event).
            if (maxAllDayEvents == 1) {
                allDayHeight = SINGLE_ALLDAY_HEIGHT
            } else if (maxAllDayEvents <= mMaxUnexpandedAlldayEventCount) {
                // Allow the all-day area to grow in height depending on the
                // number of all-day events we need to show, up to a limit.
                allDayHeight = maxAllDayEvents * MAX_HEIGHT_OF_ONE_ALLDAY_EVENT
                if (allDayHeight > MAX_UNEXPANDED_ALLDAY_HEIGHT) {
                    allDayHeight = MAX_UNEXPANDED_ALLDAY_HEIGHT
                }
            } else {
                // if we have more than the magic number, check if we're animating
                // and if not adjust the sizes appropriately
                if (mAnimateDayHeight != 0) {
                    // Don't shrink the space past the final allDay space. The animation
                    // continues to hide the last event so the more events text can
                    // fade in.
                    allDayHeight = Math.max(mAnimateDayHeight, MAX_UNEXPANDED_ALLDAY_HEIGHT)
                } else {
                    // Try to fit all the events in
                    allDayHeight = (maxAllDayEvents * MIN_UNEXPANDED_ALLDAY_EVENT_HEIGHT).toInt()
                    // But clip the area depending on which mode we're in
                    if (!mShowAllAllDayEvents && allDayHeight > MAX_UNEXPANDED_ALLDAY_HEIGHT) {
                        allDayHeight = (mMaxUnexpandedAlldayEventCount *
                            MIN_UNEXPANDED_ALLDAY_EVENT_HEIGHT).toInt()
                    } else if (allDayHeight > maxAllAllDayHeight) {
                        allDayHeight = maxAllAllDayHeight
                    }
                }
            }
            mFirstCell = DAY_HEADER_HEIGHT + allDayHeight + ALLDAY_TOP_MARGIN
        } else {
            mSelectionAllday = false
        }
        mAlldayHeight = allDayHeight
        mGridAreaHeight = height - mFirstCell

        // Set up the expand icon position
        val allDayIconWidth: Int = mExpandAlldayDrawable.getIntrinsicWidth()
        mExpandAllDayRect.left = Math.max(
            (mHoursWidth - allDayIconWidth) / 2,
            EVENT_ALL_DAY_TEXT_LEFT_MARGIN
        )
        mExpandAllDayRect.right = Math.min(
            mExpandAllDayRect.left + allDayIconWidth, mHoursWidth -
                EVENT_ALL_DAY_TEXT_RIGHT_MARGIN
        )
        mExpandAllDayRect.bottom = mFirstCell - EXPAND_ALL_DAY_BOTTOM_MARGIN
        mExpandAllDayRect.top = (mExpandAllDayRect.bottom -
            mExpandAlldayDrawable.getIntrinsicHeight())
        mNumHours = mGridAreaHeight / (mCellHeight + HOUR_GAP)
        mEventGeometry.setHourHeight(mCellHeight.toFloat())
        val minimumDurationMillis =
            (MIN_EVENT_HEIGHT * DateUtils.MINUTE_IN_MILLIS / (mCellHeight / 60.0f)).toLong()
        Event.computePositions(mEvents, minimumDurationMillis)

        // Compute the top of our reachable view
        mMaxViewStartY = HOUR_GAP + 24 * (mCellHeight + HOUR_GAP) - mGridAreaHeight
        if (DEBUG) {
            Log.e(TAG, "mViewStartY: $mViewStartY")
            Log.e(TAG, "mMaxViewStartY: $mMaxViewStartY")
        }
        if (mViewStartY > mMaxViewStartY) {
            mViewStartY = mMaxViewStartY
            computeFirstHour()
        }
        if (mFirstHour == -1) {
            initFirstHour()
            mFirstHourOffset = 0
        }

        // When we change the base date, the number of all-day events may
        // change and that changes the cell height.  When we switch dates,
        // we use the mFirstHourOffset from the previous view, but that may
        // be too large for the new view if the cell height is smaller.
        if (mFirstHourOffset >= mCellHeight + HOUR_GAP) {
            mFirstHourOffset = mCellHeight + HOUR_GAP - 1
        }
        mViewStartY = mFirstHour * (mCellHeight + HOUR_GAP) - mFirstHourOffset
        val eventAreaWidth = mNumDays * (mCellWidth + DAY_GAP)
        // When we get new events we don't want to dismiss the popup unless the event changes
        if (mSelectedEvent != null && mLastPopupEventID != mSelectedEvent!!.id) {
            mPopup?.dismiss()
        }
        mPopup?.setWidth(eventAreaWidth - 20)
        mPopup?.setHeight(WindowManager.LayoutParams.WRAP_CONTENT)
    }

    /**
     * Initialize the state for another view.  The given view is one that has
     * its own bitmap and will use an animation to replace the current view.
     * The current view and new view are either both Week views or both Day
     * views.  They differ in their base date.
     *
     * @param view the view to initialize.
     */
    private fun initView(view: DayView) {
        view.setSelectedHour(mSelectionHour)
        view.mSelectedEvents.clear()
        view.mComputeSelectedEvents = true
        view.mFirstHour = mFirstHour
        view.mFirstHourOffset = mFirstHourOffset
        view.remeasure(getWidth(), getHeight())
        view.initAllDayHeights()
        view.setSelectedEvent(null)
        view.mPrevSelectedEvent = null
        view.mFirstDayOfWeek = mFirstDayOfWeek
        if (view.mEvents.size > 0) {
            view.mSelectionAllday = mSelectionAllday
        } else {
            view.mSelectionAllday = false
        }

        // Redraw the screen so that the selection box will be redrawn.  We may
        // have scrolled to a different part of the day in some other view
        // so the selection box in this view may no longer be visible.
        view.recalc()
    }

    /**
     * Switch to another view based on what was selected (an event or a free
     * slot) and how it was selected (by touch or by trackball).
     *
     * @param trackBallSelection true if the selection was made using the
     * trackball.
     */
    private fun switchViews(trackBallSelection: Boolean) {
        val selectedEvent: Event? = mSelectedEvent
        mPopup?.dismiss()
        mLastPopupEventID = INVALID_EVENT_ID
        if (mNumDays > 1) {
            // This is the Week view.
            // With touch, we always switch to Day/Agenda View
            // With track ball, if we selected a free slot, then create an event.
            // If we selected a specific event, switch to EventInfo view.
            if (trackBallSelection) {
                if (selectedEvent != null) {
                    if (mIsAccessibilityEnabled) {
                        mAccessibilityMgr?.interrupt()
                    }
                }
            }
        }
    }

    @Override
    override fun onKeyUp(keyCode: Int, event: KeyEvent?): Boolean {
        mScrolling = false
        return super.onKeyUp(keyCode, event)
    }

    @Override
    override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
        return super.onKeyDown(keyCode, event)
    }

    @Override
    override fun onHoverEvent(event: MotionEvent?): Boolean {
        return true
    }

    private val isTouchExplorationEnabled: Boolean
        private get() = mIsAccessibilityEnabled && mAccessibilityMgr!!.isTouchExplorationEnabled()

    private fun sendAccessibilityEventAsNeeded(speakEvents: Boolean) {
        if (!mIsAccessibilityEnabled) {
            return
        }
        val dayChanged = mLastSelectionDayForAccessibility != mSelectionDayForAccessibility
        val hourChanged = mLastSelectionHourForAccessibility != mSelectionHourForAccessibility
        if (dayChanged || hourChanged || mLastSelectedEventForAccessibility !==
            mSelectedEventForAccessibility) {
            mLastSelectionDayForAccessibility = mSelectionDayForAccessibility
            mLastSelectionHourForAccessibility = mSelectionHourForAccessibility
            mLastSelectedEventForAccessibility = mSelectedEventForAccessibility
            val b = StringBuilder()

            // Announce only the changes i.e. day or hour or both
            if (dayChanged) {
                b.append(selectedTimeForAccessibility.format("%A "))
            }
            if (hourChanged) {
                b.append(selectedTimeForAccessibility.format(if (mIs24HourFormat) "%k" else "%l%p"))
            }
            if (dayChanged || hourChanged) {
                b.append(PERIOD_SPACE)
            }
            if (speakEvents) {
                if (mEventCountTemplate == null) {
                    mEventCountTemplate = mContext?.getString(R.string.template_announce_item_index)
                }

                // Read out the relevant event(s)
                val numEvents: Int = mSelectedEvents.size
                if (numEvents > 0) {
                    if (mSelectedEventForAccessibility == null) {
                        // Read out all the events
                        var i = 1
                        for (calEvent in mSelectedEvents) {
                            if (numEvents > 1) {
                                // Read out x of numEvents if there are more than one event
                                mStringBuilder.setLength(0)
                                b.append(mFormatter.format(mEventCountTemplate, i++, numEvents))
                                b.append(" ")
                            }
                            appendEventAccessibilityString(b, calEvent)
                        }
                    } else {
                        if (numEvents > 1) {
                            // Read out x of numEvents if there are more than one event
                            mStringBuilder.setLength(0)
                            b.append(
                                mFormatter.format(
                                    mEventCountTemplate, mSelectedEvents
                                        .indexOf(mSelectedEventForAccessibility) + 1, numEvents
                                )
                            )
                            b.append(" ")
                        }
                        appendEventAccessibilityString(b, mSelectedEventForAccessibility)
                    }
                }
            }
            if (dayChanged || hourChanged || speakEvents) {
                val event: AccessibilityEvent = AccessibilityEvent
                    .obtain(AccessibilityEvent.TYPE_VIEW_FOCUSED)
                val msg: CharSequence = b.toString()
                event.getText().add(msg)
                event.setAddedCount(msg.length)
                sendAccessibilityEventUnchecked(event)
            }
        }
    }

    /**
     * @param b
     * @param calEvent
     */
    private fun appendEventAccessibilityString(b: StringBuilder, calEvent: Event?) {
        b.append(calEvent!!.titleAndLocation)
        b.append(PERIOD_SPACE)
        val `when`: String?
        var flags: Int = DateUtils.FORMAT_SHOW_DATE
        if (calEvent!!.allDay) {
            flags = flags or (DateUtils.FORMAT_UTC or DateUtils.FORMAT_SHOW_WEEKDAY)
        } else {
            flags = flags or DateUtils.FORMAT_SHOW_TIME
            if (DateFormat.is24HourFormat(mContext)) {
                flags = flags or DateUtils.FORMAT_24HOUR
            }
        }
        `when` = Utils.formatDateRange(mContext, calEvent!!.startMillis, calEvent!!.endMillis,
            flags)
        b.append(`when`)
        b.append(PERIOD_SPACE)
    }

    private inner class GotoBroadcaster(start: Time, end: Time) : Animation.AnimationListener {
        private val mCounter: Int
        private val mStart: Time
        private val mEnd: Time
        @Override
        override fun onAnimationEnd(animation: Animation?) {
            var view = mViewSwitcher.getCurrentView() as DayView
            view.mViewStartX = 0
            view = mViewSwitcher.getNextView() as DayView
            view.mViewStartX = 0
            if (mCounter == sCounter) {
                mController.sendEvent(
                    this as Object?, EventType.GO_TO, mStart, mEnd, null, -1,
                    ViewType.CURRENT, CalendarController.EXTRA_GOTO_DATE, null, null
                )
            }
        }

        @Override
        override fun onAnimationRepeat(animation: Animation?) {
        }

        @Override
        override fun onAnimationStart(animation: Animation?) {
        }

        init {
            mCounter = ++sCounter
            mStart = start
            mEnd = end
        }
    }

    private fun switchViews(forward: Boolean, xOffSet: Float, width: Float, velocity: Float): View {
        mAnimationDistance = width - xOffSet
        if (DEBUG) {
            Log.d(TAG, "switchViews($forward) O:$xOffSet Dist:$mAnimationDistance")
        }
        var progress: Float = Math.abs(xOffSet) / width
        if (progress > 1.0f) {
            progress = 1.0f
        }
        val inFromXValue: Float
        val inToXValue: Float
        val outFromXValue: Float
        val outToXValue: Float
        if (forward) {
            inFromXValue = 1.0f - progress
            inToXValue = 0.0f
            outFromXValue = -progress
            outToXValue = -1.0f
        } else {
            inFromXValue = progress - 1.0f
            inToXValue = 0.0f
            outFromXValue = progress
            outToXValue = 1.0f
        }
        val start = Time(mBaseDate!!.timezone)
        start.set(mController.time as Long)
        if (forward) {
            start.monthDay += mNumDays
        } else {
            start.monthDay -= mNumDays
        }
        mController.time = start.normalize(true)
        var newSelected: Time? = start
        if (mNumDays == 7) {
            newSelected = Time(start)
            adjustToBeginningOfWeek(start)
        }
        val end = Time(start)
        end.monthDay += mNumDays - 1

        // We have to allocate these animation objects each time we switch views
        // because that is the only way to set the animation parameters.
        val inAnimation = TranslateAnimation(
            Animation.RELATIVE_TO_SELF, inFromXValue,
            Animation.RELATIVE_TO_SELF, inToXValue,
            Animation.ABSOLUTE, 0.0f,
            Animation.ABSOLUTE, 0.0f
        )
        val outAnimation = TranslateAnimation(
            Animation.RELATIVE_TO_SELF, outFromXValue,
            Animation.RELATIVE_TO_SELF, outToXValue,
            Animation.ABSOLUTE, 0.0f,
            Animation.ABSOLUTE, 0.0f
        )
        val duration = calculateDuration(width - Math.abs(xOffSet), width, velocity)
        inAnimation.setDuration(duration)
        inAnimation.setInterpolator(mHScrollInterpolator)
        outAnimation.setInterpolator(mHScrollInterpolator)
        outAnimation.setDuration(duration)
        outAnimation.setAnimationListener(GotoBroadcaster(start, end))
        mViewSwitcher.setInAnimation(inAnimation)
        mViewSwitcher.setOutAnimation(outAnimation)
        var view = mViewSwitcher.getCurrentView() as DayView
        view.cleanup()
        mViewSwitcher.showNext()
        view = mViewSwitcher.getCurrentView() as DayView
        view.setSelected(newSelected, true, false)
        view.requestFocus()
        view.reloadEvents()
        view.updateTitle()
        view.restartCurrentTimeUpdates()
        return view
    }

    // This is called after scrolling stops to move the selected hour
    // to the visible part of the screen.
    private fun resetSelectedHour() {
        if (mSelectionHour < mFirstHour + 1) {
            setSelectedHour(mFirstHour + 1)
            setSelectedEvent(null)
            mSelectedEvents.clear()
            mComputeSelectedEvents = true
        } else if (mSelectionHour > mFirstHour + mNumHours - 3) {
            setSelectedHour(mFirstHour + mNumHours - 3)
            setSelectedEvent(null)
            mSelectedEvents.clear()
            mComputeSelectedEvents = true
        }
    }

    private fun initFirstHour() {
        mFirstHour = mSelectionHour - mNumHours / 5
        if (mFirstHour < 0) {
            mFirstHour = 0
        } else if (mFirstHour + mNumHours > 24) {
            mFirstHour = 24 - mNumHours
        }
    }

    /**
     * Recomputes the first full hour that is visible on screen after the
     * screen is scrolled.
     */
    private fun computeFirstHour() {
        // Compute the first full hour that is visible on screen
        mFirstHour = (mViewStartY + mCellHeight + HOUR_GAP - 1) / (mCellHeight + HOUR_GAP)
        mFirstHourOffset = mFirstHour * (mCellHeight + HOUR_GAP) - mViewStartY
    }

    private fun adjustHourSelection() {
        if (mSelectionHour < 0) {
            setSelectedHour(0)
            if (mMaxAlldayEvents > 0) {
                mPrevSelectedEvent = null
                mSelectionAllday = true
            }
        }
        if (mSelectionHour > 23) {
            setSelectedHour(23)
        }

        // If the selected hour is at least 2 time slots from the top and
        // bottom of the screen, then don't scroll the view.
        if (mSelectionHour < mFirstHour + 1) {
            // If there are all-days events for the selected day but there
            // are no more normal events earlier in the day, then jump to
            // the all-day event area.
            // Exception 1: allow the user to scroll to 8am with the trackball
            // before jumping to the all-day event area.
            // Exception 2: if 12am is on screen, then allow the user to select
            // 12am before going up to the all-day event area.
            val daynum = mSelectionDay - mFirstJulianDay
            if (daynum < mEarliestStartHour!!.size && daynum >= 0 && mMaxAlldayEvents > 0 &&
                mEarliestStartHour!![daynum] > mSelectionHour &&
                mFirstHour > 0 && mFirstHour < 8) {
                mPrevSelectedEvent = null
                mSelectionAllday = true
                setSelectedHour(mFirstHour + 1)
                return
            }
            if (mFirstHour > 0) {
                mFirstHour -= 1
                mViewStartY -= mCellHeight + HOUR_GAP
                if (mViewStartY < 0) {
                    mViewStartY = 0
                }
                return
            }
        }
        if (mSelectionHour > mFirstHour + mNumHours - 3) {
            if (mFirstHour < 24 - mNumHours) {
                mFirstHour += 1
                mViewStartY += mCellHeight + HOUR_GAP
                if (mViewStartY > mMaxViewStartY) {
                    mViewStartY = mMaxViewStartY
                }
                return
            } else if (mFirstHour == 24 - mNumHours && mFirstHourOffset > 0) {
                mViewStartY = mMaxViewStartY
            }
        }
    }

    fun clearCachedEvents() {
        mLastReloadMillis = 0
    }

    private val mCancelCallback: Runnable = object : Runnable {
        override fun run() {
            clearCachedEvents()
        }
    }

    /* package */
    fun reloadEvents() {
        // Protect against this being called before this view has been
        // initialized.
//        if (mContext == null) {
//            return;
//        }

        // Make sure our time zones are up to date
        mTZUpdater.run()
        setSelectedEvent(null)
        mPrevSelectedEvent = null
        mSelectedEvents.clear()

        // The start date is the beginning of the week at 12am
        val weekStart = Time(Utils.getTimeZone(mContext, mTZUpdater))
        weekStart.set(mBaseDate)
        weekStart.hour = 0
        weekStart.minute = 0
        weekStart.second = 0
        val millis: Long = weekStart.normalize(true /* ignore isDst */)

        // Avoid reloading events unnecessarily.
        if (millis == mLastReloadMillis) {
            return
        }
        mLastReloadMillis = millis

        // load events in the background
        // mContext.startProgressSpinner();
        val events: ArrayList<Event> = ArrayList<Event>()
        mEventLoader.loadEventsInBackground(mNumDays, events as ArrayList<Event?>, mFirstJulianDay,
            object : Runnable {
            override fun run() {
                val fadeinEvents = mFirstJulianDay != mLoadedFirstJulianDay
                mEvents = events
                mLoadedFirstJulianDay = mFirstJulianDay
                if (mAllDayEvents == null) {
                    mAllDayEvents = ArrayList<Event>()
                } else {
                    mAllDayEvents?.clear()
                }

                // Create a shorter array for all day events
                for (e in events) {
                    if (e.drawAsAllday()) {
                        mAllDayEvents?.add(e)
                    }
                }

                // New events, new layouts
                if (mLayouts == null || mLayouts!!.size < events.size) {
                    mLayouts = arrayOfNulls<StaticLayout>(events.size)
                } else {
                    Arrays.fill(mLayouts, null)
                }
                if (mAllDayLayouts == null || mAllDayLayouts!!.size < mAllDayEvents!!.size) {
                    mAllDayLayouts = arrayOfNulls<StaticLayout>(events.size)
                } else {
                    Arrays.fill(mAllDayLayouts, null)
                }
                computeEventRelations()
                mRemeasure = true
                mComputeSelectedEvents = true
                recalc()

                // Start animation to cross fade the events
                if (fadeinEvents) {
                    if (mEventsCrossFadeAnimation == null) {
                        mEventsCrossFadeAnimation =
                            ObjectAnimator.ofInt(this@DayView, "EventsAlpha", 0, 255)
                        mEventsCrossFadeAnimation?.setDuration(EVENTS_CROSS_FADE_DURATION.toLong())
                    }
                    mEventsCrossFadeAnimation?.start()
                } else {
                    invalidate()
                }
            }
        }, mCancelCallback)
    }

    var eventsAlpha: Int
        get() = mEventsAlpha
        set(alpha) {
            mEventsAlpha = alpha
            invalidate()
        }

    fun stopEventsAnimation() {
        if (mEventsCrossFadeAnimation != null) {
            mEventsCrossFadeAnimation?.cancel()
        }
        mEventsAlpha = 255
    }

    private fun computeEventRelations() {
        // Compute the layout relation between each event before measuring cell
        // width, as the cell width should be adjusted along with the relation.
        //
        // Examples: A (1:00pm - 1:01pm), B (1:02pm - 2:00pm)
        // We should mark them as "overwapped". Though they are not overwapped logically, but
        // minimum cell height implicitly expands the cell height of A and it should look like
        // (1:00pm - 1:15pm) after the cell height adjustment.

        // Compute the space needed for the all-day events, if any.
        // Make a pass over all the events, and keep track of the maximum
        // number of all-day events in any one day.  Also, keep track of
        // the earliest event in each day.
        var maxAllDayEvents = 0
        val events: ArrayList<Event> = mEvents
        val len: Int = events.size
        // Num of all-day-events on each day.
        val eventsCount = IntArray(mLastJulianDay - mFirstJulianDay + 1)
        Arrays.fill(eventsCount, 0)
        for (ii in 0 until len) {
            val event: Event = events.get(ii)
            if (event.startDay > mLastJulianDay || event.endDay < mFirstJulianDay) {
                continue
            }
            if (event.drawAsAllday()) {
                // Count all the events being drawn as allDay events
                val firstDay: Int = Math.max(event.startDay, mFirstJulianDay)
                val lastDay: Int = Math.min(event.endDay, mLastJulianDay)
                for (day in firstDay..lastDay) {
                    val count = ++eventsCount[day - mFirstJulianDay]
                    if (maxAllDayEvents < count) {
                        maxAllDayEvents = count
                    }
                }
                var daynum: Int = event.startDay - mFirstJulianDay
                var durationDays: Int = event.endDay - event.startDay + 1
                if (daynum < 0) {
                    durationDays += daynum
                    daynum = 0
                }
                if (daynum + durationDays > mNumDays) {
                    durationDays = mNumDays - daynum
                }
                var day = daynum
                while (durationDays > 0) {
                    mHasAllDayEvent!![day] = true
                    day++
                    durationDays--
                }
            } else {
                var daynum: Int = event.startDay - mFirstJulianDay
                var hour: Int = event.startTime / 60
                if (daynum >= 0 && hour < mEarliestStartHour!![daynum]) {
                    mEarliestStartHour!![daynum] = hour
                }

                // Also check the end hour in case the event spans more than
                // one day.
                daynum = event.endDay - mFirstJulianDay
                hour = event.endTime / 60
                if (daynum < mNumDays && hour < mEarliestStartHour!![daynum]) {
                    mEarliestStartHour!![daynum] = hour
                }
            }
        }
        mMaxAlldayEvents = maxAllDayEvents
        initAllDayHeights()
    }

    @Override
    protected override fun onDraw(canvas: Canvas) {
        if (mRemeasure) {
            remeasure(getWidth(), getHeight())
            mRemeasure = false
        }
        canvas.save()
        val yTranslate = (-mViewStartY + DAY_HEADER_HEIGHT + mAlldayHeight).toFloat()
        // offset canvas by the current drag and header position
        canvas.translate(-mViewStartX.toFloat(), yTranslate)
        // clip to everything below the allDay area
        val dest: Rect = mDestRect
        dest.top = (mFirstCell - yTranslate).toInt()
        dest.bottom = (mViewHeight - yTranslate).toInt()
        dest.left = 0
        dest.right = mViewWidth
        canvas.save()
        canvas.clipRect(dest)
        // Draw the movable part of the view
        doDraw(canvas)
        // restore to having no clip
        canvas.restore()
        if (mTouchMode and TOUCH_MODE_HSCROLL != 0) {
            val xTranslate: Float
            xTranslate = if (mViewStartX > 0) {
                mViewWidth.toFloat()
            } else {
                -mViewWidth.toFloat()
            }
            // Move the canvas around to prep it for the next view
            // specifically, shift it by a screen and undo the
            // yTranslation which will be redone in the nextView's onDraw().
            canvas.translate(xTranslate, -yTranslate)
            val nextView = mViewSwitcher.getNextView() as DayView

            // Prevent infinite recursive calls to onDraw().
            nextView.mTouchMode = TOUCH_MODE_INITIAL_STATE
            nextView.onDraw(canvas)
            // Move it back for this view
            canvas.translate(-xTranslate, 0f)
        } else {
            // If we drew another view we already translated it back
            // If we didn't draw another view we should be at the edge of the
            // screen
            canvas.translate(mViewStartX.toFloat(), -yTranslate)
        }

        // Draw the fixed areas (that don't scroll) directly to the canvas.
        drawAfterScroll(canvas)
        if (mComputeSelectedEvents && mUpdateToast) {
            mUpdateToast = false
        }
        mComputeSelectedEvents = false

        // Draw overscroll glow
        if (!mEdgeEffectTop.isFinished()) {
            if (DAY_HEADER_HEIGHT != 0) {
                canvas.translate(0f, DAY_HEADER_HEIGHT.toFloat())
            }
            if (mEdgeEffectTop.draw(canvas)) {
                invalidate()
            }
            if (DAY_HEADER_HEIGHT != 0) {
                canvas.translate(0f, -DAY_HEADER_HEIGHT.toFloat())
            }
        }
        if (!mEdgeEffectBottom.isFinished()) {
            canvas.rotate(180f, mViewWidth.toFloat() / 2f, mViewHeight.toFloat() / 2f)
            if (mEdgeEffectBottom.draw(canvas)) {
                invalidate()
            }
        }
        canvas.restore()
    }

    private fun drawAfterScroll(canvas: Canvas) {
        val p: Paint = mPaint
        val r: Rect = mRect
        drawAllDayHighlights(r, canvas, p)
        if (mMaxAlldayEvents != 0) {
            drawAllDayEvents(mFirstJulianDay, mNumDays, canvas, p)
            drawUpperLeftCorner(r, canvas, p)
        }
        drawScrollLine(r, canvas, p)
        drawDayHeaderLoop(r, canvas, p)

        // Draw the AM and PM indicators if we're in 12 hour mode
        if (!mIs24HourFormat) {
            drawAmPm(canvas, p)
        }
    }

    // This isn't really the upper-left corner. It's the square area just
    // below the upper-left corner, above the hours and to the left of the
    // all-day area.
    private fun drawUpperLeftCorner(r: Rect, canvas: Canvas, p: Paint) {
        setupHourTextPaint(p)
        if (mMaxAlldayEvents > mMaxUnexpandedAlldayEventCount) {
            // Draw the allDay expand/collapse icon
            if (mUseExpandIcon) {
                mExpandAlldayDrawable.setBounds(mExpandAllDayRect)
                mExpandAlldayDrawable.draw(canvas)
            } else {
                mCollapseAlldayDrawable.setBounds(mExpandAllDayRect)
                mCollapseAlldayDrawable.draw(canvas)
            }
        }
    }

    private fun drawScrollLine(r: Rect, canvas: Canvas, p: Paint) {
        val right = computeDayLeftPosition(mNumDays)
        val y = mFirstCell - 1
        p.setAntiAlias(false)
        p.setStyle(Style.FILL)
        p.setColor(mCalendarGridLineInnerHorizontalColor)
        p.setStrokeWidth(GRID_LINE_INNER_WIDTH)
        canvas.drawLine(GRID_LINE_LEFT_MARGIN, y.toFloat(), right.toFloat(), y.toFloat(), p)
        p.setAntiAlias(true)
    }

    // Computes the x position for the left side of the given day (base 0)
    private fun computeDayLeftPosition(day: Int): Int {
        val effectiveWidth = mViewWidth - mHoursWidth
        return day * effectiveWidth / mNumDays + mHoursWidth
    }

    private fun drawAllDayHighlights(r: Rect, canvas: Canvas, p: Paint) {
        if (mFutureBgColor != 0) {
            // First, color the labels area light gray
            r.top = 0
            r.bottom = DAY_HEADER_HEIGHT
            r.left = 0
            r.right = mViewWidth
            p.setColor(mBgColor)
            p.setStyle(Style.FILL)
            canvas.drawRect(r, p)
            // and the area that says All day
            r.top = DAY_HEADER_HEIGHT
            r.bottom = mFirstCell - 1
            r.left = 0
            r.right = mHoursWidth
            canvas.drawRect(r, p)
            var startIndex = -1
            val todayIndex = mTodayJulianDay - mFirstJulianDay
            if (todayIndex < 0) {
                // Future
                startIndex = 0
            } else if (todayIndex >= 1 && todayIndex + 1 < mNumDays) {
                // Multiday - tomorrow is visible.
                startIndex = todayIndex + 1
            }
            if (startIndex >= 0) {
                // Draw the future highlight
                r.top = 0
                r.bottom = mFirstCell - 1
                r.left = computeDayLeftPosition(startIndex) + 1
                r.right = computeDayLeftPosition(mNumDays)
                p.setColor(mFutureBgColor)
                p.setStyle(Style.FILL)
                canvas.drawRect(r, p)
            }
        }
    }

    private fun drawDayHeaderLoop(r: Rect, canvas: Canvas, p: Paint) {
        // Draw the horizontal day background banner
        // p.setColor(mCalendarDateBannerBackground);
        // r.top = 0;
        // r.bottom = DAY_HEADER_HEIGHT;
        // r.left = 0;
        // r.right = mHoursWidth + mNumDays * (mCellWidth + DAY_GAP);
        // canvas.drawRect(r, p);
        //
        // Fill the extra space on the right side with the default background
        // r.left = r.right;
        // r.right = mViewWidth;
        // p.setColor(mCalendarGridAreaBackground);
        // canvas.drawRect(r, p);
        if (mNumDays == 1 && ONE_DAY_HEADER_HEIGHT == 0) {
            return
        }
        p.setTypeface(mBold)
        p.setTextAlign(Paint.Align.RIGHT)
        var cell = mFirstJulianDay
        val dayNames: Array<String?>?
        dayNames = if (mDateStrWidth < mCellWidth) {
            mDayStrs
        } else {
            mDayStrs2Letter
        }
        p.setAntiAlias(true)
        var day = 0
        while (day < mNumDays) {
            var dayOfWeek = day + mFirstVisibleDayOfWeek
            if (dayOfWeek >= 14) {
                dayOfWeek -= 14
            }
            var color = mCalendarDateBannerTextColor
            if (mNumDays == 1) {
                if (dayOfWeek == Time.SATURDAY) {
                    color = mWeek_saturdayColor
                } else if (dayOfWeek == Time.SUNDAY) {
                    color = mWeek_sundayColor
                }
            } else {
                val column = day % 7
                if (Utils.isSaturday(column, mFirstDayOfWeek)) {
                    color = mWeek_saturdayColor
                } else if (Utils.isSunday(column, mFirstDayOfWeek)) {
                    color = mWeek_sundayColor
                }
            }
            p.setColor(color)
            drawDayHeader(dayNames!![dayOfWeek], day, cell, canvas, p)
            day++
            cell++
        }
        p.setTypeface(null)
    }

    private fun drawAmPm(canvas: Canvas, p: Paint) {
        p.setColor(mCalendarAmPmLabel)
        p.setTextSize(AMPM_TEXT_SIZE)
        p.setTypeface(mBold)
        p.setAntiAlias(true)
        p.setTextAlign(Paint.Align.RIGHT)
        var text = mAmString
        if (mFirstHour >= 12) {
            text = mPmString
        }
        var y = mFirstCell + mFirstHourOffset + 2 * mHoursTextHeight + HOUR_GAP
        canvas.drawText(text as String, HOURS_LEFT_MARGIN.toFloat(), y.toFloat(), p)
        if (mFirstHour < 12 && mFirstHour + mNumHours > 12) {
            // Also draw the "PM"
            text = mPmString
            y =
                mFirstCell + mFirstHourOffset + (12 - mFirstHour) * (mCellHeight + HOUR_GAP) +
                    2 * mHoursTextHeight + HOUR_GAP
            canvas.drawText(text as String, HOURS_LEFT_MARGIN.toFloat(), y.toFloat(), p)
        }
    }

    private fun drawCurrentTimeLine(
        r: Rect,
        day: Int,
        top: Int,
        canvas: Canvas,
        p: Paint
    ) {
        r.left = computeDayLeftPosition(day) - CURRENT_TIME_LINE_SIDE_BUFFER + 1
        r.right = computeDayLeftPosition(day + 1) + CURRENT_TIME_LINE_SIDE_BUFFER + 1
        r.top = top - CURRENT_TIME_LINE_TOP_OFFSET
        r.bottom = r.top + mCurrentTimeLine.getIntrinsicHeight()
        mCurrentTimeLine.setBounds(r)
        mCurrentTimeLine.draw(canvas)
        if (mAnimateToday) {
            mCurrentTimeAnimateLine.setBounds(r)
            mCurrentTimeAnimateLine.setAlpha(mAnimateTodayAlpha)
            mCurrentTimeAnimateLine.draw(canvas)
        }
    }

    private fun doDraw(canvas: Canvas) {
        val p: Paint = mPaint
        val r: Rect = mRect
        if (mFutureBgColor != 0) {
            drawBgColors(r, canvas, p)
        }
        drawGridBackground(r, canvas, p)
        drawHours(r, canvas, p)

        // Draw each day
        var cell = mFirstJulianDay
        p.setAntiAlias(false)
        val alpha: Int = p.getAlpha()
        p.setAlpha(mEventsAlpha)
        var day = 0
        while (day < mNumDays) {

            // TODO Wow, this needs cleanup. drawEvents loop through all the
            // events on every call.
            drawEvents(cell, day, HOUR_GAP, canvas, p)
            // If this is today
            if (cell == mTodayJulianDay) {
                val lineY: Int =
                    mCurrentTime!!.hour * (mCellHeight + HOUR_GAP) + mCurrentTime!!.minute *
                        mCellHeight / 60 + 1

                // And the current time shows up somewhere on the screen
                if (lineY >= mViewStartY && lineY < mViewStartY + mViewHeight - 2) {
                    drawCurrentTimeLine(r, day, lineY, canvas, p)
                }
            }
            day++
            cell++
        }
        p.setAntiAlias(true)
        p.setAlpha(alpha)
    }

    private fun drawHours(r: Rect, canvas: Canvas, p: Paint) {
        setupHourTextPaint(p)
        var y = HOUR_GAP + mHoursTextHeight + HOURS_TOP_MARGIN
        for (i in 0..23) {
            val time = mHourStrs!![i]
            canvas.drawText(time, HOURS_LEFT_MARGIN.toFloat(), y.toFloat(), p)
            y += mCellHeight + HOUR_GAP
        }
    }

    private fun setupHourTextPaint(p: Paint) {
        p.setColor(mCalendarHourLabelColor)
        p.setTextSize(HOURS_TEXT_SIZE)
        p.setTypeface(Typeface.DEFAULT)
        p.setTextAlign(Paint.Align.RIGHT)
        p.setAntiAlias(true)
    }

    private fun drawDayHeader(dayStr: String?, day: Int, cell: Int, canvas: Canvas, p: Paint) {
        var dateNum = mFirstVisibleDate + day
        var x: Int
        if (dateNum > mMonthLength) {
            dateNum -= mMonthLength
        }
        p.setAntiAlias(true)
        val todayIndex = mTodayJulianDay - mFirstJulianDay
        // Draw day of the month
        val dateNumStr: String = dateNum.toString()
        if (mNumDays > 1) {
            val y = (DAY_HEADER_HEIGHT - DAY_HEADER_BOTTOM_MARGIN).toFloat()

            // Draw day of the month
            x = computeDayLeftPosition(day + 1) - DAY_HEADER_RIGHT_MARGIN
            p.setTextAlign(Align.RIGHT)
            p.setTextSize(DATE_HEADER_FONT_SIZE)
            p.setTypeface(if (todayIndex == day) mBold else Typeface.DEFAULT)
            canvas.drawText(dateNumStr as String, x.toFloat(), y, p)

            // Draw day of the week
            x -= (p.measureText(" $dateNumStr")).toInt()
            p.setTextSize(DAY_HEADER_FONT_SIZE)
            p.setTypeface(Typeface.DEFAULT)
            canvas.drawText(dayStr as String, x.toFloat(), y, p)
        } else {
            val y = (ONE_DAY_HEADER_HEIGHT - DAY_HEADER_ONE_DAY_BOTTOM_MARGIN).toFloat()
            p.setTextAlign(Align.LEFT)

            // Draw day of the week
            x = computeDayLeftPosition(day) + DAY_HEADER_ONE_DAY_LEFT_MARGIN
            p.setTextSize(DAY_HEADER_FONT_SIZE)
            p.setTypeface(Typeface.DEFAULT)
            canvas.drawText(dayStr as String, x.toFloat(), y, p)

            // Draw day of the month
            x += (p.measureText(dayStr) + DAY_HEADER_ONE_DAY_RIGHT_MARGIN).toInt()
            p.setTextSize(DATE_HEADER_FONT_SIZE)
            p.setTypeface(if (todayIndex == day) mBold else Typeface.DEFAULT)
            canvas.drawText(dateNumStr, x.toFloat(), y, p)
        }
    }

    private fun drawGridBackground(r: Rect, canvas: Canvas, p: Paint) {
        val savedStyle: Style = p.getStyle()
        val stopX = computeDayLeftPosition(mNumDays).toFloat()
        var y = 0f
        val deltaY = (mCellHeight + HOUR_GAP).toFloat()
        var linesIndex = 0
        val startY = 0f
        val stopY = (HOUR_GAP + 24 * (mCellHeight + HOUR_GAP)).toFloat()
        var x = mHoursWidth.toFloat()

        // Draw the inner horizontal grid lines
        p.setColor(mCalendarGridLineInnerHorizontalColor)
        p.setStrokeWidth(GRID_LINE_INNER_WIDTH)
        p.setAntiAlias(false)
        y = 0f
        linesIndex = 0
        for (hour in 0..24) {
            mLines[linesIndex++] = GRID_LINE_LEFT_MARGIN
            mLines[linesIndex++] = y
            mLines[linesIndex++] = stopX
            mLines[linesIndex++] = y
            y += deltaY
        }
        if (mCalendarGridLineInnerVerticalColor != mCalendarGridLineInnerHorizontalColor) {
            canvas.drawLines(mLines, 0, linesIndex, p)
            linesIndex = 0
            p.setColor(mCalendarGridLineInnerVerticalColor)
        }

        // Draw the inner vertical grid lines
        for (day in 0..mNumDays) {
            x = computeDayLeftPosition(day).toFloat()
            mLines[linesIndex++] = x
            mLines[linesIndex++] = startY
            mLines[linesIndex++] = x
            mLines[linesIndex++] = stopY
        }
        canvas.drawLines(mLines, 0, linesIndex, p)

        // Restore the saved style.
        p.setStyle(savedStyle)
        p.setAntiAlias(true)
    }

    /**
     * @param r
     * @param canvas
     * @param p
     */
    private fun drawBgColors(r: Rect, canvas: Canvas, p: Paint) {
        val todayIndex = mTodayJulianDay - mFirstJulianDay
        // Draw the hours background color
        r.top = mDestRect.top
        r.bottom = mDestRect.bottom
        r.left = 0
        r.right = mHoursWidth
        p.setColor(mBgColor)
        p.setStyle(Style.FILL)
        p.setAntiAlias(false)
        canvas.drawRect(r, p)

        // Draw background for grid area
        if (mNumDays == 1 && todayIndex == 0) {
            // Draw a white background for the time later than current time
            var lineY: Int =
                mCurrentTime!!.hour * (mCellHeight + HOUR_GAP) + mCurrentTime!!.minute *
                    mCellHeight / 60 + 1
            if (lineY < mViewStartY + mViewHeight) {
                lineY = Math.max(lineY, mViewStartY)
                r.left = mHoursWidth
                r.right = mViewWidth
                r.top = lineY
                r.bottom = mViewStartY + mViewHeight
                p.setColor(mFutureBgColor)
                canvas.drawRect(r, p)
            }
        } else if (todayIndex >= 0 && todayIndex < mNumDays) {
            // Draw today with a white background for the time later than current time
            var lineY: Int =
                mCurrentTime!!.hour * (mCellHeight + HOUR_GAP) + mCurrentTime!!.minute *
                    mCellHeight / 60 + 1
            if (lineY < mViewStartY + mViewHeight) {
                lineY = Math.max(lineY, mViewStartY)
                r.left = computeDayLeftPosition(todayIndex) + 1
                r.right = computeDayLeftPosition(todayIndex + 1)
                r.top = lineY
                r.bottom = mViewStartY + mViewHeight
                p.setColor(mFutureBgColor)
                canvas.drawRect(r, p)
            }

            // Paint Tomorrow and later days with future color
            if (todayIndex + 1 < mNumDays) {
                r.left = computeDayLeftPosition(todayIndex + 1) + 1
                r.right = computeDayLeftPosition(mNumDays)
                r.top = mDestRect.top
                r.bottom = mDestRect.bottom
                p.setColor(mFutureBgColor)
                canvas.drawRect(r, p)
            }
        } else if (todayIndex < 0) {
            // Future
            r.left = computeDayLeftPosition(0) + 1
            r.right = computeDayLeftPosition(mNumDays)
            r.top = mDestRect.top
            r.bottom = mDestRect.bottom
            p.setColor(mFutureBgColor)
            canvas.drawRect(r, p)
        }
        p.setAntiAlias(true)
    }

    private fun computeMaxStringWidth(currentMax: Int, strings: Array<String?>, p: Paint): Int {
        var maxWidthF = 0.0f
        val len = strings.size
        for (i in 0 until len) {
            val width: Float = p.measureText(strings[i])
            maxWidthF = Math.max(width, maxWidthF)
        }
        var maxWidth = (maxWidthF + 0.5).toInt()
        if (maxWidth < currentMax) {
            maxWidth = currentMax
        }
        return maxWidth
    }

    private fun saveSelectionPosition(left: Float, top: Float, right: Float, bottom: Float) {
        mPrevBox.left = left.toInt()
        mPrevBox.right = right.toInt()
        mPrevBox.top = top.toInt()
        mPrevBox.bottom = bottom.toInt()
    }

    private fun setupTextRect(r: Rect) {
        if (r.bottom <= r.top || r.right <= r.left) {
            r.bottom = r.top
            r.right = r.left
            return
        }
        if (r.bottom - r.top > EVENT_TEXT_TOP_MARGIN + EVENT_TEXT_BOTTOM_MARGIN) {
            r.top += EVENT_TEXT_TOP_MARGIN
            r.bottom -= EVENT_TEXT_BOTTOM_MARGIN
        }
        if (r.right - r.left > EVENT_TEXT_LEFT_MARGIN + EVENT_TEXT_RIGHT_MARGIN) {
            r.left += EVENT_TEXT_LEFT_MARGIN
            r.right -= EVENT_TEXT_RIGHT_MARGIN
        }
    }

    private fun setupAllDayTextRect(r: Rect) {
        if (r.bottom <= r.top || r.right <= r.left) {
            r.bottom = r.top
            r.right = r.left
            return
        }
        if (r.bottom - r.top > EVENT_ALL_DAY_TEXT_TOP_MARGIN + EVENT_ALL_DAY_TEXT_BOTTOM_MARGIN) {
            r.top += EVENT_ALL_DAY_TEXT_TOP_MARGIN
            r.bottom -= EVENT_ALL_DAY_TEXT_BOTTOM_MARGIN
        }
        if (r.right - r.left > EVENT_ALL_DAY_TEXT_LEFT_MARGIN + EVENT_ALL_DAY_TEXT_RIGHT_MARGIN) {
            r.left += EVENT_ALL_DAY_TEXT_LEFT_MARGIN
            r.right -= EVENT_ALL_DAY_TEXT_RIGHT_MARGIN
        }
    }

    /**
     * Return the layout for a numbered event. Create it if not already existing
     */
    private fun getEventLayout(
        layouts: Array<StaticLayout?>?,
        i: Int,
        event: Event,
        paint: Paint,
        r: Rect
    ): StaticLayout? {
        if (i < 0 || i >= layouts!!.size) {
            return null
        }
        var layout: StaticLayout? = layouts!![i]
        // Check if we have already initialized the StaticLayout and that
        // the width hasn't changed (due to vertical resizing which causes
        // re-layout of events at min height)
        if (layout == null || r.width() !== layout.getWidth()) {
            val bob = SpannableStringBuilder()
            if (event.title != null) {
                // MAX - 1 since we add a space
                bob.append(drawTextSanitizer(event.title.toString(),
                    MAX_EVENT_TEXT_LEN - 1))
                bob.setSpan(StyleSpan(android.graphics.Typeface.BOLD), 0, bob.length, 0)
                bob.append(' ')
            }
            if (event.location != null) {
                bob.append(
                    drawTextSanitizer(
                        event.location.toString(),
                        MAX_EVENT_TEXT_LEN - bob.length
                    )
                )
            }
            when (event.selfAttendeeStatus) {
                Attendees.ATTENDEE_STATUS_INVITED -> paint.setColor(event.color)
                Attendees.ATTENDEE_STATUS_DECLINED -> {
                    paint.setColor(mEventTextColor)
                    paint.setAlpha(Utils.DECLINED_EVENT_TEXT_ALPHA)
                }
                Attendees.ATTENDEE_STATUS_NONE, Attendees.ATTENDEE_STATUS_ACCEPTED,
                    Attendees.ATTENDEE_STATUS_TENTATIVE -> paint.setColor(
                    mEventTextColor
                )
                else -> paint.setColor(mEventTextColor)
            }

            // Leave a one pixel boundary on the left and right of the rectangle for the event
            layout = StaticLayout(
                bob, 0, bob.length, TextPaint(paint), r.width(),
                Alignment.ALIGN_NORMAL, 1.0f, 0.0f, true, null, r.width()
            )
            layouts[i] = layout
        }
        layout.getPaint().setAlpha(mEventsAlpha)
        return layout
    }

    private fun drawAllDayEvents(firstDay: Int, numDays: Int, canvas: Canvas, p: Paint) {
        p.setTextSize(NORMAL_FONT_SIZE)
        p.setTextAlign(Paint.Align.LEFT)
        val eventTextPaint: Paint = mEventTextPaint
        val startY = DAY_HEADER_HEIGHT.toFloat()
        val stopY = startY + mAlldayHeight + ALLDAY_TOP_MARGIN
        var x = 0f
        var linesIndex = 0

        // Draw the inner vertical grid lines
        p.setColor(mCalendarGridLineInnerVerticalColor)
        x = mHoursWidth.toFloat()
        p.setStrokeWidth(GRID_LINE_INNER_WIDTH)
        // Line bounding the top of the all day area
        mLines!![linesIndex++] = GRID_LINE_LEFT_MARGIN
        mLines!![linesIndex++] = startY
        mLines!![linesIndex++] = computeDayLeftPosition(mNumDays).toFloat()
        mLines!![linesIndex++] = startY
        for (day in 0..mNumDays) {
            x = computeDayLeftPosition(day).toFloat()
            mLines!![linesIndex++] = x
            mLines!![linesIndex++] = startY
            mLines!![linesIndex++] = x
            mLines!![linesIndex++] = stopY
        }
        p.setAntiAlias(false)
        canvas.drawLines(mLines, 0, linesIndex, p)
        p.setStyle(Style.FILL)
        val y = DAY_HEADER_HEIGHT + ALLDAY_TOP_MARGIN
        val lastDay = firstDay + numDays - 1
        val events: ArrayList<Event>? = mAllDayEvents
        val numEvents: Int = events!!.size
        // Whether or not we should draw the more events text
        var hasMoreEvents = false
        // size of the allDay area
        val drawHeight = mAlldayHeight.toFloat()
        // max number of events being drawn in one day of the allday area
        var numRectangles = mMaxAlldayEvents.toFloat()
        // Where to cut off drawn allday events
        var allDayEventClip = DAY_HEADER_HEIGHT + mAlldayHeight + ALLDAY_TOP_MARGIN
        // The number of events that weren't drawn in each day
        mSkippedAlldayEvents = IntArray(numDays)
        if (mMaxAlldayEvents > mMaxUnexpandedAlldayEventCount &&
            !mShowAllAllDayEvents && mAnimateDayHeight == 0) {
            // We draw one fewer event than will fit so that more events text
            // can be drawn
            numRectangles = (mMaxUnexpandedAlldayEventCount - 1).toFloat()
            // We also clip the events above the more events text
            allDayEventClip -= MIN_UNEXPANDED_ALLDAY_EVENT_HEIGHT.toInt()
            hasMoreEvents = true
        } else if (mAnimateDayHeight != 0) {
            // clip at the end of the animating space
            allDayEventClip = DAY_HEADER_HEIGHT + mAnimateDayHeight + ALLDAY_TOP_MARGIN
        }
        var alpha: Int = eventTextPaint.getAlpha()
        eventTextPaint.setAlpha(mEventsAlpha)
        for (i in 0 until numEvents) {
            val event: Event = events!!.get(i)
            var startDay: Int = event.startDay
            var endDay: Int = event.endDay
            if (startDay > lastDay || endDay < firstDay) {
                continue
            }
            if (startDay < firstDay) {
                startDay = firstDay
            }
            if (endDay > lastDay) {
                endDay = lastDay
            }
            val startIndex = startDay - firstDay
            val endIndex = endDay - firstDay
            var height =
                if (mMaxAlldayEvents > mMaxUnexpandedAlldayEventCount)
                    mAnimateDayEventHeight.toFloat() else drawHeight / numRectangles

            // Prevent a single event from getting too big
            if (height > MAX_HEIGHT_OF_ONE_ALLDAY_EVENT) {
                height = MAX_HEIGHT_OF_ONE_ALLDAY_EVENT.toFloat()
            }

            // Leave a one-pixel space between the vertical day lines and the
            // event rectangle.
            event.left = computeDayLeftPosition(startIndex).toFloat()
            event.right = computeDayLeftPosition(endIndex + 1).toFloat() - DAY_GAP
            event.top = y + height * event.getColumn()
            event.bottom = event.top + height - ALL_DAY_EVENT_RECT_BOTTOM_MARGIN
            if (mMaxAlldayEvents > mMaxUnexpandedAlldayEventCount) {
                // check if we should skip this event. We skip if it starts
                // after the clip bound or ends after the skip bound and we're
                // not animating.
                if (event.top >= allDayEventClip) {
                    incrementSkipCount(mSkippedAlldayEvents, startIndex, endIndex)
                    continue
                } else if (event.bottom > allDayEventClip) {
                    if (hasMoreEvents) {
                        incrementSkipCount(mSkippedAlldayEvents, startIndex, endIndex)
                        continue
                    }
                    event.bottom = allDayEventClip.toFloat()
                }
            }
            val r: Rect = drawEventRect(
                event, canvas, p, eventTextPaint, event.top.toInt(),
                event.bottom.toInt()
            )
            setupAllDayTextRect(r)
            val layout: StaticLayout? = getEventLayout(mAllDayLayouts, i, event, eventTextPaint, r)
            drawEventText(layout, r, canvas, r.top, r.bottom, true)

            // Check if this all-day event intersects the selected day
            if (mSelectionAllday && mComputeSelectedEvents) {
                if (startDay <= mSelectionDay && endDay >= mSelectionDay) {
                    mSelectedEvents.add(event)
                }
            }
        }
        eventTextPaint.setAlpha(alpha)
        if (mMoreAlldayEventsTextAlpha != 0 && mSkippedAlldayEvents != null) {
            // If the more allday text should be visible, draw it.
            alpha = p.getAlpha()
            p.setAlpha(mEventsAlpha)
            p.setColor(mMoreAlldayEventsTextAlpha shl 24 and mMoreEventsTextColor)
            for (i in mSkippedAlldayEvents!!.indices) {
                if (mSkippedAlldayEvents!![i] > 0) {
                    drawMoreAlldayEvents(canvas, mSkippedAlldayEvents!![i], i, p)
                }
            }
            p.setAlpha(alpha)
        }
        if (mSelectionAllday) {
            // Compute the neighbors for the list of all-day events that
            // intersect the selected day.
            computeAllDayNeighbors()

            // Set the selection position to zero so that when we move down
            // to the normal event area, we will highlight the topmost event.
            saveSelectionPosition(0f, 0f, 0f, 0f)
        }
    }

    // Helper method for counting the number of allday events skipped on each day
    private fun incrementSkipCount(counts: IntArray?, startIndex: Int, endIndex: Int) {
        if (counts == null || startIndex < 0 || endIndex > counts.size) {
            return
        }
        for (i in startIndex..endIndex) {
            counts[i]++
        }
    }

    // Draws the "box +n" text for hidden allday events
    protected fun drawMoreAlldayEvents(canvas: Canvas, remainingEvents: Int, day: Int, p: Paint) {
        var x = computeDayLeftPosition(day) + EVENT_ALL_DAY_TEXT_LEFT_MARGIN
        var y = (mAlldayHeight - .5f * MIN_UNEXPANDED_ALLDAY_EVENT_HEIGHT - (.5f *
            EVENT_SQUARE_WIDTH) + DAY_HEADER_HEIGHT + ALLDAY_TOP_MARGIN).toInt()
        val r: Rect = mRect
        r.top = y
        r.left = x
        r.bottom = y + EVENT_SQUARE_WIDTH
        r.right = x + EVENT_SQUARE_WIDTH
        p.setColor(mMoreEventsTextColor)
        p.setStrokeWidth(EVENT_RECT_STROKE_WIDTH.toFloat())
        p.setStyle(Style.STROKE)
        p.setAntiAlias(false)
        canvas.drawRect(r, p)
        p.setAntiAlias(true)
        p.setStyle(Style.FILL)
        p.setTextSize(EVENT_TEXT_FONT_SIZE)
        val text: String =
            mResources.getQuantityString(R.plurals.month_more_events, remainingEvents)
        y += EVENT_SQUARE_WIDTH
        x += EVENT_SQUARE_WIDTH + EVENT_LINE_PADDING
        canvas.drawText(String.format(text, remainingEvents), x.toFloat(), y.toFloat(), p)
    }

    private fun computeAllDayNeighbors() {
        val len: Int = mSelectedEvents.size
        if (len == 0 || mSelectedEvent != null) {
            return
        }

        // First, clear all the links
        for (ii in 0 until len) {
            val ev: Event = mSelectedEvents.get(ii)
            ev.nextUp = null
            ev.nextDown = null
            ev.nextLeft = null
            ev.nextRight = null
        }

        // For each event in the selected event list "mSelectedEvents", find
        // its neighbors in the up and down directions. This could be done
        // more efficiently by sorting on the Event.getColumn() field, but
        // the list is expected to be very small.

        // Find the event in the same row as the previously selected all-day
        // event, if any.
        var startPosition = -1
        if (mPrevSelectedEvent != null && mPrevSelectedEvent!!.drawAsAllday()) {
            startPosition = mPrevSelectedEvent?.getColumn() as Int
        }
        var maxPosition = -1
        var startEvent: Event? = null
        var maxPositionEvent: Event? = null
        for (ii in 0 until len) {
            val ev: Event = mSelectedEvents.get(ii)
            val position: Int = ev.getColumn()
            if (position == startPosition) {
                startEvent = ev
            } else if (position > maxPosition) {
                maxPositionEvent = ev
                maxPosition = position
            }
            for (jj in 0 until len) {
                if (jj == ii) {
                    continue
                }
                val neighbor: Event = mSelectedEvents.get(jj)
                val neighborPosition: Int = neighbor.getColumn()
                if (neighborPosition == position - 1) {
                    ev.nextUp = neighbor
                } else if (neighborPosition == position + 1) {
                    ev.nextDown = neighbor
                }
            }
        }
        if (startEvent != null) {
            setSelectedEvent(startEvent)
        } else {
            setSelectedEvent(maxPositionEvent)
        }
    }

    private fun drawEvents(date: Int, dayIndex: Int, top: Int, canvas: Canvas, p: Paint) {
        val eventTextPaint: Paint = mEventTextPaint
        val left = computeDayLeftPosition(dayIndex) + 1
        val cellWidth = computeDayLeftPosition(dayIndex + 1) - left + 1
        val cellHeight = mCellHeight

        // Use the selected hour as the selection region
        val selectionArea: Rect = mSelectionRect
        selectionArea.top = top + mSelectionHour * (cellHeight + HOUR_GAP)
        selectionArea.bottom = selectionArea.top + cellHeight
        selectionArea.left = left
        selectionArea.right = selectionArea.left + cellWidth
        val events: ArrayList<Event> = mEvents
        val numEvents: Int = events.size
        val geometry: EventGeometry = mEventGeometry
        val viewEndY = mViewStartY + mViewHeight - DAY_HEADER_HEIGHT - mAlldayHeight
        val alpha: Int = eventTextPaint.getAlpha()
        eventTextPaint.setAlpha(mEventsAlpha)
        for (i in 0 until numEvents) {
            val event: Event = events.get(i)
            if (!geometry.computeEventRect(date, left, top, cellWidth, event)) {
                continue
            }

            // Don't draw it if it is not visible
            if (event.bottom < mViewStartY || event.top > viewEndY) {
                continue
            }
            if (date == mSelectionDay && !mSelectionAllday && mComputeSelectedEvents &&
                geometry.eventIntersectsSelection(event, selectionArea)
            ) {
                mSelectedEvents.add(event)
            }
            val r: Rect = drawEventRect(event, canvas, p, eventTextPaint, mViewStartY, viewEndY)
            setupTextRect(r)

            // Don't draw text if it is not visible
            if (r.top > viewEndY || r.bottom < mViewStartY) {
                continue
            }
            val layout: StaticLayout? = getEventLayout(mLayouts, i, event, eventTextPaint, r)
            // TODO: not sure why we are 4 pixels off
            drawEventText(
                layout,
                r,
                canvas,
                mViewStartY + 4,
                mViewStartY + mViewHeight - DAY_HEADER_HEIGHT - mAlldayHeight,
                false
            )
        }
        eventTextPaint.setAlpha(alpha)
    }

    private fun drawEventRect(
        event: Event,
        canvas: Canvas,
        p: Paint,
        eventTextPaint: Paint,
        visibleTop: Int,
        visibleBot: Int
    ): Rect {
        // Draw the Event Rect
        val r: Rect = mRect
        r.top = Math.max(event.top.toInt() + EVENT_RECT_TOP_MARGIN, visibleTop)
        r.bottom = Math.min(event.bottom.toInt() - EVENT_RECT_BOTTOM_MARGIN, visibleBot)
        r.left = event.left.toInt() + EVENT_RECT_LEFT_MARGIN
        r.right = event.right.toInt()
        var color: Int = event.color
        when (event.selfAttendeeStatus) {
            Attendees.ATTENDEE_STATUS_INVITED -> if (event !== mClickedEvent) {
                p.setStyle(Style.STROKE)
            }
            Attendees.ATTENDEE_STATUS_DECLINED -> {
                if (event !== mClickedEvent) {
                    color = Utils.getDeclinedColorFromColor(color)
                }
                p.setStyle(Style.FILL_AND_STROKE)
            }
            Attendees.ATTENDEE_STATUS_NONE, Attendees.ATTENDEE_STATUS_ACCEPTED,
                Attendees.ATTENDEE_STATUS_TENTATIVE -> p.setStyle(
                Style.FILL_AND_STROKE
            )
            else -> p.setStyle(Style.FILL_AND_STROKE)
        }
        p.setAntiAlias(false)
        val floorHalfStroke = Math.floor(EVENT_RECT_STROKE_WIDTH.toDouble() / 2.0).toInt()
        val ceilHalfStroke = Math.ceil(EVENT_RECT_STROKE_WIDTH.toDouble() / 2.0).toInt()
        r.top = Math.max(event.top.toInt() + EVENT_RECT_TOP_MARGIN + floorHalfStroke, visibleTop)
        r.bottom = Math.min(
            event.bottom.toInt() - EVENT_RECT_BOTTOM_MARGIN - ceilHalfStroke,
            visibleBot
        )
        r.left += floorHalfStroke
        r.right -= ceilHalfStroke
        p.setStrokeWidth(EVENT_RECT_STROKE_WIDTH.toFloat())
        p.setColor(color)
        val alpha: Int = p.getAlpha()
        p.setAlpha(mEventsAlpha)
        canvas.drawRect(r, p)
        p.setAlpha(alpha)
        p.setStyle(Style.FILL)

        // Setup rect for drawEventText which follows
        r.top = event.top.toInt() + EVENT_RECT_TOP_MARGIN
        r.bottom = event.bottom.toInt() - EVENT_RECT_BOTTOM_MARGIN
        r.left = event.left.toInt() + EVENT_RECT_LEFT_MARGIN
        r.right = event.right.toInt() - EVENT_RECT_RIGHT_MARGIN
        return r
    }

    private val drawTextSanitizerFilter: Pattern = Pattern.compile("[\t\n],")

    // Sanitize a string before passing it to drawText or else we get little
    // squares. For newlines and tabs before a comma, delete the character.
    // Otherwise, just replace them with a space.
    private fun drawTextSanitizer(string: String, maxEventTextLen: Int): String {
        var string = string
        val m: Matcher = drawTextSanitizerFilter.matcher(string)
        string = m.replaceAll(",")
        var len: Int = string.length
        if (maxEventTextLen <= 0) {
            string = ""
            len = 0
        } else if (len > maxEventTextLen) {
            string = string.substring(0, maxEventTextLen)
            len = maxEventTextLen
        }
        return string.replace('\n', ' ')
    }

    private fun drawEventText(
        eventLayout: StaticLayout?,
        rect: Rect,
        canvas: Canvas,
        top: Int,
        bottom: Int,
        center: Boolean
    ) {
        // drawEmptyRect(canvas, rect, 0xFFFF00FF); // for debugging
        val width: Int = rect.right - rect.left
        val height: Int = rect.bottom - rect.top

        // If the rectangle is too small for text, then return
        if (eventLayout == null || width < MIN_CELL_WIDTH_FOR_TEXT) {
            return
        }
        var totalLineHeight = 0
        val lineCount: Int = eventLayout.getLineCount()
        for (i in 0 until lineCount) {
            val lineBottom: Int = eventLayout.getLineBottom(i)
            totalLineHeight = if (lineBottom <= height) {
                lineBottom
            } else {
                break
            }
        }

        // + 2 is small workaround when the font is slightly bigger than the rect. This will
        // still allow the text to be shown without overflowing into the other all day rects.
        if (totalLineHeight == 0 || rect.top > bottom || rect.top + totalLineHeight + 2 < top) {
            return
        }

        // Use a StaticLayout to format the string.
        canvas.save()
        //  canvas.translate(rect.left, rect.top + (rect.bottom - rect.top / 2));
        val padding = if (center) (rect.bottom - rect.top - totalLineHeight) / 2 else 0
        canvas.translate(rect.left.toFloat(), rect.top.toFloat() + padding)
        rect.left = 0
        rect.right = width
        rect.top = 0
        rect.bottom = totalLineHeight

        // There's a bug somewhere. If this rect is outside of a previous
        // cliprect, this becomes a no-op. What happens is that the text draw
        // past the event rect. The current fix is to not draw the staticLayout
        // at all if it is completely out of bound.
        canvas.clipRect(rect)
        eventLayout.draw(canvas)
        canvas.restore()
    }

    // The following routines are called from the parent activity when certain
    // touch events occur.
    private fun doDown(ev: MotionEvent) {
        mTouchMode = TOUCH_MODE_DOWN
        mViewStartX = 0
        mOnFlingCalled = false
        mHandler?.removeCallbacks(mContinueScroll)
        val x = ev.getX().toInt()
        val y = ev.getY().toInt()

        // Save selection information: we use setSelectionFromPosition to find the selected event
        // in order to show the "clicked" color. But since it is also setting the selected info
        // for new events, we need to restore the old info after calling the function.
        val oldSelectedEvent: Event? = mSelectedEvent
        val oldSelectionDay = mSelectionDay
        val oldSelectionHour = mSelectionHour
        if (setSelectionFromPosition(x, y, false)) {
            // If a time was selected (a blue selection box is visible) and the click location
            // is in the selected time, do not show a click on an event to prevent a situation
            // of both a selection and an event are clicked when they overlap.
            val pressedSelected = (mSelectionMode != SELECTION_HIDDEN &&
                oldSelectionDay == mSelectionDay && oldSelectionHour == mSelectionHour)
            if (!pressedSelected && mSelectedEvent != null) {
                mSavedClickedEvent = mSelectedEvent
                mDownTouchTime = System.currentTimeMillis()
                postDelayed(mSetClick, mOnDownDelay.toLong())
            } else {
                eventClickCleanup()
            }
        }
        mSelectedEvent = oldSelectedEvent
        mSelectionDay = oldSelectionDay
        mSelectionHour = oldSelectionHour
        invalidate()
    }

    // Kicks off all the animations when the expand allday area is tapped
    private fun doExpandAllDayClick() {
        mShowAllAllDayEvents = !mShowAllAllDayEvents
        ObjectAnimator.setFrameDelay(0)

        // Determine the starting height
        if (mAnimateDayHeight == 0) {
            mAnimateDayHeight =
                if (mShowAllAllDayEvents) mAlldayHeight - MIN_UNEXPANDED_ALLDAY_EVENT_HEIGHT.toInt()
                else mAlldayHeight
        }
        // Cancel current animations
        mCancellingAnimations = true
        if (mAlldayAnimator != null) {
            mAlldayAnimator?.cancel()
        }
        if (mAlldayEventAnimator != null) {
            mAlldayEventAnimator?.cancel()
        }
        if (mMoreAlldayEventsAnimator != null) {
            mMoreAlldayEventsAnimator?.cancel()
        }
        mCancellingAnimations = false
        // get new animators
        mAlldayAnimator = allDayAnimator
        mAlldayEventAnimator = allDayEventAnimator
        mMoreAlldayEventsAnimator = ObjectAnimator.ofInt(
            this,
            "moreAllDayEventsTextAlpha",
            if (mShowAllAllDayEvents) MORE_EVENTS_MAX_ALPHA else 0,
            if (mShowAllAllDayEvents) 0 else MORE_EVENTS_MAX_ALPHA
        )

        // Set up delays and start the animators
        mAlldayAnimator?.setStartDelay(if (mShowAllAllDayEvents) ANIMATION_SECONDARY_DURATION
            else 0)
        mAlldayAnimator?.start()
        mMoreAlldayEventsAnimator?.setStartDelay(if (mShowAllAllDayEvents) 0
            else ANIMATION_DURATION)
        mMoreAlldayEventsAnimator?.setDuration(ANIMATION_SECONDARY_DURATION)
        mMoreAlldayEventsAnimator?.start()
        if (mAlldayEventAnimator != null) {
            // This is the only animator that can return null, so check it
            mAlldayEventAnimator
                ?.setStartDelay(if (mShowAllAllDayEvents) ANIMATION_SECONDARY_DURATION else 0)
            mAlldayEventAnimator?.start()
        }
    }

    /**
     * Figures out the initial heights for allDay events and space when
     * a view is being set up.
     */
    fun initAllDayHeights() {
        if (mMaxAlldayEvents <= mMaxUnexpandedAlldayEventCount) {
            return
        }
        if (mShowAllAllDayEvents) {
            var maxADHeight = mViewHeight - DAY_HEADER_HEIGHT - MIN_HOURS_HEIGHT
            maxADHeight = Math.min(
                maxADHeight,
                (mMaxAlldayEvents * MIN_UNEXPANDED_ALLDAY_EVENT_HEIGHT).toInt()
            )
            mAnimateDayEventHeight = maxADHeight / mMaxAlldayEvents
        } else {
            mAnimateDayEventHeight = MIN_UNEXPANDED_ALLDAY_EVENT_HEIGHT.toInt()
        }
    } // First calculate the absolute max height
    // Now expand to fit but not beyond the absolute max
    // calculate the height of individual events in order to fit
    // if there's nothing to animate just return

    // Set up the animator with the calculated values
    // Sets up an animator for changing the height of allday events
    private val allDayEventAnimator: ObjectAnimator?
        private get() {
            // First calculate the absolute max height
            var maxADHeight = mViewHeight - DAY_HEADER_HEIGHT - MIN_HOURS_HEIGHT
            // Now expand to fit but not beyond the absolute max
            maxADHeight = Math.min(
                maxADHeight,
                (mMaxAlldayEvents * MIN_UNEXPANDED_ALLDAY_EVENT_HEIGHT).toInt()
            )
            // calculate the height of individual events in order to fit
            val fitHeight = maxADHeight / mMaxAlldayEvents
            val currentHeight = mAnimateDayEventHeight
            val desiredHeight =
                if (mShowAllAllDayEvents) fitHeight else MIN_UNEXPANDED_ALLDAY_EVENT_HEIGHT.toInt()
            // if there's nothing to animate just return
            if (currentHeight == desiredHeight) {
                return null
            }

            // Set up the animator with the calculated values
            val animator: ObjectAnimator = ObjectAnimator.ofInt(
                this, "animateDayEventHeight",
                currentHeight, desiredHeight
            )
            animator.setDuration(ANIMATION_DURATION)
            return animator
        }

    // Set up the animator with the calculated values
    // Sets up an animator for changing the height of the allday area
    private val allDayAnimator: ObjectAnimator
        private get() {
            // Calculate the absolute max height
            var maxADHeight = mViewHeight - DAY_HEADER_HEIGHT - MIN_HOURS_HEIGHT
            // Find the desired height but don't exceed abs max
            maxADHeight = Math.min(
                maxADHeight,
                (mMaxAlldayEvents * MIN_UNEXPANDED_ALLDAY_EVENT_HEIGHT).toInt()
            )
            // calculate the current and desired heights
            val currentHeight = if (mAnimateDayHeight != 0) mAnimateDayHeight else mAlldayHeight
            val desiredHeight =
                if (mShowAllAllDayEvents) maxADHeight else (MAX_UNEXPANDED_ALLDAY_HEIGHT -
                    MIN_UNEXPANDED_ALLDAY_EVENT_HEIGHT - 1).toInt()

            // Set up the animator with the calculated values
            val animator: ObjectAnimator = ObjectAnimator.ofInt(
                this, "animateDayHeight",
                currentHeight, desiredHeight
            )
            animator.setDuration(ANIMATION_DURATION)
            animator.addListener(object : AnimatorListenerAdapter() {
                @Override
                override fun onAnimationEnd(animation: Animator?) {
                    if (!mCancellingAnimations) {
                        // when finished, set this to 0 to signify not animating
                        mAnimateDayHeight = 0
                        mUseExpandIcon = !mShowAllAllDayEvents
                    }
                    mRemeasure = true
                    invalidate()
                }
            })
            return animator
        }

    // setter for the 'box +n' alpha text used by the animator
    fun setMoreAllDayEventsTextAlpha(alpha: Int) {
        mMoreAlldayEventsTextAlpha = alpha
        invalidate()
    }

    // setter for the height of the allday area used by the animator
    fun setAnimateDayHeight(height: Int) {
        mAnimateDayHeight = height
        mRemeasure = true
        invalidate()
    }

    // setter for the height of allday events used by the animator
    fun setAnimateDayEventHeight(height: Int) {
        mAnimateDayEventHeight = height
        mRemeasure = true
        invalidate()
    }

    private fun doSingleTapUp(ev: MotionEvent) {
        if (!mHandleActionUp || mScrolling) {
            return
        }
        val x = ev.getX().toInt()
        val y = ev.getY().toInt()
        val selectedDay = mSelectionDay
        val selectedHour = mSelectionHour
        if (mMaxAlldayEvents > mMaxUnexpandedAlldayEventCount) {
            // check if the tap was in the allday expansion area
            val bottom = mFirstCell
            if (x < mHoursWidth && y > DAY_HEADER_HEIGHT && y < DAY_HEADER_HEIGHT + mAlldayHeight ||
                !mShowAllAllDayEvents && mAnimateDayHeight == 0 && y < bottom && y >= bottom -
                MIN_UNEXPANDED_ALLDAY_EVENT_HEIGHT
            ) {
                doExpandAllDayClick()
                return
            }
        }
        val validPosition = setSelectionFromPosition(x, y, false)
        if (!validPosition) {
            if (y < DAY_HEADER_HEIGHT) {
                val selectedTime = Time(mBaseDate)
                selectedTime.setJulianDay(mSelectionDay)
                selectedTime.hour = mSelectionHour
                selectedTime.normalize(true /* ignore isDst */)
                mController.sendEvent(
                    this as? Object, EventType.GO_TO, null, null, selectedTime, -1,
                    ViewType.DAY, CalendarController.EXTRA_GOTO_DATE, null, null
                )
            }
            return
        }
        val hasSelection = mSelectionMode != SELECTION_HIDDEN
        val pressedSelected = ((hasSelection || mTouchExplorationEnabled) &&
            selectedDay == mSelectionDay && selectedHour == mSelectionHour)
        if (mSelectedEvent != null) {
            // If the tap is on an event, launch the "View event" view
            if (mIsAccessibilityEnabled) {
                mAccessibilityMgr?.interrupt()
            }
            mSelectionMode = SELECTION_HIDDEN
            var yLocation = ((mSelectedEvent!!.top + mSelectedEvent!!.bottom) / 2) as Int
            // Y location is affected by the position of the event in the scrolling
            // view (mViewStartY) and the presence of all day events (mFirstCell)
            if (!mSelectedEvent!!.allDay) {
                yLocation += mFirstCell - mViewStartY
            }
            mClickedYLocation = yLocation
            val clearDelay: Long = CLICK_DISPLAY_DURATION + mOnDownDelay -
                (System.currentTimeMillis() - mDownTouchTime)
            if (clearDelay > 0) {
                this.postDelayed(mClearClick, clearDelay)
            } else {
                this.post(mClearClick)
            }
        }
        invalidate()
    }

    private fun doLongPress(ev: MotionEvent) {
        eventClickCleanup()
        if (mScrolling) {
            return
        }

        // Scale gesture in progress
        if (mStartingSpanY != 0f) {
            return
        }
        val x = ev.getX().toInt()
        val y = ev.getY().toInt()
        val validPosition = setSelectionFromPosition(x, y, false)
        if (!validPosition) {
            // return if the touch wasn't on an area of concern
            return
        }
        invalidate()
        performLongClick()
    }

    private fun doScroll(e1: MotionEvent, e2: MotionEvent, deltaX: Float, deltaY: Float) {
        cancelAnimation()
        if (mStartingScroll) {
            mInitialScrollX = 0f
            mInitialScrollY = 0f
            mStartingScroll = false
        }
        mInitialScrollX += deltaX
        mInitialScrollY += deltaY
        val distanceX = mInitialScrollX.toInt()
        val distanceY = mInitialScrollY.toInt()
        val focusY = getAverageY(e2)
        if (mRecalCenterHour) {
            // Calculate the hour that correspond to the average of the Y touch points
            mGestureCenterHour = ((mViewStartY + focusY - DAY_HEADER_HEIGHT - mAlldayHeight) /
                (mCellHeight + DAY_GAP))
            mRecalCenterHour = false
        }

        // If we haven't figured out the predominant scroll direction yet,
        // then do it now.
        if (mTouchMode == TOUCH_MODE_DOWN) {
            val absDistanceX: Int = Math.abs(distanceX)
            val absDistanceY: Int = Math.abs(distanceY)
            mScrollStartY = mViewStartY
            mPreviousDirection = 0
            if (absDistanceX > absDistanceY) {
                val slopFactor = if (mScaleGestureDetector.isInProgress()) 20 else 2
                if (absDistanceX > mScaledPagingTouchSlop * slopFactor) {
                    mTouchMode = TOUCH_MODE_HSCROLL
                    mViewStartX = distanceX
                    initNextView(-mViewStartX)
                }
            } else {
                mTouchMode = TOUCH_MODE_VSCROLL
            }
        } else if (mTouchMode and TOUCH_MODE_HSCROLL != 0) {
            // We are already scrolling horizontally, so check if we
            // changed the direction of scrolling so that the other week
            // is now visible.
            mViewStartX = distanceX
            if (distanceX != 0) {
                val direction = if (distanceX > 0) 1 else -1
                if (direction != mPreviousDirection) {
                    // The user has switched the direction of scrolling
                    // so re-init the next view
                    initNextView(-mViewStartX)
                    mPreviousDirection = direction
                }
            }
        }
        if (mTouchMode and TOUCH_MODE_VSCROLL != 0) {
            // Calculate the top of the visible region in the calendar grid.
            // Increasing/decrease this will scroll the calendar grid up/down.
            mViewStartY = ((mGestureCenterHour * (mCellHeight + DAY_GAP) -
                focusY) + DAY_HEADER_HEIGHT + mAlldayHeight).toInt()

            // If dragging while already at the end, do a glow
            val pulledToY = (mScrollStartY + deltaY).toInt()
            if (pulledToY < 0) {
                mEdgeEffectTop.onPull(deltaY / mViewHeight)
                if (!mEdgeEffectBottom.isFinished()) {
                    mEdgeEffectBottom.onRelease()
                }
            } else if (pulledToY > mMaxViewStartY) {
                mEdgeEffectBottom.onPull(deltaY / mViewHeight)
                if (!mEdgeEffectTop.isFinished()) {
                    mEdgeEffectTop.onRelease()
                }
            }
            if (mViewStartY < 0) {
                mViewStartY = 0
                mRecalCenterHour = true
            } else if (mViewStartY > mMaxViewStartY) {
                mViewStartY = mMaxViewStartY
                mRecalCenterHour = true
            }
            if (mRecalCenterHour) {
                // Calculate the hour that correspond to the average of the Y touch points
                mGestureCenterHour = ((mViewStartY + focusY - DAY_HEADER_HEIGHT - mAlldayHeight) /
                    (mCellHeight + DAY_GAP))
                mRecalCenterHour = false
            }
            computeFirstHour()
        }
        mScrolling = true
        mSelectionMode = SELECTION_HIDDEN
        invalidate()
    }

    private fun getAverageY(me: MotionEvent): Float {
        val count: Int = me.getPointerCount()
        var focusY = 0f
        for (i in 0 until count) {
            focusY += me.getY(i)
        }
        focusY /= count.toFloat()
        return focusY
    }

    private fun cancelAnimation() {
        val `in`: Animation? = mViewSwitcher?.getInAnimation()
        if (`in` != null) {
            // cancel() doesn't terminate cleanly.
            `in`?.scaleCurrentDuration(0f)
        }
        val out: Animation? = mViewSwitcher?.getOutAnimation()
        if (out != null) {
            // cancel() doesn't terminate cleanly.
            out?.scaleCurrentDuration(0f)
        }
    }

    private fun doFling(e1: MotionEvent, e2: MotionEvent, velocityX: Float, velocityY: Float) {
        cancelAnimation()
        mSelectionMode = SELECTION_HIDDEN
        eventClickCleanup()
        mOnFlingCalled = true
        if (mTouchMode and TOUCH_MODE_HSCROLL != 0) {
            // Horizontal fling.
            // initNextView(deltaX);
            mTouchMode = TOUCH_MODE_INITIAL_STATE
            if (DEBUG) Log.d(TAG, "doFling: velocityX $velocityX")
            val deltaX = e2.getX().toInt() - e1.getX().toInt()
            switchViews(deltaX < 0, mViewStartX.toFloat(), mViewWidth.toFloat(), velocityX)
            mViewStartX = 0
            return
        }
        if (mTouchMode and TOUCH_MODE_VSCROLL == 0) {
            if (DEBUG) Log.d(TAG, "doFling: no fling")
            return
        }

        // Vertical fling.
        mTouchMode = TOUCH_MODE_INITIAL_STATE
        mViewStartX = 0
        if (DEBUG) {
            Log.d(TAG, "doFling: mViewStartY$mViewStartY velocityY $velocityY")
        }

        // Continue scrolling vertically
        mScrolling = true
        mScroller.fling(
            0 /* startX */, mViewStartY /* startY */, 0 /* velocityX */,
            (-velocityY).toInt(), 0 /* minX */, 0 /* maxX */, 0 /* minY */,
            mMaxViewStartY /* maxY */, OVERFLING_DISTANCE, OVERFLING_DISTANCE
        )

        // When flinging down, show a glow when it hits the end only if it
        // wasn't started at the top
        if (velocityY > 0 && mViewStartY != 0) {
            mCallEdgeEffectOnAbsorb = true
        } else if (velocityY < 0 && mViewStartY != mMaxViewStartY) {
            mCallEdgeEffectOnAbsorb = true
        }
        mHandler?.post(mContinueScroll)
    }

    private fun initNextView(deltaX: Int): Boolean {
        // Change the view to the previous day or week
        val view = mViewSwitcher.getNextView() as DayView
        val date: Time? = view.mBaseDate
        date?.set(mBaseDate)
        val switchForward: Boolean
        if (deltaX > 0) {
            date!!.monthDay -= mNumDays
            view.setSelectedDay(mSelectionDay - mNumDays)
            switchForward = false
        } else {
            date!!.monthDay += mNumDays
            view.setSelectedDay(mSelectionDay + mNumDays)
            switchForward = true
        }
        date?.normalize(true /* ignore isDst */)
        initView(view)
        view.layout(getLeft(), getTop(), getRight(), getBottom())
        view.reloadEvents()
        return switchForward
    }

    // ScaleGestureDetector.OnScaleGestureListener
    override fun onScaleBegin(detector: ScaleGestureDetector): Boolean {
        mHandleActionUp = false
        val gestureCenterInPixels: Float = detector.getFocusY() - DAY_HEADER_HEIGHT - mAlldayHeight
        mGestureCenterHour = (mViewStartY + gestureCenterInPixels) / (mCellHeight + DAY_GAP)
        mStartingSpanY = Math.max(MIN_Y_SPAN.toFloat(),
            Math.abs(detector.getCurrentSpanY().toFloat()))
        mCellHeightBeforeScaleGesture = mCellHeight
        if (DEBUG_SCALING) {
            val ViewStartHour = mViewStartY / (mCellHeight + DAY_GAP).toFloat()
            Log.d(
                TAG, "onScaleBegin: mGestureCenterHour:" + mGestureCenterHour +
                    "\tViewStartHour: " + ViewStartHour + "\tmViewStartY:" + mViewStartY +
                    "\tmCellHeight:" + mCellHeight + " SpanY:" + detector.getCurrentSpanY()
            )
        }
        return true
    }

    // ScaleGestureDetector.OnScaleGestureListener
    override fun onScale(detector: ScaleGestureDetector): Boolean {
        val spanY: Float = Math.max(MIN_Y_SPAN.toFloat(),
            Math.abs(detector.getCurrentSpanY().toFloat()))
        mCellHeight = (mCellHeightBeforeScaleGesture * spanY / mStartingSpanY).toInt()
        if (mCellHeight < mMinCellHeight) {
            // If mStartingSpanY is too small, even a small increase in the
            // gesture can bump the mCellHeight beyond MAX_CELL_HEIGHT
            mStartingSpanY = spanY
            mCellHeight = mMinCellHeight
            mCellHeightBeforeScaleGesture = mMinCellHeight
        } else if (mCellHeight > MAX_CELL_HEIGHT) {
            mStartingSpanY = spanY
            mCellHeight = MAX_CELL_HEIGHT
            mCellHeightBeforeScaleGesture = MAX_CELL_HEIGHT
        }
        val gestureCenterInPixels = detector.getFocusY().toInt() - DAY_HEADER_HEIGHT - mAlldayHeight
        mViewStartY = (mGestureCenterHour * (mCellHeight + DAY_GAP)).toInt() - gestureCenterInPixels
        mMaxViewStartY = HOUR_GAP + 24 * (mCellHeight + HOUR_GAP) - mGridAreaHeight
        if (DEBUG_SCALING) {
            val ViewStartHour = mViewStartY / (mCellHeight + DAY_GAP).toFloat()
            Log.d(
                TAG, "onScale: mGestureCenterHour:" + mGestureCenterHour + "\tViewStartHour: " +
                    ViewStartHour + "\tmViewStartY:" + mViewStartY + "\tmCellHeight:" +
                    mCellHeight + " SpanY:" + detector.getCurrentSpanY()
            )
        }
        if (mViewStartY < 0) {
            mViewStartY = 0
            mGestureCenterHour = ((mViewStartY + gestureCenterInPixels) /
                (mCellHeight + DAY_GAP).toFloat())
        } else if (mViewStartY > mMaxViewStartY) {
            mViewStartY = mMaxViewStartY
            mGestureCenterHour = ((mViewStartY + gestureCenterInPixels) /
                (mCellHeight + DAY_GAP).toFloat())
        }
        computeFirstHour()
        mRemeasure = true
        invalidate()
        return true
    }

    // ScaleGestureDetector.OnScaleGestureListener
    override fun onScaleEnd(detector: ScaleGestureDetector?) {
        mScrollStartY = mViewStartY
        mInitialScrollY = 0f
        mInitialScrollX = 0f
        mStartingSpanY = 0f
    }

    @Override
    override fun onTouchEvent(ev: MotionEvent): Boolean {
        val action: Int = ev.getAction()
        if (DEBUG) Log.e(TAG, "" + action + " ev.getPointerCount() = " + ev.getPointerCount())
        if (ev.getActionMasked() === MotionEvent.ACTION_DOWN ||
            ev.getActionMasked() === MotionEvent.ACTION_UP ||
            ev.getActionMasked() === MotionEvent.ACTION_POINTER_UP ||
            ev.getActionMasked() === MotionEvent.ACTION_POINTER_DOWN
        ) {
            mRecalCenterHour = true
        }
        if (mTouchMode and TOUCH_MODE_HSCROLL == 0) {
            mScaleGestureDetector.onTouchEvent(ev)
        }
        return when (action) {
            MotionEvent.ACTION_DOWN -> {
                mStartingScroll = true
                if (DEBUG) {
                    Log.e(
                        TAG,
                        "ACTION_DOWN ev.getDownTime = " + ev.getDownTime().toString() + " Cnt=" +
                            ev.getPointerCount()
                    )
                }
                val bottom =
                    mAlldayHeight + DAY_HEADER_HEIGHT + ALLDAY_TOP_MARGIN
                mTouchStartedInAlldayArea = if (ev.getY() < bottom) {
                    true
                } else {
                    false
                }
                mHandleActionUp = true
                mGestureDetector.onTouchEvent(ev)
                true
            }
            MotionEvent.ACTION_MOVE -> {
                if (DEBUG) Log.e(
                    TAG,
                    "ACTION_MOVE Cnt=" + ev.getPointerCount() + this@DayView
                )
                mGestureDetector.onTouchEvent(ev)
                true
            }
            MotionEvent.ACTION_UP -> {
                if (DEBUG) Log.e(
                    TAG,
                    "ACTION_UP Cnt=" + ev.getPointerCount() + mHandleActionUp
                )
                mEdgeEffectTop.onRelease()
                mEdgeEffectBottom.onRelease()
                mStartingScroll = false
                mGestureDetector.onTouchEvent(ev)
                if (!mHandleActionUp) {
                    mHandleActionUp = true
                    mViewStartX = 0
                    invalidate()
                    return true
                }
                if (mOnFlingCalled) {
                    return true
                }

                // If we were scrolling, then reset the selected hour so that it
                // is visible.
                if (mScrolling) {
                    mScrolling = false
                    resetSelectedHour()
                    invalidate()
                }
                if (mTouchMode and TOUCH_MODE_HSCROLL != 0) {
                    mTouchMode = TOUCH_MODE_INITIAL_STATE
                    if (Math.abs(mViewStartX) > mHorizontalSnapBackThreshold) {
                        // The user has gone beyond the threshold so switch views
                        if (DEBUG) Log.d(
                            TAG,
                            "- horizontal scroll: switch views"
                        )
                        switchViews(
                            mViewStartX > 0,
                            mViewStartX.toFloat(),
                            mViewWidth.toFloat(),
                            0f
                        )
                        mViewStartX = 0
                        return true
                    } else {
                        // Not beyond the threshold so invalidate which will cause
                        // the view to snap back. Also call recalc() to ensure
                        // that we have the correct starting date and title.
                        if (DEBUG) Log.d(
                            TAG,
                            "- horizontal scroll: snap back"
                        )
                        recalc()
                        invalidate()
                        mViewStartX = 0
                    }
                }
                true
            }
            MotionEvent.ACTION_CANCEL -> {
                if (DEBUG) Log.e(
                    TAG,
                    "ACTION_CANCEL"
                )
                mGestureDetector.onTouchEvent(ev)
                mScrolling = false
                resetSelectedHour()
                true
            }
            else -> {
                if (DEBUG) Log.e(
                    TAG,
                    "Not MotionEvent " + ev.toString()
                )
                if (mGestureDetector.onTouchEvent(ev)) {
                    true
                } else super.onTouchEvent(ev)
            }
        }
    }

    override fun onCreateContextMenu(menu: ContextMenu, view: View?, menuInfo: ContextMenuInfo?) {
        var item: MenuItem

        // If the trackball is held down, then the context menu pops up and
        // we never get onKeyUp() for the long-press. So check for it here
        // and change the selection to the long-press state.
        if (mSelectionMode != SELECTION_LONGPRESS) {
            invalidate()
        }
        val startMillis = selectedTimeInMillis
        val flags: Int = (DateUtils.FORMAT_SHOW_TIME
            or DateUtils.FORMAT_CAP_NOON_MIDNIGHT
            or DateUtils.FORMAT_SHOW_WEEKDAY)
        val title: String? = Utils.formatDateRange(mContext, startMillis, startMillis, flags)
        menu.setHeaderTitle(title)
        mPopup?.dismiss()
    }

    /**
     * Sets mSelectionDay and mSelectionHour based on the (x,y) touch position.
     * If the touch position is not within the displayed grid, then this
     * method returns false.
     *
     * @param x the x position of the touch
     * @param y the y position of the touch
     * @param keepOldSelection - do not change the selection info (used for invoking accessibility
     * messages)
     * @return true if the touch position is valid
     */
    private fun setSelectionFromPosition(x: Int, y: Int, keepOldSelection: Boolean): Boolean {
        var x = x
        var savedEvent: Event? = null
        var savedDay = 0
        var savedHour = 0
        var savedAllDay = false
        if (keepOldSelection) {
            // Store selection info and restore it at the end. This way, we can invoke the
            // right accessibility message without affecting the selection.
            savedEvent = mSelectedEvent
            savedDay = mSelectionDay
            savedHour = mSelectionHour
            savedAllDay = mSelectionAllday
        }
        if (x < mHoursWidth) {
            x = mHoursWidth
        }
        var day = (x - mHoursWidth) / (mCellWidth + DAY_GAP)
        if (day >= mNumDays) {
            day = mNumDays - 1
        }
        day += mFirstJulianDay
        setSelectedDay(day)
        if (y < DAY_HEADER_HEIGHT) {
            sendAccessibilityEventAsNeeded(false)
            return false
        }
        setSelectedHour(mFirstHour) /* First fully visible hour */
        mSelectionAllday = if (y < mFirstCell) {
            true
        } else {
            // y is now offset from top of the scrollable region
            val adjustedY = y - mFirstCell
            if (adjustedY < mFirstHourOffset) {
                setSelectedHour(mSelectionHour - 1) /* In the partially visible hour */
            } else {
                setSelectedHour(
                    mSelectionHour +
                        (adjustedY - mFirstHourOffset) / (mCellHeight + HOUR_GAP)
                )
            }
            false
        }
        findSelectedEvent(x, y)
        sendAccessibilityEventAsNeeded(true)

        // Restore old values
        if (keepOldSelection) {
            mSelectedEvent = savedEvent
            mSelectionDay = savedDay
            mSelectionHour = savedHour
            mSelectionAllday = savedAllDay
        }
        return true
    }

    private fun findSelectedEvent(x: Int, y: Int) {
        var y = y
        val date = mSelectionDay
        val cellWidth = mCellWidth
        var events: ArrayList<Event>? = mEvents
        var numEvents: Int = events!!.size
        val left = computeDayLeftPosition(mSelectionDay - mFirstJulianDay)
        val top = 0
        setSelectedEvent(null)
        mSelectedEvents.clear()
        if (mSelectionAllday) {
            var yDistance: Float
            var minYdistance = 10000.0f // any large number
            var closestEvent: Event? = null
            val drawHeight = mAlldayHeight.toFloat()
            val yOffset = DAY_HEADER_HEIGHT + ALLDAY_TOP_MARGIN
            var maxUnexpandedColumn = mMaxUnexpandedAlldayEventCount
            if (mMaxAlldayEvents > mMaxUnexpandedAlldayEventCount) {
                // Leave a gap for the 'box +n' text
                maxUnexpandedColumn--
            }
            events = mAllDayEvents
            numEvents = events!!.size
            for (i in 0 until numEvents) {
                val event: Event? = events?.get(i)
                if (!event!!.drawAsAllday() ||
                    !mShowAllAllDayEvents && event!!.getColumn() >= maxUnexpandedColumn
                ) {
                    // Don't check non-allday events or events that aren't shown
                    continue
                }
                if (event!!.startDay <= mSelectionDay && event!!.endDay >= mSelectionDay) {
                    val numRectangles =
                        if (mShowAllAllDayEvents) mMaxAlldayEvents.toFloat()
                        else mMaxUnexpandedAlldayEventCount.toFloat()
                    var height = drawHeight / numRectangles
                    if (height > MAX_HEIGHT_OF_ONE_ALLDAY_EVENT) {
                        height = MAX_HEIGHT_OF_ONE_ALLDAY_EVENT.toFloat()
                    }
                    val eventTop: Float = yOffset + height * event?.getColumn()
                    val eventBottom = eventTop + height
                    if (eventTop < y && eventBottom > y) {
                        // If the touch is inside the event rectangle, then
                        // add the event.
                        mSelectedEvents.add(event)
                        closestEvent = event
                        break
                    } else {
                        // Find the closest event
                        yDistance = if (eventTop >= y) {
                            eventTop - y
                        } else {
                            y - eventBottom
                        }
                        if (yDistance < minYdistance) {
                            minYdistance = yDistance
                            closestEvent = event
                        }
                    }
                }
            }
            setSelectedEvent(closestEvent)
            return
        }

        // Adjust y for the scrollable bitmap
        y += mViewStartY - mFirstCell

        // Use a region around (x,y) for the selection region
        val region: Rect = mRect
        region.left = x - 10
        region.right = x + 10
        region.top = y - 10
        region.bottom = y + 10
        val geometry: EventGeometry = mEventGeometry
        for (i in 0 until numEvents) {
            val event: Event? = events?.get(i)
            // Compute the event rectangle.
            if (!geometry.computeEventRect(date, left, top, cellWidth, event as Event)) {
                continue
            }

            // If the event intersects the selection region, then add it to
            // mSelectedEvents.
            if (geometry.eventIntersectsSelection(event as Event, region)) {
                mSelectedEvents.add(event as Event)
            }
        }

        // If there are any events in the selected region, then assign the
        // closest one to mSelectedEvent.
        if (mSelectedEvents.size > 0) {
            val len: Int = mSelectedEvents.size
            var closestEvent: Event? = null
            var minDist = (mViewWidth + mViewHeight).toFloat() // some large distance
            for (index in 0 until len) {
                val ev: Event? = mSelectedEvents?.get(index)
                val dist: Float = geometry.pointToEvent(x.toFloat(), y.toFloat(), ev as Event)
                if (dist < minDist) {
                    minDist = dist
                    closestEvent = ev
                }
            }
            setSelectedEvent(closestEvent)

            // Keep the selected hour and day consistent with the selected
            // event. They could be different if we touched on an empty hour
            // slot very close to an event in the previous hour slot. In
            // that case we will select the nearby event.
            val startDay: Int = mSelectedEvent!!.startDay
            val endDay: Int = mSelectedEvent!!.endDay
            if (mSelectionDay < startDay) {
                setSelectedDay(startDay)
            } else if (mSelectionDay > endDay) {
                setSelectedDay(endDay)
            }
            val startHour: Int = mSelectedEvent!!.startTime / 60
            val endHour: Int
            endHour = if (mSelectedEvent!!.startTime < mSelectedEvent!!.endTime) {
                (mSelectedEvent!!.endTime - 1) / 60
            } else {
                mSelectedEvent!!.endTime / 60
            }
            if (mSelectionHour < startHour && mSelectionDay == startDay) {
                setSelectedHour(startHour)
            } else if (mSelectionHour > endHour && mSelectionDay == endDay) {
                setSelectedHour(endHour)
            }
        }
    }

    // Encapsulates the code to continue the scrolling after the
    // finger is lifted. Instead of stopping the scroll immediately,
    // the scroll continues to "free spin" and gradually slows down.
    private inner class ContinueScroll : Runnable {
        override fun run() {
            mScrolling = mScrolling && mScroller.computeScrollOffset()
            if (!mScrolling || mPaused) {
                resetSelectedHour()
                invalidate()
                return
            }
            mViewStartY = mScroller.getCurrY()
            if (mCallEdgeEffectOnAbsorb) {
                if (mViewStartY < 0) {
                    mEdgeEffectTop.onAbsorb(mLastVelocity.toInt())
                    mCallEdgeEffectOnAbsorb = false
                } else if (mViewStartY > mMaxViewStartY) {
                    mEdgeEffectBottom.onAbsorb(mLastVelocity.toInt())
                    mCallEdgeEffectOnAbsorb = false
                }
                mLastVelocity = mScroller.getCurrVelocity()
            }
            if (mScrollStartY == 0 || mScrollStartY == mMaxViewStartY) {
                // Allow overscroll/springback only on a fling,
                // not a pull/fling from the end
                if (mViewStartY < 0) {
                    mViewStartY = 0
                } else if (mViewStartY > mMaxViewStartY) {
                    mViewStartY = mMaxViewStartY
                }
            }
            computeFirstHour()
            mHandler?.post(this)
            invalidate()
        }
    }

    /**
     * Cleanup the pop-up and timers.
     */
    fun cleanup() {
        // Protect against null-pointer exceptions
        if (mPopup != null) {
            mPopup?.dismiss()
        }
        mPaused = true
        mLastPopupEventID = INVALID_EVENT_ID
        if (mHandler != null) {
            mHandler?.removeCallbacks(mDismissPopup)
            mHandler?.removeCallbacks(mUpdateCurrentTime)
        }
        Utils.setSharedPreference(
            mContext, GeneralPreferences.KEY_DEFAULT_CELL_HEIGHT,
            mCellHeight
        )
        // Clear all click animations
        eventClickCleanup()
        // Turn off redraw
        mRemeasure = false
        // Turn off scrolling to make sure the view is in the correct state if we fling back to it
        mScrolling = false
    }

    private fun eventClickCleanup() {
        this.removeCallbacks(mClearClick)
        this.removeCallbacks(mSetClick)
        mClickedEvent = null
        mSavedClickedEvent = null
    }

    private fun setSelectedEvent(e: Event?) {
        mSelectedEvent = e
        mSelectedEventForAccessibility = e
    }

    private fun setSelectedHour(h: Int) {
        mSelectionHour = h
        mSelectionHourForAccessibility = h
    }

    private fun setSelectedDay(d: Int) {
        mSelectionDay = d
        mSelectionDayForAccessibility = d
    }

    /**
     * Restart the update timer
     */
    fun restartCurrentTimeUpdates() {
        mPaused = false
        if (mHandler != null) {
            mHandler?.removeCallbacks(mUpdateCurrentTime)
            mHandler?.post(mUpdateCurrentTime)
        }
    }

    @Override
    protected override fun onDetachedFromWindow() {
        cleanup()
        super.onDetachedFromWindow()
    }

    internal inner class DismissPopup : Runnable {
        override fun run() {
            // Protect against null-pointer exceptions
            if (mPopup != null) {
                mPopup?.dismiss()
            }
        }
    }

    internal inner class UpdateCurrentTime : Runnable {
        override fun run() {
            val currentTime: Long = System.currentTimeMillis()
            mCurrentTime?.set(currentTime)
            // % causes update to occur on 5 minute marks (11:10, 11:15, 11:20, etc.)
            if (!mPaused) {
                mHandler?.postDelayed(
                    mUpdateCurrentTime, UPDATE_CURRENT_TIME_DELAY -
                        currentTime % UPDATE_CURRENT_TIME_DELAY
                )
            }
            mTodayJulianDay = Time.getJulianDay(currentTime, mCurrentTime!!.gmtoff)
            invalidate()
        }
    }

    internal inner class CalendarGestureListener : GestureDetector.SimpleOnGestureListener() {
        @Override
        override fun onSingleTapUp(ev: MotionEvent): Boolean {
            if (DEBUG) Log.e(TAG, "GestureDetector.onSingleTapUp")
            doSingleTapUp(ev)
            return true
        }

        @Override
        override fun onLongPress(ev: MotionEvent) {
            if (DEBUG) Log.e(TAG, "GestureDetector.onLongPress")
            doLongPress(ev)
        }

        @Override
        override fun onScroll(
            e1: MotionEvent,
            e2: MotionEvent,
            distanceX: Float,
            distanceY: Float
        ): Boolean {
            var distanceY = distanceY
            if (DEBUG) Log.e(TAG, "GestureDetector.onScroll")
            eventClickCleanup()
            if (mTouchStartedInAlldayArea) {
                if (Math.abs(distanceX) < Math.abs(distanceY)) {
                    // Make sure that click feedback is gone when you scroll from the
                    // all day area
                    invalidate()
                    return false
                }
                // don't scroll vertically if this started in the allday area
                distanceY = 0f
            }
            doScroll(e1, e2, distanceX, distanceY)
            return true
        }

        @Override
        override fun onFling(
            e1: MotionEvent,
            e2: MotionEvent,
            velocityX: Float,
            velocityY: Float
        ): Boolean {
            var velocityY = velocityY
            if (DEBUG) Log.e(TAG, "GestureDetector.onFling")
            if (mTouchStartedInAlldayArea) {
                if (Math.abs(velocityX) < Math.abs(velocityY)) {
                    return false
                }
                // don't fling vertically if this started in the allday area
                velocityY = 0f
            }
            doFling(e1, e2, velocityX, velocityY)
            return true
        }

        @Override
        override fun onDown(ev: MotionEvent): Boolean {
            if (DEBUG) Log.e(TAG, "GestureDetector.onDown")
            doDown(ev)
            return true
        }
    }

    @Override
    override fun onLongClick(v: View?): Boolean {
        return true
    }

    private inner class ScrollInterpolator : Interpolator {
        override fun getInterpolation(t: Float): Float {
            var t = t
            t -= 1.0f
            t = t * t * t * t * t + 1
            if ((1 - t) * mAnimationDistance < 1) {
                cancelAnimation()
            }
            return t
        }
    }

    private fun calculateDuration(delta: Float, width: Float, velocity: Float): Long {
        /*
         * Here we compute a "distance" that will be used in the computation of
         * the overall snap duration. This is a function of the actual distance
         * that needs to be traveled; we keep this value close to half screen
         * size in order to reduce the variance in snap duration as a function
         * of the distance the page needs to travel.
         */
        var velocity = velocity
        val halfScreenSize = width / 2
        val distanceRatio = delta / width
        val distanceInfluenceForSnapDuration = distanceInfluenceForSnapDuration(distanceRatio)
        val distance = halfScreenSize + halfScreenSize * distanceInfluenceForSnapDuration
        velocity = Math.abs(velocity)
        velocity = Math.max(MINIMUM_SNAP_VELOCITY.toFloat(), velocity)

        /*
         * we want the page's snap velocity to approximately match the velocity
         * at which the user flings, so we scale the duration by a value near to
         * the derivative of the scroll interpolator at zero, ie. 5. We use 6 to
         * make it a little slower.
         */
        val duration: Long = 6L * Math.round(1000 * Math.abs(distance / velocity))
        if (DEBUG) {
            Log.e(
                TAG, "halfScreenSize:" + halfScreenSize + " delta:" + delta + " distanceRatio:" +
                    distanceRatio + " distance:" + distance + " velocity:" + velocity +
                    " duration:" + duration + " distanceInfluenceForSnapDuration:" +
                    distanceInfluenceForSnapDuration
            )
        }
        return duration
    }

    /*
     * We want the duration of the page snap animation to be influenced by the
     * distance that the screen has to travel, however, we don't want this
     * duration to be effected in a purely linear fashion. Instead, we use this
     * method to moderate the effect that the distance of travel has on the
     * overall snap duration.
     */
    private fun distanceInfluenceForSnapDuration(f: Float): Float {
        var f = f
        f -= 0.5f // center the values about 0.
        f *= (0.3f * Math.PI / 2.0f).toFloat()
        return Math.sin(f.toDouble()).toFloat()
    }

    companion object {
        private const val TAG = "DayView"
        private const val DEBUG = false
        private const val DEBUG_SCALING = false
        private const val PERIOD_SPACE = ". "
        private var mScale = 0f // Used for supporting different screen densities
        private const val INVALID_EVENT_ID: Long = -1 // This is used for remembering a null event

        // Duration of the allday expansion
        private const val ANIMATION_DURATION: Long = 400

        // duration of the more allday event text fade
        private const val ANIMATION_SECONDARY_DURATION: Long = 200

        // duration of the scroll to go to a specified time
        private const val GOTO_SCROLL_DURATION = 200

        // duration for events' cross-fade animation
        private const val EVENTS_CROSS_FADE_DURATION = 400

        // duration to show the event clicked
        private const val CLICK_DISPLAY_DURATION = 50
        private const val MENU_DAY = 3
        private const val MENU_EVENT_VIEW = 5
        private const val MENU_EVENT_CREATE = 6
        private const val MENU_EVENT_EDIT = 7
        private const val MENU_EVENT_DELETE = 8
        private var DEFAULT_CELL_HEIGHT = 64
        private var MAX_CELL_HEIGHT = 150
        private var MIN_Y_SPAN = 100
        private val CALENDARS_PROJECTION = arrayOf<String>(
            Calendars._ID, // 0
            Calendars.CALENDAR_ACCESS_LEVEL, // 1
            Calendars.OWNER_ACCOUNT
        )
        private const val CALENDARS_INDEX_ACCESS_LEVEL = 1
        private const val CALENDARS_INDEX_OWNER_ACCOUNT = 2
        private val CALENDARS_WHERE: String = Calendars._ID.toString() + "=%d"
        private const val FROM_NONE = 0
        private const val FROM_ABOVE = 1
        private const val FROM_BELOW = 2
        private const val FROM_LEFT = 4
        private const val FROM_RIGHT = 8
        private const val ACCESS_LEVEL_NONE = 0
        private const val ACCESS_LEVEL_DELETE = 1
        private const val ACCESS_LEVEL_EDIT = 2
        private var mHorizontalSnapBackThreshold = 128

        // Update the current time line every five minutes if the window is left open that long
        private const val UPDATE_CURRENT_TIME_DELAY = 300000
        private var mOnDownDelay = 0
        protected var mStringBuilder: StringBuilder = StringBuilder(50)

        // TODO recreate formatter when locale changes
        protected var mFormatter: Formatter = Formatter(mStringBuilder, Locale.getDefault())

        // The number of milliseconds to show the popup window
        private const val POPUP_DISMISS_DELAY = 3000
        private var GRID_LINE_LEFT_MARGIN = 0f
        private const val GRID_LINE_INNER_WIDTH = 1f
        private const val DAY_GAP = 1
        private const val HOUR_GAP = 1

        // This is the standard height of an allday event with no restrictions
        private var SINGLE_ALLDAY_HEIGHT = 34

        /**
         * This is the minimum desired height of a allday event.
         * When unexpanded, allday events will use this height.
         * When expanded allDay events will attempt to grow to fit all
         * events at this height.
         */
        private var MIN_UNEXPANDED_ALLDAY_EVENT_HEIGHT = 28.0f // in pixels

        /**
         * This is how big the unexpanded allday height is allowed to be.
         * It will get adjusted based on screen size
         */
        private var MAX_UNEXPANDED_ALLDAY_HEIGHT = (MIN_UNEXPANDED_ALLDAY_EVENT_HEIGHT * 4).toInt()

        /**
         * This is the minimum size reserved for displaying regular events.
         * The expanded allDay region can't expand into this.
         */
        private const val MIN_HOURS_HEIGHT = 180
        private var ALLDAY_TOP_MARGIN = 1

        // The largest a single allDay event will become.
        private var MAX_HEIGHT_OF_ONE_ALLDAY_EVENT = 34
        private var HOURS_TOP_MARGIN = 2
        private var HOURS_LEFT_MARGIN = 2
        private var HOURS_RIGHT_MARGIN = 4
        private var HOURS_MARGIN = HOURS_LEFT_MARGIN + HOURS_RIGHT_MARGIN
        private var NEW_EVENT_MARGIN = 4
        private var NEW_EVENT_WIDTH = 2
        private var NEW_EVENT_MAX_LENGTH = 16
        private var CURRENT_TIME_LINE_SIDE_BUFFER = 4
        private var CURRENT_TIME_LINE_TOP_OFFSET = 2

        /* package */
        const val MINUTES_PER_HOUR = 60

        /* package */
        const val MINUTES_PER_DAY = MINUTES_PER_HOUR * 24

        /* package */
        const val MILLIS_PER_MINUTE = 60 * 1000

        /* package */
        const val MILLIS_PER_HOUR = 3600 * 1000

        /* package */
        const val MILLIS_PER_DAY = MILLIS_PER_HOUR * 24

        // More events text will transition between invisible and this alpha
        private const val MORE_EVENTS_MAX_ALPHA = 0x4C
        private var DAY_HEADER_ONE_DAY_LEFT_MARGIN = 0
        private var DAY_HEADER_ONE_DAY_RIGHT_MARGIN = 5
        private var DAY_HEADER_ONE_DAY_BOTTOM_MARGIN = 6
        private var DAY_HEADER_RIGHT_MARGIN = 4
        private var DAY_HEADER_BOTTOM_MARGIN = 3
        private var DAY_HEADER_FONT_SIZE = 14f
        private var DATE_HEADER_FONT_SIZE = 32f
        private var NORMAL_FONT_SIZE = 12f
        private var EVENT_TEXT_FONT_SIZE = 12f
        private var HOURS_TEXT_SIZE = 12f
        private var AMPM_TEXT_SIZE = 9f
        private var MIN_HOURS_WIDTH = 96
        private var MIN_CELL_WIDTH_FOR_TEXT = 20
        private const val MAX_EVENT_TEXT_LEN = 500

        // smallest height to draw an event with
        private var MIN_EVENT_HEIGHT = 24.0f // in pixels
        private var CALENDAR_COLOR_SQUARE_SIZE = 10
        private var EVENT_RECT_TOP_MARGIN = 1
        private var EVENT_RECT_BOTTOM_MARGIN = 0
        private var EVENT_RECT_LEFT_MARGIN = 1
        private var EVENT_RECT_RIGHT_MARGIN = 0
        private var EVENT_RECT_STROKE_WIDTH = 2
        private var EVENT_TEXT_TOP_MARGIN = 2
        private var EVENT_TEXT_BOTTOM_MARGIN = 2
        private var EVENT_TEXT_LEFT_MARGIN = 6
        private var EVENT_TEXT_RIGHT_MARGIN = 6
        private var ALL_DAY_EVENT_RECT_BOTTOM_MARGIN = 1
        private var EVENT_ALL_DAY_TEXT_TOP_MARGIN = EVENT_TEXT_TOP_MARGIN
        private var EVENT_ALL_DAY_TEXT_BOTTOM_MARGIN = EVENT_TEXT_BOTTOM_MARGIN
        private var EVENT_ALL_DAY_TEXT_LEFT_MARGIN = EVENT_TEXT_LEFT_MARGIN
        private var EVENT_ALL_DAY_TEXT_RIGHT_MARGIN = EVENT_TEXT_RIGHT_MARGIN

        // margins and sizing for the expand allday icon
        private var EXPAND_ALL_DAY_BOTTOM_MARGIN = 10

        // sizing for "box +n" in allDay events
        private var EVENT_SQUARE_WIDTH = 10
        private var EVENT_LINE_PADDING = 4
        private var NEW_EVENT_HINT_FONT_SIZE = 12
        private var mEventTextColor = 0
        private var mMoreEventsTextColor = 0
        private var mWeek_saturdayColor = 0
        private var mWeek_sundayColor = 0
        private var mCalendarDateBannerTextColor = 0
        private var mCalendarAmPmLabel = 0
        private var mCalendarGridAreaSelected = 0
        private var mCalendarGridLineInnerHorizontalColor = 0
        private var mCalendarGridLineInnerVerticalColor = 0
        private var mFutureBgColor = 0
        private var mFutureBgColorRes = 0
        private var mBgColor = 0
        private var mNewEventHintColor = 0
        private var mCalendarHourLabelColor = 0
        private var mMoreAlldayEventsTextAlpha = MORE_EVENTS_MAX_ALPHA
        private var mCellHeight = 0 // shared among all DayViews
        private var mMinCellHeight = 32
        private var mScaledPagingTouchSlop = 0

        /**
         * Whether to use the expand or collapse icon.
         */
        private var mUseExpandIcon = true

        /**
         * The height of the day names/numbers
         */
        private var DAY_HEADER_HEIGHT = 45

        /**
         * The height of the day names/numbers for multi-day views
         */
        private var MULTI_DAY_HEADER_HEIGHT = DAY_HEADER_HEIGHT

        /**
         * The height of the day names/numbers when viewing a single day
         */
        private var ONE_DAY_HEADER_HEIGHT = DAY_HEADER_HEIGHT

        /**
         * Whether or not to expand the allDay area to fill the screen
         */
        private var mShowAllAllDayEvents = false
        private var sCounter = 0

        /**
         * The initial state of the touch mode when we enter this view.
         */
        private const val TOUCH_MODE_INITIAL_STATE = 0

        /**
         * Indicates we just received the touch event and we are waiting to see if
         * it is a tap or a scroll gesture.
         */
        private const val TOUCH_MODE_DOWN = 1

        /**
         * Indicates the touch gesture is a vertical scroll
         */
        private const val TOUCH_MODE_VSCROLL = 0x20

        /**
         * Indicates the touch gesture is a horizontal scroll
         */
        private const val TOUCH_MODE_HSCROLL = 0x40

        /**
         * The selection modes are HIDDEN, PRESSED, SELECTED, and LONGPRESS.
         */
        private const val SELECTION_HIDDEN = 0
        private const val SELECTION_PRESSED = 1 // D-pad down but not up yet
        private const val SELECTION_SELECTED = 2
        private const val SELECTION_LONGPRESS = 3

        // The rest of this file was borrowed from Launcher2 - PagedView.java
        private const val MINIMUM_SNAP_VELOCITY = 2200
    }

    init {
        mContext = context
        initAccessibilityVariables()
        mResources = context!!.getResources()
        mNewEventHintString = mResources.getString(R.string.day_view_new_event_hint)
        mNumDays = numDays
        DATE_HEADER_FONT_SIZE =
            mResources.getDimension(R.dimen.date_header_text_size).toInt().toFloat()
        DAY_HEADER_FONT_SIZE =
            mResources.getDimension(R.dimen.day_label_text_size).toInt().toFloat()
        ONE_DAY_HEADER_HEIGHT = mResources.getDimension(R.dimen.one_day_header_height).toInt()
        DAY_HEADER_BOTTOM_MARGIN = mResources.getDimension(R.dimen.day_header_bottom_margin).toInt()
        EXPAND_ALL_DAY_BOTTOM_MARGIN =
            mResources.getDimension(R.dimen.all_day_bottom_margin).toInt()
        HOURS_TEXT_SIZE = mResources.getDimension(R.dimen.hours_text_size).toInt().toFloat()
        AMPM_TEXT_SIZE = mResources.getDimension(R.dimen.ampm_text_size).toInt().toFloat()
        MIN_HOURS_WIDTH = mResources.getDimension(R.dimen.min_hours_width).toInt()
        HOURS_LEFT_MARGIN = mResources.getDimension(R.dimen.hours_left_margin).toInt()
        HOURS_RIGHT_MARGIN = mResources.getDimension(R.dimen.hours_right_margin).toInt()
        MULTI_DAY_HEADER_HEIGHT = mResources.getDimension(R.dimen.day_header_height).toInt()
        val eventTextSizeId: Int
        eventTextSizeId = if (mNumDays == 1) {
            R.dimen.day_view_event_text_size
        } else {
            R.dimen.week_view_event_text_size
        }
        EVENT_TEXT_FONT_SIZE = mResources.getDimension(eventTextSizeId).toFloat()
        NEW_EVENT_HINT_FONT_SIZE = mResources.getDimension(R.dimen.new_event_hint_text_size).toInt()
        MIN_EVENT_HEIGHT = mResources.getDimension(R.dimen.event_min_height)
        MIN_UNEXPANDED_ALLDAY_EVENT_HEIGHT = MIN_EVENT_HEIGHT
        EVENT_TEXT_TOP_MARGIN = mResources.getDimension(R.dimen.event_text_vertical_margin).toInt()
        EVENT_TEXT_BOTTOM_MARGIN = EVENT_TEXT_TOP_MARGIN
        EVENT_ALL_DAY_TEXT_TOP_MARGIN = EVENT_TEXT_TOP_MARGIN
        EVENT_ALL_DAY_TEXT_BOTTOM_MARGIN = EVENT_TEXT_TOP_MARGIN
        EVENT_TEXT_LEFT_MARGIN = mResources
            .getDimension(R.dimen.event_text_horizontal_margin).toInt()
        EVENT_TEXT_RIGHT_MARGIN = EVENT_TEXT_LEFT_MARGIN
        EVENT_ALL_DAY_TEXT_LEFT_MARGIN = EVENT_TEXT_LEFT_MARGIN
        EVENT_ALL_DAY_TEXT_RIGHT_MARGIN = EVENT_TEXT_LEFT_MARGIN
        if (mScale == 0f) {
            mScale = mResources.getDisplayMetrics().density
            if (mScale != 1f) {
                SINGLE_ALLDAY_HEIGHT *= mScale.toInt()
                ALLDAY_TOP_MARGIN *= mScale.toInt()
                MAX_HEIGHT_OF_ONE_ALLDAY_EVENT *= mScale.toInt()
                NORMAL_FONT_SIZE *= mScale
                GRID_LINE_LEFT_MARGIN *= mScale
                HOURS_TOP_MARGIN *= mScale.toInt()
                MIN_CELL_WIDTH_FOR_TEXT *= mScale.toInt()
                MAX_UNEXPANDED_ALLDAY_HEIGHT *= mScale.toInt()
                mAnimateDayEventHeight = MIN_UNEXPANDED_ALLDAY_EVENT_HEIGHT.toInt()
                CURRENT_TIME_LINE_SIDE_BUFFER *= mScale.toInt()
                CURRENT_TIME_LINE_TOP_OFFSET *= mScale.toInt()
                MIN_Y_SPAN *= mScale.toInt()
                MAX_CELL_HEIGHT *= mScale.toInt()
                DEFAULT_CELL_HEIGHT *= mScale.toInt()
                DAY_HEADER_HEIGHT *= mScale.toInt()
                DAY_HEADER_RIGHT_MARGIN *= mScale.toInt()
                DAY_HEADER_ONE_DAY_LEFT_MARGIN *= mScale.toInt()
                DAY_HEADER_ONE_DAY_RIGHT_MARGIN *= mScale.toInt()
                DAY_HEADER_ONE_DAY_BOTTOM_MARGIN *= mScale.toInt()
                CALENDAR_COLOR_SQUARE_SIZE *= mScale.toInt()
                EVENT_RECT_TOP_MARGIN *= mScale.toInt()
                EVENT_RECT_BOTTOM_MARGIN *= mScale.toInt()
                ALL_DAY_EVENT_RECT_BOTTOM_MARGIN *= mScale.toInt()
                EVENT_RECT_LEFT_MARGIN *= mScale.toInt()
                EVENT_RECT_RIGHT_MARGIN *= mScale.toInt()
                EVENT_RECT_STROKE_WIDTH *= mScale.toInt()
                EVENT_SQUARE_WIDTH *= mScale.toInt()
                EVENT_LINE_PADDING *= mScale.toInt()
                NEW_EVENT_MARGIN *= mScale.toInt()
                NEW_EVENT_WIDTH *= mScale.toInt()
                NEW_EVENT_MAX_LENGTH *= mScale.toInt()
            }
        }
        HOURS_MARGIN = HOURS_LEFT_MARGIN + HOURS_RIGHT_MARGIN
        DAY_HEADER_HEIGHT = if (mNumDays == 1) ONE_DAY_HEADER_HEIGHT else MULTI_DAY_HEADER_HEIGHT
        mCurrentTimeLine = mResources.getDrawable(R.drawable.timeline_indicator_holo_light)
        mCurrentTimeAnimateLine = mResources
            .getDrawable(R.drawable.timeline_indicator_activated_holo_light)
        mTodayHeaderDrawable = mResources.getDrawable(R.drawable.today_blue_week_holo_light)
        mExpandAlldayDrawable = mResources.getDrawable(R.drawable.ic_expand_holo_light)
        mCollapseAlldayDrawable = mResources.getDrawable(R.drawable.ic_collapse_holo_light)
        mNewEventHintColor = mResources.getColor(R.color.new_event_hint_text_color)
        mAcceptedOrTentativeEventBoxDrawable = mResources
            .getDrawable(R.drawable.panel_month_event_holo_light)
        mEventLoader = eventLoader as EventLoader
        mEventGeometry = EventGeometry()
        mEventGeometry.setMinEventHeight(MIN_EVENT_HEIGHT)
        mEventGeometry.setHourGap(HOUR_GAP.toFloat())
        mEventGeometry.setCellMargin(DAY_GAP)
        mLastPopupEventID = INVALID_EVENT_ID
        mController = controller as CalendarController
        mViewSwitcher = viewSwitcher as ViewSwitcher
        mGestureDetector = GestureDetector(context, CalendarGestureListener())
        mScaleGestureDetector = ScaleGestureDetector(getContext(), this)
        if (mCellHeight == 0) {
            mCellHeight = Utils.getSharedPreference(
                mContext,
                GeneralPreferences.KEY_DEFAULT_CELL_HEIGHT, DEFAULT_CELL_HEIGHT
            )
        }
        mScroller = OverScroller(context)
        mHScrollInterpolator = ScrollInterpolator()
        mEdgeEffectTop = EdgeEffect(context)
        mEdgeEffectBottom = EdgeEffect(context)
        val vc: ViewConfiguration = ViewConfiguration.get(context)
        mScaledPagingTouchSlop = vc.getScaledPagingTouchSlop()
        mOnDownDelay = ViewConfiguration.getTapTimeout()
        OVERFLING_DISTANCE = vc.getScaledOverflingDistance()
        init(context as Context)
    }
}