package calc_test

import (
	"math"
	"testing"

	"galaxy/calc"
)

func TestShortestDelta(t *testing.T) {
	cases := []struct {
		name string
		a, b float64
		size uint32
		want float64
	}{
		{"identity", 5, 5, 100, 0},
		{"forward small", 10, 30, 100, 20},
		{"backward small", 30, 10, 100, -20},
		{"wraps right edge", 95, 5, 100, 10},
		{"wraps left edge", 5, 95, 100, -10},
		{"exact half wraps positive", 0, 50, 100, 50},
		{"slight beyond half goes negative", 0, 51, 100, -49},
		{"size zero is degenerate identity", 5, 30, 0, 25},
	}
	for _, tc := range cases {
		t.Run(tc.name, func(t *testing.T) {
			got := calc.ShortestDelta(tc.a, tc.b, tc.size)
			if got != tc.want {
				t.Fatalf("ShortestDelta(%v, %v, %d) = %v, want %v",
					tc.a, tc.b, tc.size, got, tc.want)
			}
		})
	}
}

// TestDeltasRectangularGalaxy guards against the pre-Phase-19 bug
// where the x-axis wrap used the height instead of the width on
// rectangular maps.
func TestDeltasRectangularGalaxy(t *testing.T) {
	w, h := uint32(100), uint32(50)
	dx, dy := calc.Deltas(w, h, 95, 10, 5, 15)
	if dx != 10 {
		t.Errorf("dx = %v, want 10 (wrap distance on width 100)", dx)
	}
	if dy != 5 {
		t.Errorf("dy = %v, want 5 (no wrap on height 50)", dy)
	}
}

func TestShortDistanceTorus(t *testing.T) {
	got := calc.ShortDistance(100, 100, 95, 95, 5, 5)
	want := math.Hypot(10, 10)
	if math.Abs(got-want) > 1e-9 {
		t.Fatalf("ShortDistance through wrap = %v, want %v", got, want)
	}
}
