// Copyright (c) 2011, 2015 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 p1cycles

import (
	basegraph 
	
)

// InteractiveCycleBreaker first follows the direction suggested by existing
// x coordinates, then uses ELK's DFS pass to remove any remaining cycles.
type InteractiveCycleBreaker struct{}

func (*InteractiveCycleBreaker) (
	 *layered.LGraphArena,
	 layered.LGraphID,
) layered.ProcessorConfiguration {
	var  layered.ProcessorConfiguration
	.
		AddBefore(layered.PhaseCycleBreaking, layered.InteractiveExternalPortPositioner).
		AddAfter(layered.PhaseEdgeRouting, layered.ReversedEdgeRestorer)
	return 
}

func (*InteractiveCycleBreaker) ( *layered.LGraphArena,  layered.LGraphID) error {
	 := .Graph().LayerlessNodes
	 := make([]layered.LEdgeID, 0)
	for ,  := range  {
		.Node().ID = 1
		 := interactiveReferencePoint(, ).X
		for ,  := range .NodeOutgoingEdges() {
			 := .EdgeTargetNode()
			if  !=  && interactiveReferencePoint(, ).X <  {
				 = append(, )
			}
		}
	}
	for ,  := range  {
		.ReverseEdge(, , true)
	}

	 = [:0]
	var  func(layered.LNodeID)
	 = func( layered.LNodeID) {
		.Node().ID = -1
		for ,  := range .NodeOutgoingEdges() {
			 := .EdgeTargetNode()
			if  ==  {
				continue
			}
			switch {
			case .Node().ID < 0:
				 = append(, )
			case .Node().ID > 0:
				()
			}
		}
		.Node().ID = 0
	}
	for ,  := range  {
		if .Node().ID > 0 {
			()
		}
	}
	for ,  := range  {
		.ReverseEdge(, , true)
	}
	return nil
}

func interactiveReferencePoint( *layered.LGraphArena,  layered.LNodeID) ( struct{ ,  float64 }) {
	 := .Node()
	., . = .Position.X, .Position.Y
	if basegraph.Get(&.Graph(.NodeGraph()).Properties, layered.InteractiveReferencePointOption) == layered.InteractiveReferenceCenter {
		. += .Size.X / 2
		. += .Size.Y / 2
	}
	return 
}