// Copyright 2023 schukai GmbH // SPDX-License-Identifier: AGPL-3.0 package document import "fmt" type Tree[T any] struct { Level int Children []*Tree[T] Parent *Tree[T] Payload T } func newTree[T any]() *Tree[T] { return &Tree[T]{} } func (t *Tree[T]) traverseAndInitLevel(level int) { t.Level = level for _, child := range t.Children { child.traverseAndInitLevel(level + 1) } } func (t *Tree[T]) addChild(child *Tree[T]) { t.Children = append(t.Children, child) child.Parent = t t.getRoot().traverseAndInitLevel(0) } func (t *Tree[T]) addChildren(children []*Tree[T]) { for _, child := range children { t.addChild(child) child.Parent = t } t.getRoot().traverseAndInitLevel(0) } func (t *Tree[T]) getChildren() []*Tree[T] { return t.Children } func (t *Tree[T]) getLevel() int { return t.Level } func (t *Tree[T]) getParent() *Tree[T] { return t.Parent } func (t *Tree[T]) getRoot() *Tree[T] { if t.Parent == nil { return t } return t.Parent.getRoot() } func (t *Tree[T]) getPayload() T { return t.Payload } func (t *Tree[T]) setPayload(payload T) { t.Payload = payload } func (t *Tree[T]) getPayloadAsString() string { return fmt.Sprintf("%v", t.Payload) } func (t *Tree[T]) appendAndGet() *Tree[T] { parent := t.getParent() if parent == nil { parent = t } n := newTree[T]() parent.addChild(n) return n } func (t *Tree[T]) up(level int) *Tree[T] { if level > t.getLevel() { panic("level>t.getLevel()") } if level == t.getLevel() { return t } return t.Parent.up(level) } func (t *Tree[T]) recursiveIterate(f func(*Tree[T])) { f(t) for _, child := range t.Children { child.recursiveIterate(f) } } func (t *Tree[T]) down(level int) *Tree[T] { if level < t.Level { panic("level < t.Level") } if t.Level == level { return t } if t.Children == nil { t.addChild(newTree[T]()) return t.down(level) } return t.Children[len(t.Children)-1].down(level) } //func (t *Tree[T]) getSubTree() []Tree { // return t.getSubTreeWithLevel(t.Level) //} // //func (t *Tree[T]) getSubTreeWithLevel(level int) []Tree { // if t.Level == level { // return []Tree{*t} // } // var result []Tree // for _, child := range t.Children { // result = append(result, child.getSubTreeWithLevel(level)...) // } // return result //}