<commit_before>package rs.emulate.editor.workspace.components

import javafx.beans.value.ObservableValue
import javafx.collections.ObservableMap
import org.controlsfx.control.PropertySheet
import rs.emulate.editor.workspace.resource.bundles.legacy.config.ConfigResource
import rs.emulate.legacy.config.SerializableProperty
import tornadofx.*
import java.util.Optional

class EditorPropertySheet : EditorComponent() {
    override val root: PropertySheet = PropertySheet()

    init {
        title = messages["title"]

        model.onResourceSelected.map {
            if (it is ConfigResource<*>) {
                it.properties.map { (property) ->
                    StringPropertyItem(property, it.properties as ObservableMap<SerializableProperty<*>, Any?>)
                }
            } else {
                emptyList()
            }
        }.subscribe {
            root.items.setAll(it)
        }
    }

}

class StringPropertyItem(
    val property: SerializableProperty<*>,
    val properties: ObservableMap<SerializableProperty<*>, Any?>
) : PropertySheet.Item {

    override fun setValue(value: Any?) {
        properties[property] = value
    }

    override fun getName(): String = property.name

    override fun getDescription(): String = "Filler description"

    override fun getType(): Class<*> = SerializableProperty::class.java

    override fun getValue(): Any = property.value ?: ""

    override fun getObservableValue(): Optional<ObservableValue<out Any>> {
        // TODO
        return Optional.empty()
    }

    override fun getCategory(): String {
        return "Property"
    }

}<commit_msg>Listen for property changes in StringPropertyItem<commit_after>package rs.emulate.editor.workspace.components

import com.github.thomasnield.rxkotlinfx.changes
import com.github.thomasnield.rxkotlinfx.toBinding
import io.reactivex.Observable
import javafx.beans.property.ReadOnlyObjectWrapper
import javafx.beans.value.ObservableValue
import javafx.collections.ObservableMap
import org.controlsfx.control.PropertySheet
import rs.emulate.editor.workspace.resource.bundles.legacy.config.ConfigResource
import rs.emulate.legacy.config.SerializableProperty
import tornadofx.*
import java.util.Optional

class EditorPropertySheet : EditorComponent() {
    override val root: PropertySheet = PropertySheet()

    init {
        title = messages["title"]

        model.onResourceSelected.map {
            when (it) {
                is ConfigResource<*> -> it.properties.map { (property) ->
                    val propertyValueChanges = it.properties.changes()
                        .distinctUntilChanged()
                        .filter(property::equals)
                        .map { it.value }
                        .startWith(property.value)

                    StringPropertyItem(it.properties, property, propertyValueChanges)
                }
                else -> emptyList()
            }
        }.subscribe {
            root.items.setAll(it)
        }
    }

}

class StringPropertyItem(
    val properties: ObservableMap<SerializableProperty<*>, out Any?>,
    val property: SerializableProperty<*>,
    val propertyChanges: Observable<*>
) : PropertySheet.Item {

    val valueProperty = ReadOnlyObjectWrapper<Any>()

    init {
        valueProperty.bind(propertyChanges.toBinding())
    }

    override fun setValue(value: Any?) {
        // @todo - using `property` as the key here is weird
        val propertyMap = properties as ObservableMap<SerializableProperty<*>, Any?>
        propertyMap[property] = value as Any
    }

    override fun getName(): String = property.name

    override fun getDescription(): String = "Filler description"

    override fun getType(): Class<*> = SerializableProperty::class.java

    override fun getValue(): Any = property.value ?: ""

    override fun getObservableValue(): Optional<ObservableValue<out Any>>? = Optional.of(valueProperty)

    override fun getCategory(): String {
        return "Property"
    }

}
{'fraction_non_alphanumeric': 0.09827887253679221, 'fraction_numerical': 0.0, 'mean_word_length': 2.804554079696395, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 27, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5664353', 'n_tokens_mistral': 1061, 'n_tokens_neox': 1023, 'n_words': 231}