package com.adlerosn.brasilfurfest.schedule import android.os.Bundle import androidx.annotation.StringRes import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AppCompatActivity import androidx.recyclerview.widget.LinearLayoutManager import android.text.Editable import android.text.TextWatcher import com.adlerosn.brasilfurfest.R import com.adlerosn.brasilfurfest.helper.* import com.adlerosn.brasilfurfest.helper.observables.Observer import com.adlerosn.brasilfurfest.schedule.managers.ScheduleManagerGetter import com.adlerosn.brasilfurfest.schedule.abstractDataTypes.convention.FilterableNamedColoredAttribute import com.adlerosn.brasilfurfest.schedule.abstractDataTypes.convention.Place import com.adlerosn.brasilfurfest.schedule.abstractDataTypes.convention.Tag import com.adlerosn.brasilfurfest.schedule.abstractDataTypes.dataholder.PeekableEvent import com.adlerosn.brasilfurfest.schedule.adapters.FilterCriteriaRecyclerViewAdapter import com.adlerosn.brasilfurfest.schedule.adapters.PeekableEventRecyclerViewAdapter import com.adlerosn.brasilfurfest.schedule.adapters.TagTripleListAdapter import kotlinx.android.synthetic.main.activity_search_filter.* import org.jetbrains.anko.doAsync import org.jetbrains.anko.uiThread class SearchFilterActivity : AppCompatActivity() { val tags = mutableListOf() val places = mutableListOf() var query = "" val scheduleManager = ScheduleManagerGetter[this] lateinit var filteredEventsListAdapter: PeekableEventRecyclerViewAdapter lateinit var filterTagsListAdapter: FilterCriteriaRecyclerViewAdapter lateinit var filterPlacesListAdapter: FilterCriteriaRecyclerViewAdapter lateinit var everyPeekableEvent: List val observer = Observer { _, _: Any? -> runOnUiThread { updateView() } } private val nullPair = Pair(null, nullFun) override fun onCreate(savedInstanceState: Bundle?) { ActivitiesForFragments[this.javaClass.simpleName] = this super.onCreate(savedInstanceState) setContentView(R.layout.activity_search_filter) resourcesAliased = this.resources scheduleManager.addObserver(observer) queryText.addTextChangedListener(object: TextWatcher{ override fun afterTextChanged(s: Editable?) { query = s.toString() updateView() } override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {} override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {} }) val rl = recyclerList!! val fct = filterCriteriaTags!! val fcp = filterCriteriaPlaces!! filteredEventsListAdapter = PeekableEventRecyclerViewAdapter(mutableListOf(), scheduleManager, this) {updateView()} filterTagsListAdapter = FilterCriteriaRecyclerViewAdapter( listOf() ) { callAddTags() } filterPlacesListAdapter = FilterCriteriaRecyclerViewAdapter( listOf() ) { callAddPlaces() } rl.adapter = filteredEventsListAdapter rl.layoutManager = LinearLayoutManager(this@SearchFilterActivity) everyPeekableEvent = ( scheduleManager.convention.events.map { PeekableEvent(it) } + scheduleManager.attendeeFavorites.toList().filter { it.isCustom }.map { PeekableEvent(it) } ).sortedWith(compareBy( { it.timeRange.start.timeInMillis }, { it.timeRange.finish.timeInMillis }, { it.title.solved } )) fct.adapter = filterTagsListAdapter fct.layoutManager = LinearLayoutManager(this@SearchFilterActivity, LinearLayoutManager.HORIZONTAL, false) fcp.adapter = filterPlacesListAdapter fcp.layoutManager = LinearLayoutManager(this@SearchFilterActivity, LinearLayoutManager.HORIZONTAL, false) updateView() } override fun onBackPressed() { scheduleManager.deleteObserver(observer) super.onBackPressed() } private fun callAddSomething( wholeCollection: Collection, currentCollection: MutableCollection, @StringRes dialogTitleResource: Int ){ doAsync { val placeChoices = wholeCollection.filterNot { it in currentCollection }.map { Triple(it.names.solved!!, it.color, { currentCollection.add(it) }) } uiThread { val choicesAdapted = TagTripleListAdapter(placeChoices) AlertDialog.Builder(this@SearchFilterActivity) .setTitle(dialogTitleResource) .setAdapter(choicesAdapted) { dialog, which: Int -> placeChoices[which].third() dialog.dismiss() updateView() } .show() } } } fun callAddPlaces() = callAddSomething( scheduleManager.convention.places, places, R.string.schedule_event_key_places ) fun callAddTags() = callAddSomething( scheduleManager.convention.tags, tags, R.string.schedule_event_key_categories ) fun updateFilterItemView( wholeCollection: Collection, currentCollection: MutableCollection, adapter: FilterCriteriaRecyclerViewAdapter ){ doAsync { val hasPlusButtons = currentCollection.size < wholeCollection.size val plusButtons = if (hasPlusButtons) listOf(nullPair) else listOf() val filterableChoices = currentCollection.map { Pair(it) { currentCollection.remove(it); updateView() } }.let { when (it.size) { 0 -> plusButtons 1 -> plusButtons+it else -> plusButtons+it+plusButtons } } uiThread { adapter.onDataChanged(filterableChoices) } } } fun updateView() { updateFilterItemView( scheduleManager.convention.tags, tags, filterTagsListAdapter ) updateFilterItemView( scheduleManager.convention.places, places, filterPlacesListAdapter ) doAsync { val toRemoveByName = if (query.isEmpty()) listOf() else everyPeekableEvent.filter { (query.toLowerCase() !in it.title.solved?.toLowerCase()?:"") && (query.toLowerCase() !in it.subtitles?.solved?.toLowerCase()?:"") && (query.toLowerCase() !in it.descriptions?.solved?.toLowerCase()?:"") } val toRemoveByTag = if(tags.isEmpty()) listOf() else everyPeekableEvent.filter { event -> !tags.any { event.tags?.contains(it) ?: false } } val toRemoveByPlace = if(places.isEmpty()) listOf() else everyPeekableEvent.filter { event -> !places.any { event.places?.contains(it) ?: false } } val toDisplay = everyPeekableEvent - (toRemoveByName+toRemoveByTag+toRemoveByPlace).toSet() filteredEventsListAdapter.onDataChanged(toDisplay) } } }