// Copyright (c) 2022 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 components

import (
	
	

	
	basegraph 
	
)

// componentGroupModelOrderGraphPlacer is ELK 0.8.1's
// ComponentGroupModelOrderGraphPlacer. Unlike the base placer, it only tries
// to append to the latest group and advances groups in layout direction.
type componentGroupModelOrderGraphPlacer struct {
	sectorPlacer    componentGroupGraphPlacer
	componentGroups []*modelOrderComponentGroup
}

func ( *componentGroupModelOrderGraphPlacer) (
	 *layered.LGraphArena,
	 []layered.LGraphID,
	 layered.LGraphID,
) error {
	.componentGroups = nil
	for ,  := range  {
		if  ==  {
			return fmt.Errorf("components: target graph cannot be a component group member")
		}
	}
	 := .Graph()
	.LayerlessNodes = nil
	if len() == 0 {
		.Size = geometry.Point{}
		return nil
	}

	 := .Graph([0])
	.Properties = .Properties.Clone()
	for ,  := range  {
		.addComponent(, )
	}

	 := geometry.Point{}
	 := geometry.Point{}
	 := geometry.Point{}
	 := geometry.Point{}
	 := basegraph.Get(
		&.Properties, layered.SpacingComponentComponent)
	 := basegraph.Get(&.Properties, layered.DirectionOption)
	for ,  := range .componentGroups {
		if  == layered.DirectionRight ||  == layered.DirectionLeft {
			.X = .X
			for ,  := range .group.portSides() {
				if &sidesNorth != 0 {
					.X = .X
					break
				}
			}
		} else if  == layered.DirectionDown ||  == layered.DirectionUp {
			.Y = .Y
			for ,  := range .group.portSides() {
				if &sidesWest != 0 {
					.Y = .Y
					break
				}
			}
		}

		 := .sectorPlacer.placeComponents(, .group, )
		offsetGraphs(, .group.components(), )
		if  == layered.DirectionRight ||  == layered.DirectionLeft {
			.X = .X + .X
			.X = math.Max(.X, .X)
			for ,  := range .group.portSides() {
				if &sidesSouth != 0 {
					.X = .X + .X
					break
				}
			}
			.Y = .Y + .Y
			.Y = .Y
			.Y = math.Max(.Y, .Y)
		} else if  == layered.DirectionDown ||  == layered.DirectionUp {
			.Y = .Y + .Y
			.Y = math.Max(.Y, .Y)
			for ,  := range .group.portSides() {
				if &sidesEast != 0 {
					.Y = .Y + .Y
					break
				}
			}
			.X = .X + .X
			.X = .X
			.X = math.Max(.X, .X)
		}
	}
	.Size = geometry.Point{X: .X - , Y: .Y - }

	if basegraph.Get(&.Properties, connectedComponentsCompaction) &&
		basegraph.Get(&.Properties, layered.EdgeRoutingOption) ==
			layered.EdgeRoutingOrthogonal {
		if  := compactExternalComponentGroups(
			, , , );  != nil {
			return 
		}
	}
	for ,  := range .componentGroups {
		moveGraphs(, , .group.components(), geometry.Point{})
	}
	return nil
}

func ( *componentGroupModelOrderGraphPlacer) (
	 *layered.LGraphArena,
	 layered.LGraphID,
) {
	if len(.componentGroups) != 0 {
		 := .componentGroups[len(.componentGroups)-1]
		if .add(, ) {
			return
		}
	}
	.componentGroups = append(
		.componentGroups, newModelOrderComponentGroup(, ))
}