package ui

import "math"

// fftInPlace runs a radix-2 Cooley-Tukey FFT on buf in place. len(buf) must be
// a power of 2. w must hold len(buf)/2 precomputed complex roots of unity
// where w[k] = exp(-2πi·k/n). Allocates nothing.
func fftInPlace(buf []complex128, w []complex128) {
	n := len(buf)
	if n < 2 {
		return
	}

	// Bit-reversal permutation: reorder buf so butterflies operate on in-order pairs.
	j := 0
	for i := 1; i < n; i++ {
		bit := n >> 1
		for ; j&bit != 0; bit >>= 1 {
			j ^= bit
		}
		j ^= bit
		if i < j {
			buf[i], buf[j] = buf[j], buf[i]
		}
	}

	// Butterfly stages using the shared twiddle table. At stage `size`, stride
	// into the n-sized root-of-unity table is n/size so we reuse w across sizes.
	for size := 2; size <= n; size <<= 1 {
		half := size >> 1
		step := n / size
		for start := 0; start < n; start += size {
			for k := 0; k < half; k++ {
				t := w[k*step] * buf[start+k+half]
				u := buf[start+k]
				buf[start+k] = u + t
				buf[start+k+half] = u - t
			}
		}
	}
}

// buildTwiddles returns the first n/2 complex nth-roots of unity used by
// fftInPlace for an n-point transform.
func buildTwiddles(n int) []complex128 {
	w := make([]complex128, n/2)
	for k := range w {
		angle := -2 * math.Pi * float64(k) / float64(n)
		w[k] = complex(math.Cos(angle), math.Sin(angle))
	}
	return w
}
