package net.hareworks.ghostdisplays.display import java.time.Instant import java.util.UUID import java.util.concurrent.ConcurrentHashMap import net.hareworks.ghostdisplays.api.DisplayController import net.hareworks.ghostdisplays.api.click.HandlerRegistration import net.kyori.adventure.text.Component import org.bukkit.Location import org.bukkit.block.data.BlockData import org.bukkit.entity.BlockDisplay import org.bukkit.entity.Display import org.bukkit.entity.ItemDisplay import org.bukkit.entity.TextDisplay import org.bukkit.inventory.ItemStack enum class DisplayKind { TEXT, BLOCK, ITEM } data class AudienceBinding( val key: String, val description: String, private val registration: HandlerRegistration ) { fun unregister() { registration.unregister() } } sealed class ManagedDisplay( val id: String, val kind: DisplayKind, val controller: DisplayController, location: Location, val createdAt: Instant, val createdBy: UUID? ) { val location: Location = location.clone() private val audienceBindings = ConcurrentHashMap() fun audienceBindings(): Collection = audienceBindings.values fun registerAudienceBinding(binding: AudienceBinding) { audienceBindings.put(binding.key, binding)?.unregister() } fun removeAudienceBinding(key: String): Boolean { return audienceBindings.remove(key)?.let { it.unregister() true } ?: false } fun clearAudiences() { audienceBindings.values.forEach { it.unregister() } audienceBindings.clear() } class Text( id: String, controller: DisplayController, location: Location, createdAt: Instant, createdBy: UUID?, var rawContent: String, var component: Component ) : ManagedDisplay(id, DisplayKind.TEXT, controller, location, createdAt, createdBy) class Block( id: String, controller: DisplayController, location: Location, createdAt: Instant, createdBy: UUID?, var blockData: BlockData ) : ManagedDisplay(id, DisplayKind.BLOCK, controller, location, createdAt, createdBy) class Item( id: String, controller: DisplayController, location: Location, createdAt: Instant, createdBy: UUID?, var itemStack: ItemStack ) : ManagedDisplay(id, DisplayKind.ITEM, controller, location, createdAt, createdBy) }