/*
 * Copyright 2018 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.
 */
@file:Suppress("NOTHING_TO_INLINE")

package androidx.ui.unit

import androidx.compose.Immutable
import androidx.compose.Stable
import androidx.ui.unit.Dp.Companion.Hairline
import androidx.ui.util.lerp
import androidx.ui.util.packFloats
import androidx.ui.util.unpackFloat1
import androidx.ui.util.unpackFloat2
import kotlin.math.max
import kotlin.math.min
import kotlin.math.sqrt

/**
 * Dimension value representing device-independent pixels (dp). Component APIs specify their
 * dimensions such as line thickness in DP with Dp objects. Hairline (1 pixel) thickness
 * may be specified with [Hairline], a dimension that take up no space. Dp are normally
 * defined using [dp], which can be applied to [Int], [Double], and [Float].
 *     val leftMargin = 10.dp
 *     val rightMargin = 10f.dp
 *     val topMargin = 20.0.dp
 *     val bottomMargin = 10.dp
 * Drawing is done in pixels. To retrieve the pixel size of a Dp, use [toPx]:
 *     val lineThicknessPx = lineThickness.toPx(context)
 * [toPx] is normally needed only for painting operations.
 */
@Suppress("EXPERIMENTAL_FEATURE_WARNING")
@Immutable
inline class Dp(val value: Float) : Comparable<Dp> {
    /**
     * Add two [Dp]s together.
     */
    @Stable
    inline operator fun plus(other: Dp) =
        Dp(value = this.value + other.value)

    /**
     * Subtract a Dp from another one.
     */
    @Stable
    inline operator fun minus(other: Dp) =
        Dp(value = this.value - other.value)

    /**
     * This is the same as multiplying the Dp by -1.0.
     */
    @Stable
    inline operator fun unaryMinus() = Dp(-value)

    /**
     * Divide a Dp by a scalar.
     */
    @Stable
    inline operator fun div(other: Float): Dp =
        Dp(value = value / other)

    @Stable
    inline operator fun div(other: Int): Dp =
        Dp(value = value / other)

    /**
     * Divide by another Dp to get a scalar.
     */
    @Stable
    inline operator fun div(other: Dp): Float = value / other.value

    /**
     * Divide by [DpSquared] to get a [DpInverse].
     */
    @Stable
    inline operator fun div(other: DpSquared): DpInverse =
        DpInverse(value = value / other.value)

    /**
     * Multiply a Dp by a scalar.
     */
    @Stable
    inline operator fun times(other: Float): Dp =
        Dp(value = value * other)

    @Stable
    inline operator fun times(other: Int): Dp =
        Dp(value = value * other)

    /**
     * Multiply by a Dp to get a [DpSquared] result.
     */
    @Stable
    inline operator fun times(other: Dp): DpSquared =
        DpSquared(value = value * other.value)

    /**
     * Multiply by a Dp to get a [DpSquared] result.
     */
    @Stable
    inline operator fun times(other: DpSquared): DpCubed =
        DpCubed(value = value * other.value)

    /**
     * Support comparing Dimensions with comparison operators.
     */
    @Stable
    override /* TODO: inline */ operator fun compareTo(other: Dp) = value.compareTo(other.value)

    @Stable
    override fun toString() = "$value.dp"

    companion object {
        /**
         * A dimension used to represent a hairline drawing element. Hairline elements take up no
         * space, but will draw a single pixel, independent of the device's resolution and density.
         */
        @Stable
        val Hairline = Dp(value = 0f)

        /**
         * Infinite dp dimension.
         */
        @Stable
        val Infinity = Dp(value = Float.POSITIVE_INFINITY)

        /**
         * Constant that means unspecified Dp
         */
        @Stable
        val Unspecified = Dp(value = Float.NaN)
    }
}

/**
 * Create a [Dp] using an [Int]:
 *     val left = 10
 *     val x = left.dp
 *     // -- or --
 *     val y = 10.dp
 */
@Stable
inline val Int.dp: Dp get() = Dp(value = this.toFloat())

/**
 * Create a [Dp] using a [Double]:
 *     val left = 10.0
 *     val x = left.dp
 *     // -- or --
 *     val y = 10.0.dp
 */
@Stable
inline val Double.dp: Dp get() = Dp(value = this.toFloat())

/**
 * Create a [Dp] using a [Float]:
 *     val left = 10f
 *     val x = left.dp
 *     // -- or --
 *     val y = 10f.dp
 */
@Stable
inline val Float.dp: Dp get() = Dp(value = this)

@Stable
inline operator fun Float.div(other: Dp) =
    DpInverse(this / other.value)

@Stable
inline operator fun Double.div(other: Dp) =
    DpInverse(this.toFloat() / other.value)

@Stable
inline operator fun Int.div(other: Dp) =
    DpInverse(this / other.value)

@Stable
inline operator fun Float.times(other: Dp) =
    Dp(this * other.value)

@Stable
inline operator fun Double.times(other: Dp) =
    Dp(this.toFloat() * other.value)

@Stable
inline operator fun Int.times(other: Dp) =
    Dp(this * other.value)

@Stable
inline fun min(a: Dp, b: Dp): Dp = Dp(value = min(a.value, b.value))

@Stable
inline fun max(a: Dp, b: Dp): Dp = Dp(value = max(a.value, b.value))

/**
 * Ensures that this value lies in the specified range [minimumValue]..[maximumValue].
 *
 * @return this value if it's in the range, or [minimumValue] if this value is less than
 * [minimumValue], or [maximumValue] if this value is greater than [maximumValue].
 */
@Stable
inline fun Dp.coerceIn(minimumValue: Dp, maximumValue: Dp): Dp =
    Dp(value = value.coerceIn(minimumValue.value, maximumValue.value))

/**
 * Ensures that this value is not less than the specified [minimumValue].
 * @return this value if it's greater than or equal to the [minimumValue] or the
 * [minimumValue] otherwise.
 */
@Stable
inline fun Dp.coerceAtLeast(minimumValue: Dp): Dp =
    Dp(value = value.coerceAtLeast(minimumValue.value))

/**
 * Ensures that this value is not greater than the specified [maximumValue].
 *
 * @return this value if it's less than or equal to the [maximumValue] or the
 * [maximumValue] otherwise.
 */
@Stable
inline fun Dp.coerceAtMost(maximumValue: Dp): Dp =
    Dp(value = value.coerceAtMost(maximumValue.value))

/**
 *
 * Return `true` when it is finite or `false` when it is [Dp.Infinity]
 */
@Stable
inline fun Dp.isFinite(): Boolean = value != Float.POSITIVE_INFINITY

/**
 * Linearly interpolate between two [Dp]s.
 *
 * The [fraction] argument represents position on the timeline, with 0.0 meaning
 * that the interpolation has not started, returning [start] (or something
 * equivalent to [start]), 1.0 meaning that the interpolation has finished,
 * returning [stop] (or something equivalent to [stop]), and values in between
 * meaning that the interpolation is at the relevant point on the timeline
 * between [start] and [stop]. The interpolation can be extrapolated beyond 0.0 and
 * 1.0, so negative values and values greater than 1.0 are valid.
 */
@Stable
fun lerp(start: Dp, stop: Dp, fraction: Float): Dp {
    return Dp(lerp(start.value, stop.value, fraction))
}

/**
 * Holds a unit of squared dimensions, such as `1.value * 2.dp`. [DpSquared], [DpCubed],
 * and [DpInverse] are used primarily for [Dp] calculations to ensure resulting
 * units are as expected. Many times, [Dp] calculations use scalars to determine the final
 * dimension during calculation:
 *     val width = oldWidth * stretchAmount
 * Other times, it is useful to do intermediate calculations with Dimensions directly:
 *     val width = oldWidth * newTotalWidth / oldTotalWidth
 */
@Suppress("EXPERIMENTAL_FEATURE_WARNING")
@Immutable
inline class DpSquared(val value: Float) : Comparable<DpSquared> {
    /**
     * Add two DimensionSquares together.
     */
    @Stable
    inline operator fun plus(other: DpSquared) =
        DpSquared(value = value + other.value)

    /**
     * Subtract a DimensionSquare from another one.
     */
    @Stable
    inline operator fun minus(other: DpSquared) =
        DpSquared(value = value - other.value)

    /**
     * Divide a DimensionSquare by a scalar.
     */
    @Stable
    inline operator fun div(other: Float): DpSquared =
        DpSquared(value = value / other)

    /**
     * Divide by a [Dp] to get a [Dp] result.
     */
    @Stable
    inline operator fun div(other: Dp): Dp =
        Dp(value = value / other.value)

    /**
     * Divide by a DpSquared to get a scalar result.
     */
    @Stable
    inline operator fun div(other: DpSquared): Float = value / other.value

    /**
     * Divide by a [DpCubed] to get a [DpInverse] result.
     */
    @Stable
    inline operator fun div(other: DpCubed): DpInverse =
        DpInverse(value / other.value)

    /**
     * Multiply by a scalar to get a DpSquared result.
     */
    @Stable
    inline operator fun times(other: Float): DpSquared =
        DpSquared(value = value * other)

    /**
     * Multiply by a scalar to get a DpSquared result.
     */
    @Stable
    inline operator fun times(other: Dp): DpCubed =
        DpCubed(value = value * other.value)

    /**
     * Support comparing DpSquared with comparison operators.
     */
    @Stable
    override /* TODO: inline */ operator fun compareTo(other: DpSquared) =
        value.compareTo(other.value)

    @Stable
    override fun toString(): String = "$value.dp^2"
}

/**
 * Holds a unit of cubed dimensions, such as `1.value * 2.value * 3.dp`. [DpSquared],
 * [DpCubed], and [DpInverse] are used primarily for [Dp] calculations to
 * ensure resulting units are as expected. Many times, [Dp] calculations use scalars to
 * determine the final dimension during calculation:
 *     val width = oldWidth * stretchAmount
 * Other times, it is useful to do intermediate calculations with Dimensions directly:
 *     val width = oldWidth * newTotalWidth / oldTotalWidth
 */
@Suppress("EXPERIMENTAL_FEATURE_WARNING")
@Immutable
inline class DpCubed(val value: Float) : Comparable<DpCubed> {

    /**
     * Add two DpCubed together.
     */
    @Stable
    inline operator fun plus(dimension: DpCubed) =
        DpCubed(value = value + dimension.value)

    /**
     * Subtract a DpCubed from another one.
     */
    @Stable
    inline operator fun minus(dimension: DpCubed) =
        DpCubed(value = value - dimension.value)

    /**
     * Divide a DpCubed by a scalar.
     */
    @Stable
    inline operator fun div(other: Float): DpCubed =
        DpCubed(value = value / other)

    /**
     * Divide by a [Dp] to get a [DpSquared] result.
     */
    @Stable
    inline operator fun div(other: Dp): DpSquared =
        DpSquared(value = value / other.value)

    /**
     * Divide by a [DpSquared] to get a [Dp] result.
     */
    @Stable
    inline operator fun div(other: DpSquared): Dp =
        Dp(value = value / other.value)

    /**
     * Divide by a DpCubed to get a scalar result.
     */
    @Stable
    inline operator fun div(other: DpCubed): Float = value / other.value

    /**
     * Multiply by a scalar to get a DpCubed result.
     */
    @Stable
    inline operator fun times(other: Float): DpCubed =
        DpCubed(value = value * other)

    /**
     * Support comparing DpCubed with comparison operators.
     */
    @Stable
    override /* TODO: inline */ operator fun compareTo(other: DpCubed) =
        value.compareTo(other.value)

    @Stable
    override fun toString(): String = "$value.dp^3"
}
/**
 * Holds a unit of an inverse dimensions, such as `1.dp / (2.value * 3.dp)`. [DpSquared],
 * [DpCubed], and [DpInverse] are used primarily for [Dp] calculations to
 * ensure resulting units are as expected. Many times, [Dp] calculations use scalars to
 * determine the final dimension during calculation:
 *     val width = oldWidth * stretchAmount
 * Other times, it is useful to do intermediate calculations with Dimensions directly:
 *     val width = oldWidth * newTotalWidth / oldTotalWidth
 */
@Suppress("EXPERIMENTAL_FEATURE_WARNING")
@Immutable
inline class DpInverse(val value: Float) : Comparable<DpInverse> {
    /**
     * Add two DpInverse together.
     */
    @Stable
    inline operator fun plus(dimension: DpInverse) =
        DpInverse(value = value + dimension.value)

    /**
     * Subtract a DpInverse from another one.
     */
    @Stable
    inline operator fun minus(dimension: DpInverse) =
        DpInverse(value = value - dimension.value)

    /**
     * Divide a DpInverse by a scalar.
     */
    @Stable
    inline operator fun div(other: Float): DpInverse =
        DpInverse(value = value / other)

    /**
     * Multiply by a scalar to get a DpInverse result.
     */
    @Stable
    inline operator fun times(other: Float): DpInverse =
        DpInverse(value = value * other)

    /**
     * Multiply by a [Dp] to get a scalar result.
     */
    @Stable
    inline operator fun times(other: Dp): Float = value * other.value

    /**
     * Multiply by a [DpSquared] to get a [Dp] result.
     */
    @Stable
    inline operator fun times(other: DpSquared): Dp =
        Dp(value = value * other.value)

    /**
     * Multiply by a [DpCubed] to get a [DpSquared] result.
     */
    @Stable
    inline operator fun times(other: DpCubed): DpSquared =
        DpSquared(value = value * other.value)

    /**
     * Support comparing DpInverse with comparison operators.
     */
    @Stable
    override /* TODO: inline */ operator fun compareTo(other: DpInverse) =
        value.compareTo(other.value)

    @Stable
    override fun toString(): String = "$value.dp^-1"
}

// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
// Structures using Dp
// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

/**
 * A two-dimensional position using [Dp] for units
 */
@OptIn(ExperimentalUnsignedTypes::class)
@Suppress("EXPERIMENTAL_FEATURE_WARNING")
@Immutable
inline class Position(@PublishedApi internal val packedValue: Long) {
    /**
     * The horizontal aspect of the position in [Dp]
     */
    @Stable
    /*inline*/ val x: Dp
        get() = unpackFloat1(packedValue).dp

    /**
     * The vertical aspect of the position in [Dp]
     */
    @Stable
    /*inline*/ val y: Dp
        get() = unpackFloat2(packedValue).dp

    /**
     * Subtract a [Position] from another one.
     */
    @Stable
    inline operator fun minus(other: Position) =
        Position(x - other.x, y - other.y)

    /**
     * Add a [Position] to another one.
     */
    @Stable
    inline operator fun plus(other: Position) =
        Position(x + other.x, y + other.y)

    @Stable
    override fun toString(): String = "($x, $y)"
}

/**
 * Constructs a [Position] from [x] and [y] position [Dp] values.
 */
@OptIn(ExperimentalUnsignedTypes::class)
@Stable
inline fun Position(x: Dp, y: Dp): Position = Position(packFloats(x.value, y.value))

/**
 * The magnitude of the offset represented by this [Position].
 */
@Stable
fun Position.getDistance(): Dp {
    return Dp(sqrt(x.value * x.value + y.value * y.value))
}

/**
 * Linearly interpolate between two [Position]s.
 *
 * The [fraction] argument represents position on the timeline, with 0.0 meaning
 * that the interpolation has not started, returning [start] (or something
 * equivalent to [start]), 1.0 meaning that the interpolation has finished,
 * returning [stop] (or something equivalent to [stop]), and values in between
 * meaning that the interpolation is at the relevant point on the timeline
 * between [start] and [stop]. The interpolation can be extrapolated beyond 0.0 and
 * 1.0, so negative values and values greater than 1.0 are valid.
 */
@Stable
fun lerp(start: Position, stop: Position, fraction: Float): Position =
    Position(lerp(start.x, stop.x, fraction), lerp(start.y, stop.y, fraction))

/**
 * A four dimensional bounds using [Dp] for units
 */
@Immutable
data class Bounds(
    @Stable
    val left: Dp,
    @Stable
    val top: Dp,
    @Stable
    val right: Dp,
    @Stable
    val bottom: Dp
)

/**
 * A width of this Bounds in [Dp].
 */
@Stable
inline val Bounds.width: Dp get() = right - left

/**
 * A height of this Bounds in [Dp].
 */
@Stable
inline val Bounds.height: Dp get() = bottom - top
