// 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 

type CrossingCountSide uint8

const (
	CrossingsWest CrossingCountSide = iota
	CrossingsEast
)

// CrossingMatrixFiller lazily caches both orders of each node pair. Node.ID
// is the immutable identity assigned by GraphInfoHolder initialization; it is
// deliberately not changed when the current order swaps nodes.
type CrossingMatrixFiller struct {
	filled   [][]bool
	matrix   [][]int
	counter  *betweenLayerEdgeTwoNodeCrossingsCounter
	side     CrossingCountSide
	oneSided bool
}

func (
	 *layered.LGraphArena,
	 CrossMinType,
	 [][]layered.LNodeID,
	 int,
	 CrossingCountSide,
) *CrossingMatrixFiller {
	 := len([])
	 := make([][]bool, )
	 := make([][]int, )
	for  := 0;  < ; ++ {
		[] = make([]bool, )
		[] = make([]int, )
	}
	return &CrossingMatrixFiller{
		filled:   ,
		matrix:   ,
		counter:  newBetweenLayerEdgeTwoNodeCrossingsCounter(, , ),
		side:     ,
		oneSided:  == CrossMinOneSidedGreedySwitch,
	}
}

func ( *CrossingMatrixFiller) (
	 *layered.LGraphArena,
	,  layered.LNodeID,
) int {
	,  := .Node().ID, .Node().ID
	if !.filled[][] {
		if .oneSided {
			if .side == CrossingsEast {
				.counter.countEasternEdgeCrossings(, , )
			} else {
				.counter.countWesternEdgeCrossings(, , )
			}
		} else {
			.counter.countBothSideCrossings(, , )
		}
		.matrix[][] = .counter.upperLowerCrossings
		.matrix[][] = .counter.lowerUpperCrossings
		.filled[][] = true
		.filled[][] = true
	}
	return .matrix[][]
}