Program LETISTE;

uses crt, graph;

type TLetadlo = record
                  lcislo_letadla     : integer;
                  lkapacita_letadla  : integer;
                  lpocet_cestujicich : integer;
     		end;

     PCestujici = ^TCestujici;
     TCestujici = record
      		    cjmeno      : string;
		    cprijmeni   : string;
		    ccislo_letu : integer;
                    cnext       : PCestujici;
                  end;

     PNahradnici = ^TNahradnici;
     TNahradnici = record
                     njmeno      : string;
                     nprijmeni   : string;
                     ncislo_letu : integer;
                     nnext       : PNahradnici;
                   end;

var Letadlo              : array[1..10] of TLetadlo;
    SLetadlo             : file of TLetadlo;
    Cestujici, AktualniCestujici : PCestujici;
    SCestujici           : file of TCestujici;
    Nahradnici, AktualniNahradnici : PNahradnici;
    SNahradnici          : file of TNahradnici;
    podminka             : char;
    cyklus, i            : integer;




{***************************************************************************}
{***************************************************************************}

{******************       HLAVNI  NABIDKA         **************************}
procedure Hlavni_Nabidka;
begin
  textbackground(0);
  clrscr;
  textcolor(lightred);
  gotoxy(14,6); writeln('Program na demonstraci rezervace letenek na letisti');
  gotoxy(28,8); writeln('David Padrta  -  IVT 3');
  textcolor(white);
  gotoxy(16,10); writeln('Uvodni informace k programu : ');
  textcolor(lightred);
  gotoxy(16,11); writeln('様様様様様様様様様様様様様様様様様様様様様様様');
  textcolor(white);
  gotoxy(16,12); writeln('Rezervace letenky           : ');
  gotoxy(16,13); writeln('Zruseni rezervace           : ');
  gotoxy(16,14); writeln('Informace o letech          :  ');
  gotoxy(16,15); writeln('Informace o cestujicich     :  ');
  gotoxy(16,16); writeln('Informace o nahradnicich    :  ');
  gotoxy(16,18); writeln('Nove datove soubory         :  ');
  textcolor(lightred);
  gotoxy(16,17); writeln('様様様様様様様様様様様様様様様様様様様様様様様');
  gotoxy(16,19); writeln('様様様様様様様様様様様様様様様様様様様様様様様');
  textcolor(white);
  gotoxy(16,20); writeln('Ukonceni programu           :  ');
  textcolor(lightgreen);
  gotoxy(47,10); writeln('zmackni U nebo u');
  gotoxy(47,12); writeln('zmackni R nebo r');
  gotoxy(47,13); writeln('zmackni Z nebo z');
  gotoxy(47,14); writeln('zmackni I nebo i');
  gotoxy(47,15); writeln('zmackni C nebo c');
  gotoxy(47,16); writeln('zmackni N nebo n');
  gotoxy(47,18); writeln('zmackni Q nebo q');
  gotoxy(47,20); writeln('zmackni K nebo k');
end;

procedure Uvod;
begin
  clrscr;
  textcolor(white);
  writeln('Tento program provadi rezervace letenek na letisti a jejich odhlaseni.');
  writeln('Dale lze zjistovat informace o jednotlivych letech, cestujicich');
  writeln('i nahradnicich.');
  write('V polozce uvodniho menu ');
  textcolor(lightred);
  write('Informace o letech');
  textcolor(white);
  writeln(' jsou uvedeny jednotlive lety');
  writeln('a jejich cisla.');
  writeln('Pri rezervaci letenky se krome jmena a prijmeni cestujiciho uvadi take');
  writeln('ono cislo letu. Je proto vhodne se nejprve podivat na lety a pote teprve');
  writeln('rezervovat letenku.');
  writeln('Obdobne je tomu i u zruseni rezervace.');
  writeln('Cestujici, kteri se jiz do letadla nevejdou a rezervovali si let, jsou');
  writeln('automaticky prevedeni do seznamu nahradniku. Pokud se nejaky cestujici');
  writeln('z letu odhlasi, je ze seznamu nahradniku prerazen prvni nahradnik do seznamu');
  writeln('cestujicich.');
  gotoxy(1,25);
  write('Stiskni ENTER ...');
  readln;
end;


{*********************       INICIALIZACE_SEZNAMU         ******************}
procedure Inicializace_Seznamu;
var poc: integer;
begin
  poc := 1;
  assign(SLetadlo,'letadla.dat');
  reset(SLetadlo);
  while not(eof(SLetadlo)) do
  begin
    read(SLetadlo,Letadlo[poc]);
    poc := poc + 1;
  end;
  close(SLetadlo);
  {*********************************}
  assign(SCestujici,'cestuj.dat');
  reset(SCestujici);
  seek(SCestujici,0);
  new(Cestujici);
  AktualniCestujici := Cestujici;
  Cestujici^.cjmeno := ' ';
  Cestujici^.cprijmeni := ' ';
  Cestujici^.ccislo_letu := 0;
  if not(eof(SCestujici)) then
  begin
    read(SCestujici,Cestujici^);
    while not(eof(SCestujici)) do begin
      new(Cestujici^.cnext);
      read(SCestujici,Cestujici^.cnext^);
      Cestujici := Cestujici^.cnext;
    end;
  end;
  Cestujici^.cnext := nil;
  close(SCestujici);
  {*********************************}
  assign(SNahradnici,'nahradn.dat');
  reset(SNahradnici);
  seek(SNahradnici,0);
  new(Nahradnici);
  AktualniNahradnici := Nahradnici;
  Nahradnici^.njmeno := ' ';
  Nahradnici^.nprijmeni := ' ';
  Nahradnici^.ncislo_letu := 0;
  if not(eof(SNahradnici)) then
  begin
    read(SNahradnici,Nahradnici^);
    while not(eof(SNahradnici)) do begin
      new(Nahradnici^.nnext);
      read(SNahradnici,Nahradnici^.nnext^);
      Nahradnici := Nahradnici^.nnext;
    end;
  end;
  Nahradnici^.nnext := nil;
  close(SNahradnici);
end;

{*******************          ULOZENI_SEZNAMU        ***********************}
procedure Ulozeni_Seznamu;
var i: integer;
begin
  assign(SLetadlo,'letadla.dat');
  rewrite(SLetadlo);
  for i:= 1 to 4 do write(SLetadlo,Letadlo[i]);
  close(SLetadlo);
  {*********************************}
  assign(SCestujici,'cestuj.dat');
  rewrite(SCestujici);
  while (AktualniCestujici <> nil) do
  begin
    write(SCestujici,AktualniCestujici^);
    AktualniCestujici := AktualniCestujici^.cnext;
  end;
  close(SCestujici);
  {*********************************}
  assign(SNahradnici,'nahradn.dat');
  rewrite(SNahradnici);
  while (AktualniNahradnici <> nil) do
  begin
    write(SNahradnici,AktualniNahradnici^);
    AktualniNahradnici := AktualniNahradnici^.nnext;
  end;
  close(SNahradnici);
end;

{**********************        LETISTE_REZERVACE        ********************}
procedure Letiste_Rezervace;
var i: integer;
    probehnuti: boolean;
    cjm: string;
    cpr: string;
    ccl: integer;

begin
  clrscr;
  textcolor(11);
  gotoxy(20,10); write('Jmeno ucastnika    : '); readln(cjm);
  gotoxy(20,11); write('Prijmeni ucastnika : '); readln(cpr);
  gotoxy(20,12); write('Cislo letu         : '); readln(ccl);
  probehnuti := false;
  for i := 1 to 4 do
  begin
    if ((Letadlo[i].lcislo_letadla = ccl) and
        (Letadlo[i].lkapacita_letadla >
         Letadlo[i].lpocet_cestujicich)) then
    begin
      probehnuti := true;
      new(Cestujici^.cnext);
      Cestujici := Cestujici^.cnext;
      Cestujici^.cjmeno := cjm;
      Cestujici^.cprijmeni := cpr;
      Cestujici^.ccislo_letu := ccl;
      Cestujici^.cnext := nil;
      Letadlo[i].lpocet_cestujicich := Letadlo[i].lpocet_cestujicich + 1;
    end
    else if ((Letadlo[i].lcislo_letadla = ccl) and
            (Letadlo[i].lkapacita_letadla <=
             Letadlo[i].lpocet_cestujicich)) then
         begin
           probehnuti := true;
           new(Nahradnici^.nnext);
           Nahradnici := Nahradnici^.nnext;
           Nahradnici^.njmeno := cjm;
           Nahradnici^.nprijmeni := cpr;
           Nahradnici^.ncislo_letu := ccl;
           Nahradnici^.nnext := nil;
         end
         else if((i = 4) and (probehnuti = false)) then Exit;
  end;
  readln;
end;

{********************        LETISTE_ZRUSENI           *********************}
procedure Letiste_Zruseni;
var i: integer;
    zjm, njm: string;
    zpr, npr: string;
    zcl, ncl: integer;
    probehnuti2, probehnuti3, Pruchod: boolean;
    pom2cest, pom1: PCestujici;
    pom2nahr, pom3nahr, pom2: PNahradnici;

begin
  clrscr;
  textcolor(6);
  gotoxy(20,10); write('Jmeno ucastnika    : '); readln(zjm);
  gotoxy(20,11); write('Prijmeni ucastnika : '); readln(zpr);
  gotoxy(20,12); write('Cislo letu         : '); readln(zcl);
  probehnuti2 := false;
  probehnuti3 := false;
  pom2cest := AktualniCestujici;
  pom2nahr := AktualniNahradnici;
  pom3nahr := AktualniNahradnici;
  {##################  ZRUSENI CESTUJICIHO  #############}
  for i := 1 to 4 do
  begin
    while (pom2cest <> nil) do
    begin
      if ((pom2cest^.cnext^.cjmeno = zjm) and
          (pom2cest^.cnext^.cprijmeni = zpr) and
          (pom2cest^.cnext^.ccislo_letu = zcl) and
          (Letadlo[i].lcislo_letadla = zcl)) then
      begin
        probehnuti2 := true;
        pom1 := pom2cest^.cnext;
        pom2cest^.cnext := pom1^.cnext;
        dispose(pom1);
        Letadlo[i].lpocet_cestujicich := Letadlo[i].lpocet_cestujicich - 1;
      end;
      pom2cest := pom2cest^.cnext;
    end;
    pom2cest := AktualniCestujici;
  end;
  pom2cest := AktualniCestujici;
  pom2nahr := AktualniNahradnici;
  for i := 1 to 4 do
  begin
    Pruchod := false;
    if ((Letadlo[i].lkapacita_letadla >
         Letadlo[i].lpocet_cestujicich)) then
    begin
      while (pom2nahr <> nil)do
      begin
        if ((Letadlo[i].lcislo_letadla = pom2nahr^.ncislo_letu) and not(Pruchod))then
        begin
          njm := pom2nahr^.njmeno;
          npr := pom2nahr^.nprijmeni;
          ncl := pom2nahr^.ncislo_letu;
          new(Cestujici^.cnext);
          Cestujici := Cestujici^.cnext;
          Cestujici^.cjmeno := njm;
          Cestujici^.cprijmeni := npr;
          Cestujici^.ccislo_letu := ncl;
          Cestujici^.cnext := nil;
          Letadlo[i].lpocet_cestujicich := Letadlo[i].lpocet_cestujicich + 1;
          Pruchod := true;
        end;
        pom2nahr := pom2nahr^.nnext;
      end;
      pom2nahr := AktualniNahradnici;
  {###########   ZRUSENI NAHRADNIKA   #####################}
      while (pom2nahr <> nil) do
      begin
        if ((pom2nahr^.nnext^.njmeno = njm) and
            (pom2nahr^.nnext^.nprijmeni = npr) and
            (pom2nahr^.nnext^.ncislo_letu = ncl)) then
        begin
          pom2 := pom2nahr^.nnext;
          pom2nahr^.nnext := pom2^.nnext;
          dispose(pom2);
        end;
        pom2nahr := pom2nahr^.nnext;
      end;
      pom2nahr := AktualniNahradnici;
    end;
  end;
  pom2cest := AktualniCestujici;
  pom2nahr := AktualniNahradnici;
  if((i = 4) and (probehnuti2 = false)) then
    for i := 1 to 4 do
    while (pom2nahr <> nil) do
    begin
      if ((pom2nahr^.nnext^.njmeno = zjm) and
          (pom2nahr^.nnext^.nprijmeni = zpr) and
          (pom2nahr^.nnext^.ncislo_letu = zcl)) then
          begin
            probehnuti3 := true;
            pom2 := pom2nahr^.nnext;
            pom2nahr^.nnext := pom2^.nnext;
            dispose(pom2);
          end;
      pom2nahr := pom2nahr^.nnext;
    end;
  if((i = 4) and (probehnuti2 = false) and (probehnuti3 = false)) then
  begin
    textbackground(red);
    clrscr;
    textbackground(blue);
    textcolor(lightred + blink);
    gotoxy(20,11); write('!!! Tento let neni uveden v seznamu letu. !!!');
    gotoxy(20,13); write('!!!      Tento zaznam nelze zrusit.       !!!');
  end;
  readln;
end;

{***********************       LETISTE_INFORAMCE      **********************}
procedure Letiste_Informace;
var retezec: array[1..3] of char;

  procedure C_R(cislo: integer);
  var vysledek, zbytek, i: integer;
  begin
    for i:= 3 downto 1 do
    begin
      vysledek := cislo div 10;
      zbytek := cislo mod 10;
      retezec[i] := chr(zbytek + 48);
      cislo := vysledek;
    end;
  end;

begin
  clrscr;
  textcolor(10);
  gotoxy(6,3); writeln('Moskva   : let c. 328, delka letu 2.20 hod.');
  gotoxy(17,4); writeln('letadlo typu Boeing, cena letenky 3.290,- Kc.');
  gotoxy(17,5); writeln('kapacita 200 cest., obsazeno:');
  C_R(Letadlo[1].lpocet_cestujicich);
  if (Letadlo[1].lpocet_cestujicich = Letadlo[1].lkapacita_letadla) then
  begin
    textcolor(12 + blink);
    gotoxy(47,5); writeln(retezec);
  end
  else begin
    textcolor(4);
    gotoxy(47,5); writeln(retezec);
  end;
  textcolor(10);
  gotoxy(51,5); writeln('mist.');

  gotoxy(6,9); writeln('New York : let c. 925, delka letu 7.30 hod.');
  gotoxy(17,10); writeln('letadlo typu Boeing, cena letenky 22.590,- Kc.');
  gotoxy(17,11); writeln('kapacita 220 cest., obsazeno:');
  C_R(Letadlo[2].lpocet_cestujicich);
  if (Letadlo[2].lpocet_cestujicich = Letadlo[2].lkapacita_letadla) then
  begin
    textcolor(12 + blink);
    gotoxy(47,11); writeln(retezec);
  end
  else begin
    textcolor(4);
    gotoxy(47,11); writeln(retezec);
  end;
  textcolor(10);
  gotoxy(51,11); writeln('mist.');

  gotoxy(6,15); writeln('Pariz    : let c. 731, delka letu 3.00 hod.');
  gotoxy(17,16); writeln('letadlo typu Boeing, cena letenky 4.990,- Kc.');
  gotoxy(17,17); writeln('kapacita 190 cest., obsazeno:');
  C_R(Letadlo[3].lpocet_cestujicich);
  if (Letadlo[3].lpocet_cestujicich = Letadlo[3].lkapacita_letadla) then
  begin
    textcolor(12 + blink);
    gotoxy(47,17); writeln(retezec);
  end
  else begin
    textcolor(4);
    gotoxy(47,17); writeln(retezec);
  end;
  textcolor(10);
  gotoxy(51,17); writeln('mist.');

  gotoxy(6,21); writeln('Londyn   : let c. 222, delka letu 4.10 hod.');
  gotoxy(17,22); writeln('letadlo typu Boeing, cena letenky 6.550,- Kc.');
  gotoxy(17,23); writeln('kapacita 160 cest., obsazeno:');
  C_R(Letadlo[4].lpocet_cestujicich);
  if (Letadlo[4].lpocet_cestujicich = Letadlo[4].lkapacita_letadla) then
  begin
    textcolor(12 + blink);
    gotoxy(47,23); writeln(retezec);
  end
  else begin
    textcolor(4);
    gotoxy(47,23); writeln(retezec);
  end;
  textcolor(10);
  gotoxy(51,23); writeln('mist.');
  textcolor(7);
  gotoxy(1,25); write('Stiskni ENTER ...');
  readln;
end;

{*********************       LETISTE_CESTUJICI        **********************}
procedure Letiste_Cestujici;
var pozicex, pozicey: integer;
    pomcest: PCestujici;

begin
  clrscr;
  textcolor(9);
  pomcest := AktualniCestujici^.cnext;
  pozicex := -1; pozicey := 0;
  while (pomcest <> nil) do
  begin
    if (pozicex < 3) then
    begin
      pozicex := pozicex + 1;
      gotoxy(1 + pozicex*20,2 + pozicey*4); write(pomcest^.cjmeno);
      gotoxy(1 + pozicex*20,3 + pozicey*4); write(pomcest^.cprijmeni);
      gotoxy(1 + pozicex*20,4 + pozicey*4); write(pomcest^.ccislo_letu);
      pomcest := pomcest^.cnext;
    end;
    if (pozicex = 3) then
    begin
      pozicex := -1;
      pozicey := pozicey + 1;
    end;
  end;
  textcolor(7);
  gotoxy(1,25); write('Stiskni ENTER ...');
  readln;
end;

{****************         LETISTE_NAHRADNICI     ***************************}
procedure Letiste_Nahradnici;
var pozicex, pozicey: integer;
    pomnahr: PNahradnici;
    retezec: array[1..3]of char;

begin
  clrscr;
  textcolor(13);
  pomnahr := AktualniNahradnici^.nnext;
  pozicex := -1; pozicey := 0;
  while (pomnahr <> nil) do
  begin
    if (pozicex < 3) then
    begin
      pozicex := pozicex + 1;
      gotoxy(1 + pozicex*20,2 + pozicey*4); write(pomnahr^.njmeno);
      gotoxy(1 + pozicex*20,3 + pozicey*4); write(pomnahr^.nprijmeni);
      gotoxy(1 + pozicex*20,4 + pozicey*4); write(pomnahr^.ncislo_letu);
      pomnahr := pomnahr^.nnext;
    end;
    if (pozicex = 3) then
    begin
      pozicex := -1;
      pozicey := pozicey + 1;
    end;
  end;
  textcolor(7);
  gotoxy(1,25); write('Stiskni ENTER ...');
  readln;
end;

procedure Inicializace_Souboru;
var F : file;
begin
  clrscr;
  assign(SLetadlo,'letadla.dat');
  rewrite(SLetadlo);
  Letadlo[1].lcislo_letadla := 328;
  Letadlo[1].lkapacita_letadla := 200;
  Letadlo[1].lpocet_cestujicich := 195;
  write(SLetadlo,Letadlo[1]);
  Letadlo[2].lcislo_letadla := 925;
  Letadlo[2].lkapacita_letadla := 220;
  Letadlo[2].lpocet_cestujicich := 215;
  write(SLetadlo,Letadlo[2]);
  Letadlo[3].lcislo_letadla := 731;
  Letadlo[3].lkapacita_letadla := 190;
  Letadlo[3].lpocet_cestujicich := 185;
  write(SLetadlo,Letadlo[3]);
  Letadlo[4].lcislo_letadla := 222;
  Letadlo[4].lkapacita_letadla := 160;
  Letadlo[4].lpocet_cestujicich := 155;
  write(SLetadlo,Letadlo[4]);
  close(SLetadlo);
  rewrite(SCestujici);
  close(SCestujici);
  rewrite(SNahradnici);
  close(SNahradnici);
  Inicializace_Seznamu;
end;

{***************************************************************************}
{***************************************************************************}

{***************************************************************************}
{                     V L A S T N I   P R O G R A M                         }
{***************************************************************************}


BEGIN
  clrscr;
  repeat
    Inicializace_Seznamu;
    Hlavni_nabidka;
    podminka := readkey;
    case podminka of
     'U','u': Uvod;
     'R','r': Letiste_Rezervace;
     'Z','y': Letiste_Zruseni;
     'I','i': Letiste_Informace;
     'C','c': Letiste_Cestujici;
     'N','n': Letiste_Nahradnici;
     'Q','q': Inicializace_Souboru;
    end;
    Ulozeni_Seznamu;
  until ((podminka = 'K') or (podminka = 'k'));
  clrscr;
  gotoxy(20,10); write('Uspesne jste ukoncil(a) tento program ...');
  delay(3000);
  clrscr;
END.