/*
* Copyright 2018 Allan Wang
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
package com.pitchedapps.frost.activities
import android.animation.ValueAnimator
import android.content.res.ColorStateList
import android.graphics.Color
import android.os.Bundle
import android.view.View
import android.view.WindowManager
import android.widget.ImageView
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import androidx.fragment.app.FragmentPagerAdapter
import androidx.viewpager.widget.ViewPager
import ca.allanwang.kau.internal.KauBaseActivity
import ca.allanwang.kau.utils.color
import ca.allanwang.kau.utils.fadeScaleTransition
import ca.allanwang.kau.utils.navigationBarColor
import ca.allanwang.kau.utils.postDelayed
import ca.allanwang.kau.utils.scaleXY
import ca.allanwang.kau.utils.setIcon
import ca.allanwang.kau.utils.statusBarColor
import com.mikepenz.iconics.typeface.library.googlematerial.GoogleMaterial
import com.pitchedapps.frost.R
import com.pitchedapps.frost.databinding.ActivityIntroBinding
import com.pitchedapps.frost.intro.BaseIntroFragment
import com.pitchedapps.frost.intro.IntroAccountFragment
import com.pitchedapps.frost.intro.IntroFragmentAnalytics
import com.pitchedapps.frost.intro.IntroFragmentEnd
import com.pitchedapps.frost.intro.IntroFragmentTheme
import com.pitchedapps.frost.intro.IntroFragmentWelcome
import com.pitchedapps.frost.intro.IntroTabContextFragment
import com.pitchedapps.frost.intro.IntroTabTouchFragment
import com.pitchedapps.frost.prefs.Prefs
import com.pitchedapps.frost.utils.cookies
import com.pitchedapps.frost.utils.launchNewTask
import com.pitchedapps.frost.utils.loadAssets
import com.pitchedapps.frost.utils.setFrostTheme
import com.pitchedapps.frost.widgets.NotificationWidget
import kotlinx.coroutines.NonCancellable
import kotlinx.coroutines.launch
import org.koin.android.ext.android.inject
/**
* Created by Allan Wang on 2017-07-25.
*
* A beautiful intro activity
* Phone showcases are drawn via layers
*/
class IntroActivity : KauBaseActivity(), ViewPager.PageTransformer,
ViewPager.OnPageChangeListener {
private val prefs: Prefs by inject()
lateinit var binding: ActivityIntroBinding
private var barHasNext = true
val fragments = listOf(
IntroFragmentWelcome(),
IntroFragmentTheme(),
IntroAccountFragment(),
IntroTabTouchFragment(),
IntroTabContextFragment(),
IntroFragmentAnalytics(),
IntroFragmentEnd()
)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityIntroBinding.inflate(layoutInflater)
setContentView(binding.root)
binding.init()
}
private fun ActivityIntroBinding.init() {
viewpager.apply {
setPageTransformer(true, this@IntroActivity)
addOnPageChangeListener(this@IntroActivity)
adapter = IntroPageAdapter(supportFragmentManager, fragments)
}
indicator.setViewPager(viewpager)
next.setIcon(GoogleMaterial.Icon.gmd_navigate_next)
next.setOnClickListener {
if (barHasNext) viewpager.setCurrentItem(viewpager.currentItem + 1, true)
else finish(next.x + next.pivotX, next.y + next.pivotY)
}
skip.setOnClickListener { finish() }
ripple.set(prefs.bgColor)
theme()
}
fun theme() {
statusBarColor = prefs.headerColor
navigationBarColor = prefs.headerColor
with(binding) {
skip.setTextColor(prefs.textColor)
next.imageTintList = ColorStateList.valueOf(prefs.textColor)
indicator.setColour(prefs.textColor)
indicator.invalidate()
}
fragments.forEach { it.themeFragment() }
setFrostTheme(prefs, true)
}
/**
* Transformations are mainly handled on a per view basis
* This sifies it by making the first fragment fade out as the second fragment comes in
* All fragments are locked in position
*/
override fun transformPage(page: View, position: Float) {
// only apply to adjacent pages
if ((position < 0 && position > -1) || (position > 0 && position < 1)) {
val pageWidth = page.width
val translateValue = position * -pageWidth
page.translationX = (if (translateValue > -pageWidth) translateValue else 0f)
page.alpha = if (position < 0) 1 + position else 1f
} else {
page.alpha = 1f
page.translationX = 0f
}
}
fun finish(x: Float, y: Float) {
val blue = color(R.color.facebook_blue)
window.setFlags(
WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE,
WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
)
binding.ripple.ripple(blue, x, y, 600) {
postDelayed(1000) { finish() }
}
val lastView: View? = fragments.last().view
arrayOf(
binding.skip, binding.indicator, binding.next,
lastView?.findViewById(R.id.intro_title),
lastView?.findViewById(R.id.intro_desc)
).forEach {
it?.animate()?.alpha(0f)?.setDuration(600)?.start()
}
if (prefs.textColor != Color.WHITE) {
val f = lastView?.findViewById(R.id.intro_image)?.drawable
if (f != null)
ValueAnimator.ofFloat(0f, 1f).apply {
addUpdateListener {
f.setTint(prefs.textColor.blendWith(Color.WHITE, it.animatedValue as Float))
}
duration = 600
start()
}
}
if (prefs.headerColor != blue) {
ValueAnimator.ofFloat(0f, 1f).apply {
addUpdateListener {
val c = prefs.headerColor.blendWith(blue, it.animatedValue as Float)
statusBarColor = c
navigationBarColor = c
}
duration = 600
start()
}
}
}
override fun finish() {
launch(NonCancellable) {
loadAssets(prefs)
NotificationWidget.forceUpdate(this@IntroActivity)
launchNewTask(cookies(), false)
super.finish()
}
}
override fun onBackPressed() {
with(binding) {
if (viewpager.currentItem > 0) viewpager.setCurrentItem(viewpager.currentItem - 1, true)
else finish()
}
}
override fun onPageScrollStateChanged(state: Int) {
}
override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {
fragments[position].onPageScrolled(positionOffset)
if (position + 1 < fragments.size)
fragments[position + 1].onPageScrolled(positionOffset - 1)
}
override fun onPageSelected(position: Int) {
fragments[position].onPageSelected()
val hasNext = position != fragments.size - 1
if (barHasNext == hasNext) return
barHasNext = hasNext
binding.next.fadeScaleTransition {
setIcon(
if (barHasNext) GoogleMaterial.Icon.gmd_navigate_next else GoogleMaterial.Icon.gmd_done,
color = prefs.textColor
)
}
binding.skip.animate().scaleXY(if (barHasNext) 1f else 0f)
}
class IntroPageAdapter(fm: FragmentManager, private val fragments: List) :
FragmentPagerAdapter(fm) {
override fun getItem(position: Int): Fragment = fragments[position]
override fun getCount(): Int = fragments.size
}
}