package body Chaines_De_Caracteres is

--  La fonction Correspond est une fonction auxiliaire utilisee par Indice_De.
--  Elle prend en arguments deux chaines (Chaine et Dans) qui sont les entrée de Indice_De
--  et deux entiers (Position_Chaine et Position_Dans) qui correspondent aux positions
--  de la recherche du motif dans le mot.
--  Elle renvoie vrai si Chaine(Position_Chaine..Chaine'Last) apparait à la position Position_Dans
--  dans Dans.
--  exemple Correspond("tu",1,"voiture",4) retourne vrai.
--  Cette fonction est récursive. Lorsque le ième caractère de Chaine correspond au nième
--  caractère de Dans, on réitere jusqu'a ce que l'on arrive au bout de l'une des deux chaines.

   function Correspond (Chaine : String; Position_Chaine : Natural;
                                         Dans : String; Position_Dans : Natural) return Boolean is
   begin
      if Position_Dans > (Dans'Last+1)
      then
         return(False);
      elsif Position_Chaine > Chaine'Last
      then
         return(True);
      elsif Chaine(Position_Chaine) /= Dans(Position_Dans)
      then
         return(False);
      else
         return(Correspond(Chaine, (Position_Chaine+1), Dans, Position_Dans+1));
      end if;
   end Correspond;

--  Indice_De utilise Correspond sur tout les indices de Dans.
--  Cette méthode de recherche n'est pas optimale mais à l'avantage d'etre facile
--  à coder.

   function Indice_De (Chaine : String; Dans : String) return Natural is
   begin
      for I in 1..Dans'Last
      loop
         if Correspond (Chaine, 1, Dans, I)
         then
            return(I);
         end if;
      end loop;
      return(0);
   end Indice_De;

--  Remplacement fait d'abord des tests sur les arguments puis remplace la chaine De
--  par la chaine par.

   function Remplacement (De : String; Par : String; Dans : String) return String is
      Resultat : String := Dans;
      Indice_De_De : Integer;
   begin
      if De'Last /= Par'Last
      then
         raise Taille_Differente;
      end if;
      Indice_De_De := Indice_De(De, Dans) - 1;
      if Indice_De_De = -1
      then
         raise Motif_Non_Present;
      end if;
      for I in 1..(De'Last)
      loop
         Resultat(I+Indice_De_De) := Par(I);
      end loop;
      return(Resultat);
   exception
      when Taille_Differente =>
         Put_Line("Les entrees " & De & " et " & Par & " doivent etre de meme longueur.");
         raise Taille_Differente;
      when Motif_Non_Present =>
         Put_Line(De & " n'apparait pas dans " & Dans & ".");
         raise Motif_Non_Present;
   end Remplacement;

end Chaines_De_Caracteres;
