package audio

import "math"

// Generates audio samples for a given waveform type
func (g *Generator) generateOscillator(waveType string, freq, duration, amplitude, phase float64) []float64 {
	samples := int(duration * g.sampleRate)
	if samples <= 0 {
		return nil
	}
	output := make([]float64, samples)
	
	sampleRateInv := 1.0 / g.sampleRate
	twoPiFreq := 2 * math.Pi * freq
	fadeSamples := int(math.Min(0.005*g.sampleRate, float64(samples)*0.1))
	fadeSamplesInv := 1.0 / float64(fadeSamples)
	switch waveType {
	case "sine":
		for i := 0; i < samples; i++ {
			t := float64(i)*sampleRateInv + phase
			sample := math.Sin(twoPiFreq*t) * amplitude
			
			if i < fadeSamples {
				sample *= float64(i) * fadeSamplesInv
			} else if i >= samples-fadeSamples {
				sample *= float64(samples-i) * fadeSamplesInv
			}
			
			output[i] = sample
		}
	case "square":
		for i := 0; i < samples; i++ {
			t := float64(i)*sampleRateInv + phase
			var sample float64
			if math.Sin(twoPiFreq*t) > 0 {
				sample = amplitude
			} else {
				sample = -amplitude
			}
			
			if i < fadeSamples {
				sample *= float64(i) * fadeSamplesInv
			} else if i >= samples-fadeSamples {
				sample *= float64(samples-i) * fadeSamplesInv
			}
			
			output[i] = sample
		}
	case "saw":
		for i := 0; i < samples; i++ {
			t := float64(i)*sampleRateInv + phase
			sample := (2*(t*freq-math.Floor(0.5+t*freq))) * amplitude
			
			if i < fadeSamples {
				sample *= float64(i) * fadeSamplesInv
			} else if i >= samples-fadeSamples {
				sample *= float64(samples-i) * fadeSamplesInv
			}
			
			output[i] = sample
		}
	case "triangle":
		for i := 0; i < samples; i++ {
			t := float64(i)*sampleRateInv + phase
			sample := (math.Abs(2*(t*freq-math.Floor(t*freq+0.5)))*2 - 1) * amplitude
			
			if i < fadeSamples {
				sample *= float64(i) * fadeSamplesInv
			} else if i >= samples-fadeSamples {
				sample *= float64(samples-i) * fadeSamplesInv
			}
			
			output[i] = sample
		}
	default:
		return output
	}

	return output
}
