// Copyright (c) 2015 Kiel University and others.
//
// 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 p3order

import 

// crossingMinimizationHeuristic is the source ICrossingMinimizationHeuristic
// contract shared by barycenter and greedy switch.
type crossingMinimizationHeuristic interface {
	MinimizeCrossings(order [][]layered.LNodeID, freeLayerIndex int, forwardSweep, firstSweep bool) bool
	SetFirstLayerOrder(order [][]layered.LNodeID, forward bool) bool
}

type sweepPortDistributor interface {
	DistributePortsWhileSweeping(
		arena *layered.LGraphArena,
		order [][]layered.LNodeID,
		currentIndex int,
		forward bool,
	) bool
}

// GreedySwitchHeuristic switches adjacent nodes whenever doing so strictly
// reduces the selected one- or two-sided crossing count.
type GreedySwitchHeuristic struct {
	Arena         *layered.LGraphArena
	Type          CrossMinType
	GraphData     *GraphInfoHolder
	PortPositions []int
	nPorts        int
}

func (
	 *layered.LGraphArena,
	 CrossMinType,
	 *GraphInfoHolder,
) *GreedySwitchHeuristic {
	return &GreedySwitchHeuristic{Arena: , Type: , GraphData: }
}

func ( *GreedySwitchHeuristic) (
	 [][]layered.LNodeID,
	 int,
	,  bool,
) bool {
	 := .setUp(, , )
	 := false
	for {
		 := .sweepDownwardInLayer(, , )
		 =  || 
		if ! {
			return 
		}
	}
}

func ( *GreedySwitchHeuristic) (
	 [][]layered.LNodeID,
	 bool,
) bool {
	 := 0
	if ! {
		 = len() - 1
	}
	 := .setUp(, , )
	return .sweepDownwardInLayer(, , )
}

func ( *GreedySwitchHeuristic) (
	 [][]layered.LNodeID,
	 int,
	 bool,
) *SwitchDecider {
	 := CrossingsEast
	if  {
		 = CrossingsWest
	}
	 := NewCrossingMatrixFiller(.Arena, .Type, , , )
	return NewSwitchDecider(
		.Arena,
		,
		,
		,
		.PortPositions,
		.GraphData,
		.Type == CrossMinOneSidedGreedySwitch,
	)
}

func ( *GreedySwitchHeuristic) (
	 [][]layered.LNodeID,
	 *SwitchDecider,
	 int,
) bool {
	 := false
	for  := 0; +1 < len([]); ++ {
		 :=  + 1
		if !.DoesSwitchReduceCrossings(.Arena, , ) {
			continue
		}
		.NotifyOfSwitch(.Arena, [][], [][])
		[][], [][] = [][], [][]
		 = true
	}
	return 
}

func ( *GreedySwitchHeuristic) (
	 *layered.LGraphArena,
	 int,
	 [][]layered.LNodeID,
) {
	 := *.Node([][0]).Layer
	.Layer().ID = 
}

func ( *GreedySwitchHeuristic) () { .nPorts++ }

func ( *GreedySwitchHeuristic) () {
	.PortPositions = make([]int, .nPorts)
}