# Specifiche e Considerazioni di Design: Editor Visuale Intelligente

Questo documento raccoglie l'analisi e le specifiche di design per l'implementazione del sistema di **Scansione Fotocamera & AI** per la digitalizzazione rapida dei canti nella PWA. 
L'obiettivo è progettare un'esperienza utente a "sfregamento zero" (zero friction), robusta anche in ambienti ostili (es. chiese senza campo) e capace di gestire le imperfezioni storiche dei libretti parrocchiali.

---

## 1. Architettura della Pipeline Visiva

Il processo si basa su un'interazione fluida tra client (PWA), proxy server ed il motore multimodale di visione artificiale (Google Gemini 2.5 Flash).

```mermaid
graph TD
    A[Inquadratura Fotocamera PWA] --> B[Compressione Client Canvas JPEG ~200KB]
    B --> C{Connessione Rete?}
    C -- Online --> D[Invia POST a /scanSong]
    C -- Offline --> E[Salva in IndexedDB localmente]
    E --> F[In attesa di Connessione...]
    F --> C
    D --> G[Chiamata a Gemini 2.5 Flash]
    G --> H[Analisi Spaziale ed Estrazione JSON]
    H --> I[Popolamento Automatico dell'Editor PWA]
```

---

## 2. Casi d'Uso Avanzati e Soluzioni Specifiche

### A. Gestione Multi-Pagina (Canti Lunghi)
*   **Problema**: Molti canti liturgici (es. Salmi o canti d'ingresso lunghi) si sviluppano su due pagine adiacenti o su foglietti fronte-retro separati.
*   **Soluzione**: L'interfaccia dell'editor consentirà all'utente di aggiungere più scatti all'interno della stessa sessione di scansione prima dell'invio.
*   **Gestione AI**: Le immagini verranno inviate in blocco al modello di visione (sfruttando l'enorme finestra di contesto di Gemini). Il prompt istruirà l'IA a considerare le foto come sequenziali, unendo il testo in un unico flusso coerente senza duplicare il titolo ed ordinando le strofe in modo corretto.

### B. Correzione dei Refusi Storici (Libretti Anni '90)
*   **Problema**: I libretti parrocchiali stampati decenni fa o digitati a macchina presentano spesso refusi tipografici, lettere scambiate o scorrettezze sugli accenti (es. `perche'` al posto di `perché`, `piu'` per `più`, `Gesu'` per `Gesù`).
*   **Soluzione**: Sfruttando la comprensione semantica del modello di linguaggio (LLM), l'IA non effettua una mera trascrizione pixel-per-pixel, ma analizza il senso delle parole nel contesto dei canti liturgici italiani (molti dei quali fanno già parte della sua conoscenza pregressa).
*   **Risultato**: Restituzione di un testo grammaticalmente perfetto e pulito, correggendo automaticamente i vecchi accenti e gli errori di battitura della carta originale.

### C. Traduzione ed Uniformazione degli Accordi
*   **Problema**: Gli spartiti o canzonieri cartacei possono utilizzare la notazione internazionale (`C, D, E, F, G, A, B`) anziché la notazione latina standard italiana (`Do, Re, Mi, Fa, Sol, La, Si`).
*   **Soluzione**: Nel prompt di sistema, l'IA viene istruita ad uniformare tutti gli accordi alla notazione italiana standard. 
*   **Esempio**: Se l'utente inquadra un canzonierino scout o internazionale scritto in notazione inglese (es. `[C] [G] [Am]`), il sistema lo tradurrà istantaneamente in `[Do] [Sol] [Lam]` prima di inviarlo all'editor della PWA, garantendo la compatibilità al 100% con il modulo di trasposizione interna dei toni.

---

## 3. Strategia Offline (Resilienza in Chiesa)

Le chiese sono notoriamente ambienti difficili per la connettività di rete (mura in pietra spesse, sotterranei, assenza di ripetitori vicini). Il sistema non deve dipendere da una connessione sempre attiva.

### Flusso Offline con IndexedDB
1.  L'utente scatta la foto (o seleziona l'immagine) dall'editor mentre si trova offline.
2.  L'app converte l'immagine in `Blob` e la salva localmente all'interno di **IndexedDB** associandola a una coda di scansioni pendenti (`scan-offline-queue`).
3.  L'interfaccia mostra un avviso rassicurante: 
    > 💾 *Fogli acquisiti offline! L'app elaborerà automaticamente la scansione del canto non appena rileverai una connessione internet stabile.*
4.  Il `ConnectivityService` della PWA monitora lo stato della rete. Non appena il dispositivo torna online (es. all'uscita dalla chiesa o sotto WiFi):
    *   L'app estrae l'immagine da IndexedDB.
    *   Effettua la chiamata POST a `/scanSong`.
    *   Riceve il JSON tradotto e notifica l'utente (o precompila la scheda dei canti proposti).

---

## 4. Specifiche del Prompt di Sistema (System Prompt)

L'output del backend deve essere rigidamente controllato e tipizzato per consentire al client Angular di digerirlo senza eccezioni di parsing. Il prompt di sistema da implementare sul proxy API sarà il seguente:

```text
Sei un OCR musicale multimodale specializzato in canti liturgici e religiosi cristiani.
Analizza l'immagine fornita (o il set di immagini sequenziali) e restituisci ESCLUSIVAMENTE un oggetto JSON valido. Non aggiungere spiegazioni o markdown.

Schema JSON di risposta:
{
  "titolo": "String (titolo del canto)",
  "autore": "String o null",
  "sezioni": [
    {
      "tipo": "ritornello" | "strofa",
      "numero": Number o null (solo per le strofe, es. 1, 2, 3),
      "righe": [
        "Testo completo della riga con accordi musicali inseriti in linea tra parentesi quadre prima della sillaba corretta. Es: [Do]Tu sei la mia [Sol]vita"
      ]
    }
  ]
}

Regole di formattazione:
1. Traduci tutti gli accordi in notazione italiana (Do, Re, Mi, Fa, Sol, La, Si, con 'm' per i minori, '7' per le settime, ecc.).
2. Inserisci gli accordi esattamente nel punto in cui cadono spazialmente sopra le parole dell'immagine.
3. Correggi accenti storici errati (es. trasformando 'perche'' in 'perché') e refusi evidenti.
```

Questo approccio garantisce che la PWA riceva un formato perfettamente strutturato e pronto per essere inserito direttamente nelle righe del database locale.

---

## 5. Approccio 100% Locale e Gratuito (Client-Side)

Se il vincolo fondamentale è **non utilizzare alcun servizio cloud a pagamento o esterno**, possiamo spostare l'intero carico di elaborazione (OCR ed allineamento) **direttamente all'interno del browser dell'utente (client-side)** in modo 100% gratuito ed autonomo.

Ciò è realizzabile integrando due componenti open-source nella PWA:

1. **Tesseract.js** (compilato in WebAssembly per il browser): si occupa di estrarre il testo e, soprattutto, di fornirci i metadati spaziali di ogni singola parola.
2. **Algoritmo Euristico di Allineamento Spaziale**: un algoritmo scritto da noi in TypeScript che mappa la posizione fisica degli accordi rispetto al testo.

### Come funziona l'algoritmo di allineamento locale?

Quando Tesseract.js scansiona l'immagine, non restituisce solo una stringa, ma un array di parole in cui ogni parola contiene il testo ed il suo **Bounding Box (rettangolo di coordinate fisiche sull'immagine: `x0`, `y0`, `x1`, `y1`)**:

```typescript
interface OCRWord {
  text: string;
  bbox: { x0: number; y0: number; x1: number; y1: number };
}
```

L'algoritmo elabora questi dati in 4 fasi:

#### Fase 1: Raggruppamento in Righe Fisiche
Le parole vengono ordinate per coordinata `y0`. Le parole che hanno valori di `y0` simili (con una tolleranza basata sull'altezza dei caratteri, es. ±15 pixel) vengono raggruppate nella stessa **riga orizzontale**.

#### Fase 2: Classificazione delle Righe (Accordi vs. Testo)
Ogni riga viene analizzata per determinare la sua natura:
* **Riga di Accordi**: Se più del 70% delle parole nella riga corrisponde a pattern di accordi noti (es. parole corte come `Do`, `Sol`, `Re7`, `Lam`, `C`, `G`, `D7`), la riga viene marcata come riga di accordi.
* **Riga di Testo**: In tutti gli altri casi, viene considerata una riga di testo normale.

#### Fase 3: Mappatura e Iniezione degli Accordi
Per ogni **Riga di Accordi**, individuiamo la **Riga di Testo** immediatamente sottostante (quella con coordinata `y` successiva più vicina).
Per ciascun accordo presente nella riga:
1. Calcoliamo la sua coordinata orizzontale centrale: `x_accordo = (bbox.x0 + bbox.x1) / 2`.
2. Scorriamo le parole della riga di testo sottostante per trovare quale parola (o lettera) ha la coordinata `x` più vicina a `x_accordo`.
3. Inseriamo la stringa dell'accordo tra parentesi quadre (es. `[Re]`) esattamente prima di quella parola nel testo finale.

```text
Spaziatura fisica sull'immagine:
Riga 1 (Accordi):       [Do]                    [Sol]
Riga 2 (Testo):         Tu sei la mia vita,     altro io non ho.
                        ↑                       ↑
                        x=120                   x=480
```

#### Fase 4: Segmentazione Strutturale delle Sezioni
L'algoritmo identifica i cambi di sezione (es. il passaggio da Ritornello a Strofa) misurando lo spazio verticale (`gap y`) tra le righe di testo. Un distanziamento verticale significativamente maggiore della media indica una separazione di strofa, consentendo di dividere il canto in blocchi strutturati.

### Pro e Contro dell'Approccio Locale

| Vantaggi | Svantaggi |
| :--- | :--- |
| 🟢 **100% Gratuito**: Nessun costo di licenza o API esterne. | 🔴 **Uso Risorse**: L'elaborazione OCR avviene sul telefono dell'utente (richiede 3-5 secondi). |
| 🟢 **Totale Privacy**: Le immagini non lasciano mai il dispositivo. | 🔴 **Meno tolleranza alle pieghe**: Rispetto a Gemini, un OCR locale soffre di più se la foto è storta o con ombre. |
| 🟢 **Funzionamento Offline**: Funziona anche nel deserto, senza alcuna rete. | 🔴 **Nessuna correzione lessicale**: Non corregge gli errori grammaticali storici del foglio cartaceo. |

---

## 6. Il Compromesso Ideale: Gemini API Free Tier

Esiste una terza via che unisce il meglio dei due mondi (la precisione assoluta dell'AI e il costo zero): **il Free Tier delle API di Google Gemini 2.5 Flash**.

Google offre tramite **Google AI Studio** un piano d'uso completamente gratuito con i seguenti limiti:
*   **15 Richieste al minuto (RPM)**
*   **1500 Richieste al giorno (RPD)**

Per un'applicazione di canti religiosi dove l'aggiunta di nuovi brani è un'operazione sporadica (eseguita da pochi amministratori/chitarristi solo quando si impara un canto nuovo), **questi limiti gratuiti non verranno mai superati**.

*   **Implementazione sicura**: Per evitare di inserire la chiave API gratuita all'interno del codice frontend (dove chiunque potrebbe rubarla), si fa passare la richiesta attraverso una semplice funzione serverless gratuita (es. su *Vercel Free Tier* o *Cloudflare Workers*), che funge da proxy sicuro e vi applica la chiave API prima di chiamare Google.

