/*
 * 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.month
// TODO Remove calendar imports when the required methods have been
// refactored into the public api
import com.android.calendar.CalendarController
import com.android.calendar.Utils
import android.content.Context
import android.text.format.Time
import android.util.Log
import android.view.GestureDetector
import android.view.MotionEvent
import android.view.View
import android.view.View.OnTouchListener
import android.view.ViewGroup
import android.widget.AbsListView.LayoutParams
import android.widget.BaseAdapter
import android.widget.ListView
import java.util.Calendar
import java.util.HashMap
import java.util.Locale

/**
 *
 *
 * This is a specialized adapter for creating a list of weeks with selectable
 * days. It can be configured to display the week number, start the week on a
 * given day, show a reduced number of days, or display an arbitrary number of
 * weeks at a time. See [SimpleDayPickerFragment] for usage.
 *
 */
open class SimpleWeeksAdapter(context: Context, params: HashMap<String?, Int?>?) : BaseAdapter(),
    OnTouchListener {
    protected var mContext: Context

    // The day to highlight as selected
    protected var mSelectedDay: Time? = null

    // The week since 1970 that the selected day is in
    protected var mSelectedWeek = 0

    // When the week starts; numbered like Time.<WEEKDAY> (e.g. SUNDAY=0).
    protected var mFirstDayOfWeek: Int
    protected var mShowWeekNumber = false
    protected var mGestureDetector: GestureDetector? = null
    protected var mNumWeeks = DEFAULT_NUM_WEEKS
    protected var mDaysPerWeek = DEFAULT_DAYS_PER_WEEK
    protected var mFocusMonth = DEFAULT_MONTH_FOCUS

    /**
     * Set up the gesture detector and selected time
     */
    protected open fun init() {
        mGestureDetector = GestureDetector(mContext, CalendarGestureListener())
        mSelectedDay = Time()
        mSelectedDay?.setToNow()
    }

    /**
     * Parse the parameters and set any necessary fields. See
     * [.WEEK_PARAMS_NUM_WEEKS] for parameter details.
     *
     * @param params A list of parameters for this adapter
     */
    fun updateParams(params: HashMap<String?, Int?>?) {
        if (params == null) {
            Log.e(TAG, "WeekParameters are null! Cannot update adapter.")
            return
        }
        if (params.containsKey(WEEK_PARAMS_FOCUS_MONTH)) {
            // Casting from Int? --> Int
            mFocusMonth = params.get(WEEK_PARAMS_FOCUS_MONTH) as Int
        }
        if (params.containsKey(WEEK_PARAMS_FOCUS_MONTH)) {
            // Casting from Int? --> Int
            mNumWeeks = params.get(WEEK_PARAMS_NUM_WEEKS) as Int
        }
        if (params.containsKey(WEEK_PARAMS_SHOW_WEEK)) {
            // Casting from Int? --> Int
            mShowWeekNumber = params.get(WEEK_PARAMS_SHOW_WEEK) as Int != 0
        }
        if (params.containsKey(WEEK_PARAMS_WEEK_START)) {
            // Casting from Int? --> Int
            mFirstDayOfWeek = params.get(WEEK_PARAMS_WEEK_START) as Int
        }
        if (params.containsKey(WEEK_PARAMS_JULIAN_DAY)) {
            // Casting from Int? --> Int
            val julianDay: Int = params.get(WEEK_PARAMS_JULIAN_DAY) as Int
            mSelectedDay?.setJulianDay(julianDay)
            mSelectedWeek = Utils.getWeeksSinceEpochFromJulianDay(julianDay, mFirstDayOfWeek)
        }
        if (params.containsKey(WEEK_PARAMS_DAYS_PER_WEEK)) {
            // Casting from Int? --> Int
            mDaysPerWeek = params.get(WEEK_PARAMS_DAYS_PER_WEEK) as Int
        }
        refresh()
    }

    /**
     * Updates the selected day and related parameters.
     *
     * @param selectedTime The time to highlight
     */
    open fun setSelectedDay(selectedTime: Time?) {
        mSelectedDay?.set(selectedTime)
        val millis: Long = mSelectedDay!!.normalize(true)
        mSelectedWeek = Utils.getWeeksSinceEpochFromJulianDay(
            Time.getJulianDay(millis, mSelectedDay!!.gmtoff), mFirstDayOfWeek
        )
        notifyDataSetChanged()
    }

    /**
     * Returns the currently highlighted day
     *
     * @return
     */
    fun getSelectedDay(): Time? {
        return mSelectedDay
    }

    /**
     * updates any config options that may have changed and refreshes the view
     */
    internal open fun refresh() {
        notifyDataSetChanged()
    }

    @Override
    override fun getCount(): Int {
        return WEEK_COUNT
    }

    @Override
    override fun getItem(position: Int): Any? {
        return null
    }

    @Override
    override fun getItemId(position: Int): Long {
        return position.toLong()
    }

    @SuppressWarnings("unchecked")
    @Override
    override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
        val v: SimpleWeekView
        var drawingParams: HashMap<String?, Int?>? = null
        if (convertView != null) {
            v = convertView as SimpleWeekView
            // We store the drawing parameters in the view so it can be recycled
            drawingParams = v.getTag() as HashMap<String?, Int?>
        } else {
            v = SimpleWeekView(mContext)
            // Set up the new view
            val params = LayoutParams(
                LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT
            )
            v.setLayoutParams(params)
            v.setClickable(true)
            v.setOnTouchListener(this)
        }
        if (drawingParams == null) {
            drawingParams = HashMap<String?, Int?>()
        }
        drawingParams.clear()
        var selectedDay = -1
        if (mSelectedWeek == position) {
            selectedDay = mSelectedDay!!.weekDay
        }

        // pass in all the view parameters
        drawingParams.put(
            SimpleWeekView.VIEW_PARAMS_HEIGHT,
            (parent.getHeight() - WEEK_7_OVERHANG_HEIGHT) / mNumWeeks
        )
        drawingParams.put(SimpleWeekView.VIEW_PARAMS_SELECTED_DAY, selectedDay)
        drawingParams.put(SimpleWeekView.VIEW_PARAMS_SHOW_WK_NUM, if (mShowWeekNumber) 1 else 0)
        drawingParams.put(SimpleWeekView.VIEW_PARAMS_WEEK_START, mFirstDayOfWeek)
        drawingParams.put(SimpleWeekView.VIEW_PARAMS_NUM_DAYS, mDaysPerWeek)
        drawingParams.put(SimpleWeekView.VIEW_PARAMS_WEEK, position)
        drawingParams.put(SimpleWeekView.VIEW_PARAMS_FOCUS_MONTH, mFocusMonth)
        v.setWeekParams(drawingParams, mSelectedDay!!.timezone)
        v.invalidate()
        return v
    }

    /**
     * Changes which month is in focus and updates the view.
     *
     * @param month The month to show as in focus [0-11]
     */
    fun updateFocusMonth(month: Int) {
        mFocusMonth = month
        notifyDataSetChanged()
    }

    @Override
    override fun onTouch(v: View, event: MotionEvent): Boolean {
        if (mGestureDetector!!.onTouchEvent(event)) {
            val view: SimpleWeekView = v as SimpleWeekView
            val day: Time? = (v as SimpleWeekView).getDayFromLocation(event.getX())
            if (Log.isLoggable(TAG, Log.DEBUG)) {
                Log.d(TAG, "Touched day at Row=" + view.mWeek.toString() + " day=" +
                    day?.toString())
            }
            if (day != null) {
                onDayTapped(day)
            }
            return true
        }
        return false
    }

    /**
     * Maintains the same hour/min/sec but moves the day to the tapped day.
     *
     * @param day The day that was tapped
     */
    protected open fun onDayTapped(day: Time) {
        day.hour = mSelectedDay!!.hour
        day.minute = mSelectedDay!!.minute
        day.second = mSelectedDay!!.second
        setSelectedDay(day)
    }

    /**
     * This is here so we can identify single tap events and set the selected
     * day correctly
     */
    protected inner class CalendarGestureListener : GestureDetector.SimpleOnGestureListener() {
        @Override
        override fun onSingleTapUp(e: MotionEvent?): Boolean {
            return true
        }
    }

    var mListView: ListView? = null
    fun setListView(lv: ListView?) {
        mListView = lv
    }

    companion object {
        private const val TAG = "MonthByWeek"

        /**
         * The number of weeks to display at a time.
         */
        const val WEEK_PARAMS_NUM_WEEKS = "num_weeks"

        /**
         * Which month should be in focus currently.
         */
        const val WEEK_PARAMS_FOCUS_MONTH = "focus_month"

        /**
         * Whether the week number should be shown. Non-zero to show them.
         */
        const val WEEK_PARAMS_SHOW_WEEK = "week_numbers"

        /**
         * Which day the week should start on. [Time.SUNDAY] through
         * [Time.SATURDAY].
         */
        const val WEEK_PARAMS_WEEK_START = "week_start"

        /**
         * The Julian day to highlight as selected.
         */
        const val WEEK_PARAMS_JULIAN_DAY = "selected_day"

        /**
         * How many days of the week to display [1-7].
         */
        const val WEEK_PARAMS_DAYS_PER_WEEK = "days_per_week"
        protected const val WEEK_COUNT = CalendarController.MAX_CALENDAR_WEEK -
            CalendarController.MIN_CALENDAR_WEEK
        protected var DEFAULT_NUM_WEEKS = 6
        protected var DEFAULT_MONTH_FOCUS = 0
        protected var DEFAULT_DAYS_PER_WEEK = 7
        protected var DEFAULT_WEEK_HEIGHT = 32
        protected var WEEK_7_OVERHANG_HEIGHT = 7
        protected var mScale = 0f
    }

    init {
        mContext = context

        // Get default week start based on locale, subtracting one for use with android Time.
        val cal: Calendar = Calendar.getInstance(Locale.getDefault())
        mFirstDayOfWeek = cal.getFirstDayOfWeek() - 1
        if (mScale == 0f) {
            mScale = context.getResources().getDisplayMetrics().density
            if (mScale != 1f) {
                WEEK_7_OVERHANG_HEIGHT *= mScale.toInt()
            }
        }
        init()
        updateParams(params)
    }
}