/*
 * Copyright 2016-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
 */

package org.jetbrains.kotlinx.animation

import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModel
import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.RectF
import android.util.AttributeSet
import android.view.View
import kotlinx.coroutines.*
import kotlinx.coroutines.android.*
import java.util.*

sealed class AnimatedShape {
    var x = 0.5f // 0 .. 1
    var y = 0.5f // 0 .. 1
    var color = Color.BLACK
    var r = 0.05f
}

class AnimatedCircle : AnimatedShape()
class AnimatedSquare : AnimatedShape()

private val NO_SHAPES = emptySet<AnimatedShape>()

class AnimationView(
        context: Context, attributeSet: AttributeSet
) : View(context, attributeSet), Observer<Set<AnimatedShape>> {
    private var shapes = NO_SHAPES
    private val paint = Paint()
    private val rect = RectF()

    override fun onChanged(shapes: Set<AnimatedShape>?) {
        this.shapes = shapes ?: NO_SHAPES
        invalidate()
    }

    override fun onDraw(canvas: Canvas) {
        val scale = minOf(width, height) / 2.0f
        shapes.forEach { shape ->
            val x = (shape.x - 0.5f) * scale + width / 2
            val y = (shape.y - 0.5f) * scale + height / 2
            val r = shape.r * scale
            rect.set(x - r, y - r, x + r, y + r)
            paint.color = shape.color
            when (shape) {
                is AnimatedCircle -> canvas.drawArc(rect, 0.0f, 360.0f, true, paint)
                is AnimatedSquare -> canvas.drawRect(rect, paint)
            }
        }
    }
}

private val rnd = Random()

class AnimationModel : ViewModel(), CoroutineScope {

    override val coroutineContext = Job() + Dispatchers.Main

    private val shapes = MutableLiveData<Set<AnimatedShape>>()

    fun observe(owner: LifecycleOwner, observer: Observer<Set<AnimatedShape>>) =
        shapes.observe(owner, observer)

    fun update(shape: AnimatedShape) {
        val old = shapes.value ?: NO_SHAPES
        shapes.value = if (shape in old) old else old + shape
    }

    fun addAnimation() {
        launch {
            animateShape(if (rnd.nextBoolean()) AnimatedCircle() else AnimatedSquare())
        }
    }

    fun clearAnimations() {
        coroutineContext.cancelChildren()
        shapes.value = NO_SHAPES
    }
}

private fun norm(x: Float, y: Float) = Math.hypot(x.toDouble(), y.toDouble()).toFloat()

private const val ACC = 1e-18f
private const val MAX_SPEED = 2e-9f // in screen_fraction/nanos
private const val INIT_POS = 0.8f

private fun Random.nextColor() = Color.rgb(nextInt(256), nextInt(256), nextInt(256))
private fun Random.nextPos() = nextFloat() * INIT_POS + (1 - INIT_POS) / 2
private fun Random.nextSpeed() = nextFloat() * MAX_SPEED - MAX_SPEED / 2

suspend fun AnimationModel.animateShape(shape: AnimatedShape) {
    shape.x = rnd.nextPos()
    shape.y = rnd.nextPos()
    shape.color = rnd.nextColor()
    var sx = rnd.nextSpeed()
    var sy = rnd.nextSpeed()
    var time = System.nanoTime() // nanos
    var checkTime = time
    while (true) {
        val dt = time.let { old -> awaitFrame().also { time = it } - old }
        if (dt > 0.5e9) continue // don't animate through over a half second lapses
        val dx = shape.x - 0.5f
        val dy = shape.y - 0.5f
        val dn = norm(dx, dy)
        sx -= dx / dn * ACC * dt
        sy -= dy / dn * ACC * dt
        val sn = norm(sx, sy)
        val trim = sn.coerceAtMost(MAX_SPEED)
        sx = sx / sn * trim
        sy = sy / sn * trim
        shape.x += sx * dt
        shape.y += sy * dt
        update(shape)
        // check once a second
        if (time > checkTime + 1e9) {
            checkTime = time
            when (rnd.nextInt(20)) { // roll d20
                0 -> {
                    animateColor(shape) // wait a second & animate color
                    time = awaitFrame() // and sync with next frame
                }
                1 -> { // random speed change
                    sx = rnd.nextSpeed()
                    sy = rnd.nextSpeed()
                }
            }
        }
    }
}

suspend fun AnimationModel.animateColor(shape: AnimatedShape) {
    val duration = 1e9f
    val startTime = System.nanoTime()
    val aColor = shape.color
    val bColor = rnd.nextColor()
    while (true) {
        val time = awaitFrame()
        val b = (time - startTime) / duration
        if (b >= 1.0f) break
        val a = 1 - b
        shape.color = Color.rgb(
            (Color.red(bColor) * b + Color.red(aColor) * a).toInt(),
            (Color.green(bColor) * b + Color.green(aColor) * a).toInt(),
            (Color.blue(bColor) * b + Color.blue(aColor) * a).toInt()
        )
        update(shape)
    }
    shape.color = bColor
    update(shape)
}
