package ocelot.desktop.util

/**
  * Keeps a value and tracks its changes.
  */
abstract class BaseWatcher[T](initialValue: T) {
  private var dirty = false
  private var _callback: Option[T => Unit] = None
  private var _value: T = initialValue

  protected def value: T = _value
  protected def value_=(newValue: T): Unit = {
    dirty = _value != newValue
    if (dirty) {
      _callback.foreach(_(newValue))
    }
    _value = newValue
  }
  
  def onChange: Option[T => Unit] = _callback

  def onChange_=(callback: T => Unit): Unit = {
    _callback = Some(callback)
  }

  def changed(): Boolean = {
    if (dirty) {
      dirty = false
      true
    } else false
  }
}

object Watcher {
  def apply[T](initialValue: T) = new Watcher(initialValue)

  class Watcher[T](initialValue: T) extends BaseWatcher(initialValue) {
    override def value: T = super.value
    override def value_=(newValue: T): Unit = super.value_=(newValue)
  }
}
