program Video;

{$I "include:Exec/Ports.i"}
{$I "include:Intuition/Intuition.i"}
{$I "include:Utils/CRT.i"}
{$I "include:Utils/StringLib.i"}
{$I "include:Utils/TimerUtils.i"}
{$I "include:Utils/GDateTools.i"}
{$I-}

const
    line="________________________________________________________________________________";
    space="                                                                                ";
    fkey:array[1..10]of string=(	{ Immer 41 Zeichen incl. 0-Byte! }
	"Action\0                                  ",
	"Krimi\0                                   ",
	"Komödie\0                                 ",
	"Fantasy\0                                 ",
	"Horror\0                                  ",
	"Science Fiction\0                         ",
	"Zeichentrick\0                            ",
	"Abenteuerfilm\0                           ",
	"Psycho\0                                  ",
	"Thriller\0                                ");
    StdInName:String=NIL;
    StdOutName:String=NIL;	{ Öffnet dann kein CLI-Fenster }

type
    t_eintrag=record
        titel,komment,nummer:string;
        laenge:short;
        next,prev:^t_eintrag
    end;
    t_video=^t_eintrag;
    t_erlaubt=(ALLES,ZAHLEN,BUCHST);

var w:WindowPtr;
    ConBuf:Address;
    last,cass:t_video;
    anzahl:short;
    saved:boolean;
    timer:TimeRequestPtr;
    suchnum,suchstr:string;

function OpenTheWindow:Boolean;
var nw:NewWindowPtr;
begin
  new(nw);
  with nw^ do begin
    LeftEdge:=0; TopEdge:=0; Width:=640; Height:=256;
    DetailPen:=-1; BlockPen:=-1; IDCMPFlags:=0;
    Flags:=WINDOWSIZING+WINDOWDRAG+WINDOWDEPTH+SMART_REFRESH+ACTIVATE;
    FirstGadget:=nil; CheckMark:=nil;
    Title:=" Video-Datei-Verwaltung  V1.3  ·  © Copyright 92-95 by Henning Peters ";
    Screen:=Nil; BitMap:=nil;
    MinWidth:=640; MaxWidth:=-1; MinHeight:=200; MaxHeight:=-1;
    WType:=WBENCHSCREEN_f;
  end;
  w:=OpenWindow(nw); dispose(nw);
  OpenTheWindow:=w<>nil;
end;

procedure WriteChar(c:char);
var s:string;
begin
  s:=AllocString(2); s[1]:='\0'; s[0]:=c; WriteString(ConBuf,s)
end;

function str_int(str:string):integer;
var i,j:integer;
begin
  i:=0;
  for j:=0 to pred(strlen(str)) do i:=i*10+ord(str[j])-48;
  str_int:=i
end;

function int_str(i:integer):string;    { i=0..9999 }
var str:string;
begin str:=AllocString(5); strcpy(str,"\0\0\0\0\0");
  if i<10 then str[0]:=chr(i+48)
  else if i<100 then begin
    str[0]:=chr(i div 10+48); str[1]:=chr(i mod 10+48)
  end else if i<999 then begin
	     str[0]:=chr(i div 100+48); str[1]:=chr((i mod 100)div 10+48);
	     str[2]:=chr(i mod 10+48)
	   end else begin
	     str[0]:=chr(i div 1000+48); str[1]:=chr((i mod 1000)div 100+48);
	     str[2]:=chr((i mod 100)div 10+48); str[3]:=chr(i mod 10+48)
	   end;
  int_str:=str
end;

function lowercase(str:string):string;
var s:string;
  i,j:integer;
begin
  s:=strdup(str); j:=pred(strlen(s));
  for i:=0 to j do s[i]:=tolower(s[i]);
  lowercase:=s
end;

function strpart(s:string; p,l:short):string;
var str:string;
  i:integer;
  e:byte;
begin
  str:=AllocString(succ(l)); e:=pred(p+l);
  for i:=p to e do str[i-p]:=s[i];
  str[succ(l)]:='\0'; strpart:=str
end;

function ja_nein:boolean;
var c:char;
begin
  repeat c:=tolower(readkey(ConBuf)) until (c='j') or (c='n') or (c='\e');
  if c='\e' then c:='n'; WriteChar(c); ja_nein:=(c='j')
end;

function stringlen(str:string):byte;
var i:byte;
begin
  i:=pred(strlen(str));
  while (str[i]='_') and (i>-1) do dec(i);
  stringlen:=succ(i)
end;

function GetString(vorgabe:string; len:byte; erlaubt:t_erlaubt):string;
var l,x,y,b,pos,slen:byte;
  str,s1,s2:string;
  c:char;
  i:integer;
  ok:boolean;
begin
  x:=succ(wherex(ConBuf)); y:=succ(wherey(ConBuf));
	{ Scheint so, als wenn where_=[0..max-1] und gotoxy=[1..max] }
  str:=AllocString(succ(len)); slen:=strlen(vorgabe); pos:=0;
  strcpy(str,vorgabe); if slen<len then strncat(str,line,len-slen); s1:=strdup(str);
  GotoXY(ConBuf,x,y); WriteString(ConBuf,str); GotoXY(ConBuf,x,y);
  repeat
    c:=readkey(ConBuf); b:=ord(c);
    if (erlaubt=ALLES) or (erlaubt=BUCHST) then ok:=((b>31) and (b<127)) or (b>160)
    else ok:=(b>47) and (b<58); { Nur '0'..'9' }
    if ok then begin
      if (pos=slen) and (slen<len) then begin
	str[pos]:=c; GotoXY(ConBuf,x+pos,y); WriteChar(c)
      end else
	if (slen<len) then begin
	  for i:=pred(slen) downto pos do str[succ(i)]:=str[i];
	  str[pos]:=c;
	  GotoXY(ConBuf,x,y); WriteString(ConBuf,str); GotoXY(ConBuf,x+pos,y)
	end else if pos<len then str[pos]:=c;
      if (slen<len) then begin inc(slen); inc(pos) end
    end else begin
      case b of
       155:begin
	  c:=readkey(ConBuf);
	  case ord(c) of
	    65:pos:=0;
	    66:pos:=slen;
	    67:if pos<slen then inc(pos);
	    68:if pos>0 then dec(pos);
	    63:if erlaubt=ALLES then begin    { Help }
	      WriteString(ConBuf,"\n\n");
	      for i:=1 to 10 do begin
		WriteChar('\t'); WriteString(ConBuf,fkey[i]);
		WriteChar('\n') end;
	      y:=wherey(ConBuf)-11;
	      GotoXY(ConBuf,0,succ(y));
WriteString(ConBuf,"\n\e[4m\e[41m\e[30m F1 \n F2 \n F3 \n F4 \n F5 \n F6 \n F7 \n F8 \n F9 \n F10 \e[0m");
	      GotoXY(ConBuf,x,y)
	    end;
	    48..57:if (erlaubt=ALLES) and
		(strlen(fkey[ord(c)-47])+pos<=len) then begin { F-Tasten }
	      b:=ord(c)-47; s2:=fkey[b]; l:=strlen(s2); 
	      if slen>0 then for i:=slen downto pos do str[i+l]:=str[i];
	      for i:=0 to pred(l) do str[pos+i]:=s2[i];
	      inc(slen,l); inc(pos,l); ok:=true
	    end
	  end;
	  while keypressed(ConBuf) do c:=readkey(ConBuf);
	end;    { Fuer '~' am Ende, Shift-F-Tasten etc. }
       27:begin s2:=str; str:=s1; s1:=s2; ok:=true; slen:=stringlen(str); pos:=slen end;
       160:begin s2:=str; str:=s1; s1:=s2; ok:=true;
	     strncpy(str,line,len); slen:=0; pos:=0 end;
       8:if pos>0 then begin
	  dec(slen); for i:=pos to slen do str[pred(i)]:=str[i];
	  str[slen]:='_'; dec(pos); ok:=true
	end;
       127:if pos<slen then begin
	  if pos<pred(slen) then
	    for i:=pos to pred(slen) do str[i]:=str[succ(i)];
	  dec(slen); str[slen]:='_'; ok:=true;
	  if (pos=slen) and (pos>0) then dec(pos)
	end
      end;
      if ok then begin GotoXY(ConBuf,x,y); WriteString(ConBuf,str) end
    end;
    GotoXY(ConBuf,x+pos,y)
  until b=13;
  if slen=0 then begin if erlaubt=ZAHLEN then str[0]:='0' else str[0]:=' '; slen:=1 end;
  strncpy(str,str,slen); strcpy(s1,str); if slen<len then strncat(s1,space,len-slen);
  GotoXY(ConBuf,x,y); WriteString(ConBuf,s1); GetString:=str
end;

procedure funktionstasten;
var i:integer;
  s:string;
  c1,c2:char;
begin
  WriteString(ConBuf,"\f	\e[42m Funktionstastenbelegung ändern \e[0m\n\n");
WriteString(ConBuf,"\e[4m\e[41m\e[30m F1 \n F2 \n F3 \n F4 \n F5 \n F6 \n F7 \n F8 \n F9 \n F10 \e[0m");
  for i:=1 to 10 do begin GotoXY(ConBuf,8,2+i); WriteString(ConBuf,fkey[i]) end;
  WriteString(ConBuf,"\n\n\e[41m\e[30m Esc \e[0m    Abbruch\n\n    Welche Taste ändern? ");
  repeat
    repeat
      repeat c1:=readkey(ConBuf) until (c1='\c') or (c1='\e');
      if c1='\e' then return;
      c2:=readkey(ConBuf);
    until (c2>'/') and (c2<':');
    c1:=readkey(ConBuf); if c1<'~' then begin c2:=c1; c1:=readkey(ConBuf) end;
    i:=ord(c2)-47; GotoXY(ConBuf,8,2+i); CursOn(ConBuf);
    s:=GetString(fkey[i],40,ALLES); CursOff(ConBuf);
    strcpy(fkey[i],s)
  until false
end;

procedure einsort(neu:t_video);
var c:t_video;
begin
  if cass=nil then begin
    neu^.next:=neu; neu^.prev:=neu; cass:=neu; last:=neu
  end else begin
    c:=cass;
    while (stricmp(neu^.titel,c^.titel)>0) and (c<>last) do c:=c^.next;
    if (c=last) and (stricmp(neu^.titel,c^.titel)>0) then c:=cass;
    neu^.next:=c; neu^.prev:=c^.prev; c^.prev^.next:=neu; c^.prev:=neu;
    if (c=cass) then
      if (stricmp(neu^.titel,cass^.titel)<0) then cass:=neu
      else last:=neu
  end; inc(anzahl);
end;

procedure ausklinken(var v:t_video);
var d:t_video;
begin
  v^.prev^.next:=v^.next; v^.next^.prev:=v^.prev; d:=v; v:=v^.next;
  dispose(d); saved:=false; dec(anzahl);
end;

procedure eingabe(a,b,c,d:string; var t,k,l,n:string);
begin
  WriteChar('\n'); InsLine(ConBuf); InsLine(ConBuf);
  WriteString(ConBuf,"\nTitel    : "); t:=strdup(GetString(a,60,ALLES));
  WriteChar('\n'); InsLine(ConBuf);
  WriteString(ConBuf,"Kommentar: "); k:=strdup(GetString(b,60,ALLES));
  WriteChar('\n'); InsLine(ConBuf);
  WriteString(ConBuf,"Länge    :   min");
  GotoXY(ConBuf,wherex(ConBuf)-6,succ(wherey(ConBuf)));
  l:=strdup(GetString(c,3,ZAHLEN)); WriteChar('\n'); InsLine(ConBuf);
  WriteString(ConBuf,"Nummer   : "); n:=strdup(GetString(d,3,BUCHST));
  saved:=false
end;

procedure eingeben;
var neu:t_video;
  c:char;
  t,k,l,n:string;
begin
  WriteString(ConBuf,"\f	\e[42m Neue Titel eingeben \e[0m");
  repeat
    new(neu); eingabe("","","","",t,k,l,n);
    neu^.titel:=t; neu^.komment:=k;
    neu^.laenge:=str_int(l); neu^.nummer:=n;
    einsort(neu); WriteChar('\n'); InsLine(ConBuf); InsLine(ConBuf);
    WriteString(ConBuf,"\n    Noch ein Titel (j/n)? ");
  until not ja_nein
end;

procedure ausgabe(v:t_video);
begin
  WriteString(ConBuf,"\n\n\e[2mTitel    : \e[0m");
  WriteString(ConBuf,v^.titel);
  WriteString(ConBuf,"\n\e[2mKommentar: \e[0m");
  WriteString(ConBuf,v^.komment);
  WriteString(ConBuf,"\n\e[2mLänge    : \e[0m");
  WriteString(ConBuf,int_str(v^.laenge));
  WriteString(ConBuf," min      \e[2mNummer: \e[0m");
  WriteString(ConBuf,v^.nummer)
end;

procedure ansehen;
var v:t_video;
  c:byte;
begin
  WriteString(ConBuf,"\e[0 p\f	\e[42m Alle Titel ansehen \e[0m");
  v:=cass;
  repeat
    ausgabe(v);
    WriteString(ConBuf,
"\n\n    \e[42m    \e[0m=Weiter, \e[42m Esc \e[0m=Abbruch, \e[42m ^ \e[0m=Zurück");
    repeat
      c:=ord(readkey(ConBuf));
      if c=155 then c:=ord(readkey(ConBuf))
    until (c=65) or (c=32) or (c=27);
    case c of
      65:v:=v^.prev;
      32:v:=v^.next
    end
  until c=27
end;

function such_text(wie:char; v:t_video):t_video;
var l:byte;
  q,p:integer;
  s:string;
begin
  l:=strlen(suchstr); s:=lowercase(suchstr); FreeString(suchstr); suchstr:=s;
  repeat
    if wie='k' then s:=lowercase(v^.komment) else s:=lowercase(v^.titel);
    p:=strlen(s)-l;
    if p>0 then for q:=0 to p do
      if s[q]=suchstr[0] then
	if strieq(strpart(s,q,l),suchstr) then such_text:=v;
    v:=v^.next;
  until v=cass;
  such_text:=nil
end;

function such_nummer(v:t_video):t_video;
begin
  repeat
    if strcmp(suchnum,v^.nummer)=0 then such_nummer:=v;
    v:=v^.next
  until v=cass;
  such_nummer:=nil
end;
  
function such_video(var c:char):t_video;
begin
  WriteString(ConBuf,
"\n\nSuchen nach \e[42m T \e[0mitel, \e[42m K \e[0mommentar oder \e[42m N \e[0mummer? ");
  repeat c:=tolower(readkey(ConBuf)) until (c='t') or (c='k') or (c='n');
  WriteChar(toupper(c));
  if (c='k') or (c='t') then begin
    WriteString(ConBuf,"\nSuchstring: "); suchstr:=strdup(GetString("",60,ALLES));
    such_video:=such_text(c,cass)
  end else begin
    WriteString(ConBuf,"\nSuchnummer: "); suchnum:=strdup(GetString("",3,BUCHST));
    such_video:=such_nummer(cass)
  end
end;

procedure aendern;
var v,d:t_video;
  c:char;
  str,l,n:string;
  num:byte;
  jn:boolean;
begin
  WriteString(ConBuf,"\f	\e[42m Titel ändern \e[0m");
  repeat
    v:=such_video(c); jn:=true;
    if v<>nil then repeat
      ausgabe(v);
      WriteString(ConBuf,"\n\n    Diesen Titel \e[33mändern\e[0m (j/n)? ");
      if ja_nein then begin
	l:=int_str(v^.laenge); n:=v^.nummer;
	eingabe(v^.titel,v^.komment,l,n,v^.titel,v^.komment,l,n);
	new(d); d^.titel:=v^.titel; d^.komment:=v^.komment;
	d^.laenge:=str_int(l); d^.nummer:=n;
	ausklinken(v); einsort(d)    { Neu einsortieren }
      end;
      WriteString(ConBuf,"\n\n    Nächsten Titel suchen (j/n)? ");
      jn:=ja_nein;
      if jn then if (c='t') or (c='k') then v:=such_text(c,v^.next)
	    else v:=such_nummer(v^.next)
    until (not jn) or (v=nil);
    if v=nil then WriteString(ConBuf,"\n\n    Keinen passenden Titel gefunden!");
    WriteString(ConBuf,"\n\n    Noch einen Titel suchen (j/n)? ");
    jn:=ja_nein
  until not jn
end;

procedure suchen;
var v:t_video;
  c:char;
  str,l,n:string;
  num:byte;
  jn:boolean;
begin
  WriteString(ConBuf,"\f	\e[42m Titel suchen \e[0m");
  repeat
    v:=such_video(c); jn:=true;
    if v<>nil then repeat
      ausgabe(v);
      WriteString(ConBuf,"\n\n    Nächsten Titel suchen (j/n)? ");
      jn:=ja_nein;
      if jn then if (c='t') or (c='k') then v:=such_text(c,v^.next)
	    else v:=such_nummer(v^.next)
     until (not jn) or (v=nil);
    if v=nil then WriteString(ConBuf,"\n\n    Keinen passenden Titel gefunden!");
    WriteString(ConBuf,"\n\n    Noch einen Titel suchen (j/n)? ");
    jn:=ja_nein
  until not jn
end;

procedure loeschen;
var v:t_video;
  c:char;
  str:string;
  num:byte;
  jn:boolean;
begin
  WriteString(ConBuf,"\f	\e[42m Titel löschen \e[0m");
  repeat
    v:=such_video(c);
    if v<>nil then repeat
      ausgabe(v);
      WriteString(ConBuf,"\n\n    Diesen Titel \e[33mlöschen\e[0m (j/n)? ");
      if ja_nein then begin
        ausklinken(v); WriteString(ConBuf,"\n\n	Titel gelöscht.\n")
      end;
      WriteString(ConBuf,"\n    Nächsten Titel suchen (j/n)? ");
      jn:=ja_nein;
      if jn then if (c='t') or (c='k') then v:=such_text(c,v^.next)
	    else v:=such_nummer(v^.next)
    until (not jn) or (v=nil);
    if v=nil then WriteString(ConBuf,"\n\n    Keinen passenden Titel gefunden!");
    WriteString(ConBuf,"\n\n    Noch einen Titel suchen (j/n)? ");
    jn:=ja_nein
  until not jn
end;

procedure IO_error(txt:string; err:byte);
var s:string;
begin
  case err of
     50:s:="Kein Speicher für IO-Puffer";
    103:s:="Nicht genug Speicherplatz";
    202:s:="Datei in Gebrauch";
    203:s:="Datei existiert bereits";
    204:s:="Verzeichnis nicht gefunden";
    205:s:="Datei nicht gefunden";
    213:s:="Disk ist nicht validiert";
    214:s:="Disk ist schreibgeschützt";
    218:s:="Gerät nicht ansprechbar";
    221:s:="Disk ist voll";
    223:s:="Datei ist schreibgeschützt";
    224:s:="Datei ist lesegeschützt";
    225:s:="Keine DOS-Disk";
    226:s:="Keine Disk im Laufwerk";
    else begin
      s:=AllocString(20); strcpy(s,"Fehler Nummer "); strcat(s,int_str(err))
    end
  end;
  WriteString(ConBuf,"\n\n\a    \e[33mFehler\e[0m beim ");
  WriteString(ConBuf,txt); WriteString(ConBuf,": "); WriteString(ConBuf,s);
  WriteString(ConBuf,".\n\n	Weiter mit einer Taste ");
  while not keypressed(ConBuf) do
end;

procedure speichern;
var v:t_video;
  f:text;
  s:string;
  err:byte;
  over:boolean;
  i:integer;
begin
  WriteString(ConBuf,
    "\f	\e[42m Titel speichern \e[0m\n\nFilename (voller Pfad):\n");
  s:=strdup(GetString("s:Video-Datei",75,ALLES));
  reset(f,s); err:=ioresult; close(f);
  if err=0 then begin
    WriteString(ConBuf,"\n\n\a    Datei existiert bereits! \e[33mÜberschreiben\e[0m (j/n)? ");
    over:=ja_nein; if not over then return
  end;
  WriteString(ConBuf,"\n\nSchreibe Daten");
  rewrite(f,s); err:=ioresult;
  if not ((err=203) and over) then if err>0 then begin
    if over then io_error("Überschreiben der alten Datei",err)
    else io_error("Öffnen der Datei: ",err); close(f); return
  end;
  v:=cass; i:=1; err:=0;
  while (err=0) and (i<11) do begin writeln(f,fkey[i]); err:=ioresult; inc(i) end;
  if err>0 then begin io_error("Schreiben",err); close(f); return end;
  repeat
    writeln(f,v^.titel,"\n",v^.komment,"\n",v^.laenge,":",v^.nummer);
    err:=ioresult; WriteChar('.');
    if err>0 then begin io_error("Schreiben",err); close(f); return end;
    v:=v^.next
  until v=cass;
  close(f); err:=ioresult;
  if err>0 then io_error("Schließen der Datei",err)
  else begin
    WriteString(ConBuf,"Ok."); saved:=true;
    WriteString(ConBuf,"\n\n	Weiter mit einer Taste ");
    while not keypressed(ConBuf) do
  end
end;

procedure laden;
var v:t_video;
  f:text;
  t,k,n:string;
  err:byte;
  l:short;
  i:integer;
  c:char;
begin
  WriteString(ConBuf,"\f	\e[42m Titel laden \e[0m");
  if not saved then begin
    WriteString(ConBuf,"\n\nDaten sind nicht gepeichert! \e[33mÜberschreiben?\e[0m (j/n)? ");
    if not ja_nein then return
  end;
  WriteString(ConBuf,"\n\nFilename (voller Pfad):\n");
  t:=strdup(GetString("s:Video-Datei",75,ALLES));
  reset(f,t); err:=ioresult;
  if err>0 then begin io_error("Öffnen der Datei",err); close(f); return end;
  if anzahl>0 then		{ Alte Daten löschen }
    if anzahl=1 then dispose(cass)
    else begin
      v:=cass;
      repeat ausklinken(v^.prev) until v=v^.next;
      dispose(v)
    end;
  WriteString(ConBuf,"\n\nLese Daten"); anzahl:=0; cass:=nil; i:=1; err:=0;
  FreeString(t); t:=AllocString(61); k:=AllocString(61); n:=AllocString(4);
  while (err=0) and (i<11) do begin
    readln(f,t); err:=ioresult; if err=0 then strcpy(fkey[i],t); inc(i)
  end;
  if err>0 then begin io_error("Lesen",err); close(f); return end;
  repeat
    readln(f,t); err:=ioresult;
    if err=0 then begin readln(f,k); err:=ioresult end;
    if err=0 then begin readln(f,l,c,n); err:=ioresult end;
    if err>0 then begin io_error("Lesen",err); close(f); return end;
    new(v); v^.titel:=strdup(t); v^.komment:=strdup(k); v^.laenge:=l;
    v^.nummer:=strdup(n); WriteChar('.'); einsort(v)
  until eof(f);
  close(f); WriteString(ConBuf,"Ok.\n\n	Weiter mit einer Taste ");
  while not keypressed(ConBuf) do; saved:=true
end;

procedure drucken;
var drucker:text;
    v:t_video;
    c:byte;
begin
  WriteString(ConBuf,"\e[0 p\f	\e[42m Alle Titel drucken \e[0m\n\nAbbruch mit \e[42m Esc \e[0m.\n");
  reset(drucker,"prt:"); c:=ioresult;
  if c>0 then begin
    io_error("Ansprechen des Druckers",c); close(drucker); return
  end;
  v:=cass; c:=0; WriteString(ConBuf,"\nDrucke Titel");
  repeat
    WriteLn(drucker,"\n\e[1mTitel    : \e[0m",v^.titel,"\n\e[1mKommentar: \e[0m",
	v^.komment,"\n\e[1mLänge    : \e[0m",int_str(v^.laenge):4,
	" min      \e[1mNummer: \e[0m",v^.nummer);
    v:=v^.next; WriteChar('.');
    if keypressed(ConBuf) then c:=ord(readkey(ConBuf));
  until (v=cass) or (c=27);
  close(drucker)
end;

function my_menu:char;
var c1,c2:char;
  h,m,s:byte;
  sec,t:integer;
  time:DateDescription;
  tv:timeval;
  str:string;
begin
  str:=AllocString(42);
  WriteString(ConBuf,"\e[0 p\f\n	\e[42m H a u p t m e n ü \e[0m\n\n");
  WriteString(ConBuf,"    \e[4;30;41m F1  \e[0m Titel eingeben\n");
  WriteString(ConBuf,"    \e[4;30;41m F2  \e[0m Titel ansehen\n");
  WriteString(ConBuf,"    \e[4;30;41m F3  \e[0m Titel ändern\n");
  WriteString(ConBuf,"    \e[4;30;41m F4  \e[0m Titel suchen\n");
  WriteString(ConBuf,"    \e[4;30;41m F5  \e[0m Titel löschen\n");
  WriteString(ConBuf,"    \e[4;30;41m F6  \e[0m Titel speichern\n");
  WriteString(ConBuf,"    \e[4;30;41m F7  \e[0m Titel laden\n");
  WriteString(ConBuf,"    \e[4;30;41m F8  \e[0m Titel drucken\n");
  WriteString(ConBuf,"    \e[4;30;41m F9  \e[0m Funktionstastenbelegung ändern\n");
  WriteString(ConBuf,"    \e[4;30;41m F10 \e[0m Programm beenden\n\n");
  WriteString(ConBuf,int_str(anzahl));
  WriteString(ConBuf," Titel im Speicher");
  if not saved then WriteString(ConBuf,", Daten wurden verändert");
  WriteString(ConBuf,".");
  repeat sec:=0;
   repeat
    GetSysTime(timer,tv);
    if sec<>tv.tv_secs then begin
      sec:=tv.tv_secs; t:=sec mod 86400;
      h:=t div 3600; m:=(t mod 3600)div 60; s:=t mod 60;
      GetDescription(tv.tv_secs,time);    { TimeDesc() gibt Müll bei h/m/s }
      strcpy(str," "); strcat(str,DayNames[time.dow]); strcat(str,", ");
      strcat(str,int_str(time.day)); strcat(str,".");
      strcat(str,int_str(time.month)); strcat(str,".");
      strcat(str,int_str(time.year)); strcat(str,", ");
      strcat(str,int_str(h)); strcat(str,":");
      if m<10 then strcat(str,"0"); strcat(str,int_str(m)); strcat(str,":");
      if s<10 then strcat(str,"0"); strcat(str,int_str(s));
      GotoXY(ConBuf,MaxX(ConBuf)-strlen(str),1); WriteString(ConBuf,str)
    end;
    if keypressed(ConBuf) then c1:=readkey(ConBuf)
   until c1='\c';
   c2:=readkey(ConBuf)
  until (c2>'/') and (c2<':');    { F-Tasten='<CSI>[0..9]~' }
  c1:=readkey(ConBuf); if c1<'~' then begin c2:=c1; c1:=readkey(ConBuf) end;
  CursOn(ConBuf);	    { Shift-Fxx='<CSI>1[0..9]~' }
  case c2 of
    '0':eingeben;
    '1':if anzahl>0 then ansehen;
    '2':if anzahl>0 then aendern;
    '3':if anzahl>0 then suchen;
    '4':if anzahl>0 then loeschen;
    '5':if anzahl>0 then speichern;
    '6':laden;
    '7':if anzahl>0 then drucken;
    '8':funktionstasten;
    '9':begin
       GotoXY(ConBuf,15,17);
       if not saved then WriteString(ConBuf,"\e[33mDatei wurde verändert! \e[0m");
       WriteString(ConBuf,"\e[43m Programm beenden (j/n)?\e[0m");
       if ja_nein then c2:='\0';
      end
  end;
  my_menu:=c2
end;

begin    { Main }
  if OpenTheWindow then begin
    ConBuf:=AttachConsole(w);
    if ConBuf<>Nil then begin
      timer:=CreateTimer;
      if timer<>nil then begin
	cass:=nil; anzahl:=0; saved:=true;
	while my_menu>'\0' do;
	DetachConsole(ConBuf); DeleteTimer(timer)
      end else writeln("\aKann \e[33mtimer.device\e[0m nicht öffnen!")
    end else writeln("\aKann \e[33mconsole.device\e[0m nicht öffnen!");
    CloseWindow(w)
  end else writeln("\aKann \e[33mFenster\e[0m nicht öffnen!")
end.
