// Copyright (c) 2017 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 spore

import (
	
	

	
)

// triangulate is BowyerWatsonTriangulation.triangulate. Slices model the
// source's deterministically iterated GWT sets while explicit equality keeps
// their undirected-edge and unordered-triangle semantics.
func triangulate( []*vertex) []*tEdge {
	 := geometry.Point{X: math.Inf(1), Y: math.Inf(1)}
	 := geometry.Point{X: math.Inf(-1), Y: math.Inf(-1)}
	for ,  := range  {
		.X = math.Min(.X, .point.X)
		.Y = math.Min(.Y, .point.Y)
		.X = math.Max(.X, .point.X)
		.Y = math.Max(.Y, .point.Y)
	}
	 := geometry.Point{X: .X - .X, Y: .Y - .Y}
	 := &vertex{point: geometry.Point{X: .X - superWiggleRoom, Y: .Y - .X - superWiggleRoom}}
	 := &vertex{point: geometry.Point{X: .X - superWiggleRoom, Y: .Y + .X + superWiggleRoom}}
	 := &vertex{point: geometry.Point{X: .X + .Y/2 + superWiggleRoom, Y: .Y + .Y/2}}
	 := newTriangle(, , )
	 := []*triangle{}

	for ,  := range  {
		 := make([]*triangle, 0)
		for ,  := range  {
			if .inCircumcircle() {
				 = append(, )
			}
		}

		 := make([]*tEdge, 0)
		for ,  := range  {
			for ,  := range .edges {
				 := true
				for ,  := range  {
					if  !=  && .containsEdge() {
						 = false
					}
				}
				if  {
					 = append(, )
				}
			}
		}

		 := [:0]
		for ,  := range  {
			if !containsTrianglePointer(, ) {
				 = append(, )
			}
		}
		 = 
		for ,  := range  {
			 := newTriangle(, .u, .v)
			if !containsEqualTriangle(, ) {
				 = append(, )
			}
		}
	}

	 := make([]*tEdge, 0)
	for ,  := range  {
		for ,  := range .edges {
			 = addEdge(, )
		}
	}
	 := [:0]
	for ,  := range  {
		if !.containsVertex(.u) && !.containsVertex(.v) {
			 = append(, )
		}
	}
	return 
}

func containsTrianglePointer( []*triangle,  *triangle) bool {
	for ,  := range  {
		if  ==  {
			return true
		}
	}
	return false
}

func containsEqualTriangle( []*triangle,  *triangle) bool {
	for ,  := range  {
		if .containsVertex(.a) && .containsVertex(.b) && .containsVertex(.c) {
			return true
		}
	}
	return false
}

func createSpanningTreeForNodes( []*tEdge,  *vertex,  func(*tEdge) float64,  []*node) *tree {
	 := make(map[*tEdge]float64, len())
	for ,  := range  {
		[] = ()
	}
	 := append([]*tEdge(nil), ...)
	sort.SliceStable(, func(,  int) bool {
		return javaDoubleCompare([[]], [[]]) < 0
	})
	 := &tree{node: nodeForVertex(, )}
	 := map[*vertex]*tree{: }
	for len() > 0 {
		var  *tEdge
		var ,  *vertex
		 := math.Inf(1)
		for ,  := range  {
			if [] <=  {
				,  := [.u]
				,  := [.v]
				if  && ! {
					, ,  = .v, .u, 
					break
				}
				if  && ! {
					, ,  = .u, .v, 
					break
				}
			}
		}
		if  == nil {
			break
		}
		 := &tree{node: nodeForVertex(, )}
		[].children = append([].children, )
		[] = 
		 = removeEdge(, )
	}
	return 
}

func nodeForVertex( *vertex,  []*node) *node {
	for ,  := range  {
		if .original ==  {
			return 
		}
	}
	return nil
}

func javaDoubleCompare(,  float64) int {
	if  <  {
		return -1
	}
	if  >  {
		return 1
	}
	,  := math.Float64bits(), math.Float64bits()
	if math.IsNaN() {
		if math.IsNaN() {
			return 0
		}
		return 1
	}
	if math.IsNaN() {
		return -1
	}
	if  ==  {
		return 0
	}
	if >>63 != 0 {
		return -1
	}
	return 1
}