package ru.dbotthepony.mc.otm.core.util

import ru.dbotthepony.kommons.util.Listenable
import java.util.function.BooleanSupplier
import java.util.function.Consumer
import java.util.function.IntConsumer
import java.util.function.IntSupplier

class IntCounter : IntSupplier, Listenable<Int> {
	/**
	 * Doesn't subscribe to counter (counter does not reference this invalidator)
	 */
	inner class WeakInvalidator : BooleanSupplier {
		private var thisValue = value

		override fun getAsBoolean(): Boolean {
			if (thisValue != value) {
				thisValue = value
				return true
			}

			return false
		}
	}

	/**
	 * Subscribes to counter (counter references this invalidator, can be removed using [remove])
	 */
	inner class StrongInvalidator : BooleanSupplier, Listenable.L {
		private var isValid = true
		private val l = listeners.addListener(Runnable { isValid = false })

		override fun getAsBoolean(): Boolean {
			val isValid = isValid
			this.isValid = true
			return isValid
		}

		override fun remove() {
			l.remove()
		}
	}

	private val listeners = Listenable.Impl<Int>()
	private var value = 0

	fun increment() {
		value++
		listeners.accept(value)
	}

	override fun addListener(listener: Consumer<Int>): Listenable.L {
		return listeners.addListener(listener)
	}

	override fun addListener(listener: Runnable): Listenable.L {
		return listeners.addListener(listener)
	}

	override fun getAsInt(): Int {
		return value
	}
}
