package me.saket.fluidresize.sample

import android.animation.ObjectAnimator
import android.animation.ValueAnimator
import android.app.Activity
import android.view.View
import androidx.interpolator.view.animation.FastOutSlowInInterpolator
import me.saket.fluidresize.ActivityViewHolder
import me.saket.fluidresize.KeyboardVisibilityChanged
import me.saket.fluidresize.KeyboardVisibilityDetector

object FluidContentResizer {

  private var heightAnimator: ValueAnimator = ObjectAnimator()

  fun listen(activity: Activity) {
    val viewHolder = ActivityViewHolder.createFrom(activity)

    KeyboardVisibilityDetector.listen(viewHolder) {
      animateHeight(viewHolder, it)
    }
    viewHolder.onDetach {
      heightAnimator.cancel()
      heightAnimator.removeAllUpdateListeners()
    }
  }

  private fun animateHeight(viewHolder: ActivityViewHolder, event: KeyboardVisibilityChanged) {
    val contentView = viewHolder.contentView
    contentView.setHeight(event.contentHeightBeforeResize)

    heightAnimator.cancel()

    // Warning: animating height might not be very performant. Try turning on
    // "Profile GPI rendering" in developer options and check if the bars stay
    // under 16ms in your app. Using Transitions API would be more efficient, but
    // for some reason it skips the first animation and I cannot figure out why.
    heightAnimator = ObjectAnimator.ofInt(event.contentHeightBeforeResize, event.contentHeight).apply {
      interpolator = FastOutSlowInInterpolator()
      duration = 300
    }
    heightAnimator.addUpdateListener { contentView.setHeight(it.animatedValue as Int) }
    heightAnimator.start()
  }

  private fun View.setHeight(height: Int) {
    val params = layoutParams
    params.height = height
    layoutParams = params
  }
}
