package application.controller

import application.model.MessageListener
import application.model.Vessel
import application.model.observableSelectedVessel
import application.model.observableVessel
import javafx.collections.FXCollections
import javafx.collections.ObservableList
import javafx.collections.transformation.FilteredList
import javafx.fxml.FXML
import javafx.fxml.Initializable
import javafx.scene.control.*
import javafx.scene.input.MouseEvent
import java.net.URL
import java.util.*


class VesselListPanelController : Initializable, MessageListener {

    @FXML
    var shipListView: ListView<String?> = ListView()

    @FXML
    var filterInput: TextField = TextField()

    private var shipList: ObservableList<String?> = FXCollections.observableArrayList()

    private val filterMMSI = FilteredList(shipList)

    override fun initialize(location: URL?, resources: ResourceBundle?) {


        shipListView.items = filterMMSI

        observableVessel.listeners.add(this)
        shipListView.selectionModel.selectedItemProperty().addListener { _, _, newValue ->
            if (newValue == null) {
                observableSelectedVessel.value = Vessel(null)
            } else {
                observableSelectedVessel.value = observableVessel.vessels[newValue]!!
            }
        }


        setCellFactory()
        setFilterTextListener()
    }

    override fun onValueChanged(newValue: MutableMap<String?, Vessel>) {
        shipList.clear()
        shipList.addAll(newValue.keys)
    }

    private fun setFilterTextListener() {
        filterInput.textProperty().addListener { _ ->
            val filter: String = filterInput.text
            if (filter.isEmpty()) {
                filterMMSI.setPredicate { true }
            } else {
                filterMMSI.setPredicate { s: String? -> s!!.contains(filter) }
            }
        }
    }

    private fun setCellFactory() {
        val selectionModel: MultipleSelectionModel<String?>? = shipListView.selectionModel
        selectionModel?.selectionMode = SelectionMode.SINGLE
        shipListView.setCellFactory {
            val cell = ListCell<String?>()
            cell.textProperty().bind(cell.itemProperty())
            cell.addEventFilter(MouseEvent.MOUSE_PRESSED) { event: MouseEvent ->
                shipListView.requestFocus()
                if (!cell.isEmpty) {
                    val index = cell.index
                    if (selectionModel!!.selectedIndices.contains(index)) {
                        selectionModel.clearSelection()
                    } else {
                        selectionModel.select(index)
                    }
                    event.consume()
                }
            }
            cell
        }
    }
}

