textualize/core/ContextGroup/ContextGroupCollection.go
Yehoshua Sandler 7dd6de064f
Refactor Context Groups & Area Detection (#4)
* feat: make new connections

* refact: context groups | feat: area detection

and a bunch of small things. hate yourself for this massive commit
2023-09-02 10:58:38 -05:00

148 lines
4.7 KiB
Go

package contextGroup
import (
"fmt"
"textualize/entities"
)
type ContextGroupCollection struct {
Groups []entities.LinkedAreaList
}
var contextGroupCollectionInstance *ContextGroupCollection
func GetContextGroupCollection() *ContextGroupCollection {
if contextGroupCollectionInstance == nil {
contextGroupCollectionInstance = &ContextGroupCollection{}
}
return contextGroupCollectionInstance
}
func SetContextGroupCollection(collection ContextGroupCollection) *ContextGroupCollection {
contextGroupCollectionInstance = &collection
return contextGroupCollectionInstance
}
func SetContextGroupCollectionBySerialized(serialized []entities.SerializedLinkedProcessedArea) *ContextGroupCollection {
newInstance := ContextGroupCollection{}
newInstance.Groups = append(newInstance.Groups, entities.DeserializeLinkedAreaList(serialized))
SetContextGroupCollection(newInstance)
return &newInstance
}
func (collection *ContextGroupCollection) DoesGroupExistBetweenProcessedAreas(ancestorAreaId string, descendantAreaId string) bool {
ancestorGroup, _ := collection.FindGroupByLinkedProcessedAreaId(ancestorAreaId)
descendantGroup, _ := collection.FindGroupByLinkedProcessedAreaId(descendantAreaId)
isAncestorInAnyInGroup := ancestorGroup != nil
isDescendantInAnyInGroup := descendantGroup != nil
areBothInAnyInGroup := isAncestorInAnyInGroup && isDescendantInAnyInGroup
areBothInSameGroup := false
if areBothInAnyInGroup {
areBothInSameGroup = ancestorGroup.Id == descendantGroup.Id
}
return areBothInSameGroup
}
func (collection *ContextGroupCollection) DisconnectProcessedAreas(ancestorAreaId string, descendantAreaId string) bool {
doesConnectionExist := collection.DoesGroupExistBetweenProcessedAreas(ancestorAreaId, descendantAreaId)
if !doesConnectionExist {
return false
}
ancestorGroup, _ := collection.FindGroupByLinkedProcessedAreaId(ancestorAreaId)
wasRemoved := false
for i, group := range collection.Groups {
if group.Id == ancestorGroup.Id {
collection.Groups = append(collection.Groups[:i], collection.Groups[i+1:]...)
wasRemoved = true
break
}
}
return wasRemoved
}
func (collection *ContextGroupCollection) FindGroupById(id string) (*entities.LinkedAreaList, error) {
found := false
var foundGroup *entities.LinkedAreaList = nil
for _, group := range collection.Groups {
if group.Id == id {
found = true
foundGroup = &group
}
}
if !found {
return nil, fmt.Errorf("ContextGroupCollection.FindGroupById: Group with id %s not found", id)
}
return foundGroup, nil
}
func (collection *ContextGroupCollection) FindGroupByLinkedProcessedAreaId(id string) (*entities.LinkedAreaList, error) {
found := false
var foundGroup *entities.LinkedAreaList = nil
for _, group := range collection.Groups {
for n := group.First(); n != nil && !found; n = n.GetNext() {
if n.Area.Id == id {
found = true
foundGroup = &group
}
}
}
if !found {
return nil, fmt.Errorf("ContextGroupCollection.FindGroupByLinkedProcessedAreaId: Group with LinkedProcessedArea.Id %s not found", id)
}
return foundGroup, nil
}
func (collection *ContextGroupCollection) ConnectProcessedAreas(ancestorNode entities.ProcessedArea, descendantNode entities.ProcessedArea) bool {
ancestorGroup, _ := collection.FindGroupByLinkedProcessedAreaId(ancestorNode.Id)
descendantGroup, _ := collection.FindGroupByLinkedProcessedAreaId(descendantNode.Id)
isAncestorInAnyInGroup := ancestorGroup != nil
isDescendantInAnyInGroup := descendantGroup != nil
isEitherInAnyInGroup := isAncestorInAnyInGroup || isDescendantInAnyInGroup
areBothInAnyInGroup := isAncestorInAnyInGroup && isDescendantInAnyInGroup
areBothInSameGroup := false
if areBothInAnyInGroup {
areBothInSameGroup = ancestorGroup.Id == descendantGroup.Id
}
if areBothInSameGroup {
return true
}
if !isEitherInAnyInGroup {
collection.createNewGroupAndConnectNodes(ancestorNode, descendantNode)
return true
}
if isAncestorInAnyInGroup && !isDescendantInAnyInGroup {
ancestorGroup.InsertAfter(ancestorNode.Id, descendantNode)
return true
}
if !isAncestorInAnyInGroup && isDescendantInAnyInGroup {
descendantGroup.InsertBefore(descendantNode.Id, ancestorNode)
return true
}
return false
}
func (collection *ContextGroupCollection) createNewGroupAndConnectNodes(ancestorNode entities.ProcessedArea, descendantNode entities.ProcessedArea) {
newGroup := entities.LinkedAreaList{
Id: ancestorNode.Id,
DocumentId: ancestorNode.DocumentId,
Head: &entities.LinkedProcessedArea{Area: ancestorNode},
Tail: &entities.LinkedProcessedArea{Area: descendantNode},
}
newGroup.Head.Next = newGroup.Tail
newGroup.Tail.Previous = newGroup.Head
collection.Groups = append(collection.Groups, newGroup)
}