package me.eater.threedom.dom

import me.eater.threedom.dom.render.IRenderNode
import me.eater.threedom.dom.render.IRenderTarget
import me.eater.threedom.event.Event
import me.eater.threedom.event.EventDispatcher
import me.eater.threedom.utils.joml.Vector3d
import org.joml.Vector3dc
import kotlin.reflect.KClass

interface IDocument : EventDispatcher, INodeContainer {
    fun <T : INode<T>> createNode(nodeType: KClass<T>): T
    fun deleteNode(refNode: INode<*>)
    fun <T> addEventListener(eventName: String, refNode: INode<*>, block: (Event<T>) -> Unit)
    fun getNodeByNodeId(nodeId: Long): INode<*>?
    fun findAt(x: Number, y: Number, z: Number) = findAt(Vector3d(x, y, z))
    fun findAt(vec: Vector3dc): Collection<INode<*>>
    fun rebalance()

    fun <C, T : IRenderTarget<C>, N : IRenderNode<*, T, C>> render(target: T, renderer: C) {
        for (node in getNodesByRenderTarget<T, C>(target.type)) {
            node.render(renderer)
        }
    }
}

inline fun <reified T : INode<T>> IDocument.createNode() = createNode(T::class)
