package calc

import "math"

// ShortDistance returns the shortest Euclidean distance between two
// points on a torus of size w×h.
func ShortDistance(w, h uint32, x1, y1, x2, y2 float64) float64 {
	return math.Hypot(Deltas(w, h, x1, y1, x2, y2))
}

// Deltas returns the per-axis absolute distance between two points on
// a torus of size w×h. Each axis wraps independently: the x-axis
// against width w, the y-axis against height h. The returned values
// are always non-negative; combine via math.Hypot for the Euclidean
// torus distance, or use [ShortestDelta] when the signed direction
// matters (for example when drawing a wrap-aware line).
func Deltas(w, h uint32, x1, y1, x2, y2 float64) (float64, float64) {
	return math.Abs(ShortestDelta(x1, x2, w)), math.Abs(ShortestDelta(y1, y2, h))
}

// ShortestDelta returns the signed delta (b - a) on a 1-D circle of
// circumference size, picking whichever direction has the shorter
// absolute distance. The result lies in (-size/2, size/2]: at exactly
// half the circumference the function returns +size/2 so the tie-case
// is deterministic regardless of input order.
func ShortestDelta(a, b float64, size uint32) float64 {
	if size == 0 {
		return b - a
	}
	s := float64(size)
	d := math.Mod(b-a, s)
	half := s / 2
	if d > half {
		d -= s
	} else if d <= -half {
		d += s
	}
	return d
}
