package main import ( "context" "encoding/csv" "gegio-ue1/model" "os" "slices" "strconv" "github.com/wailsapp/wails/v2/pkg/runtime" "gorm.io/gorm" ) // App struct type App struct { ctx context.Context db *gorm.DB } // NewApp creates a new App application struct func NewApp(db *gorm.DB) *App { return &App{ db: db, } } // startup is called when the app starts. The context is saved // so we can call the runtime methods func (a *App) startup(ctx context.Context) { a.ctx = ctx } func (a *App) GetGames() (gs []model.Game, err error) { err = a.db.Find(&gs).Error return } func (a *App) GetTournaments() (ts []model.Tournament, err error) { err = a.db.Preload("Game").Preload("WinnerParticipant").Find(&ts).Error return } func (a *App) GetTournament(id int) (t model.Tournament, err error) { err = a.db.Preload("Game").Preload("Participants").Preload("Matches").First(&t, id).Error return } func (a *App) SaveTournament(t model.Tournament) error { err := a.db.Save(&t).Error return err } func (a *App) FillRandom(t model.Tournament) { for range t.Size - len(t.Participants) { t.Participants = append(t.Participants, &model.Participant{ Name: model.RandomName(), IsTemporary: true, IsTeam: true, }) } a.db.Save(&t.Participants) a.db.Save(&t) } func (a *App) StartTournament(t model.Tournament) { t.TournamentState = 1 a.SaveTournament(t) t, _ = a.GetTournament(int(t.ID)) matches := make([]model.Match, 0, len(t.Participants)/2) for i := range len(t.Participants) / 2 { matches = append(matches, model.Match{ TournamentID: t.ID, Stage: 1, Order: i, Participant1ID: t.Participants[i].ID, Participant2ID: t.Participants[i+len(t.Participants)/2].ID, }) } if len(t.Participants)%2 != 0 { matches = append(matches, model.Match{ TournamentID: t.ID, Stage: 1, Order: len(t.Participants)/2 + 1, Participant1ID: t.Participants[len(t.Participants)-1].ID, Participant2ID: t.Participants[len(t.Participants)-1].ID, }) } a.db.Save(matches) } func (a *App) ExportTournament(t model.Tournament) { dirname, _ := os.UserHomeDir() str, err := runtime.SaveFileDialog(a.ctx, runtime.SaveDialogOptions{DefaultDirectory: dirname, DefaultFilename: "tournament.csv"}) if err != nil { panic(err) } file, err := os.Create(str) if err != nil { panic(err) } defer file.Close() // Create a CSV writer writer := csv.NewWriter(file) defer writer.Flush() var matches []model.Match a.db.Where("tournament_id = ?", t.ID).Order("stage ASC").Order("`order` ASC").Preload("Participant1").Preload("Participant2").Preload("WinnerParticipant").Find(&matches) // Write header header := []string{"Stage", "Order", "Winner", "Looser"} if err := writer.Write(header); err != nil { panic(err) } for _, m := range matches { record := []string{strconv.Itoa(m.Stage), strconv.Itoa(m.Order), m.WinnerParticipant.Name} if m.WinnerParticipantID == m.Participant1ID { record = append(record, m.Participant2.Name) } else { record = append(record, m.Participant1.Name) } if err := writer.Write(record); err != nil { panic(err) } } } func (a *App) GetParticipants() (ps []model.Participant, err error) { err = a.db.Find(&ps).Error return } func (a *App) SaveParticipant(p model.Participant) error { return a.db.Save(&p).Error } func (a *App) DeleteParticipat(p model.Participant) { a.db.Delete(&p) } func (a *App) RemoveParticipantFromTournament(p model.Participant, t model.Tournament) { if p.IsTemporary { a.db.Delete(&p) return } a.db.Model(&t).Association("Participants").Delete(&p) } func (a *App) GetMatches(tID uint) [][]model.Match { rawMatches := make([]model.Match, 0) a.db.Preload("Participant1").Preload("Participant2").Preload("WinnerParticipant").Where("tournament_id = ?", tID).Find(&rawMatches) slices.SortFunc(rawMatches, func(a model.Match, b model.Match) int { return a.Stage - b.Stage }) if len(rawMatches) < 1 { return [][]model.Match{} } matches := make([][]model.Match, rawMatches[len(rawMatches)-1].Stage) for _, match := range rawMatches { matches[match.Stage-1] = append(matches[match.Stage-1], match) } return matches } func (a *App) CreateStage(tID uint) { oldMatches := a.GetMatches(tID) if len(oldMatches) < 1 { return } participants := make([]model.Participant, 0, len(oldMatches[len(oldMatches)-1])) for _, m := range oldMatches[len(oldMatches)-1] { participants = append(participants, m.WinnerParticipant) } if len(participants) == 0 { return } stage := oldMatches[len(oldMatches)-1][len(oldMatches[len(oldMatches)-1])-1].Stage + 1 matches := make([]model.Match, 0, len(participants)/2) for i := range len(participants) / 2 { matches = append(matches, model.Match{ TournamentID: tID, Order: i, Stage: stage, Participant1ID: participants[i].ID, Participant2ID: participants[i+len(participants)/2].ID, }) } if len(participants)%2 != 0 { matches = append(matches, model.Match{ TournamentID: tID, Order: len(participants)/2 + 1, Stage: stage, Participant1ID: participants[len(participants)-1].ID, Participant2ID: participants[len(participants)-1].ID, WinnerParticipantID: participants[len(participants)-1].ID, }) } a.db.Save(matches) } func (a *App) SaveMatch(m *model.Match) { a.db.Save(m) }