{ File: figure7.pas }

{ Scopo: esempio di uso di procedure con variabili locali e con parametri;
         esempio di attivazione di procedura da un'altra procedura }

program StampaFigure;
{ Permette all'utente di stampare su schermo figure geometriche.
  L'utente interagisce con il programma tramite una semplice interfaccia.
  E' possibile scegliere:
   - la forma della figura  (quadrato, triangolo o CERCHIO)
   - la dimensione della figura
   - il tipo di carattere con cui riempire la figura
   - di quanto spostare la figura a destra
}

var                          { VARIABILI GLOBALI }
  ch              : char;    { carattere che determina la figura o la fine }
  dimensione      : integer; { dimensione della figura }
  quale_carattere : char;    { carattere da usare per la stampa della figura }
  spostamento     : integer; { spostamento a destra della figura }
  fine            : boolean; { indica se terminare il ciclo }


  procedure StampaRiga (spazi, lung: integer; ch: char);
                      { PARAMETRI FORMALI }

  var                 { VARIABILI LOCALI }
    i : integer;      { indice del ciclo che scandisce le posizioni }
  begin   
    for i := 1 to spazi do
      write(' ');
    for i := 1 to lung do
      write(ch);
    writeln
  end; { StampaRiga }


  procedure StampaQuadrato (lato  : integer;     { lato del quadrato }
                            spost : integer;     { spostamento a destra }
                            car   : char);       { carattere di stampa }
                          { PARAMETRI FORMALI }

  var                     { VARIABILI LOCALI }
    i : integer;          { indice del ciclo che scandisce le righe }
  begin
    for i := 1 to lato do
      StampaRiga(spost, lato, car)
  end; { StampaQuadrato }


  procedure StampaTriangolo (altezza : integer;   { altezza del triangolo }
                             spost   : integer;   { spostamento a destra }
                             car     : char);     { carattere di stampa }
                           { PARAMETRI FORMALI }

  var                      { VARIABILI LOCALI }
    i : integer;           { indice del ciclo che scandisce le righe }
  begin
    for i := 1 to altezza do
      StampaRiga(spost+altezza-i, 2*i-1, car)
  end; { StampaTriangolo }


  procedure StampaCerchio (raggio : integer; { raggio del cerchio }
                           spost  : integer; { spostamento a destra del centro}
                           car    : char);   { carattere di stampa }
                         { PARAMETRI FORMALI }

  var                    { VARIABILI LOCALI }
    mezza_amp : integer; { meta` ampiezza della riga di asterischi corrente }
    i         : integer; { indice del ciclo che scandisce le righe }

    function  SemiCerchio (r, x : integer): integer;
    { Dati il raggio r di un cerchio e l'ascissa x, calcola il valore della
      funzione di semicerchio, arrotondato all'intero piu` vicino. }
    begin
      SemiCerchio := round(sqrt(sqr(r) - sqr(x)))
    end; { SemiCerchio }

  begin
    for i := raggio downto 0 do
    begin
      mezza_amp := SemiCerchio(raggio, i);
      StampaRiga(spost + raggio - mezza_amp, 2 * mezza_amp, car)
    end;

    for i := 1 to raggio do
    begin
      mezza_amp := SemiCerchio(raggio, i);
      StampaRiga(spost + raggio - mezza_amp, 2 * mezza_amp, car)
    end;
  end; { StampaCerchio }


  procedure StampaSaluto;
  begin
    writeln('CIAO :-)')
  end; { StampaSaluto }


begin { StampaFigure }
  fine := FALSE;
  repeat
    writeln;
    writeln('*** IMMETTI UN CARATTERE A SCELTA FRA I SEGUENTI ***');
    writeln('***** Q: stampa un quadrato');
    writeln('***** T: stampa un triangolo');
    writeln('***** C: stampa un cerchio');
    writeln('***** F: per terminare il programma');
    writeln;
    readln(ch); { ATTENZIONE: read NON va bene }
    fine := (ch = 'f') or (ch = 'F');
    if not fine then
    begin
      write('Di che dimensione? ');
      readln(dimensione);
      write('Di quanti caratteri spostato a destra? ');
      readln(spostamento);
      write('Con quale carattere va riempita la figura? ');
      readln(quale_carattere);
      case ch of
        'Q', 'q' : StampaQuadrato(dimensione, spostamento, quale_carattere);
        'T', 't' : StampaTriangolo(dimensione, spostamento, quale_carattere);
        'C', 'c' : StampaCerchio(dimensione, spostamento, quale_carattere);
      end { case }
    end { ramo then }
    else
      StampaSaluto
  until fine
end. { StampaFigure }