import {Constructable, Mixin} from "../util/Common.js";

export type IndexNodeId = number

let ID : IndexNodeId     = 1


export const IndexNode = <T extends Constructable>(base : T) =>

class IndexNode extends base {
    id          : IndexNodeId   = ID++

    parent      : IndexNode

    children    : IndexNode[]   = []


    addChild (child : IndexNode) {
        this.children.push(child)

        return child
    }


    traverse (func : (node : IndexNode) => any) : false | undefined {
        const children      = this.children

        if (func(this) === false) return false

        for (let i = 0; i < children.length; i++)
            if (children[ i ].traverse(func) === false) return false
    }


    forEachChild (func : (node : IndexNode) => any) : false | undefined {
        const children      = this.children

        for (let i = 0; i < children.length; i++)
            if (func(children[ i ]) === false) return false
    }


    getRoot () : IndexNode {
        let root : IndexNode        = this

        while (root.parent) root    = root.parent

        return root
    }


    isRoot () : boolean {
        return !Boolean(this.parent)
    }


    // findChildById (id : IndexNodeId) : IndexNode | null {
    //     let child
    //
    //     this.forEach(node => {
    //         if (node.id === id) { child = node; return false }
    //     })
    //
    //     return child
    // }
}

export type IndexNode = Mixin<typeof IndexNode>
