// Copyright (c) 2017 Kiel University and others.
// Copyright (c) 2026 The elk-go Authors.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License 2.0 which is available at
// https://www.eclipse.org/legal/epl-2.0.
//
// SPDX-License-Identifier: EPL-2.0

package spore

import (
	

	
	
)

type overlapProvider struct {
	algorithms *core.AlgorithmRegistry
}

func ( *overlapProvider) ( *graph.Model,  graph.NodeID,  core.ProgressMonitor) error {
	if  := runUnderlying(, , , .algorithms);  != nil {
		return 
	}
	 := &.Node().Properties
	graph.Set(, RootSelection, RootCenter)
	graph.Set(, SpanningTreeCost, CostInvertedOverlap)
	graph.Set(, TreeConstruction, TreeMinimum)
	 := graph.Get(, MaxIterations)

	.Begin("Overlap removal", 1)
	defer .Done()
	 := newImporter(, )
	,  := .importGraph()
	if  != nil {
		return 
	}
	 := true
	for  := 0;  <  && ; ++ {
		if graph.Get(, RunScanline) {
			.edges = scanlineOverlaps(.vertices)
			if len(.edges) == 0 {
				break
			}
		}
		if  := executeStructureAndTree();  != nil {
			return 
		}
		 = growTree(.tree)
		.updateGraph()
	}
	.applyPositions()
	return nil
}

type compactionProvider struct {
	algorithms *core.AlgorithmRegistry
}

func ( *compactionProvider) ( *graph.Model,  graph.NodeID,  core.ProgressMonitor) error {
	if  := runUnderlying(, , , .algorithms);  != nil {
		return 
	}
	 := newImporter(, )
	,  := .importGraph()
	if  != nil {
		return 
	}
	.Begin("Compaction by shrinking a tree", 3)
	if len(.vertices) > 1 {
		if  := executeStructureAndTree();  != nil {
			return 
		}
		switch .compaction {
		case CompactionDepthFirst:
			compactTree(.tree, .orthogonal)
		default:
			return fmt.Errorf("no SPOrE compaction implementation for %q", .compaction)
		}
	}
	.Done()
	.applyPositions()
	return nil
}

func executeStructureAndTree( *sporeGraph) error {
	 := make([]*vertex, len(.vertices))
	for ,  := range .vertices {
		[] = .original
	}
	for ,  := range triangulate() {
		.edges = addEdge(.edges, )
	}
	if len(.vertices) == 0 {
		return nil
	}
	 := .cost
	if .treeConstruction == TreeMaximum {
		 = func( *tEdge) float64 { return -.cost() }
	} else if .treeConstruction != TreeMinimum {
		return fmt.Errorf("no SPOrE tree construction implementation for %q", .treeConstruction)
	}
	 := .vertices[0].original
	if .preferredRoot != nil {
		 = .preferredRoot.original
	}
	.tree = createSpanningTreeForNodes(.edges, , , .vertices)
	return nil
}