diff --git a/app/src/main/java/net/pokeranalytics/android/ui/adapter/FilterSectionAdapter.kt b/app/src/main/java/net/pokeranalytics/android/ui/adapter/FilterSectionAdapter.kt new file mode 100644 index 00000000..ae099b3f --- /dev/null +++ b/app/src/main/java/net/pokeranalytics/android/ui/adapter/FilterSectionAdapter.kt @@ -0,0 +1,202 @@ +package net.pokeranalytics.android.ui.adapter + +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.appcompat.widget.AppCompatTextView +import androidx.recyclerview.widget.RecyclerView +import io.realm.RealmModel +import io.realm.RealmQuery +import io.realm.RealmResults +import net.pokeranalytics.android.R +import net.pokeranalytics.android.exceptions.PAIllegalStateException +import net.pokeranalytics.android.model.realm.Filter +import net.pokeranalytics.android.ui.view.RowRepresentable +import net.pokeranalytics.android.ui.view.RowViewType +import net.pokeranalytics.android.util.NULL_TEXT +import net.pokeranalytics.android.util.extensions.getMonthAndYear +import java.util.* +import kotlin.collections.HashMap + +interface DateModel : RowRepresentable, RealmModel { + var date: Date +} + + +interface EntityDescriptor { + + fun bindableHolder(view: View): RecyclerView.ViewHolder + + val layout: Int + + val viewType: Int + + val sortFieldName: String + + fun distinctHeaders(realmQuery: RealmQuery): RealmQuery + +} + +/** + * An adapter capable of displaying a list of RowRepresentables + * @param dataSource the datasource providing rows + * @param delegate the delegate, notified of UI actions + */ +class FilterSectionAdapter( + override var delegate: RowRepresentableDelegate? = null, + override var dataSource: RowRepresentableDataSource, + var descriptor: EntityDescriptor, + var realmQuery: RealmQuery +// var distinctTransactionsHeaders: RealmResults +) : + RecyclerView.Adapter(), RecyclerAdapter { + + private var headersPositions = HashMap() + private lateinit var sortedHeaders: SortedMap + + private var realmEntities: RealmResults + private var realmHeaders: RealmResults + + var filter: Filter? = null + + init { + + + this.realmEntities = this.realmQuery.findAll().sort(this.descriptor.sortFieldName) +// this.realmEntities = this.filter?.results() ?: this.realmQuery.findAll().sort(this.descriptor.sortFieldName) + this.realmHeaders = this.descriptor.distinctHeaders(this.realmQuery).findAll() + + + refreshData() + } + + /** + * Display a transaction view + */ + inner class RowEntityViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), BindableHolder { + + fun bind(position: Int, row: T?, adapter: FilterSectionAdapter) { + +// itemView.transactionRow.setData(row as Transaction) +// val listener = View.OnClickListener { +// adapter.delegate?.onRowSelected(position, row) +// } +// itemView.transactionRow.setOnClickListener(listener) + } + } + + /** + * Display a header + */ + inner class HeaderTitleViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), BindableHolder { + + fun bind(title: String) { + // Title + itemView.findViewById(R.id.title)?.let { + it.text = title + } + } + } + + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { + val inflater = LayoutInflater.from(parent.context) + return if (viewType == this.descriptor.viewType) { // TODO layout + val layout = inflater.inflate(this.descriptor.layout, parent, false) + this.descriptor.bindableHolder(layout) +// RowEntityViewHolder(layout) + } else { + val layout = inflater.inflate(R.layout.row_header_title, parent, false) + HeaderTitleViewHolder(layout) + } + + } + + + override fun getItemViewType(position: Int): Int { + return if (sortedHeaders.containsKey(position)) { + RowViewType.HEADER_TITLE.ordinal + } else { + this.descriptor.viewType // RowViewType.ROW_TRANSACTION.ordinal + } + } + + + override fun getItemCount(): Int { + return realmEntities.size + realmHeaders.size + } + + override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { + + if (holder is BindableHolder) { + holder.onBind(position, getEntityForPosition(position), this) + } else if (holder is FeedTransactionRowRepresentableAdapter.HeaderTitleViewHolder) { + holder.bind(getHeaderForPosition(position)) + } + } + + /** + * Return the header + */ + private fun getHeaderForPosition(position: Int): String { + if (sortedHeaders.containsKey(position)) { + val realmHeaderPosition = sortedHeaders.keys.indexOf(position) + return realmHeaders[realmHeaderPosition]?.date?.getMonthAndYear() ?: "" + } + return NULL_TEXT + } + + /** + * Get real index + */ + private fun getEntityForPosition(position: Int): T { + + // Row position + var headersBefore = 0 + for (key in sortedHeaders.keys) { + if (position > key) { + headersBefore++ + } else { + break + } + } + + return realmEntities[position - headersBefore] ?: throw PAIllegalStateException("Nasty problem!") + } + + /** + * Refresh headers positions + */ + fun refreshData() { + + headersPositions.clear() + + var previousYear = Int.MAX_VALUE + var previousMonth = Int.MAX_VALUE + + val calendar = Calendar.getInstance() + + // Add headers if the date doesn't exist yet + for ((index, transaction) in realmEntities.withIndex()) { + calendar.time = transaction.date + if (checkHeaderCondition(calendar, previousYear, previousMonth)) { + headersPositions[index + headersPositions.size] = transaction.date + previousYear = calendar.get(Calendar.YEAR) + previousMonth = calendar.get(Calendar.MONTH) + } + } + + sortedHeaders = headersPositions.toSortedMap() + + } + + /** + * Check if we need to add a header + * Can be change to manage different condition + */ + private fun checkHeaderCondition(currentCalendar: Calendar, previousYear: Int, previousMonth: Int): Boolean { + return currentCalendar.get(Calendar.YEAR) == previousYear && currentCalendar.get(Calendar.MONTH) < previousMonth || (currentCalendar.get(Calendar.YEAR) < previousYear) + + } + +} \ No newline at end of file diff --git a/app/src/main/java/net/pokeranalytics/android/ui/adapter/SectionAdapter.kt b/app/src/main/java/net/pokeranalytics/android/ui/adapter/SectionAdapter.kt deleted file mode 100644 index 36f388fb..00000000 --- a/app/src/main/java/net/pokeranalytics/android/ui/adapter/SectionAdapter.kt +++ /dev/null @@ -1,2 +0,0 @@ -package net.pokeranalytics.android.ui.adapter -