package com.marvinelsen.willow

import com.marvinelsen.willow.domain.SearchMode
import com.marvinelsen.willow.ui.DictionaryEntryFx
import com.marvinelsen.willow.ui.util.ClipboardHelper
import com.marvinelsen.willow.ui.util.FindWordsService
import com.marvinelsen.willow.ui.util.SearchService
import javafx.beans.property.ObjectProperty
import javafx.beans.property.ReadOnlyBooleanProperty
import javafx.beans.property.ReadOnlyObjectProperty
import javafx.beans.property.SimpleObjectProperty
import javafx.collections.FXCollections
import javafx.collections.ObservableList
import javafx.event.EventHandler

class Model(private val searchService: SearchService, private val findWordsService: FindWordsService) {
    private val internalSelectedEntry: ObjectProperty<DictionaryEntryFx> = SimpleObjectProperty()
    private val internalSearchResults: ObservableList<DictionaryEntryFx> = FXCollections.observableArrayList()
    private val internalWordsContaining: ObservableList<DictionaryEntryFx> = FXCollections.observableArrayList()

    val selectedEntry: ReadOnlyObjectProperty<DictionaryEntryFx> = internalSelectedEntry

    val searchResults: ObservableList<DictionaryEntryFx> =
        FXCollections.unmodifiableObservableList(internalSearchResults)
    val wordsContaining: ObservableList<DictionaryEntryFx> =
        FXCollections.unmodifiableObservableList(internalWordsContaining)

    val isSearching: ReadOnlyBooleanProperty = searchService.runningProperty()
    val isFindingWords: ReadOnlyBooleanProperty = findWordsService.runningProperty()

    init {
        searchService.onSucceeded = EventHandler {
            internalSearchResults.setAll(searchService.value)
        }
        findWordsService.onSucceeded = EventHandler {
            internalWordsContaining.setAll(findWordsService.value)
        }
    }

    fun search(query: String, searchMode: SearchMode) {
        searchService.searchQuery = query
        searchService.searchMode = searchMode
        searchService.restart()
    }

    fun findWords() {
        findWordsService.entry = internalSelectedEntry.value
        findWordsService.restart()
    }

    fun selectEntry(entry: DictionaryEntryFx) {
        internalSelectedEntry.value = entry
    }

    fun copyHeadwordOfSelectedEntry() {
        ClipboardHelper.copyHeadword(internalSelectedEntry.get())
    }

    fun copyPronunciationOfSelectedEntry() {
        ClipboardHelper.copyPronunciation(internalSelectedEntry.get())
    }
}
