package placementcost

import (
	

	
)

// obstructionBounds encloses the straight, L-shaped, and alternate midpoint
// routes considered by placement scoring. An obstacle outside it cannot block
// any of those routes. It is only a rejection filter; intersecting boxes still
// go through the original ancestry and segment predicates in their original
// order.
type obstructionBounds struct {
	left, top, right, bottom float64
	usable                   bool
}

func scoringNodeBounds( *layoutgraph.Node) obstructionBounds {
	if  == nil || .TopLeft == nil {
		return obstructionBounds{}
	}
	,  := .TopLeft.X, .TopLeft.Y
	,  := +.Width, +.Height
	// Keep non-finite and overflow-prone trial geometry on the original path.
	const  = math.MaxFloat64 / 8
	 :=  >= - &&  <=  &&  >= - &&  <=  &&
		 >= - &&  <=  &&  >= - &&  <= 
	return obstructionBounds{min(, ), min(, ), max(, ), max(, ), }
}

func ( obstructionBounds) ( obstructionBounds) obstructionBounds {
	return obstructionBounds{
		min(.left, .left), min(.top, .top),
		max(.right, .right), max(.bottom, .bottom),
		.usable && .usable,
	}
}

func ( obstructionBounds) ( *layoutgraph.Node) bool {
	if !.usable ||  == nil || .TopLeft == nil {
		return false
	}
	,  := .TopLeft.X, .TopLeft.Y
	,  := +.Width, +.Height
	// Paired comparisons also handle negative dimensions, and never reject a
	// dimension containing NaN. Infinite obstacle bounds use the original path.
	if math.IsInf(, 0) || math.IsInf(, 0) || math.IsInf(, 0) || math.IsInf(, 0) ||
		math.IsNaN() || math.IsNaN() || math.IsNaN() || math.IsNaN() {
		return false
	}
	return ( < .left &&  < .left) ||
		( > .right &&  > .right) ||
		( < .top &&  < .top) ||
		( > .bottom &&  > .bottom)
}