PROGRAM UN_AGENDA;

(* Pour l'‚nonc‚, voir la proc‚dure AVERTIS
   Le but est d'apprendre … rechercher une donn‚e dans un tableau
   en fonction d'un critŠr pr‚cis de recherche *)

USES CRT;

CONST MAX = 10;   (* Maximum 127, sinon changer tous les types entiers courts (SHORTINT)
                     en entiers normaux sous peine d'erreurs (d‚passement de capacit‚) *)

TYPE LIGNE  = (PRENOM, NOM, TEL);                  (* Nouveau type ‚num‚r‚ et donc utilisable dans une boucle FOR *)
     STRXXX = ARRAY [LIGNE,1..MAX] OF STRING [25]; (* XXX car le nombre de cases peut changer si on modifie la CONST *)

VAR  AGENDA: STRXXX;    (* Matrice de 3 lignes et MAX colonnes *)
     COMBIEN: SHORTINT; (* Contiendra le nombre r‚el de correspondant(e)s *)

PROCEDURE AVERTIS;
          BEGIN
          WRITELN ('Ce programme gŠre un agenda ‚lectronique (sans sauvegarde!!!).');
          WRITELN ('Dans un premier temps, les coordonn‚es (pr‚nom, nom et num‚ro de t‚l‚phone)');
          WRITELN ('d''au maximum ',MAX,' personnes peuvent ˆtre stock‚es.');
          WRITELN ('Dans un second temps, il est possible de rechercher une personne soit sur');
          WRITELN ('son nom, soit sur son pr‚nom.');
          WRITELN ('Dans les deux phases, le signal d''arrˆt est l''introduction de la chaŒne zzz.');
          WRITELN;
          END;

PROCEDURE REMPLIS (VAR AGENDA: STRXXX; VAR COMBIEN: SHORTINT);
          VAR COMPTEUR: SHORTINT;
              PTIT_NOM: STRING;

          BEGIN
          COMPTEUR := 1;
          WRITE  ('Quel est le pr‚nom de ton premier correspondant ? (zzz pour arrˆter) ');
          READLN (PTIT_NOM);
          WHILE (PTIT_NOM <> 'zzz') AND (PTIT_NOM <> 'ZZZ') AND (COMPTEUR <= MAX) DO
(* On v‚rifie que le pr‚nom introduit soir <> de "zzz", mais on refuse d'office l'entr‚e
   du TANT QUE si le carnet est complet, c…d si on est en passe de compl‚ter la colonne MAX+1 *)
                BEGIN
                AGENDA [PRENOM,COMPTEUR] := PTIT_NOM;
                WRITE  ('Quel est son nom de famille ? ');
                READLN (AGENDA [NOM,COMPTEUR]);
                WRITE  ('Et quel est son num‚ro de t‚l‚phone ? ');
                READLN (AGENDA [TEL,COMPTEUR]);
                WRITELN;
                INC (COMPTEUR);  (* Pointe sur la fiche suivante … remplir *)
                IF COMPTEUR <= MAX THEN
(* On ne demande un nouveau pr‚nom que si l'agenda n'est pas complet *)
                   BEGIN
                   WRITE  ('Quel est le pr‚nom nø',COMPTEUR,' de ton agenda (zzz = arrˆt) ? ');
                   READLN (PTIT_NOM);
                   END;
                END;
(* L'utilisateur a fini de compl‚ter son agenda. Deux possibilit‚s peuvent se pr‚senter:
   1. Il a cl“tur‚ par "zzz". Dans ce cas, le nombre de correspondant(e)s est ‚gal … COMPTEUR-1
      car COMPTEUR pointait d‚j… sur la fiche suivante pour la compl‚ter.
   2. Il est all‚ jusqu'au bout de ce que peut contenir l'agenda. On sort alors de la boucle
      avec la valeur MAX+1, en d‚bordement de capacit‚. Il faut alors mettre dans combien COMPTEUR-1 *)
          COMBIEN := COMPTEUR - 1;
          WRITELN;
          WRITELN ('Ton agenda contient donc ',COMBIEN,' correspondant(e)s. Pour la suite: ENTREE');
          READLN;
          CLRSCR;
          END;

PROCEDURE RETROUVE (AGENDA: STRXXX; COMBIEN: SHORTINT);
          VAR i: INTEGER;
              MOT: STRING;
              CHOIX: CHAR;
              Y_EN_A_1: BOOLEAN;

          BEGIN
          REPEAT
                WRITELN ('L''agenda contient ',COMBIEN,' fiche(s)');
                WRITELN;
                WRITELN ('Sur quel critŠre rechercher ?');
                WRITELN ('Pr‚nom (taper p), Nom (taper n''importe quoi), Arrˆt (taper 0)');
                CHOIX := READKEY; (* DŠs qu'une touche est press‚e, CHOIX re‡oit le caractŠre (non affich‚ … l'‚cran) *)
                IF CHOIX <> '0' THEN  (* Si l'utilisateur n'a pas choisit de quitter *)
                   BEGIN
                   WRITELN (CHOIX);
                   IF (CHOIX = 'p') OR (CHOIX = 'P') THEN
                      WRITELN ('Quel est le pr‚nom … rechercher dans l''agenda ?')
                   ELSE
                       WRITELN ('Quel est le nom … rechercher dans l''agenda ?');
                   READLN  (MOT);
                   WRITELN;
                   Y_EN_A_1 := FALSE;        (* Permettra de savoir si une fiche au moins correspondait aux critŠres *)
                   FOR i := 1 TO COMBIEN DO  (* On balaie le tableau *)
                       IF (((CHOIX = 'p') OR (CHOIX = 'P')) AND (AGENDA [PRENOM,i] = MOT)) OR
                          (((CHOIX <> 'p') AND (CHOIX <> 'P')) AND (AGENDA [NOM,i] = MOT)) THEN
(* Si (le choix est "p" ET qu'un pr‚nom correspond) OU (si le choix est <> "p" ET que le nom correspond) : *)
                             BEGIN      (* on affiche la fiche *)
                             WRITELN (AGENDA [PRENOM,i]);
                             WRITELN (AGENDA [NOM,I]);
                             WRITELN (AGENDA [TEL,i]);
                             WRITELN;
                             Y_EN_A_1 := TRUE;  (* Signal qui permet de savoir qu'au moins 1 fiche a ‚t‚ trouv‚e *)
                             END;
                   IF NOT Y_EN_A_1 THEN         (* S'il n'y avait pas de fiche correspondant au critŠre, on le signale *)
                      IF (CHOIX = 'p') OR (CHOIX = 'P') THEN
                         WRITELN ('Il n''y a pas de pr‚nom "',MOT,'" dans l''agenda')
                      ELSE
                          WRITELN ('Il n''y a pas de nom "',MOT,'" dans l''agenda');
                   WRITELN;
                   WRITELN ('Pour la suite, taper ENTREE');
                   READLN;
                   CLRSCR;
                   END;
          UNTIL CHOIX = '0';  (* On arrˆte la boucle de r‚p‚tition si l'utilisateur veut quitter *)
          END;

BEGIN
CLRSCR;
AVERTIS;
REMPLIS (AGENDA, COMBIEN);
RETROUVE (AGENDA, COMBIEN);
END.
