// src/app/training.component.ts import { Component, Input, Output, EventEmitter, OnInit, ViewChild, ElementRef } from '@angular/core'; import { Deck, DeckImage, DeckService, Box } from '../deck.service'; import { CommonModule } from '@angular/common'; import { switchMap } from 'rxjs/operators'; import { forkJoin } from 'rxjs'; @Component({ selector: 'app-training', templateUrl: './training.component.html', standalone: true, imports: [CommonModule] }) export class TrainingComponent implements OnInit { @Input() deck!: Deck; @Output() close = new EventEmitter(); @ViewChild('canvas') canvasRef!: ElementRef; currentImageIndex: number = 0; currentImageData: DeckImage | null = null; currentBoxIndex: number = 0; boxes: Box[] = []; boxRevealed: boolean[] = []; knownCount: number = 0; unknownCount: number = 0; isShowingBox: boolean = false; isTrainingFinished: boolean = false; constructor(private deckService: DeckService) { } ngOnInit(): void { if (this.deck && this.deck.images.length > 0) { this.loadImage(this.currentImageIndex); } else { alert('Kein Deck oder keine Bilder vorhanden.'); this.close.emit(); } } loadImage(imageIndex: number): void { if (imageIndex >= this.deck.images.length) { this.endTraining(); return; } const imageName = this.deck.images[imageIndex].name; this.deckService.getImage(imageName).subscribe({ next: (imageData: DeckImage) => { this.currentImageData = imageData; this.boxes = imageData.boxes; this.boxRevealed = new Array(this.boxes.length).fill(false); this.currentBoxIndex = 0; this.isShowingBox = false; this.drawCanvas(); }, error: (err) => { console.error('Fehler beim Laden des Bildes:', err); alert('Fehler beim Laden des Bildes.'); this.close.emit(); } }); } drawCanvas(): void { const canvas = this.canvasRef.nativeElement; const ctx = canvas.getContext('2d'); if (!ctx || !this.currentImageData) return; const img = new Image(); img.src = `/api/debug_image/${this.currentImageData.name}`; img.onload = () => { // Set canvas size to image size canvas.width = img.width; canvas.height = img.height; // Draw image ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.drawImage(img, 0, 0, canvas.width, canvas.height); // Draw boxes this.boxes.forEach((box, index) => { if (this.boxRevealed[index]) { // Box ist bereits enthüllt, nichts zeichnen return; } ctx.beginPath(); ctx.rect(box.x1, box.y1, box.x2 - box.x1, box.y2 - box.y1); ctx.fillStyle = index === this.currentBoxIndex ? 'rgba(0, 255, 0, 0.99)' : 'rgba(255, 0, 0, 0.99)'; ctx.fill(); ctx.lineWidth = 2; ctx.strokeStyle = 'black'; ctx.stroke(); }); }; img.onerror = () => { console.error('Fehler beim Laden des Bildes für Canvas.'); alert('Fehler beim Laden des Bildes für Canvas.'); this.close.emit(); }; } showText(): void { if (this.currentBoxIndex >= this.boxes.length) return; this.boxRevealed[this.currentBoxIndex] = true; this.isShowingBox = true; this.drawCanvas(); } markKnown(): void { this.knownCount++; this.nextBox(); } markUnknown(): void { this.unknownCount++; this.nextBox(); } nextBox(): void { this.currentBoxIndex++; this.isShowingBox = false; if (this.currentBoxIndex >= this.boxes.length) { // Alle Boxen für dieses Bild sind bearbeitet this.nextImage(); } else { // Aktualisiere die Farben der Boxen this.drawCanvas(); } } nextImage(): void { this.currentImageIndex++; this.loadImage(this.currentImageIndex); } endTraining(): void { this.isTrainingFinished = true; alert(`Training beendet!\nGewusst: ${this.knownCount}\nNicht gewusst: ${this.unknownCount}`); this.close.emit(); } closeTraining(): void { if (confirm('Möchtest du das Training wirklich beenden?')) { this.close.emit(); } } get progress(): string { return `Bild ${this.currentImageIndex + 1} von ${this.deck.images.length}`; } }