# mission2.adb

    with GAda.Text_IO ;
    with Caracteres ;

    procedure Mission2 is

       --
       --  Toute cette partie est reprise du corrigé du premier TP,
       --  avec une seule modification : la table est passée en argument
       --  à chaque procédure d'affichage.
       --

       package Txt renames GAda.Text_IO ;
       package Car renames Caracteres ;

       -- Affiche une trame avec des # et des espaces.
       procedure Afficher_Trame (Trame : Car.T_Trame) is
       begin
          for Y in Trame'Range(1) loop
             for X in Trame'Range(2) loop
                case Trame(Y,X) is
                   when Car.Allume => Txt.Put("#") ;
                   when Car.Eteint => Txt.Put(" ") ;
                end case ;
             end loop ;
             Txt.New_Line ;
          end loop ;
       end Afficher_Trame ;

       procedure Tester_Afficher_Trame is
       begin
          Afficher_Trame(Car.Table(30).Trame) ;
          Afficher_Trame(Car.Table(31).Trame) ;
          Afficher_Trame(Car.Table(32).Trame) ;
       end Tester_Afficher_Trame ;

       -- À partir d'un caractère, trouve la trame associée
       -- Renvoie la trame de l'étoile (caractère '*') si le caractère n'est pas trouvé.
       function Trouver_Trame (Table : Car.T_Table ; Lettre : Character) return Car.T_Trame is
          No_Case : Integer ;
          Trouve : Boolean ;
       begin
          Trouve := False ;
          No_Case := Table'First ;

          -- Parcourt la table jusqu'à trouver le caractère ou jusqu'à sortir de la table.
          while (not Trouve) and No_Case <= Table'Last loop
             if Table(No_Case).Car = Lettre then
                Trouve := True ;
             else
                No_Case := No_Case + 1 ;
             end if ;
          end loop ;

          -- Si on a pas trouvé le caractère, on renvoie l'étoile (numéro 9)
          if not Trouve then No_Case := 9 ;
          end if ;

          return Table(No_Case).Trame ;

       end Trouver_Trame ;

       -- Affiche un mot verticalement
       procedure Afficher_Mot(Table : Car.T_Table ; Mot : String) is
       begin
          for NoCase in Mot'Range loop
             Afficher_Trame( Trouver_Trame( Table, Mot(NoCase) ) ) ;
          end loop ;
       end Afficher_Mot ;

       --
       -- La fonction demandée
       --
       function Inverser (Table : Car.T_Table) return Car.T_Table is
          Resultat : Car.T_Table(Table'Range) ;
          Modele : Car.T_Trame(1..Car.Hauteur_Car, 1..Car.Largeur_Car) ;
          Pixel : Car.T_Pixel ;
       begin
          -- Pour chaque case, copier le caractère et la trame en l'inversant
          for NoCase in Table'Range loop
             Resultat(NoCase).Car := Table(NoCase).Car ;

             -- On récupère la trame à parcourir.
             Modele := Table(NoCase).Trame ;

             for Ligne in Modele'Range(1) loop
                for Col in Modele'Range(2) loop

                   -- On va chercher le pixel dans la bonne case.
                   case Modele(Ligne, Col) is
                      when Car.Allume => Pixel := Car.Eteint ;
                      when Car.Eteint => Pixel := Car.Allume ;
                   end case ;

                   -- Important : on va écrire le pixel inverse au bon endroit dans le résultat.
                   -- (car ça ne va pas se faire tout seul par magie)
                   Resultat(NoCase).Trame(Ligne, Col) := Pixel ;

                end loop ;
             end loop ;

          end loop ;

          return Resultat ;
       end Inverser ;

    begin
       Afficher_Mot(Car.Table, "Papageno") ;
       Afficher_Mot(Inverser(Car.Table), "Papageno") ;
       Afficher_Mot(Inverser(Inverser(Car.Table)), "Papageno") ;

    end Mission2 ;