Program Seznam;
uses Crt;

const Nejvyssi = #1;
      Nejnizsi = #255;

type TKlic = string;
     THodnota = string;
     PolozkaPtr = ^Polozka;
     Polozka = record
                Dalsi : PolozkaPtr;
                Klic : TKlic;
                Hodnota : THodnota;
               end;
      THlava = record
                Zacatek, Konec : PolozkaPtr;
               end;


Procedure Init(var Hlava : THlava);
begin
 New(Hlava.Zacatek);
 Hlava.Zacatek^.Klic:=Nejvyssi;
 Hlava.Zacatek^.Hodnota:='';
 New(Hlava.Konec);
 Hlava.Konec^.Klic:=Nejnizsi;
 Hlava.Konec^.Hodnota:='';
 Hlava.Konec^.Dalsi := nil;
 Hlava.Zacatek^.Dalsi:=Hlava.Konec;
end;

Procedure Done(var Hlava : THlava);
var Dalsi, WorkPol : PolozkaPtr;
begin
 WorkPol:=Hlava.Zacatek;
 While WorkPol <> nil do
  begin
   Dalsi:=WorkPol^.Dalsi;
   WriteLn('Odstranena polozka: ',WorkPol^.Klic,': ',WorkPol^.Hodnota);
   Dispose(WorkPol); WorkPol:=nil;
   WorkPol:=Dalsi;
  end;
end;

Function A_pred_B (A, B : TKlic) : Boolean;
var I:Byte;
begin
 WriteLn('Porovnavam: ',A,'(',Length(A),') > ',B,'(',Length(B),')');
 I:=1;
 A_pred_B:=FALSE;
 If A<>'' then
  begin
   While (A[I] = B[I]) AND (I < Length(B)) AND (I < Length(A)) do Inc(I);
   If A[I] < B[I] then A_pred_B:=TRUE;
   If (A[I] = B[I]) AND (Length(B) > Length(A)) then A_pred_B:=TRUE;
  end;
end;

Procedure Pridej(var Hlava : THlava; Klic : TKlic; Hodnota : THodnota);
var Predchozi, WorkPol, Nova : PolozkaPtr;
begin
 WorkPol:=Hlava.Zacatek; Predchozi:=WorkPol;
 While WorkPol <> nil do
  begin        {KLIC je pred WORKPOL.KLIC}
   If A_pred_B(Klic, WorkPol^.Klic) then
    begin
     New(Nova); { Vlozi novou polozku pred aktualni}
     Nova^.Klic:=Klic;
     Nova^.Hodnota:=Hodnota;
     Nova^.Dalsi:=WorkPol;
     Predchozi^.Dalsi:=Nova;
     Klic:=''; { Aby to uz nezarazoval}
    end;
   Predchozi:=WorkPol;
   WorkPol:=WorkPol^.Dalsi;
  end;
end;

Procedure Vyjmi(var Hlava : THlava; Klic : TKlic);
var Predchozi, Dalsi, WorkPol : PolozkaPtr;
begin
 WorkPol:=Hlava.Zacatek;
 While WorkPol <> nil do
  begin
   Predchozi:=WorkPol;
   WorkPol:=WorkPol^.Dalsi;
   If WorkPol^.Klic = Klic then
    begin
     Predchozi^.Dalsi:=WorkPol^.Dalsi;
     Dispose(WorkPol); Workpol:=nil;
    end;
  end;
end;

Procedure ZmenHodnotu(var Hlava : THlava; Klic : TKlic; NovaHodnota : THodnota);
var WorkPol : PolozkaPtr;
begin
 WorkPol:=Hlava.Zacatek^.Dalsi;
 While WorkPol <> Hlava.Konec do
  begin
   If WorkPol^.Klic = Klic then WorkPol^.Hodnota:=NovaHodnota;
   WorkPol:=WorkPol^.Dalsi;
  end;
end;

Function NajdiHodnotu(var Hlava : THlava; Klic : TKlic) : THodnota;
var WorkPol : PolozkaPtr;
begin
 WorkPol:=Hlava.Zacatek^.Dalsi; NajdiHodnotu:='';
 While WorkPol <> Hlava.Konec do
  begin
   If WorkPol^.Klic = Klic then NajdiHodnotu:=WorkPol^.Hodnota;
   WorkPol:=WorkPol^.Dalsi;
  end;
end;

Procedure VypisVsechny(var Hlava : THlava);
var WorkPol : PolozkaPtr;
begin
 WorkPol:=Hlava.Zacatek^.Dalsi;
 While WorkPol <> Hlava.Konec do
  begin
   WriteLn(WorkPol^.Klic,':  ',WorkPol^.Hodnota);
   WorkPol:=WorkPol^.Dalsi;
  end;
end;


var S : TKlic;
    H : THodnota;
    Cmd : String;
    Hlava : THlava;

begin
 Init(Hlava);
 Repeat
  ClrScr;
  GotoXY(5,5); WriteLn('------------------------ Obsah databaze: -----------------------');
  VypisVsechny(Hlava);
  GotoXY(5,1); WriteLn('***************** DATABAZE s abecednim razenim *****************');
  Write('Napiste prikaz ("+" pridat, "-" zrusit, "/" zmenit, "k" konec) :');
  ReadLn(Cmd);
  If Cmd='+' then
   begin
    Write('Napiste novy nazev: '); ReadLn(S);
    Write('Napiste vlastnost: '); ReadLn(H);
    Pridej(Hlava,S,H);
   end;
  If Cmd='-' then
   begin
    Write('Napiste nazev ke zruseni: '); ReadLn(S);
    Vyjmi(Hlava,S);
   end;
  If Cmd='/' then
   begin
    Write('Napiste meneny nazev: '); ReadLn(S);
    GotoXY(1,3);
    WriteLn('Soucasna vlastnost ',S,' je: ',NajdiHodnotu(Hlava,S));
    Write('Zadejte novou vlastnost: '); ReadLn(H);
    ZmenHodnotu(Hlava,S,H);
   end;
 Until (Cmd='k')OR(Cmd='K');
{  WriteLn(A_pred_B('Auto','Auta'));}
 ClrScr;
 Done(Hlava);
end.
