summaryrefslogtreecommitdiff
path: root/internal/gui/generator.go
blob: f4a6c219961a0239da50226a96a7f9cfdf919d09 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
package gui

import (
	"context"
	"math/rand"
	"time"
)

// randomVoice picks a random voice from the provided list.
// Used by GenerationOrchestrator for both OpenAI and Gemini voice selection.
func randomVoice(voices []string) string {
	rng := rand.New(rand.NewSource(time.Now().UnixNano()))
	return voices[rng.Intn(len(voices))]
}

// randomOpenAISpeed picks a random speed in [0.90, 1.00) for OpenAI TTS to
// add slight variation across generations.
func randomOpenAISpeed() float64 {
	rng := rand.New(rand.NewSource(time.Now().UnixNano()))
	return 0.90 + rng.Float64()*0.10
}

// --- Application delegation methods ---
// Each method delegates to getOrchestrator() so tests that create Application
// directly (setting newAudioProvider / audioConfig / config) continue to work
// without modification, while production code uses the pre-built orchestrator.

// translateWord translates a Bulgarian word to English.
func (a *Application) translateWord(word string) (string, error) {
	return a.getOrchestrator().TranslateWord(word)
}

// translateEnglishToBulgarian translates an English word to Bulgarian.
func (a *Application) translateEnglishToBulgarian(word string) (string, error) {
	return a.getOrchestrator().TranslateEnglishToBulgarian(word)
}

// generateAudio generates audio for an en-bg card's single audio file.
func (a *Application) generateAudio(ctx context.Context, word, cardDir string) (string, error) {
	return a.getOrchestrator().GenerateAudio(ctx, word, cardDir)
}

// generateAudioFront generates the front audio file for a bg-bg card.
func (a *Application) generateAudioFront(ctx context.Context, word, cardDir string) (string, error) {
	return a.getOrchestrator().GenerateAudioFront(ctx, word, cardDir)
}

// generateAudioBack generates the back audio file for a bg-bg card.
func (a *Application) generateAudioBack(ctx context.Context, text, cardDir string) (string, error) {
	return a.getOrchestrator().GenerateAudioBack(ctx, text, cardDir)
}

// generateAudioBgBg generates audio for both sides of a bg-bg card.
func (a *Application) generateAudioBgBg(ctx context.Context, front, back, cardDir string) (string, string, error) {
	return a.getOrchestrator().GenerateAudioBgBg(ctx, front, back, cardDir)
}

// generateAudioFile generates a single audio file using the given voice/speed.
// Kept as a thin wrapper so the fallback tests in generator_test.go can call it.
func (a *Application) generateAudioFile(ctx context.Context, text, outputFile, voice string, speed float64) error {
	return a.getOrchestrator().generateAudioFile(ctx, text, outputFile, voice, speed)
}

// generateImagesWithPrompt downloads a single image for a word with optional
// custom prompt and translation hint.
func (a *Application) generateImagesWithPrompt(ctx context.Context, word, customPrompt, translation, cardDir string) (string, error) {
	o := a.getOrchestrator()

	// Wrap with a UI update callback for the current word's image prompt entry.
	promptUI := func(prompt string) {
		a.mu.Lock()
		isCurrentWord := a.currentWord == word
		a.mu.Unlock()

		if isCurrentWord && a.imagePromptEntry != nil {
			a.imagePromptEntry.SetText(prompt)
		}
	}

	return o.generateImagesWithPromptAndNotify(ctx, word, customPrompt, translation, cardDir, promptUI)
}