package com.smplayer.media3_engine

import android.content.Context
import android.widget.FrameLayout
import kotlin.math.abs

internal class Media3AspectRatioFrameLayout(context: Context) : FrameLayout(context) {
    private var videoAspectRatio: Float = 0f
    private var resizeMode: Int = RESIZE_FIT

    fun setAspectRatio(aspectRatio: Float) {
        if (videoAspectRatio == aspectRatio) return
        videoAspectRatio = aspectRatio
        requestLayout()
    }

    fun setResizeMode(mode: Int) {
        if (resizeMode == mode) return
        resizeMode = mode
        requestLayout()
    }

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
        if (videoAspectRatio <= 0f || resizeMode == RESIZE_FILL) return

        var width = measuredWidth
        var height = measuredHeight
        if (width <= 0 || height <= 0) return

        val viewAspectRatio = width.toFloat() / height
        val aspectDeformation = videoAspectRatio / viewAspectRatio - 1f
        if (abs(aspectDeformation) <= MAX_ASPECT_RATIO_DEFORMATION_FRACTION) return

        when (resizeMode) {
            RESIZE_ZOOM -> {
                if (aspectDeformation > 0f) {
                    width = (height * videoAspectRatio).toInt()
                } else {
                    height = (width / videoAspectRatio).toInt()
                }
            }
            else -> {
                if (aspectDeformation > 0f) {
                    height = (width / videoAspectRatio).toInt()
                } else {
                    width = (height * videoAspectRatio).toInt()
                }
            }
        }

        super.onMeasure(
            MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
            MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY),
        )
        setMeasuredDimension(width, height)
    }

    companion object {
        const val RESIZE_FIT = 0
        const val RESIZE_FILL = 3
        const val RESIZE_ZOOM = 4
        private const val MAX_ASPECT_RATIO_DEFORMATION_FRACTION = 0.01f
    }
}
