UNIT startup; {$project vt }
{ Wertet die Programmstartargumente für VideoText aus }
{ ToolTypes:                  CLI-Parameter:  }
{ HOMEDIR=<pathname>          -h=<pathname> }
{ FILE=<output name>          -f=<output name> }
{ FILEMODE=<flag>|<flag>|...                   }
{ EDITOR=<dos command>        -e=<dos command> }
{ SCREENMODE=<mode id>        -m<mode id> }
{ PALETTE=<rgb>,<rgb>,...     -p<rgb>,<rgb>,... }
{ COLPERM=<digits>            -r<colperm digits> }
{ MAXWAIT=<seconds>           -w<seconds> }
{ BUSDELAY=<counter>          -d<counter> }
{ BURST=<tics>                -b<tics> }
{ SHUFFLE=<tics>              -s<tics> }
{ SPEECH=<text>               -c=<text> }
{ AUTOTIMER=<seconds>         -t<seconds> }
{ DATESTYLE=[0|1|2|3]         -y<style> }
{ TVMODE=[0|1|2]                       }
{ FLAGS=<flag>|<flag>|...              }
{                             <page> <page> ... }
{                             <file> <file> ... }

INTERFACE; FROM vt USES jobs;

VAR testing: Word;
    speech: str80;
    autotimer: Integer;

FUNCTION write_to_icon: Boolean;
PROCEDURE get_args;

{ ---------------------------------------------------------------------- }

IMPLEMENTATION;

{$opt q,s+,i+ } { keine Laufzeitprüfungen außer Stack und Feldindizes }
{$incl "workbench/startup.h", "icon.lib", "dos.lib", "asl.lib" }
{$incl "exec.lib", "dos/dosextens.h" }

TYPE keyid=(hmd,fil,flm,edi,scm,pal,cpr,mxw,bdl,bst,shu,spk,aut,dts,tvm,flg,
            asc,vtx,ics,nic,fif,lif,stn,clk,wrx,big);
     keywords=ARRAY[keyid] OF Str;  { s. Inititalisierungsteil }

VAR mypath,homedir,returndir: BPTR;
    myname,colors: str80;
    homedirname: String[160];
    busdelay: Integer;
    hail: p_WBStartup;
    arg: p_WBArg;
    s: ^String[1000];
    keys,ttarry: keywords;
    strstack: String[1000]; STATIC;   { fürs Zurückschreiben der ToolTypes }
    stacked: Integer;
    
PROCEDURE read_from_icon;
{ Startparameter lesen }
VAR icon: p_DiskObject;
    entry: Str;
    olddir: BPTR;
    i,ok: Integer;
    key,key2: keyid;
BEGIN
  IF IconBase=Nil THEN Exit;
  olddir := CurrentDir(mypath);
  icon := GetDiskObject(myname);
  IF icon<>Nil THEN BEGIN
    FOR key := hmd TO flg DO BEGIN
      entry := FindToolType(icon^.do_ToolTypes, keys[key]);
      IF Ptr(entry)<>Nil THEN CASE key OF
        hmd: homedirname := entry;
        fil: outputname := entry;
        flm: FOR key2 := asc TO nic DO
          IF MatchToolValue(entry,keys[key2]) THEN CASE key2 OF
            asc: asciifile := True;
            vtx: asciifile := False;
            ics: withicon := True;
            nic: withicon := False;
            OTHERWISE;
          END;
        edi: editor := entry;
        scm: screenmode := hexval(Copy(entry,1,10));
        pal: colors := entry;
        cpr: colperm := hexval(Copy(entry,1,10));
        mxw: Val(entry,maxwait,ok);
        bdl: Val(entry,busdelay,ok);
        bst: Val(entry,burst,ok);
        shu: Val(entry,shuffle,ok);
        aut: Val(entry,autotimer,ok);
        dts: BEGIN Val(entry,i,ok); datestyle := i; END;
        tvm: Val(entry,tv_status,ok);
        spk: speech := entry;
        flg: FOR key2 := fif TO big DO
          IF MatchToolValue(entry,keys[key2]) THEN CASE key2 OF
            fif: fifo := True;
            lif: fifo := False;
            clk: testing := testing OR 1;
            stn: testing := testing OR 2;
            wrx: silentrexx := True;
            big: fontno := 2;   
            OTHERWISE;
          END;
        OTHERWISE;
      END;
    END;
    FreeDiskObject(icon);
  END;
  olddir := CurrentDir(olddir);
END;

FUNCTION add_tooltype(s: Str): Str;
{ einen String in den globalen Stringpuffer kopieren }
VAR i: Integer;
    s2: ^String[200];
BEGIN
  add_tooltype := ^strstack[stacked]; s2 := s; i := 0;
  REPEAT
    Inc(i); strstack[stacked] := s2^[i]; Inc(stacked); 
  UNTIL s2^[i]=chr(0);
END;

FUNCTION write_to_icon{: Boolean};
{ aktuelle Parameter ins Icon zurückschreiben }
VAR icon: p_DiskObject;
    olddir: BPTR;
    s1: String[200];
    j: Integer;
    key: keyid;
BEGIN
  write_to_icon := False;
  IF IconBase=Nil THEN Exit;
  olddir := CurrentDir(mypath);
  icon := GetDiskObject(myname);
  IF icon<>Nil THEN BEGIN
    FOR key := hmd TO big DO ttarry[key] := Nil; stacked := 1;
    icon^.do_ToolTypes := ^ttarry;
    { Informationen auf neuesten Stand bringen: }
    getpalette; colors := ''; FOR j := 0 TO 7 DO 
      colors := colors + hexstr(palette[j],3)+','; 
    colors[Length(colors)] := #0; { letztes "," löschen }
    IF I2CBase<>Nil THEN
      busdelay := SetI2CDelay(I2CDELAY_READONLY);
    { Ausgabetexte erzeugen: }
    FOR key := hmd TO flg DO BEGIN
      s1 := keys[key]+'=';
      CASE key OF
        hmd: s1 := s1 + homedirname;
        fil: s1 := s1 + outputname;
        flm: BEGIN
            IF asciifile THEN s1 := s1 + keys[asc] + '|'
              ELSE s1 := s1 + keys[vtx] + '|';
            IF withicon THEN s1 := s1 + keys[ics]
              ELSE s1 := s1 + keys[nic];
          END;
        edi: s1 := s1 + editor;
        scm: s1 := s1 + '$' + hexstr(screenmode,8);
        pal: s1 := s1 + colors;
        cpr: s1 := s1 + hexstr(colperm,8);
        mxw: s1 := s1 + IntStr(maxwait);
        bdl: s1 := s1 + IntStr(busdelay);
        bst: s1 := s1 + IntStr(burst);
        shu: s1 := s1 + IntStr(shuffle);
        aut: s1 := s1 + IntStr(autotimer);
        dts: s1 := s1 + IntStr(datestyle);
        tvm: s1 := s1 + IntStr(tv_status);
        spk: s1 := s1 + speech;
        flg: BEGIN
            IF fifo THEN s1 := s1 + keys[fif]
              ELSE s1 := s1 + keys[lif];
            IF (testing AND 1)<>0 THEN s1 := s1 + '|' + keys[clk];
            IF (testing AND 2)<>0 THEN s1 := s1 + '|' + keys[stn];
            IF silentrexx THEN s1 := s1 + '|' + keys[wrx];
            IF fontno=2 THEN s1 := s1 + '|' + keys[big];
          END;                                     
        OTHERWISE;
      END;
      ttarry[key] := add_tooltype(s1);
    END;
    write_to_icon := PutDiskObject(myname,icon);
    FreeDiskObject(icon);
  END;
  olddir := CurrentDir(olddir);
END;

PROCEDURE paraminfo;
{ kurze Info für CLI-Benutzer }
BEGIN
  WriteLn('legal parameters:');
  WriteLn(myname,' <page> <page> ... <file> <file> ...');
  WriteLn('  -h=<homedir> -f=<outputfile> -e=<editcommand> -c=<speechtext>');
  WriteLn('  -m<screenmode> -p<rgb>,<rgb>,... -r<colperm digits> -y<datestyle>');
  Write('  -t<secs/slide> -d<busdelay> -w<seconds> -b<ticks> -s<ticks>');
  { Irgendwer erzeugt mir nach Halt() noch zwei extra LF's ... }
END;

PROCEDURE get_args;
{ wertet CLI- oder WorkBench-Argumente aus }
VAR len,i,j,k,ok,gelesen: Integer;
    name: str80;
    is_job: Boolean;
    scrmd_bak: Long;
    olddir: BPTR;
    entry: Str;
    icon: p_DiskObject;
    smreq: p_ScreenModeRequester;
    tags: ARRAY[1..5] OF TagItem;
BEGIN
  gelesen := 0;
  busdelay := -1;
  scrmd_bak := screenmode; screenmode := -1;
  colors := '';
  read_from_icon;
  IF fromWB THEN BEGIN    { *** Workbench-Start }
    hail := StartupMessage;
    arg := hail^.sm_ArgList;
    FOR i := 1 to hail^.sm_NumArgs DO BEGIN
      IF i>1 THEN BEGIN  { zusätzliche Dateien: enthaltene Seiten einlesen }
        olddir := CurrentDir(arg^.wa_Lock);
        name := arg^.wa_Name;
        IF filetype(name)=1 THEN
          gelesen := gelesen + getpages(name,True);
        icon := GetDiskObject(arg^.wa_Name);
        { und die ToolTypes SCREENMODE, COLPERM und AUTOTIMER abfragen: }
        IF icon<>Nil THEN BEGIN
          entry := FindToolType(icon^.do_ToolTypes, keys[scm]);
          IF ptr(entry)<>Nil THEN
            screenmode := hexval(Copy(entry,1,10));
          entry := FindToolType(icon^.do_ToolTypes, keys[cpr]);
          IF ptr(entry)<>Nil THEN
            colperm := hexval(Copy(entry,1,10));
          entry := FindToolType(icon^.do_ToolTypes, keys[aut]);
          IF ptr(entry)<>Nil THEN
            Val(entry,autotimer,ok);
         FreeDiskObject(icon);
        END;
      END;
      { auf nächsten WBArg-Zeiger zugreifen: }
      arg := Ptr(Long(arg)+SizeOf(WBArg));
    END;
  END ELSE IF ParameterLen>0 THEN BEGIN    { *** CLI-Start }
    s := ParameterStr; len := ParameterLen;
    { Parameterzeile in Worte zerlegen, wie der argv[] in C es schon ist :-( }
    i := 1; WHILE i<=len DO BEGIN
      WHILE (s^[i]<=' ') AND (i<=len) DO Inc(i);
      j := i + 1;
      IF s^[i]='"' THEN BEGIN
        Inc(i); WHILE (s^[j]<>'"') AND (j<=len) DO Inc(j);
      END ELSE BEGIN
        WHILE (s^[j]>' ') AND (j<=len) DO Inc(j);
      END;
      { Zeiger i: 1. Zeichen des Wortes, j: 1. Trennzeichen dahinter }
      IF s^[i]='-' THEN BEGIN
        i := i+2;
        CASE s^[i-1] OF
          'h': BEGIN
              IF s^[i] = '=' THEN Inc(i);
              IF j>i THEN  homedirname := Copy(s^,i,j-i) ELSE homedirname := '';
            END;
          'f': BEGIN
              IF s^[i] = '=' THEN Inc(i);
              IF j>i THEN  outputname := Copy(s^,i,j-i);
            END;
          'e': BEGIN
              IF s^[i] = '=' THEN Inc(i);
              IF j>i THEN  editor := Copy(s^,i,j-i);
            END;
          'c': BEGIN
              IF s^[i] = '=' THEN Inc(i);
              IF j>i THEN  speech := Copy(s^,i,j-i) ELSE speech := '';
            END;
          'm': screenmode := hexval(Copy(s^,i,j-i));
          'p': colors := Copy(s^,i,j-i);
          'r': colperm := hexval(Copy(s^,i,j-i));
          'd': Val(Copy(s^,i,j-i),busdelay,ok);
          'w': Val(Copy(s^,i,j-i),maxwait,ok);
          'b': Val(Copy(s^,i,j-i),burst,ok);
          's': Val(Copy(s^,i,j-i),shuffle,ok);
          't': Val(Copy(s^,i,j-i),autotimer,ok);
          'y': BEGIN Val(Copy(s^,i,j-i),i,ok); datestyle := i; END;
          '?': BEGIN paraminfo; Halt(5); END;
          OTHERWISE BEGIN
            WriteLn('illegal parameter: ',Copy(s^,i-2,j-i+2));
          END;
        END;
      END ELSE IF i<=len THEN BEGIN
        { Was nur aus '0123456789/*' besteht, ist eine Seitennummer, alles andere eine }
        { Eingabedatei. }
        is_job := True;
        FOR k := i TO j-1 DO
          IF NOT (s^[k] IN ['0'..'9','-','/','*','.','!']) THEN is_job := False;
        name := Copy(s^,i,j-i);
        IF is_job THEN
          add_job(name,True)
        ELSE IF filetype(name)=1 THEN
          gelesen := gelesen + getpages(name,True)
        ELSE
          WriteLn('no VT-pages found in file "',name,'"');
      END;
      i := j + 1;
    END;
  END;
  IF editor<>'' THEN
    IF editor[Length(editor)]<>' ' THEN editor := editor + ' ';
  IF screenmode=-1 THEN BEGIN
    screenmode := scrmd_bak;  { HIRES, wie von Unit sys voreingestellt }
    IF AslBase<>Nil THEN BEGIN
      tags[1] := TagItem(ASLSM_TitleText, 0);
      tags[1].ti_Data := "VideoText-Screen wählen";
      tags[2] := TagItem(ASLSM_MinDepth, 3);
      tags[3] := TagItem(ASLSM_InitialDisplayID, screenmode);
      tags[4] := TagItem(TAG_DONE, 0);
      smreq := AllocAslRequest(ASL_ScreenModeRequester,^tags[1]);
      IF smreq<>Nil THEN BEGIN
        IF AslRequest(smreq, Nil) THEN
          screenmode := smreq^.sm_DisplayID;
        FreeAslRequest(smreq);
      END;
    END;
  END;
  IF colors<>'' THEN
    FOR i := 0 TO 7 DO
      palette[i] := hexval(Copy(colors,4*i+1,3));
  make_colperms(colperm);
  IF (I2CBase<>Nil) AND (busdelay>=0) THEN
    IF SetI2CDelay(busdelay)<>busdelay THEN;
  IF homedirname='' THEN 
    returndir := CurrentDir(mypath)  { "cd PROGDIR:" }
  ELSE BEGIN
    homedir := Lock(homedirname, ACCESS_READ);
    IF homedir<>0 THEN
      returndir := CurrentDir(homedir)
    ELSE
      returndir := CurrentDir(mypath);  { notfalls "cd PROGDIR:" }
  END;
END;

PROCEDURE retreat;
VAR egal: Long;
BEGIN
  IF IconBase<>Nil THEN CloseLibrary(IconBase); IconBase := Nil;
  IF AslBase<>Nil THEN CloseLibrary(AslBase); AslBase := Nil;
  IF returndir<>0 THEN egal := CurrentDir(returndir); returndir := 0;
  IF homedir<>0 THEN UnLock(homedir); homedir := 0;
END;

BEGIN  { Initialisierung }
  testing := 0; autotimer := 2; speech := ''; homedirname := '';
  { ToolType-Schlüsselwörter über symbolische Konstanten zugänglich machen: }
  keys := keywords('HOMEDIR','FILE','FILEMODE','EDITOR',
          'SCREENMODE','PALETTE','COLPERM','MAXWAIT','BUSDELAY','BURST',
          'SHUFFLE','SPEECH','AUTOTIMER','DATESTYLE','TVMODE','FLAGS',
          'ASCII','VT', 'ICONS','NOICONS',
          'FIFO','LIFO','STATION','CLOCK','WBREXX','BIGFONT');
  homedir := 0; returndir := 0;
  AslBase := OpenLibrary(ASLNAME,38); { brauche den ScreenMode-Requester! }
  IconBase := OpenLibrary('icon.library',0); AddExitServer(retreat);
  { herausfinden, wie ich an mein Icon komme: }
  IF FromWB THEN BEGIN
    hail := StartupMessage; arg := hail^.sm_ArgList;
    mypath := arg^.wa_Lock;
    myname := arg^.wa_Name;
  END ELSE BEGIN
    mypath := GetProgramDir;
    IF NOT GetProgramName(^myname,80) THEN ;
  END;
END.

