/*
 * Copyright 2020 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 androidx.wear.watchface

import android.graphics.Color
import androidx.annotation.ColorInt
import androidx.annotation.RestrictTo
import androidx.wear.watchface.RenderParameters.HighlightLayer
import androidx.wear.watchface.data.IdAndTapEventWireFormat
import androidx.wear.watchface.data.RenderParametersWireFormat
import androidx.wear.watchface.style.WatchFaceLayer
import androidx.wear.watchface.style.UserStyleSetting
import java.time.Instant

/* Used to parameterize watch face drawing based on the current system state. */
public enum class DrawMode {
    /**
     * This mode is used when the user is interacting with the watch face.
     *
     * This is currently the only mode that is supported when editing the watch face.
     */
    INTERACTIVE,

    /**
     * This mode is used when the user is interacting with the watch face but the battery is
     * low, the watch face should render fewer pixels, ideally with darker colors.
     */
    LOW_BATTERY_INTERACTIVE,

    /**
     * This mode is used when there's an interruption filter. The watch face should look muted.
     */
    MUTE,

    /**
     * In this mode as few pixels as possible should be turned on, ideally with darker colors.
     *
     * Typically watch faces switch to a simplified display when in ambient mode. E.g. if the watch
     * face displays seconds, it should hide them in ambient mode.
     *
     * Note: In ambient mode the watch face will be rendered once per minute.
     */
    AMBIENT
}

/**
 * Used to parameterize watch face rendering.
 *
 * Watch face rendering is split up in a number of layers: the base layer [WatchFaceLayer.BASE], the
 * [ComplicationSlot]s layer [WatchFaceLayer.COMPLICATIONS], and the layer above the
 * complicationSlots [WatchFaceLayer.COMPLICATIONS_OVERLAY]. These layers are always drawn in
 * this order, one on top of the previous one. These are the layers that are used to render the
 * watch face itself.
 *
 * An additional layer, the highlight layer, can be drawn during editing the watch face to highlight
 * different elements of the watch face, namely a set of [ComplicationSlot]s (which may be a single
 * ComplicationSlot) or the area of the watch face that is affected by a single user style setting.
 *
 * The watch face should provide a way to highlight any of the above combinations so that its own
 * editor, or the one provided by the Wear OS companion phone app is able to highlight the editable
 * part of the watch face to the user. If an individual user style setting is meant to affect the
 * entire watch face (e.g. an overall color setting),then  the entire watch face should be
 * highlighted.
 *
 * The watch face layers and highlight layer can be configured independently, so that it is possible
 * to draw only the highlight layer by passing an empty set of [watchFaceLayers].
 *
 * The semantics of rendering different layers is such that if each individual layer is rendered
 * independently and the resulting images are composited with alpha blending, the result is
 * identical to rendering all of the layers in a single request.
 *
 * @param drawMode The overall drawing parameters based on system state.
 * @param watchFaceLayers The parts of the watch face to draw.
 * @param highlightLayer Optional [HighlightLayer] used by editors to visually highlight an
 * aspect of the watch face. Rendered last on top of [watchFaceLayers]. If highlighting isn't needed
 * this will be `null`.
 * @param lastComplicationTapDownEvents Map of [ComplicationSlot] id to the latest [TapType.DOWN]
 * [TapEvent] that ComplicationSlot received, if any.
 */
public class RenderParameters @JvmOverloads constructor(
    public val drawMode: DrawMode,
    public val watchFaceLayers: Set<WatchFaceLayer>,
    public val highlightLayer: HighlightLayer? = null,
    public val lastComplicationTapDownEvents: Map<Int, TapEvent> = emptyMap()
) {
    init {
        require(watchFaceLayers.isNotEmpty() || highlightLayer != null) {
            "Either watchFaceLayers must be non empty or " +
                "renderParameters.highlightLayer must be non-null."
        }
    }

    /** An element of the watch face to highlight. */
    public sealed class HighlightedElement {
        /** All [ComplicationSlot]s will be highlighted. */
        public object AllComplicationSlots : HighlightedElement()

        /**
         * A single [androidx.wear.watchface.ComplicationSlot] with the specified [id] will be
         * highlighted.
         */
        public class ComplicationSlot(public val id: Int) : HighlightedElement() {
            override fun equals(other: Any?): Boolean {
                if (this === other) return true
                if (javaClass != other?.javaClass) return false

                other as ComplicationSlot

                if (id != other.id) return false

                return true
            }

            override fun hashCode(): Int {
                return id
            }
        }

        /**
         * A [UserStyleSetting] to highlight. E.g. for a setting that controls watch hands, the
         * location of the hands should be highlighted.
         *
         * @param id The [UserStyleSetting.Id] of the [UserStyleSetting] to highlight.
         */
        public class UserStyle(public val id: UserStyleSetting.Id) : HighlightedElement() {
            override fun equals(other: Any?): Boolean {
                if (this === other) return true
                if (javaClass != other?.javaClass) return false

                other as UserStyle

                if (id != other.id) return false
                return true
            }

            override fun hashCode(): Int {
                return id.hashCode()
            }
        }
    }

    /**
     * The definition of what to include in the highlight layer.
     *
     * The highlight layer is used by editors to show the parts of the watch face affected by a
     * setting. E.g. a set of [ComplicationSlot]s or a user style setting.
     *
     * The highlight layer is composited on top of the watch face with an alpha blend. It should
     * be cleared with [backgroundTint]. The solid or semi-transparent outline around
     * [highlightedElement] should be rendered using the provided [highlightTint]. The highlighted
     * element itself should be rendered as fully transparent (an alpha value of 0) to leave it
     * unaffected.
     *
     * @param highlightedElement The [HighlightedElement] to draw highlighted with [highlightTint].
     * @param highlightTint The highlight tint to apply to [highlightedElement].
     * @param backgroundTint The tint to apply to everything other than [highlightedElement].
     * Typically this will darken everything else to increase contrast.
     */
    public class HighlightLayer(
        public val highlightedElement: HighlightedElement,

        @ColorInt
        @get:ColorInt
        public val highlightTint: Int,

        @ColorInt
        @get:ColorInt
        public val backgroundTint: Int
    ) {
        override fun equals(other: Any?): Boolean {
            if (this === other) return true
            if (javaClass != other?.javaClass) return false

            other as HighlightLayer

            if (highlightedElement != other.highlightedElement) return false
            if (highlightTint != other.highlightTint) return false
            if (backgroundTint != other.backgroundTint) return false

            return true
        }

        override fun hashCode(): Int {
            var result = highlightedElement.hashCode()
            result = 31 * result + highlightTint
            result = 31 * result + backgroundTint
            return result
        }
    }

    public companion object {
        /** Default RenderParameters which draws everything in interactive mode. */
        @JvmField
        public val DEFAULT_INTERACTIVE: RenderParameters =
            RenderParameters(DrawMode.INTERACTIVE, WatchFaceLayer.ALL_WATCH_FACE_LAYERS, null)
    }

    /** @hide */
    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP_PREFIX)
    public constructor(wireFormat: RenderParametersWireFormat) : this(
        DrawMode.values()[wireFormat.drawMode],
        HashSet<WatchFaceLayer>().apply {
            WatchFaceLayer.values().forEachIndexed { index, layer ->
                if (wireFormat.watchFaceLayerSetBitfield and 1.shl(index) != 0) {
                    add(layer)
                }
            }
        },
        when (wireFormat.elementType) {
            RenderParametersWireFormat.ELEMENT_TYPE_NONE -> null

            RenderParametersWireFormat.ELEMENT_TYPE_ALL_COMPLICATIONS -> {
                HighlightLayer(
                    HighlightedElement.AllComplicationSlots,
                    wireFormat.highlightTint,
                    wireFormat.backgroundTint
                )
            }

            RenderParametersWireFormat.ELEMENT_TYPE_COMPLICATION -> {
                HighlightLayer(
                    HighlightedElement.ComplicationSlot(wireFormat.elementComplicationSlotId),
                    wireFormat.highlightTint,
                    wireFormat.backgroundTint
                )
            }

            RenderParametersWireFormat.ELEMENT_TYPE_USER_STYLE -> {
                HighlightLayer(
                    HighlightedElement.UserStyle(
                        UserStyleSetting.Id(wireFormat.elementUserStyleSettingId!!)
                    ),
                    wireFormat.highlightTint,
                    wireFormat.backgroundTint
                )
            }

            else -> null
        },
        wireFormat.idAndTapEventWireFormat?.associate {
            Pair(it.id, TapEvent(it.x, it.y, Instant.ofEpochMilli(it.calendarTapTimeMillis)))
        } ?: emptyMap()
    )

    /** @hide */
    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP_PREFIX)
    public fun toWireFormat(): RenderParametersWireFormat {
        val idAndTapEventWireFormats = lastComplicationTapDownEvents.map {
            IdAndTapEventWireFormat(
                it.key,
                it.value.xPos,
                it.value.yPos,
                it.value.tapTime.toEpochMilli()
            )
        }
        return when (val thingHighlighted = highlightLayer?.highlightedElement) {
            is HighlightedElement.AllComplicationSlots -> RenderParametersWireFormat(
                drawMode.ordinal,
                computeLayersBitfield(),
                RenderParametersWireFormat.ELEMENT_TYPE_ALL_COMPLICATIONS,
                0,
                null,
                highlightLayer!!.highlightTint,
                highlightLayer.backgroundTint,
                idAndTapEventWireFormats
            )

            is HighlightedElement.ComplicationSlot -> RenderParametersWireFormat(
                drawMode.ordinal,
                computeLayersBitfield(),
                RenderParametersWireFormat.ELEMENT_TYPE_COMPLICATION,
                thingHighlighted.id,
                null,
                highlightLayer!!.highlightTint,
                highlightLayer.backgroundTint,
                idAndTapEventWireFormats
            )

            is HighlightedElement.UserStyle -> RenderParametersWireFormat(
                drawMode.ordinal,
                computeLayersBitfield(),
                RenderParametersWireFormat.ELEMENT_TYPE_USER_STYLE,
                0,
                thingHighlighted.id.value,
                highlightLayer!!.highlightTint,
                highlightLayer.backgroundTint,
                idAndTapEventWireFormats
            )

            else -> RenderParametersWireFormat(
                drawMode.ordinal,
                computeLayersBitfield(),
                RenderParametersWireFormat.ELEMENT_TYPE_NONE,
                0,
                null,
                Color.BLACK,
                Color.BLACK,
                idAndTapEventWireFormats
            )
        }
    }

    private fun computeLayersBitfield(): Int {
        var bitfield = 0
        WatchFaceLayer.values().forEachIndexed { index, layer ->
            if (watchFaceLayers.contains(layer)) {
                bitfield += 1.shl(index)
            }
        }
        return bitfield
    }

    internal fun dump(writer: IndentingPrintWriter) {
        writer.println("RenderParameters:")
        writer.increaseIndent()
        writer.println("drawMode=${drawMode.name}")
        writer.println("watchFaceLayers=${watchFaceLayers.joinToString()}")
        writer.println(
            "lastComplicationTapDownEvents=" + lastComplicationTapDownEvents.map {
                it.key.toString() + "->" + it.value
            }.joinToString(", ")
        )

        highlightLayer?.let {
            writer.println("HighlightLayer:")
            writer.increaseIndent()
            when (it.highlightedElement) {
                is HighlightedElement.AllComplicationSlots -> {
                    writer.println("HighlightedElement.AllComplicationSlots:")
                }

                is HighlightedElement.ComplicationSlot -> {
                    writer.println("HighlightedElement.ComplicationSlot:")
                    writer.increaseIndent()
                    writer.println("id=${it.highlightedElement.id}")
                    writer.decreaseIndent()
                }

                is HighlightedElement.UserStyle -> {
                    writer.println("HighlightedElement.UserStyle:")
                    writer.increaseIndent()
                    writer.println("id=${it.highlightedElement.id}")
                    writer.decreaseIndent()
                }
            }
            writer.println("highlightTint=${it.highlightTint}")
            writer.println("backgroundTint=${it.backgroundTint}")
            writer.decreaseIndent()
        }
        writer.decreaseIndent()
    }

    override fun equals(other: Any?): Boolean {
        if (this === other) return true
        if (javaClass != other?.javaClass) return false

        other as RenderParameters

        if (drawMode != other.drawMode) return false
        if (watchFaceLayers != other.watchFaceLayers) return false
        if (highlightLayer != other.highlightLayer) return false
        if (lastComplicationTapDownEvents != other.lastComplicationTapDownEvents) return false

        return true
    }

    override fun hashCode(): Int {
        var result = drawMode.hashCode()
        result = 31 * result + watchFaceLayers.hashCode()
        result = 31 * result + (highlightLayer?.hashCode() ?: 0)
        result = 31 * result + lastComplicationTapDownEvents.hashCode()
        return result
    }
}
