PROGRAM VideoText;
FROM vt USES startup,info; {$opt q,s+,i+ }
{ Hauptprogramm/Ereignisverwaltung zum Projekt VideoText }

CONST version = '$VER: VideoText 5.05  (27.04.96)';

{          global       sys }
{         /  |   \      /   }
{ pagelist decode cct  /    }
{       \    |    /   /     }
{        bildschirm _/      }
{            |              }
{          datei            }
{            |              }
{           jobs            }
{          /   \            }
{      info    startup      }
{                           }
{  HAUPTPROGRAMM VIDEOTEXT  }

CONST stacksize=10;

VAR l: Long;
    stop,searching: Boolean;
    roundrobin: Byte;
    inputname: Str80;
    j,toprequest,adip_count: Integer;
    pgstack: ARRAY[1..stacksize] OF RECORD pg,sp: Integer; END;
    stackptr,stackbot: Integer;

PROCEDURE push(seite: p_onepage);
{ "vergeßlicher" Stack: Überlauf führt nicht zum Abweisen der neuen }
{ Seitennummer, sondern zum Vergessen der ältesten. }
BEGIN
  IF seite<>Nil THEN BEGIN
    pgstack[stackptr].pg := seite^.pg;
    pgstack[stackptr].sp := seite^.sp;
    Inc(stackptr); IF stackptr>stacksize THEN stackptr := 1;
    IF stackptr=stackbot THEN BEGIN
      Inc(stackbot); IF stackbot>stacksize THEN stackbot := 1;
    END;
  END;
END;

FUNCTION pop: p_onepage;
VAR seite: p_onepage;
BEGIN
  seite := Nil;
  WHILE (stackptr<>stackbot) AND (seite=Nil) DO BEGIN
    Dec(stackptr); IF stackptr=0 THEN stackptr := stacksize;
    seite := hunt_in_list(pgstack[stackptr].pg,pgstack[stackptr].sp,True);
  END;
  IF seite=Nil THEN Write('Weiter zur}ck geht''s nicht.');
  pop := seite;
END;

PROCEDURE topcleaner;
{ entfernt unnötige TOP-Seiten aus der Seitenliste, je nachdem welche noch }
{ gebraucht werden. }
VAR seite,hilf: p_onepage;
    i: Integer;
    refresh,kill: Boolean;
BEGIN
  refresh := False;
  FOR i := $1F0 TO $1F4 DO BEGIN
    seite := hunt_in_list(i,0,False);
    IF (seite<>Nil) THEN IF seite^.pg<>i THEN seite := Nil;
    CASE i OF
      $1F0: kill := toprequest=0;
      $1F1: kill := (toprequest AND 2)=0;
      OTHERWISE kill := (toprequest AND 4)=0;
    END;
    IF kill AND (seite<>Nil) THEN BEGIN
      IF seite=visblpage THEN refresh := True;
      hilf := seite^.next; del_from_list(seite); update_list(hilf,-1);
    END;
  END;
  IF refresh THEN writepage(thispage,True);
END;

PROCEDURE topscan;
{ Schaut, was für TOP-Seiten schon eingetroffen sind, und führt ggf. die }
{ angeforderten Aktionen aus. }
VAR pg: ARRAY[0..4] OF p_onepage;
    i,n: Integer;
    schluss: Boolean;
BEGIN
  FOR i := 0 TO 4 DO BEGIN
    pg[i] := hunt_in_list($1F0+i,0,False);
    IF (pg[i]<>Nil) THEN IF pg[i]^.pg<>$1F0+i THEN pg[i] := Nil;
  END;
  { Anzahl ADIP-Seiten (ADditional Info Page) aus 1F0 ermitteln: }
  IF (pg[0]<>Nil) AND (toprequest AND 4<>0) AND (adip_count=0) THEN BEGIN
    i := 840; schluss := False;
    REPEAT
      CASE topcode[pg[0]^.chars[i]] OF { Magazinnummer }
        14: { Don't Care } ;
        15: schluss := True;
        16: { ungültige Ziffer } ;
        OTHERWISE IF topcode[pg[0]^.chars[i+7]]=2 THEN Inc(adip_count);
      END;
      i := i + 8;
    UNTIL (i=960) OR schluss;
    IF adip_count>3 THEN adip_count := 3; { Nee, so geht's ja auch nicht! }
    IF adip_count<3 THEN BEGIN  { zuviele Seiten angefordert }
      cancel_job('1f4');
      IF adip_count<2 THEN cancel_job('1f3');
      redraw_queue(-1);
    END;
  END;
  { Blockseiten (d. h. Themenbereichs-Leitseiten) anfordern: }
  IF (pg[0]<>Nil) AND (toprequest AND 1<>0) THEN BEGIN
    busy_pointer; topgrab(pg[0]); normal_pointer;
    mainline; Write('Blockseiten angefordert');
    toprequest := toprequest AND NOT 1; topcleaner;
  END;
  { TOP-Statistik: }
  IF (pg[0]<>Nil) AND (pg[1]<>Nil) AND (toprequest AND 2<>0) THEN BEGIN
    busy_pointer; mainline; Write('erstelle TOP-Statistik ...');
    topinfo(pg[0],pg[1]); mainline; normal_pointer;
    mark_list(False); thispage := hunt_in_list($999,1,False);
    mark_list(True); writepage(thispage,True);
    toprequest := toprequest AND NOT 2; topcleaner;
  END;
  { TOP-Text-Menue: }
  n := 0; FOR i := 1 TO adip_count DO IF pg[i+1]<>Nil THEN Inc(n);
  IF (pg[0]<>Nil) AND (n=adip_count) AND (toprequest AND 4<>0) THEN BEGIN
    busy_pointer; mainline; Write('erstelle TOP-Men}s ...');
    create_topmenu(pg[0],pg[2],pg[3],pg[4]); mainline; normal_pointer;
    thispage := hunt_in_list($900,0,False);
    redraw_list; writepage(thispage,True);
    toprequest := toprequest AND NOT 4; topcleaner;
  END;
END;

PROCEDURE handle_menu(code: Long);
{ *die* zentrale Ereignisverarbeitung, viele Mausklick- und Tastatur- }
{ Ereignisse lassen sich hierauf abbilden! }
VAR item,subitem: Word;
    i,j: Integer;
    l: Long;
    s: str80;
    pg1,pg2: p_onepage;
    save_fifo,ok: Boolean;
BEGIN
  menupicked := False;
  mainline;
  item := code SHR 8;
  subitem := code AND $FF;
  CASE item OF
    { *** Projekt *** }
    $0101: say_hello(version);
    $0102: helpme;
    $0103: IF write_to_icon THEN Write('aktuelle Parameter gesichert')
      ELSE Write(#155'2mFehler beim Schreiben der Parameter');
    $0104: stop := True;
    { *** Datei *** }
    $0201: BEGIN { VT-Format laden }
        sleep; IF fileselect('VT-Seiten laden',False,inputname) THEN
          IF filetype(inputname)=1 THEN BEGIN
            busy_pointer; Write(getpages(inputname,True)); normal_pointer;
            Write(' Seiten gelesen'); redraw_list; writepage(thispage,True);
          END ELSE
            Write('keine VT-Seitendatei, sorry');
        wakeup;
      END;
    $0202: BEGIN { Ausgabeformat }
        asciifile := subitem=$01;
        fileinfo;
      END;
    $0203: BEGIN { überschreiben }
        overwrite := has_check($020300);
        fileinfo;
      END;
    $0204: IF subitem=$01 THEN BEGIN { Dateinamen ändern }
        sleep;
        IF fileselect('Ausgabedatei festlegen',True,outputname) THEN;
        fileinfo;
        wakeup;
      END ELSE BEGIN { Dateinamen aus Titelzeile }
        namefrompage(outputname,visblpage); fileinfo;
      END;
    $0205: BEGIN { Icons erzeugen }
        withicon := has_check($020500);
        fileinfo;
      END;
    $0206: BEGIN { numerierte Dateien }
        numbering := has_check($020600);
        fileinfo;
      END;
    { *** Seiten *** }
    $0301: BEGIN  { Rücksprung }
        pg1 := pop; IF pg1<>Nil THEN BEGIN
          mark_list(False); thispage := pg1;
          mark_list(True); writepage(thispage,True);
        END;
      END;
    $0302: BEGIN { Textausdruck }
        IF incomplete THEN pg1 := thispage
          ELSE pg1 := visblpage;
        IF pg1<>Nil THEN BEGIN
          sleep; busy_pointer;
          Write('Seite wird gedruckt ... ');
          IF printpage(pg1) THEN Write('OK.')
          ELSE Write(#155'2mFehler!');
          normal_pointer; wakeup;
        END;
      END;
    $0303: BEGIN   { IFF-Bild }
        sleep;
        IF fileselect('IFF-Bild speichern',True,iffpicname) THEN BEGIN
          IF filetype(iffpicname)<>-1 THEN BEGIN
            j := Length(iffpicname);
            IF j>30 THEN
              s := '...'+Copy(iffpicname,j-26,27)
            ELSE
              s := iffpicname;
            s := s+' überschreiben?'
            ok := ja_nein(s);
          END ELSE
            ok := True;
          IF ok THEN BEGIN
            l := colperm;  colperm := $01234567;
            s := colperms; colperms := '01234567';
            REPEAT writepage(visblpage,concealed); newevent := False;
            UNTIL NOT incomplete;
            mainline; Write('IFF-Bild ... '); busy_pointer;
            IF iffdump THEN Write('gespeichert')
              ELSE Write(#155'2mDateifehler!');
            normal_pointer;
            colperm := l; colperms := s; writepage(visblpage,concealed);
          END;
        END;
        wakeup;
      END;
    $0304: BEGIN  { Seite speichern }
        sleep; { save_action enthält meist Rückfragen }
        IF incomplete THEN j := save_action(thispage,subitem)
          ELSE j := save_action(visblpage,subitem);
        wakeup;
      END;
    $0305: BEGIN { Seite löschen }
        CASE subitem OF
          $01: IF thispage<>Nil THEN BEGIN
              del_from_list(thispage); update_list(thispage,-1);
            END;
          $02: IF thispage<>Nil THEN BEGIN
              i := 0; j := thispage^.pg; pg1 := root;
              WHILE pg1<>Nil DO BEGIN
                pg2 := pg1; pg1 := pg1^.Next;
                IF pg2^.pg=j THEN BEGIN
                  del_from_list(pg2); Inc(i);
                END;
              END;
              update_list(thispage,-i);
            END;
          $03: BEGIN kill_list; redraw_list; stackptr := stackbot; END;
          OTHERWISE;
        END;
        writepage(thispage,True);
      END;
    { *** Anfordern *** }
    $0401: BEGIN { Seite 100 }
        add_job('100',True); redraw_queue(-1);
      END;
    $0402: IF thispage<>Nil THEN BEGIN { diese Seite nochmal }
        s := hexstr(thispage^.pg,3); add_job(s,False); redraw_queue(-1);
      END;
    $0403: BEGIN { 1. Vorauswahl }
        busy_pointer; getconfig(1); normal_pointer;
      END;
    $0404: BEGIN { 2. Vorauswahl }
        busy_pointer; getconfig(2); normal_pointer;
      END;
    $0405: BEGIN  { Stichprobe }
        IF thispage<>Nil THEN say_hello(version);
        mainline; Write('Stichprobe l{uft ...');
        busy_pointer; page_grabber(True); normal_pointer;
        thispage := root; redraw_list; writepage(thispage,True);
      END;
    $0406: BEGIN { Vorauswahl editieren }
        Write('Editor-Aufruf ... '); busy_pointer;
        IF edconfig(subitem) THEN Write('abgeschlossen')
          ELSE Write(#155'2mDOS-Fehler');
        normal_pointer;
      END;
    $0407: IF root<>Nil THEN BEGIN { Seitennummern kopieren }
        busy_pointer; dump_numbers; normal_pointer;
        Write('Seitennummern als Clip gespeichert');
      END;
    $0408: IF subitem=$01 THEN BEGIN { TOP-Verzeichnis erstellen }
        Write('TOP-Text-Seiten angefordert');
        toprequest := toprequest OR 4; adip_count := 0;
        hurricane;
        save_fifo := fifo; fifo := False;
        add_job('1f4',False); add_job('1f3',False); add_job('1f2',False);
        add_job('1f0/*',False);
        fifo := save_fifo;
        redraw_queue(-1);
      END ELSE BEGIN  { ... und löschen }
        pg1 := visblpage; kill_topmenu; redraw_list;
        IF thispage<>pg1 THEN writepage(thispage,True);
      END;
    $0409: BEGIN { TOP-Statistik }
        Write('TOP-Seiten angefordert');
        toprequest := toprequest OR 2;
        save_fifo := fifo; fifo := False;
        add_job('1f1',False); add_job('1f0/*',False);
        fifo := save_fifo;
        redraw_queue(-1);
      END;
    $040A: BEGIN { Blockseiten holen }
        Write('TOP-Leitseite angefordert');
        toprequest := toprequest OR 1;
        save_fifo := fifo; fifo := False;
        add_job('1f0/*',False);
        fifo := save_fifo;
        redraw_queue(-1);
      END;
    $040B: BEGIN  { Jobs löschen }
        kill_queue; redraw_queue(-1);
        toprequest := 0; topcleaner;
      END;
    $040C: BEGIN  { einen Job löschen }
        j := thisjob; kill_job(thisjob);
        IF j>=0 THEN  redraw_queue(j)  ELSE  redraw_queue(-1);
      END;
    $040D: BEGIN { FIFO }
        fifo := has_check($040D00); redraw_queue(-1);
      END;
    { *** Extras *** }
    $0501: writepage(visblpage,False); { Rätseltaste }
    $0502: writepage(thispage,True); { Seite neu aufbauen }
    $0503: BEGIN { Sendernamen zeigen }
        IF activejobs[0].pg=0 THEN BEGIN
          anfordern(0,100,0,%000);
          j := 50; REPEAT Delay(1); Dec(j) UNTIL seite_da(0) or (j=0);
        END;
        gethead(0,s);
        IF activejobs[0].pg=0 THEN sperren(0);
        Write('Sender: '#155'2m',s);
      END;
    $0504: BEGIN  { Test/Uhr }
        testing := has_check($050400); i2c_status := 0;
        test(testing);
        IF i2c_status<>0 THEN guru(i2c_status);
      END;
    $0505: IF testing THEN BEGIN  { VT-Zeit übernehmen }
        sleep; { Uhrzeit umstellen kann 'Zeit kosten' }
        gettime(aktspeicher,s); force_time(s);
        wakeup; Write('Systemzeit von VT }bernommen');
      END;
    $0506: TV_display(3-subitem); { Fernsehdarstellung }
    $0507: BEGIN { Decoder-Reset }
        hurricane; init_CCT; Write('Decoder-Reset ausgef}hrt'); redraw_queue(-1);
      END;
    OTHERWISE;
  END;
END;

PROCEDURE write_checks;
{ Menuehäkchen an den Zustand der Programmvariablen anpassen }
BEGIN
  check($020201,asciifile);
  check($020202,NOT asciifile);
  check($020300,overwrite);
  check($020500,withicon);
  check($020600,numbering);
  check($040D00,fifo);
  check($050400,testing);
END;

PROCEDURE handle_raw(code: Long);
{ für Sondertasten }
VAR i: integer;
    key: Byte;
    pg1,pg2: p_onepage;
VAR shift,ctrl,alt,comm: Boolean;
BEGIN
  key := (code SHR 16) AND $7F;
  shift := (code AND $03)<>0; alt := (code AND $30)<>0;
  ctrl := (code AND $08)<>0; comm := (code AND $80)<>0;
  mainline;
  IF key=$5F THEN helpme;  { Help }
  IF key IN [$50..$59] THEN  { *** F-Tasten ... }
    IF NOT shift THEN CASE key OF  { ... normal }
      $53: handle_menu($040900); { F4 }
      $54: handle_menu($040801); { F5 }
      $55: handle_menu($040500); { F6 }
      $56: handle_menu($040B00); { F7 }
      $57: handle_menu($040200); { F8 }
      $58: handle_menu($040601); { F9 }
      $59: handle_menu($040300); { F10 }
      OTHERWISE Write('F',key-$4F,': ???');
    END ELSE CASE key OF  { ... geshiftet }
      $53: handle_menu($040A00); { Shift-F4 }
      $54: handle_menu($040802); { Shift-F5 }
      $55: BEGIN  { Stichprobe, inklusive Pseudoseiten }
        IF thispage<>Nil THEN say_hello(version);
        mainline; Write('erweiterte Stichprobe l{uft ...');
        busy_pointer; page_grabber(False); normal_pointer;
        thispage := root; redraw_list; writepage(thispage,True);
      END;
      $56: handle_menu($040C00); { Shift-F7 }
      $57: handle_menu($050700); { Shift-F8 }
      $58: handle_menu($040602); { Shift-F9 }
      $59: handle_menu($040400); { Shift-F10 }
      OTHERWISE Write('Shift-F',key-$4F,': ???');
    END;
  IF key IN [$4C..$4F] THEN  { *** Cursor-Tasten }
    IF jobcursor THEN BEGIN    { Warteschlange blättern }
      mark_queue(False);
      CASE key OF
        $4C: IF shift THEN thisjob := thisjob + 5 ELSE Inc(thisjob);
        $4D: IF shift THEN thisjob := thisjob - 5 ELSE Dec(thisjob);
        $4E: thisjob := -queued;
        $4F: thisjob := maxactive-1;
        OTHERWISE;
      END;
      IF thisjob<-queued THEN thisjob := -queued;
      IF thisjob>=maxactive-1 THEN thisjob := maxactive-1;
      mark_queue(True);
      IF thisjob>=0 THEN BEGIN
        aktspeicher := thisjob; display_select(aktspeicher); END;
    END ELSE IF thispage<>Nil THEN BEGIN     { Seitenliste blättern }
      mark_list(False);
      CASE key OF
        $4C: IF alt THEN
            thispage := prev_magazine(thispage)
          ELSE IF shift THEN
            WHILE (thispage^.prev<>Nil) AND thispage^.dejavu DO
              thispage := thispage^.prev
          ELSE
            IF thispage^.prev<>Nil THEN thispage := thispage^.prev;
        $4D: IF alt THEN
            thispage := next_magazine(thispage)
          ELSE IF shift THEN
            WHILE (thispage^.next<>Nil) AND thispage^.dejavu DO
              thispage := thispage^.next
          ELSE
            IF thispage^.next<>Nil THEN thispage := thispage^.next;
        $4E: IF shift THEN
            WHILE thispage^.next<>Nil DO thispage := thispage^.next
          ELSE
            FOR i := 1 TO colht DO
              IF thispage^.next<>Nil THEN thispage := thispage^.next;
        $4F: IF shift THEN
            thispage := root
          ELSE
            FOR i := 1 TO colht DO
              IF thispage^.prev<>Nil THEN thispage := thispage^.prev;
        OTHERWISE;
      END;
      mark_list(True); writepage(thispage,True);
    END;
END;

PROCEDURE handle_key;
{ einzelne Eingabetaste untersuchen }
VAR pg: p_onepage;
    nr: Integer;
    key: Char;
BEGIN
  key := taste; taste := #0;
  mainline;
  CASE key OF
    '0'..'9','a'..'f','A'..'F','-','/','*','.','!':
      IF Length(queue_input) < 8 THEN BEGIN
        queue_input := queue_input + Upcase(key); queue_me;
      END;
    #8: IF Length(queue_input) > 0 THEN BEGIN
        queue_input[Length(queue_input)] := #0; queue_me;
      END;
    #13: BEGIN
        pg := Nil;
        IF (Length(queue_input)=3) THEN BEGIN { Sprungbefehl? }
          nr := hexval(queue_input); pg := hunt_in_list(nr,0,False);
          IF pg<>Nil THEN IF pg^.pg<>nr THEN pg := Nil;
          IF thispage<>Nil THEN IF thispage^.pg=nr THEN pg := Nil;
        END;
        IF pg<>Nil THEN BEGIN  { Seite nur anspringen }
          queue_input := ''; queue_me;
          jobcursor := False; hilite_crsr; push(thispage);
          mark_list(False); thispage := pg; mark_list(True);
          writepage(thispage,True);
        END ELSE BEGIN    { Seite (neu) anfordern }
          add_job(queue_input,True);
          queue_input := ''; redraw_queue(-1);
        END;
      END;
    #9: BEGIN  { Tab: Cursor zwischen Jobliste und Seitenliste umschalten }
        jobcursor := NOT jobcursor; hilite_crsr;
      END;
    '#': BEGIN numbering := NOT numbering; write_checks; fileinfo; END;
    'i','I': BEGIN withicon := NOT withicon; write_checks; fileinfo; END;
    'n','N': handle_menu($050300);
    #14: handle_menu($020402); { Ctrl-N }
    's','S': handle_menu($030401);
    #19: handle_menu($030403); { Ctrl-S }
    't','T': BEGIN check($050400, NOT testing); handle_menu($050400); END;
    ' ': writepage(thispage,True);
    '?': writepage(visblpage,False);
    #27: handle_menu($030100); { Esc }
    #127: BEGIN { Del: erst noch die Qualifier abfragen }
        IF (rawcode AND $08)<>0 THEN handle_menu($030503) { Ctrl }
        ELSE IF (rawcode AND $03)<>0 THEN handle_menu($030502) { Shift }
        ELSE handle_menu($030501);
      END;
    #155: handle_raw(rawcode);
    OTHERWISE BEGIN
        IF key>' ' THEN Write(key,'?')
        ELSE Write('Ctrl-',Chr(Ord(key)+64),'?');
        Delay(20); mainline;
      END;
  END;
END;

PROCEDURE handle_click;
{ angeklickte Seitennummern aufsuchen/anfordern }
VAR nr,max,j: Integer;
    pg: p_onepage;
    code: Char;
BEGIN
  mouseclicked := False;
  mainline;
  nr := number_from_page(clickedx,clickedy);
  IF nr>=0 THEN BEGIN   { Nummer in einer Seite angeklickt }
    pg := hunt_in_list(nr,0,False);
    IF pg<>Nil THEN IF pg^.pg<>nr THEN pg := Nil;
    IF thispage<>Nil THEN IF thispage^.pg=nr THEN pg := Nil;
    IF pg<>Nil THEN BEGIN  { Seite nur anspringen }
      jobcursor := False; hilite_crsr; push(thispage);
      mark_list(False); thispage := pg; mark_list(True);
      writepage(thispage,True);
    END ELSE IF nr IN [$100..$899] THEN BEGIN    { Seite (neu) anfordern }
      nr := get_bcd(nr); max := nr;
      IF dblclicked THEN BEGIN
        max := number_from_page(clickedx+4,clickedy);
        IF max<0 THEN max := nr + 3 ELSE max := get_bcd(max);
        IF max<nr THEN max := nr;
        IF (max DIV 100)>(nr DIV 100) THEN max := 100*(nr DIV 100 + 1)-1;
      END;
      FOR j := nr TO max DO
        add_job(IntStr(j),False);
      redraw_queue(-1);
    END;
    Exit;
  END;
  pg := page_from_list(clickedx,clickedy);
  IF pg<>Nil THEN BEGIN
    IF (thispage<>pg) OR jobcursor THEN BEGIN
      jobcursor := False; hilite_crsr;
      mark_list(False); thispage := pg; mark_list(True);
    END ELSE IF dblclicked THEN BEGIN
      del_from_list(thispage); update_list(thispage,-1);
    END;
    writepage(thispage,True);
    Exit;
  END;
  nr := pos_from_queue(clickedx,clickedy);
  IF nr<maxactive THEN BEGIN
    IF (thisjob<>nr) OR NOT jobcursor THEN BEGIN
      jobcursor := True; hilite_crsr;
      mark_queue(False); thisjob := nr; mark_queue(True);
    END ELSE IF dblclicked THEN BEGIN
      kill_job(thisjob);
      IF thisjob>=0 THEN  redraw_queue(thisjob)  ELSE  redraw_queue(-1);
    END;
    Exit;
  END;
  code := click_action(clickedx,clickedy);
  CASE code OF
    'D': handle_menu($020401);
    'F': BEGIN asciifile := NOT asciifile; write_checks; fileinfo; END;
    'M': BEGIN overwrite := NOT overwrite; write_checks; fileinfo; END;
    'N': BEGIN numbering := NOT numbering; write_checks; fileinfo; END;
    'I': BEGIN withicon  := NOT withicon;  write_checks; fileinfo; END;
    'J': BEGIN fifo := NOT fifo; write_checks; redraw_queue(-1); END;
    '+': BEGIN jobcursor := False; hilite_crsr; handle_raw($4D0000); END;
    '0': BEGIN jobcursor := False; hilite_crsr; handle_menu($030100); END;
    '-': BEGIN jobcursor := False; hilite_crsr; handle_raw($4C0000); END;
    'K': IF dblclicked THEN handle_menu($030503);
    'T': BEGIN
        check($050400, NOT testing); handle_menu($050400);
        IF dblclicked THEN handle_menu($050300);
      END;
    'S': BEGIN
        kill_queue;
        IF dblclicked THEN getconfig(1);
        redraw_queue(-1);
      END;
    'L': BEGIN
        jobcursor := False; hilite_crsr;
        IF dblclicked THEN handle_raw($4E0001)
          ELSE handle_raw($4F0001);
      END;
    OTHERWISE;
  END;
END;

BEGIN  { Hauptprogramm }
  { Eine Menge Variablen werden bereits in den Units, wo sie auch deklariert }
  { sind, initialisiert. }
  get_args; inputname := outputname; iffpicname := outputname;
  stop := False;
  colperm := $13567402; colperms := hexstr(colperm,8);
  AddExitServer(sysclean); sysinit(version);
  write_checks;
  roundrobin := 0; toprequest := 0;
  stackbot := 1; stackptr := stackbot;
  init_CCT; { SAA 5246 initialisieren }
  cursoroff; redraw_all; IF thispage=Nil THEN say_hello(version);
  REPEAT
    IF NOT newevent THEN event_scan;
    IF newevent THEN BEGIN
      newevent := False;
      IF taste<>#0 THEN handle_key;
      IF mouseclicked THEN handle_click;
      IF menupicked THEN handle_menu(menucode);
    END ELSE IF testing OR incomplete OR (visblpage=Nil) OR
      (toprequest+queued+active>0) THEN BEGIN
      Delay(5);  { Multitasking-freundlich, wir haben Zeit ... }
      IF testing THEN test(True);
      IF visblpage=Nil THEN say_hello(version)
        ELSE IF incomplete THEN writepage(visblpage,True);
      IF toprequest>0 THEN topscan;
      searching := queued+active>0;
      IF queued>0 THEN handle_queue;
      IF active>0 THEN BEGIN
        handle_jobs;
        attempt_input(roundrobin);
        roundrobin := (roundrobin+1) MOD maxactive;
      END;
      IF searching AND (queued+active=0) THEN showscreen(True); { fertig! }
      IF (i2c_status<>0) AND NOT testing THEN BEGIN
        testing := True; test(True);
        guru(i2c_status);
      END;
    END ELSE   { nichts mehr zu tun :-) }
      l := Wait(-1);
  UNTIL stop;
  SetStdIO(Nil); CloseConsole(Con);
  kill_list; sysclean;
END.

