// Copyright (c) 2011, 2020 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 p2layers

import 

type interactiveLayerSpan struct {
	start float64
	end   float64
	nodes []layered.LNodeID
}

// InteractiveLayerer derives initial layers from overlapping horizontal node
// spans, then moves targets right until every non-loop edge advances a layer.
type InteractiveLayerer struct{}

func (*InteractiveLayerer) (
	 *layered.LGraphArena,
	 layered.LGraphID,
) layered.ProcessorConfiguration {
	var  layered.ProcessorConfiguration
	.
		AddBefore(layered.PhaseCycleBreaking, layered.InteractiveExternalPortPositioner).
		AddBefore(layered.PhaseLayering, layered.LayerConstraintPreprocessor).
		AddBefore(layered.PhaseNodeOrdering, layered.LayerConstraintPostprocessor)
	return 
}

func (*InteractiveLayerer) ( *layered.LGraphArena,  layered.LGraphID) error {
	 := .Graph()
	 := make([]interactiveLayerSpan, 0)
	for ,  := range .LayerlessNodes {
		 := .Node()
		 := .Position.X
		 := .Position.X + .Size.X
		if  < +1 {
			 =  + 1
		}

		 := len()
		 := -1
		for  := 0;  < len(); {
			 := &[]
			if .start >=  {
				 = 
				break
			}
			if .end >  {
				if  < 0 {
					.nodes = append(.nodes, )
					if  < .start {
						.start = 
					}
					if  > .end {
						.end = 
					}
					 = 
					++
					continue
				}
				[].nodes = append([].nodes, .nodes...)
				if .end > [].end {
					[].end = .end
				}
				 = append([:], [+1:]...)
				continue
			}
			++
		}
		if  < 0 {
			 := interactiveLayerSpan{start: , end: , nodes: []layered.LNodeID{}}
			 = append(, interactiveLayerSpan{})
			copy([+1:], [:])
			[] = 
		}
	}

	for ,  := range  {
		 := .AddLayer()
		.Layer().ID = 
		.Layers = append(.Layers, )
		for ,  := range .nodes {
			.SetNodeLayer(, &)
			.Node().ID = 0
		}
	}

	var  func(layered.LNodeID)
	 = func( layered.LNodeID) {
		 := .Node()
		.ID = 1
		 := .Layer(*.Layer).ID
		for ,  := range .NodeOutgoingEdges() {
			 := .EdgeTargetNode()
			if  ==  {
				continue
			}
			 := .Layer(*.Node().Layer)
			if .ID <=  {
				 :=  + 1
				var  layered.LayerID
				if  == len(.Layers) {
					 = .AddLayer()
					.Layer().ID = 
					.Layers = append(.Layers, )
				} else {
					 = .Layers[]
				}
				.SetNodeLayer(, &)
				()
			}
		}
	}
	for ,  := range .LayerlessNodes {
		if .Node().ID == 0 {
			()
		}
	}

	 := .Layers[:0]
	for ,  := range .Layers {
		if len(.Layer().Nodes) > 0 {
			 = append(, )
		}
	}
	.Layers = 
	.LayerlessNodes = .LayerlessNodes[:0]
	return nil
}