|
|
|
|
@ -4,53 +4,227 @@ import android.os.Bundle |
|
|
|
|
import android.view.LayoutInflater |
|
|
|
|
import android.view.View |
|
|
|
|
import android.view.ViewGroup |
|
|
|
|
import androidx.core.view.isVisible |
|
|
|
|
import androidx.recyclerview.widget.LinearLayoutManager |
|
|
|
|
import io.realm.Realm |
|
|
|
|
import kotlinx.android.synthetic.main.fragment_report_creation.* |
|
|
|
|
import net.pokeranalytics.android.R |
|
|
|
|
import net.pokeranalytics.android.calculus.Calculator |
|
|
|
|
import net.pokeranalytics.android.calculus.Stat |
|
|
|
|
import net.pokeranalytics.android.model.Criteria |
|
|
|
|
import net.pokeranalytics.android.model.realm.Filter |
|
|
|
|
import net.pokeranalytics.android.model.realm.ReportDisplay |
|
|
|
|
import net.pokeranalytics.android.ui.adapter.RowRepresentableAdapter |
|
|
|
|
import net.pokeranalytics.android.ui.adapter.RowRepresentableDataSource |
|
|
|
|
import net.pokeranalytics.android.ui.adapter.RowRepresentableDelegate |
|
|
|
|
import net.pokeranalytics.android.ui.fragment.components.RealmFragment |
|
|
|
|
import net.pokeranalytics.android.ui.view.RowRepresentable |
|
|
|
|
import net.pokeranalytics.android.ui.view.RowViewType |
|
|
|
|
import net.pokeranalytics.android.ui.view.rowrepresentable.CustomizableRowRepresentable |
|
|
|
|
|
|
|
|
|
class ReportCreationFragment : RealmFragment() { |
|
|
|
|
class ReportCreationFragment : RealmFragment(), RowRepresentableDataSource, RowRepresentableDelegate { |
|
|
|
|
|
|
|
|
|
class Process { |
|
|
|
|
private lateinit var optionsAdapter: RowRepresentableAdapter |
|
|
|
|
|
|
|
|
|
var step: Step = Step.TYPE |
|
|
|
|
var display: ReportDisplay? = null |
|
|
|
|
var stats = listOf<Stat>() |
|
|
|
|
var comparators = listOf<Criteria>() |
|
|
|
|
var useFilter: Boolean? = null |
|
|
|
|
var filter: Filter? = null |
|
|
|
|
private var assistant = Assistant() |
|
|
|
|
private var currentRows: List<RowRepresentable> = listOf() |
|
|
|
|
|
|
|
|
|
enum class Step { |
|
|
|
|
TYPE, |
|
|
|
|
STAT, |
|
|
|
|
COMPARATOR, |
|
|
|
|
FILTER, |
|
|
|
|
FINALIZE |
|
|
|
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { |
|
|
|
|
super.onCreateView(inflater, container, savedInstanceState) |
|
|
|
|
return inflater.inflate(R.layout.fragment_report_creation, container, false) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { |
|
|
|
|
super.onViewCreated(view, savedInstanceState) |
|
|
|
|
|
|
|
|
|
this.optionsAdapter = RowRepresentableAdapter(this, this) |
|
|
|
|
|
|
|
|
|
val viewManager = LinearLayoutManager(requireContext()) |
|
|
|
|
recyclerView.apply { |
|
|
|
|
setHasFixedSize(true) |
|
|
|
|
layoutManager = viewManager |
|
|
|
|
adapter = optionsAdapter |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
val nextStep: Step |
|
|
|
|
get() { |
|
|
|
|
return when (this.display) { |
|
|
|
|
null -> Step.TYPE |
|
|
|
|
else -> { |
|
|
|
|
if (this.stats.isEmpty()) { |
|
|
|
|
Step.STAT |
|
|
|
|
} else if (this.display!! == ReportDisplay.COMPARISON_GRAPH && this.comparators.isEmpty()) { |
|
|
|
|
Step.COMPARATOR |
|
|
|
|
} else if (this.useFilter == null) { |
|
|
|
|
Step.FILTER |
|
|
|
|
} else { |
|
|
|
|
Step.FINALIZE |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
this.updateUIWithCurrentStep() |
|
|
|
|
|
|
|
|
|
this.next.setOnClickListener { |
|
|
|
|
if (assistant.nextEnabled) { |
|
|
|
|
this.assistant.nextStep() |
|
|
|
|
|
|
|
|
|
if (this.assistant.step == Assistant.Step.FINALIZE) { |
|
|
|
|
// launch report |
|
|
|
|
|
|
|
|
|
val options = this.assistant.options |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} else { |
|
|
|
|
this.updateUIWithCurrentStep() |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private fun updateUIWithCurrentStep() { |
|
|
|
|
|
|
|
|
|
this.next.isVisible = this.assistant.nextButtonShouldAppear |
|
|
|
|
this.next.text = requireContext().getString(this.assistant.nextButtonTitleResId) |
|
|
|
|
this.next.isEnabled = this.assistant.nextEnabled |
|
|
|
|
|
|
|
|
|
val rows = mutableListOf<RowRepresentable>() |
|
|
|
|
|
|
|
|
|
this.assistant.titleResId?.let { titleResId -> |
|
|
|
|
rows.add(CustomizableRowRepresentable(RowViewType.HEADER_TITLE, resId = titleResId)) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
rows.addAll(this.assistant.dataSource) |
|
|
|
|
|
|
|
|
|
this.currentRows = rows |
|
|
|
|
this.optionsAdapter.notifyDataSetChanged() |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// RowRepresentableDataSource |
|
|
|
|
|
|
|
|
|
override fun adapterRows(): List<RowRepresentable>? { |
|
|
|
|
return this.currentRows |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
override fun rowRepresentableForPosition(position: Int): RowRepresentable? { |
|
|
|
|
return this.currentRows[position] |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
override fun numberOfRows(): Int { |
|
|
|
|
return this.currentRows.size |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
override fun viewTypeForPosition(position: Int): Int { |
|
|
|
|
return when (position) { |
|
|
|
|
0 -> RowViewType.HEADER_TITLE.ordinal |
|
|
|
|
else -> RowViewType.TITLE_CHECK.ordinal |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
override fun indexForRow(row: RowRepresentable): Int { |
|
|
|
|
return this.currentRows.indexOf(row) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
override fun isSelected(row: RowRepresentable): Boolean { |
|
|
|
|
return this.assistant.isSelected(row) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// RowRepresentableDelegate |
|
|
|
|
|
|
|
|
|
override fun onRowSelected(position: Int, row: RowRepresentable, fromAction: Boolean) { |
|
|
|
|
|
|
|
|
|
val newStep = this.assistant.onRowSelected(position - 1) |
|
|
|
|
if (newStep) { |
|
|
|
|
this.updateUIWithCurrentStep() |
|
|
|
|
} else { |
|
|
|
|
this.next.isEnabled = this.assistant.nextEnabled |
|
|
|
|
this.optionsAdapter.refreshRow(row) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fun titleForStep(step: Step) : Int? { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
class Assistant { |
|
|
|
|
|
|
|
|
|
var step: Step = Step.TYPE |
|
|
|
|
private var display: Calculator.Options.Display = Calculator.Options.Display.TABLE |
|
|
|
|
private var stats = mutableListOf<Stat>() |
|
|
|
|
private var comparators = mutableListOf<Criteria>() |
|
|
|
|
private var useFilter: Boolean? = null |
|
|
|
|
private var filter: Filter? = null |
|
|
|
|
|
|
|
|
|
val options: Calculator.Options |
|
|
|
|
get() { |
|
|
|
|
return Calculator.Options( |
|
|
|
|
this.display, |
|
|
|
|
stats = this.stats, |
|
|
|
|
criterias = this.comparators, |
|
|
|
|
filter = this.filter, |
|
|
|
|
userGenerated = true |
|
|
|
|
) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
enum class Step { |
|
|
|
|
TYPE, |
|
|
|
|
STAT, |
|
|
|
|
COMPARATOR, |
|
|
|
|
FILTER, |
|
|
|
|
FINALIZE |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Notifies the Assistant a row has been selected with a [position] |
|
|
|
|
* Returns whether the step has changed |
|
|
|
|
*/ |
|
|
|
|
fun onRowSelected(position: Int): Boolean { |
|
|
|
|
|
|
|
|
|
val stepChanges = !this.nextButtonShouldAppear |
|
|
|
|
|
|
|
|
|
when (this.step) { |
|
|
|
|
Step.TYPE -> { |
|
|
|
|
this.display = this.dataSource[position] as Calculator.Options.Display |
|
|
|
|
this.nextStep() |
|
|
|
|
} |
|
|
|
|
Step.STAT -> { |
|
|
|
|
val stat = this.dataSource[position] as Stat |
|
|
|
|
if (this.stats.contains(stat)) { |
|
|
|
|
this.stats.remove(stat) |
|
|
|
|
} else { |
|
|
|
|
this.stats.add(stat) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
Step.COMPARATOR -> { |
|
|
|
|
val comparator = this.dataSource[position] as Criteria |
|
|
|
|
if (this.comparators.contains(comparator)) { |
|
|
|
|
this.comparators.remove(comparator) |
|
|
|
|
} else { |
|
|
|
|
this.comparators.add(comparator) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
Step.FILTER -> { |
|
|
|
|
this.filter = this.dataSource[position] as Filter |
|
|
|
|
} |
|
|
|
|
else -> { |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
return stepChanges |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fun isSelected(row: RowRepresentable): Boolean { |
|
|
|
|
return when (this.step) { |
|
|
|
|
Step.STAT -> this.stats.contains(row as Stat) |
|
|
|
|
Step.COMPARATOR -> this.comparators.contains(row as Criteria) |
|
|
|
|
else -> false |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fun nextStep() { |
|
|
|
|
this.step = this.nextStep |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private val nextStep: Step |
|
|
|
|
get() { |
|
|
|
|
return if (this.stats.isEmpty()) { |
|
|
|
|
Step.STAT |
|
|
|
|
} else if (this.display == Calculator.Options.Display.COMPARISON && this.comparators.isEmpty()) { |
|
|
|
|
Step.COMPARATOR |
|
|
|
|
} else if (this.useFilter == null) { |
|
|
|
|
Step.FILTER |
|
|
|
|
} else { |
|
|
|
|
Step.FINALIZE |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
val titleResId: Int? |
|
|
|
|
get() { |
|
|
|
|
return when (step) { |
|
|
|
|
Step.TYPE -> R.string.new_report_step_type |
|
|
|
|
Step.STAT -> R.string.new_report_step_stat |
|
|
|
|
@ -60,43 +234,50 @@ class ReportCreationFragment : RealmFragment() { |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
val dataSource: List<RowRepresentable> |
|
|
|
|
get() { |
|
|
|
|
return when (this.step) { |
|
|
|
|
Step.TYPE -> return listOf(ReportDisplay.FIGURES, ReportDisplay.EVO_GRAPH, ReportDisplay.COMPARISON_GRAPH) |
|
|
|
|
Step.STAT -> return Stat.values().toList() |
|
|
|
|
Step.COMPARATOR -> Criteria.all |
|
|
|
|
Step.FILTER -> { |
|
|
|
|
val realm = Realm.getDefaultInstance() |
|
|
|
|
val filters = Filter.sortedByUsage(realm) |
|
|
|
|
realm.close() |
|
|
|
|
filters |
|
|
|
|
} |
|
|
|
|
else -> listOf() |
|
|
|
|
val dataSource: List<RowRepresentable> |
|
|
|
|
get() { |
|
|
|
|
return when (this.step) { |
|
|
|
|
Step.TYPE -> listOf( |
|
|
|
|
Calculator.Options.Display.TABLE, |
|
|
|
|
Calculator.Options.Display.EVOLUTION, |
|
|
|
|
Calculator.Options.Display.COMPARISON |
|
|
|
|
) |
|
|
|
|
Step.STAT -> Stat.userSelectableList |
|
|
|
|
Step.COMPARATOR -> Criteria.all |
|
|
|
|
Step.FILTER -> { |
|
|
|
|
val realm = Realm.getDefaultInstance() |
|
|
|
|
val filters = Filter.sortedByUsage(realm) |
|
|
|
|
realm.close() |
|
|
|
|
filters |
|
|
|
|
} |
|
|
|
|
else -> listOf() |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
val nextButtonShouldAppear: Boolean |
|
|
|
|
get() { |
|
|
|
|
return when (this.step) { |
|
|
|
|
Step.STAT, Step.COMPARATOR, Step.FILTER -> true |
|
|
|
|
else -> false |
|
|
|
|
} |
|
|
|
|
val nextEnabled: Boolean |
|
|
|
|
get() { |
|
|
|
|
return when (this.step) { |
|
|
|
|
Step.STAT -> this.stats.isNotEmpty() |
|
|
|
|
Step.COMPARATOR -> this.comparators.isNotEmpty() |
|
|
|
|
Step.FILTER -> true |
|
|
|
|
else -> false |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
val nextButtonTitle: Int |
|
|
|
|
get() { |
|
|
|
|
return when (this.step) { |
|
|
|
|
Step.FILTER -> R.string.launch_report |
|
|
|
|
else -> R.string.next |
|
|
|
|
} |
|
|
|
|
val nextButtonShouldAppear: Boolean |
|
|
|
|
get() { |
|
|
|
|
return when (this.step) { |
|
|
|
|
Step.STAT, Step.COMPARATOR, Step.FILTER -> true |
|
|
|
|
else -> false |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { |
|
|
|
|
super.onCreateView(inflater, container, savedInstanceState) |
|
|
|
|
return inflater.inflate(R.layout.fragment_report_creation, container, false) |
|
|
|
|
} |
|
|
|
|
val nextButtonTitleResId: Int |
|
|
|
|
get() { |
|
|
|
|
return when (this.step) { |
|
|
|
|
Step.FILTER -> R.string.launch_report |
|
|
|
|
else -> R.string.next |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} |