/*
 * 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.app.Activity
import android.app.Dialog
import android.app.DialogFragment
import android.app.Service
import android.content.ContentProviderOperation
import android.content.ContentUris
import android.content.ContentValues
import android.content.Context
import android.content.res.Resources
import android.database.Cursor
import android.net.Uri
import android.os.Bundle
import android.provider.CalendarContract.Attendees
import android.provider.CalendarContract.Calendars
import android.provider.CalendarContract.Events
import android.text.Spannable
import android.text.SpannableStringBuilder
import android.text.TextUtils
import android.text.style.ForegroundColorSpan
import android.util.Log
import android.util.SparseIntArray
import android.view.Gravity
import android.view.LayoutInflater
import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import android.view.View
import android.view.View.OnClickListener
import android.view.ViewGroup
import android.view.Window
import android.view.WindowManager
import android.view.accessibility.AccessibilityEvent
import android.view.accessibility.AccessibilityManager
import android.widget.AdapterView
import android.widget.RadioButton
import android.widget.RadioGroup
import android.widget.RadioGroup.OnCheckedChangeListener
import android.widget.ScrollView
import android.widget.TextView
import com.android.calendar.CalendarController.EventInfo
import com.android.calendar.CalendarController.EventType
import com.android.calendarcommon2.DateException
import com.android.calendarcommon2.Duration
import java.util.ArrayList

class EventInfoFragment : DialogFragment, OnCheckedChangeListener, CalendarController.EventHandler,
    OnClickListener {
    private var mWindowStyle = DIALOG_WINDOW_STYLE
    private var mCurrentQuery = 0

    companion object {
        const val DEBUG = false
        const val TAG = "EventInfoFragment"
        internal const val BUNDLE_KEY_EVENT_ID = "key_event_id"
        internal const val BUNDLE_KEY_START_MILLIS = "key_start_millis"
        internal const val BUNDLE_KEY_END_MILLIS = "key_end_millis"
        internal const val BUNDLE_KEY_IS_DIALOG = "key_fragment_is_dialog"
        internal const val BUNDLE_KEY_DELETE_DIALOG_VISIBLE = "key_delete_dialog_visible"
        internal const val BUNDLE_KEY_WINDOW_STYLE = "key_window_style"
        internal const val BUNDLE_KEY_CALENDAR_COLOR = "key_calendar_color"
        internal const val BUNDLE_KEY_CALENDAR_COLOR_INIT = "key_calendar_color_init"
        internal const val BUNDLE_KEY_CURRENT_COLOR = "key_current_color"
        internal const val BUNDLE_KEY_CURRENT_COLOR_KEY = "key_current_color_key"
        internal const val BUNDLE_KEY_CURRENT_COLOR_INIT = "key_current_color_init"
        internal const val BUNDLE_KEY_ORIGINAL_COLOR = "key_original_color"
        internal const val BUNDLE_KEY_ORIGINAL_COLOR_INIT = "key_original_color_init"
        internal const val BUNDLE_KEY_ATTENDEE_RESPONSE = "key_attendee_response"
        internal const val BUNDLE_KEY_USER_SET_ATTENDEE_RESPONSE = "key_user_set_attendee_response"
        internal const val BUNDLE_KEY_TENTATIVE_USER_RESPONSE = "key_tentative_user_response"
        internal const val BUNDLE_KEY_RESPONSE_WHICH_EVENTS = "key_response_which_events"
        internal const val BUNDLE_KEY_REMINDER_MINUTES = "key_reminder_minutes"
        internal const val BUNDLE_KEY_REMINDER_METHODS = "key_reminder_methods"
        private const val PERIOD_SPACE = ". "
        private const val NO_EVENT_COLOR = ""

        /**
         * These are the corresponding indices into the array of strings
         * "R.array.change_response_labels" in the resource file.
         */
        const val UPDATE_SINGLE = 0
        const val UPDATE_ALL = 1

        // Style of view
        const val FULL_WINDOW_STYLE = 0
        const val DIALOG_WINDOW_STYLE = 1

        // Query tokens for QueryHandler
        private const val TOKEN_QUERY_EVENT = 1 shl 0
        private const val TOKEN_QUERY_CALENDARS = 1 shl 1
        private const val TOKEN_QUERY_ATTENDEES = 1 shl 2
        private const val TOKEN_QUERY_DUPLICATE_CALENDARS = 1 shl 3
        private const val TOKEN_QUERY_REMINDERS = 1 shl 4
        private const val TOKEN_QUERY_VISIBLE_CALENDARS = 1 shl 5
        private const val TOKEN_QUERY_COLORS = 1 shl 6
        private const val TOKEN_QUERY_ALL = (TOKEN_QUERY_DUPLICATE_CALENDARS
            or TOKEN_QUERY_ATTENDEES or TOKEN_QUERY_CALENDARS or TOKEN_QUERY_EVENT
            or TOKEN_QUERY_REMINDERS or TOKEN_QUERY_VISIBLE_CALENDARS or TOKEN_QUERY_COLORS)
        private val EVENT_PROJECTION = arrayOf<String>(
            Events._ID, // 0  do not remove; used in DeleteEventHelper
            Events.TITLE,  // 1  do not remove; used in DeleteEventHelper
            Events.RRULE,  // 2  do not remove; used in DeleteEventHelper
            Events.ALL_DAY, // 3  do not remove; used in DeleteEventHelper
            Events.CALENDAR_ID, // 4  do not remove; used in DeleteEventHelper
            Events.DTSTART, // 5  do not remove; used in DeleteEventHelper
            Events._SYNC_ID, // 6  do not remove; used in DeleteEventHelper
            Events.EVENT_TIMEZONE, // 7  do not remove; used in DeleteEventHelper
            Events.DESCRIPTION, // 8
            Events.EVENT_LOCATION, // 9
            Calendars.CALENDAR_ACCESS_LEVEL, // 10
            Events.CALENDAR_COLOR, // 11
            Events.EVENT_COLOR, // 12
            Events.HAS_ATTENDEE_DATA, // 13
            Events.ORGANIZER,  // 14
            Events.HAS_ALARM,  // 15
            Calendars.MAX_REMINDERS, // 16
            Calendars.ALLOWED_REMINDERS, // 17
            Events.CUSTOM_APP_PACKAGE, // 18
            Events.CUSTOM_APP_URI, // 19
            Events.DTEND, // 20
            Events.DURATION, // 21
            Events.ORIGINAL_SYNC_ID // 22 do not remove; used in DeleteEventHelper
        )
        private const val EVENT_INDEX_ID = 0
        private const val EVENT_INDEX_TITLE = 1
        private const val EVENT_INDEX_RRULE = 2
        private const val EVENT_INDEX_ALL_DAY = 3
        private const val EVENT_INDEX_CALENDAR_ID = 4
        private const val EVENT_INDEX_DTSTART = 5
        private const val EVENT_INDEX_SYNC_ID = 6
        private const val EVENT_INDEX_EVENT_TIMEZONE = 7
        private const val EVENT_INDEX_DESCRIPTION = 8
        private const val EVENT_INDEX_EVENT_LOCATION = 9
        private const val EVENT_INDEX_ACCESS_LEVEL = 10
        private const val EVENT_INDEX_CALENDAR_COLOR = 11
        private const val EVENT_INDEX_EVENT_COLOR = 12
        private const val EVENT_INDEX_HAS_ATTENDEE_DATA = 13
        private const val EVENT_INDEX_ORGANIZER = 14
        private const val EVENT_INDEX_HAS_ALARM = 15
        private const val EVENT_INDEX_MAX_REMINDERS = 16
        private const val EVENT_INDEX_ALLOWED_REMINDERS = 17
        private const val EVENT_INDEX_CUSTOM_APP_PACKAGE = 18
        private const val EVENT_INDEX_CUSTOM_APP_URI = 19
        private const val EVENT_INDEX_DTEND = 20
        private const val EVENT_INDEX_DURATION = 21
        val CALENDARS_PROJECTION = arrayOf<String>(
            Calendars._ID, // 0
            Calendars.CALENDAR_DISPLAY_NAME, // 1
            Calendars.OWNER_ACCOUNT, // 2
            Calendars.CAN_ORGANIZER_RESPOND, // 3
            Calendars.ACCOUNT_NAME, // 4
            Calendars.ACCOUNT_TYPE // 5
        )
        const val CALENDARS_INDEX_DISPLAY_NAME = 1
        const val CALENDARS_INDEX_OWNER_ACCOUNT = 2
        const val CALENDARS_INDEX_OWNER_CAN_RESPOND = 3
        const val CALENDARS_INDEX_ACCOUNT_NAME = 4
        const val CALENDARS_INDEX_ACCOUNT_TYPE = 5
        val CALENDARS_WHERE: String = Calendars._ID.toString() + "=?"
        val CALENDARS_DUPLICATE_NAME_WHERE: String =
            Calendars.CALENDAR_DISPLAY_NAME.toString() + "=?"
        val CALENDARS_VISIBLE_WHERE: String = Calendars.VISIBLE.toString() + "=?"
        const val COLORS_INDEX_COLOR = 1
        const val COLORS_INDEX_COLOR_KEY = 2
        private var mScale = 0f // Used for supporting different screen densities
        private var mCustomAppIconSize = 32
        private const val FADE_IN_TIME = 300 // in milliseconds
        private const val LOADING_MSG_DELAY = 600 // in milliseconds
        private const val LOADING_MSG_MIN_DISPLAY_TIME = 600
        private var mDialogWidth = 500
        private var mDialogHeight = 600
        private var DIALOG_TOP_MARGIN = 8
        fun getResponseFromButtonId(buttonId: Int): Int {
            return Attendees.ATTENDEE_STATUS_NONE
        }

        fun findButtonIdForResponse(response: Int): Int {
            return -1
        }

        init {
            if (!Utils.isJellybeanOrLater()) {
                EVENT_PROJECTION[EVENT_INDEX_CUSTOM_APP_PACKAGE] = Events._ID // nonessential value
                EVENT_PROJECTION[EVENT_INDEX_CUSTOM_APP_URI] = Events._ID // nonessential value
            }
        }
    }

    private var mView: View? = null
    private var mUri: Uri? = null
    var eventId: Long = 0
        private set
    private val mEventCursor: Cursor? = null
    private val mCalendarsCursor: Cursor? = null
    var startMillis: Long = 0
        private set
    var endMillis: Long = 0
        private set
    private var mAllDay = false
    private var mOwnerCanRespond = false
    private var mSyncAccountName: String? = null
    private var mCalendarOwnerAccount: String? = null
    private var mIsBusyFreeCalendar = false
    private val mOriginalAttendeeResponse = 0
    private var mAttendeeResponseFromIntent: Int = Attendees.ATTENDEE_STATUS_NONE
    private val mUserSetResponse: Int = Attendees.ATTENDEE_STATUS_NONE
    private val mWhichEvents = -1

    // Used as the temporary response until the dialog is confirmed. It is also
    // able to be used as a state marker for configuration changes.
    private val mTentativeUserSetResponse: Int = Attendees.ATTENDEE_STATUS_NONE
    private var mHasAlarm = false

    // Used to prevent saving changes in event if it is being deleted.
    private val mEventDeletionStarted = false
    private var mTitle: TextView? = null
    private var mWhenDateTime: TextView? = null
    private var mWhere: TextView? = null
    private var mMenu: Menu? = null
    private var mHeadlines: View? = null
    private var mScrollView: ScrollView? = null
    private var mLoadingMsgView: View? = null
    private var mErrorMsgView: View? = null
    private var mAnimateAlpha: ObjectAnimator? = null
    private var mLoadingMsgStartTime: Long = 0
    private val mDisplayColorKeyMap: SparseIntArray = SparseIntArray()
    private val mOriginalColor = -1
    private val mOriginalColorInitialized = false
    private val mCalendarColor = -1
    private val mCalendarColorInitialized = false
    private val mCurrentColor = -1
    private val mCurrentColorInitialized = false
    private val mCurrentColorKey = -1
    private var mNoCrossFade = false // Used to prevent repeated cross-fade
    private var mResponseRadioGroup: RadioGroup? = null
    var mToEmails: ArrayList<String> = ArrayList<String>()
    var mCcEmails: ArrayList<String> = ArrayList<String>()
    private val mTZUpdater: Runnable = object : Runnable {
        @Override
        override fun run() {
            updateEvent(mView)
        }
    }
    private val mLoadingMsgAlphaUpdater: Runnable = object : Runnable {
        @Override
        override fun run() {
            // Since this is run after a delay, make sure to only show the message
            // if the event's data is not shown yet.
            if (!mAnimateAlpha!!.isRunning() && mScrollView!!.getAlpha() == 0f) {
                mLoadingMsgStartTime = System.currentTimeMillis()
                mLoadingMsgView?.setAlpha(1f)
            }
        }
    }
    private var mIsDialog = false
    private var mIsPaused = true
    private val mDismissOnResume = false
    private var mX = -1
    private var mY = -1
    private var mMinTop = 0 // Dialog cannot be above this location
    private var mIsTabletConfig = false
    private var mActivity: Activity? = null
    private var mContext: Context? = null
    private var mController: CalendarController? = null
    private fun sendAccessibilityEventIfQueryDone(token: Int) {
        mCurrentQuery = mCurrentQuery or token
        if (mCurrentQuery == TOKEN_QUERY_ALL) {
            sendAccessibilityEvent()
        }
    }

    constructor(
        context: Context,
        uri: Uri?,
        startMillis: Long,
        endMillis: Long,
        attendeeResponse: Int,
        isDialog: Boolean,
        windowStyle: Int
    ) {
        val r: Resources = context.getResources()
        if (mScale == 0f) {
            mScale = context.getResources().getDisplayMetrics().density
            if (mScale != 1f) {
                mCustomAppIconSize *= mScale.toInt()
                if (isDialog) {
                    DIALOG_TOP_MARGIN *= mScale.toInt()
                }
            }
        }
        if (isDialog) {
            setDialogSize(r)
        }
        mIsDialog = isDialog
        setStyle(DialogFragment.STYLE_NO_TITLE, 0)
        mUri = uri
        this.startMillis = startMillis
        this.endMillis = endMillis
        mAttendeeResponseFromIntent = attendeeResponse
        mWindowStyle = windowStyle
    }

    // This is currently required by the fragment manager.
    constructor() {}
    constructor(
        context: Context?,
        eventId: Long,
        startMillis: Long,
        endMillis: Long,
        attendeeResponse: Int,
        isDialog: Boolean,
        windowStyle: Int
    ) : this(
        context as Context, ContentUris.withAppendedId(Events.CONTENT_URI, eventId), startMillis,
        endMillis, attendeeResponse, isDialog, windowStyle
    ) {
        this.eventId = eventId
    }

    @Override
    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)
        if (mIsDialog) {
            applyDialogParams()
        }
        val activity: Activity = getActivity()
        mContext = activity
    }

    private fun applyDialogParams() {
        val dialog: Dialog = getDialog()
        dialog.setCanceledOnTouchOutside(true)
        val window: Window? = dialog.getWindow()
        window?.addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND)
        val a: WindowManager.LayoutParams? = window?.getAttributes()
        a!!.dimAmount = .4f
        a!!.width = mDialogWidth
        a!!.height = mDialogHeight

        // On tablets , do smart positioning of dialog
        // On phones , use the whole screen
        if (mX != -1 || mY != -1) {
            a!!.x = mX - mDialogWidth / 2
            a!!.y = mY - mDialogHeight / 2
            if (a!!.y < mMinTop) {
                a!!.y = mMinTop + DIALOG_TOP_MARGIN
            }
            a!!.gravity = Gravity.LEFT or Gravity.TOP
        }
        window?.setAttributes(a)
    }

    fun setDialogParams(x: Int, y: Int, minTop: Int) {
        mX = x
        mY = y
        mMinTop = minTop
    }

    // Implements OnCheckedChangeListener
    @Override
    override fun onCheckedChanged(group: RadioGroup?, checkedId: Int) {
    }

    fun onNothingSelected(parent: AdapterView<*>?) {}
    @Override
    override fun onDetach() {
        super.onDetach()
        mController?.deregisterEventHandler(R.layout.event_info)
    }

    @Override
    override fun onAttach(activity: Activity?) {
        super.onAttach(activity)
        mActivity = activity
        // Ensure that mIsTabletConfig is set before creating the menu.
        mIsTabletConfig = Utils.getConfigBool(mActivity as Context, R.bool.tablet_config)
        mController = CalendarController.getInstance(mActivity)
        mController?.registerEventHandler(R.layout.event_info, this)
        if (!mIsDialog) {
            setHasOptionsMenu(true)
        }
    }

    @Override
    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        mView = if (mWindowStyle == DIALOG_WINDOW_STYLE) {
            inflater.inflate(R.layout.event_info_dialog, container, false)
        } else {
            inflater.inflate(R.layout.event_info, container, false)
        }
        mScrollView = mView?.findViewById(R.id.event_info_scroll_view) as ScrollView
        mLoadingMsgView = mView?.findViewById(R.id.event_info_loading_msg)
        mErrorMsgView = mView?.findViewById(R.id.event_info_error_msg)
        mTitle = mView?.findViewById(R.id.title) as TextView
        mWhenDateTime = mView?.findViewById(R.id.when_datetime) as TextView
        mWhere = mView?.findViewById(R.id.where) as TextView
        mHeadlines = mView?.findViewById(R.id.event_info_headline)
        mResponseRadioGroup = mView?.findViewById(R.id.response_value) as RadioGroup
        mAnimateAlpha = ObjectAnimator.ofFloat(mScrollView, "Alpha", 0f, 1f)
        mAnimateAlpha?.setDuration(FADE_IN_TIME.toLong())
        mAnimateAlpha?.addListener(object : AnimatorListenerAdapter() {
            var defLayerType = 0
            @Override
            override fun onAnimationStart(animation: Animator?) {
                // Use hardware layer for better performance during animation
                defLayerType = mScrollView?.getLayerType() as Int
                mScrollView?.setLayerType(View.LAYER_TYPE_HARDWARE, null)
                // Ensure that the loading message is gone before showing the
                // event info
                mLoadingMsgView?.removeCallbacks(mLoadingMsgAlphaUpdater)
                mLoadingMsgView?.setVisibility(View.GONE)
            }

            @Override
            override fun onAnimationCancel(animation: Animator?) {
                mScrollView?.setLayerType(defLayerType, null)
            }

            @Override
            override fun onAnimationEnd(animation: Animator?) {
                mScrollView?.setLayerType(defLayerType, null)
                // Do not cross fade after the first time
                mNoCrossFade = true
            }
        })
        mLoadingMsgView?.setAlpha(0f)
        mScrollView?.setAlpha(0f)
        mErrorMsgView?.setVisibility(View.INVISIBLE)
        mLoadingMsgView?.postDelayed(mLoadingMsgAlphaUpdater, LOADING_MSG_DELAY.toLong())

        // Hide Edit/Delete buttons if in full screen mode on a phone
        if (!mIsDialog && !mIsTabletConfig || mWindowStyle == FULL_WINDOW_STYLE) {
            mView?.findViewById<View>(R.id.event_info_buttons_container)?.setVisibility(View.GONE)
        }
        return mView
    }

    private fun updateTitle() {
        val res: Resources = getActivity().getResources()
        getActivity().setTitle(res.getString(R.string.event_info_title))
    }

    /**
     * Initializes the event cursor, which is expected to point to the first
     * (and only) result from a query.
     * @return false if the cursor is empty, true otherwise
     */
    private fun initEventCursor(): Boolean {
        if (mEventCursor == null || mEventCursor.getCount() === 0) {
            return false
        }
        mEventCursor.moveToFirst()
        eventId = mEventCursor.getInt(EVENT_INDEX_ID).toLong()
        val rRule: String = mEventCursor.getString(EVENT_INDEX_RRULE)
        // mHasAlarm will be true if it was saved in the event already.
        mHasAlarm = if (mEventCursor.getInt(EVENT_INDEX_HAS_ALARM) === 1) true else false
        return true
    }

    @Override
    override fun onSaveInstanceState(outState: Bundle?) {
        super.onSaveInstanceState(outState)
    }

    @Override
    override fun onCreateOptionsMenu(menu: Menu?, inflater: MenuInflater) {
        super.onCreateOptionsMenu(menu, inflater)
        // Show color/edit/delete buttons only in non-dialog configuration
        if (!mIsDialog && !mIsTabletConfig || mWindowStyle == FULL_WINDOW_STYLE) {
            inflater.inflate(R.menu.event_info_title_bar, menu)
            mMenu = menu
        }
    }

    @Override
    override fun onOptionsItemSelected(item: MenuItem): Boolean {

        // If we're a dialog we don't want to handle menu buttons
        if (mIsDialog) {
            return false
        }
        // Handles option menu selections:
        // Home button - close event info activity and start the main calendar
        // one
        // Edit button - start the event edit activity and close the info
        // activity
        // Delete button - start a delete query that calls a runnable that close
        // the info activity
        val itemId: Int = item.getItemId()
        if (itemId == android.R.id.home) {
            Utils.returnToCalendarHome(mContext as Context)
            mActivity?.finish()
            return true
        } else if (itemId == R.id.info_action_edit) {
            mActivity?.finish()
        }
        return super.onOptionsItemSelected(item)
    }

    @Override
    override fun onStop() {
        super.onStop()
    }

    @Override
    override fun onDestroy() {
        if (mEventCursor != null) {
            mEventCursor.close()
        }
        if (mCalendarsCursor != null) {
            mCalendarsCursor.close()
        }
        super.onDestroy()
    }

    /**
     * Creates an exception to a recurring event.  The only change we're making is to the
     * "self attendee status" value.  The provider will take care of updating the corresponding
     * Attendees.attendeeStatus entry.
     *
     * @param eventId The recurring event.
     * @param status The new value for selfAttendeeStatus.
     */
    private fun createExceptionResponse(eventId: Long, status: Int) {
        val values = ContentValues()
        values.put(Events.ORIGINAL_INSTANCE_TIME, startMillis)
        values.put(Events.SELF_ATTENDEE_STATUS, status)
        values.put(Events.STATUS, Events.STATUS_CONFIRMED)
        val ops: ArrayList<ContentProviderOperation> = ArrayList<ContentProviderOperation>()
        val exceptionUri: Uri = Uri.withAppendedPath(
            Events.CONTENT_EXCEPTION_URI,
            eventId.toString()
        )
        ops.add(ContentProviderOperation.newInsert(exceptionUri).withValues(values).build())
    }

    private fun displayEventNotFound() {
        mErrorMsgView?.setVisibility(View.VISIBLE)
        mScrollView?.setVisibility(View.GONE)
        mLoadingMsgView?.setVisibility(View.GONE)
    }

    private fun updateEvent(view: View?) {
        if (mEventCursor == null || view == null) {
            return
        }
        val context: Context = view.getContext() ?: return
        var eventName: String = mEventCursor.getString(EVENT_INDEX_TITLE)
        if (eventName == null || eventName.length == 0) {
            eventName = getActivity().getString(R.string.no_title_label)
        }

        // 3rd parties might not have specified the start/end time when firing the
        // Events.CONTENT_URI intent.  Update these with values read from the db.
        if (startMillis == 0L && endMillis == 0L) {
            startMillis = mEventCursor.getLong(EVENT_INDEX_DTSTART)
            endMillis = mEventCursor.getLong(EVENT_INDEX_DTEND)
            if (endMillis == 0L) {
                val duration: String = mEventCursor.getString(EVENT_INDEX_DURATION)
                if (!TextUtils.isEmpty(duration)) {
                    try {
                        val d = Duration()
                        d.parse(duration)
                        val endMillis: Long = startMillis + d.getMillis()
                        if (endMillis >= startMillis) {
                            this.endMillis = endMillis
                        } else {
                            Log.d(TAG, "Invalid duration string: $duration")
                        }
                    } catch (e: DateException) {
                        Log.d(TAG, "Error parsing duration string $duration", e)
                    }
                }
                if (endMillis == 0L) {
                    endMillis = startMillis
                }
            }
        }
        mAllDay = mEventCursor.getInt(EVENT_INDEX_ALL_DAY) !== 0
        val location: String = mEventCursor.getString(EVENT_INDEX_EVENT_LOCATION)
        val description: String = mEventCursor.getString(EVENT_INDEX_DESCRIPTION)
        val rRule: String = mEventCursor.getString(EVENT_INDEX_RRULE)
        val eventTimezone: String = mEventCursor.getString(EVENT_INDEX_EVENT_TIMEZONE)
        mHeadlines?.setBackgroundColor(mCurrentColor)

        // What
        if (eventName != null) {
            setTextCommon(view, R.id.title, eventName)
        }

        // When
        // Set the date and repeats (if any)
        val localTimezone: String? = Utils.getTimeZone(mActivity, mTZUpdater)
        val resources: Resources = context.getResources()
        var displayedDatetime: String? = Utils.getDisplayedDatetime(
            startMillis, endMillis,
            System.currentTimeMillis(), localTimezone as String, mAllDay, context
        )
        var displayedTimezone: String? = null
        if (!mAllDay) {
            displayedTimezone = Utils.getDisplayedTimezone(
                startMillis, localTimezone,
                eventTimezone
            )
        }
        // Display the datetime.  Make the timezone (if any) transparent.
        if (displayedTimezone == null) {
            setTextCommon(view, R.id.when_datetime, displayedDatetime as CharSequence)
        } else {
            val timezoneIndex: Int = displayedDatetime!!.length
            displayedDatetime += "  $displayedTimezone"
            val sb = SpannableStringBuilder(displayedDatetime)
            val transparentColorSpan = ForegroundColorSpan(
                resources.getColor(R.color.event_info_headline_transparent_color)
            )
            sb.setSpan(
                transparentColorSpan, timezoneIndex, displayedDatetime!!.length,
                Spannable.SPAN_INCLUSIVE_INCLUSIVE
            )
            setTextCommon(view, R.id.when_datetime, sb)
        }
        view.findViewById<View>(R.id.when_repeat).setVisibility(View.GONE)

        // Organizer view is setup in the updateCalendar method

        // Where
        if (location == null || location.trim().length == 0) {
            setVisibilityCommon(view, R.id.where, View.GONE)
        } else {
            val textView: TextView? = mWhere
            if (textView != null) {
                textView.setText(location.trim())
            }
        }

        // Launch Custom App
        if (Utils.isJellybeanOrLater()) {
            updateCustomAppButton()
        }
    }

    private fun updateCustomAppButton() {
        setVisibilityCommon(mView, R.id.launch_custom_app_container, View.GONE)
        return
    }

    private fun sendAccessibilityEvent() {
        val am: AccessibilityManager =
            getActivity().getSystemService(Service.ACCESSIBILITY_SERVICE) as AccessibilityManager
        if (!am.isEnabled()) {
            return
        }
        val event: AccessibilityEvent =
            AccessibilityEvent.obtain(AccessibilityEvent.TYPE_VIEW_FOCUSED)
        event.setClassName(EventInfoFragment::class.java.getName())
        event.setPackageName(getActivity().getPackageName())
        var text = event.getText()
        if (mResponseRadioGroup?.getVisibility() == View.VISIBLE) {
            val id: Int = mResponseRadioGroup!!.getCheckedRadioButtonId()
            if (id != View.NO_ID) {
                text.add((getView()?.findViewById(R.id.response_label) as TextView)?.getText())
                text.add(
                    (mResponseRadioGroup?.findViewById(id) as RadioButton)
                        .getText().toString() + PERIOD_SPACE
                )
            }
        }
        am.sendAccessibilityEvent(event)
    }

    private fun updateCalendar(view: View?) {
        mCalendarOwnerAccount = ""
        if (mCalendarsCursor != null && mEventCursor != null) {
            mCalendarsCursor.moveToFirst()
            val tempAccount: String = mCalendarsCursor.getString(CALENDARS_INDEX_OWNER_ACCOUNT)
            mCalendarOwnerAccount = tempAccount ?: ""
            mOwnerCanRespond = mCalendarsCursor.getInt(CALENDARS_INDEX_OWNER_CAN_RESPOND) !== 0
            mSyncAccountName = mCalendarsCursor.getString(CALENDARS_INDEX_ACCOUNT_NAME)
            setVisibilityCommon(view, R.id.organizer_container, View.GONE)
            mIsBusyFreeCalendar =
                mEventCursor.getInt(EVENT_INDEX_ACCESS_LEVEL) === Calendars.CAL_ACCESS_FREEBUSY
            if (!mIsBusyFreeCalendar) {
                val b: View? = mView?.findViewById(R.id.edit)
                b?.setEnabled(true)
                b?.setOnClickListener(object : OnClickListener {
                    @Override
                    override fun onClick(v: View?) {
                        // For dialogs, just close the fragment
                        // For full screen, close activity on phone, leave it for tablet
                        if (mIsDialog) {
                            this@EventInfoFragment.dismiss()
                        } else if (!mIsTabletConfig) {
                            getActivity().finish()
                        }
                    }
                })
            }
            var button: View
            if ((!mIsDialog && !mIsTabletConfig ||
                mWindowStyle == FULL_WINDOW_STYLE) && mMenu != null
            ) {
                mActivity?.invalidateOptionsMenu()
            }
        } else {
            setVisibilityCommon(view, R.id.calendar, View.GONE)
            sendAccessibilityEventIfQueryDone(TOKEN_QUERY_DUPLICATE_CALENDARS)
        }
    }

    private fun setTextCommon(view: View, id: Int, text: CharSequence) {
        val textView: TextView = view.findViewById(id) as TextView ?: return
        textView.setText(text)
    }

    private fun setVisibilityCommon(view: View?, id: Int, visibility: Int) {
        val v: View? = view?.findViewById(id)
        if (v != null) {
            v.setVisibility(visibility)
        }
        return
    }

    @Override
    override fun onPause() {
        mIsPaused = true
        super.onPause()
    }

    @Override
    override fun onResume() {
        super.onResume()
        if (mIsDialog) {
            setDialogSize(getActivity().getResources())
            applyDialogParams()
        }
        mIsPaused = false
        if (mTentativeUserSetResponse != Attendees.ATTENDEE_STATUS_NONE) {
            val buttonId = findButtonIdForResponse(mTentativeUserSetResponse)
            mResponseRadioGroup?.check(buttonId)
        }
    }

    @Override
    override fun eventsChanged() {
    }

    @get:Override override val supportedEventTypes: Long
        get() = EventType.EVENTS_CHANGED

    @Override
    override fun handleEvent(event: EventInfo?) {
        reloadEvents()
    }

    fun reloadEvents() {}
    @Override
    override fun onClick(view: View?) {
    }

    private fun setDialogSize(r: Resources) {
        mDialogWidth = r.getDimension(R.dimen.event_info_dialog_width).toInt()
        mDialogHeight = r.getDimension(R.dimen.event_info_dialog_height).toInt()
    }
}