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 ;