-- DiagnosticsImplG.mesa  -  edited by:
-- Paul		   13-Jul-84 10:14:01

DIRECTORY
  Ascii USING [CR, SP],
  Authenticator USING [firstVerifier, nullCredentials],
  CH USING [Element, Enumerate, NamePattern, wildCard],
  CHLookup USING [
    Error, FileserverPt, LookupFileserver, LookupMailserver, LookupPrintserver],
  CHPIDs USING [ch3fileserver, ch3mailserver, ch3printserver],
  DiagnosticsOps USING [
    ConfirmIndex, confirmation, diagnosticwh, PutMessage, StringIndex, toolData],
  ExtendedString USING [AppendNumber],
  FormSW USING [Display, FindItem],
  NSString USING [AppendToMesaString, StringFromMesaString],
  OnlineDiagnostics USING [
    FloppyWhatToDoNext, GetConfirmationProc, GetFloppyChoiceProc, GetYesOrNoProc,
    YesOrNo],
  Put USING [Char, CR, Line, Text],
  String USING [
    AppendChar, AppendCharAndGrow, AppendLongNumber, AppendNumber,
    AppendStringAndGrow],
  UserInput USING [UserAbort];

DiagnosticsImplG: MONITOR
  IMPORTS
     CH, CHLookup, DiagnosticsOps, ExtendedString, FormSW, NSString,
     Put, String, UserInput
  EXPORTS DiagnosticsOps =
  BEGIN
  
  -- Routines to allow the diagnostics to talk to the window.

  PutChar: PUBLIC PROCEDURE [ch: CHARACTER, minWidth: CARDINAL ← 0] =
    BEGIN
    Put.Char[DiagnosticsOps.toolData.fileSW, ch];
    THROUGH [1..minWidth) DO 
      Put.Char[DiagnosticsOps.toolData.fileSW, Ascii.SP]; 
      ENDLOOP;
    END;

  PutCR: PUBLIC PROCEDURE = BEGIN Put.CR[DiagnosticsOps.toolData.fileSW]; END;

  PutLine: PUBLIC PROCEDURE [text: LONG STRING] =
    BEGIN Put.Line[DiagnosticsOps.toolData.fileSW, text]; END;

  PutLongNumber: PUBLIC PROCEDURE [
    number: LONG UNSPECIFIED, radix: CARDINAL, minWidth: CARDINAL ← 0] =
    BEGIN
    text: STRING = [40];
    String.AppendLongNumber[text, number, radix];
    THROUGH [text.length..minWidth) DO PutChar[Ascii.SP]; ENDLOOP;
    PutText[text];
    END;

  PutNumber: PUBLIC PROCEDURE [
    number: UNSPECIFIED, radix: CARDINAL, minWidth: CARDINAL ← 0] =
    BEGIN
    text: STRING = [40];
    String.AppendNumber[text, number, radix];
    THROUGH [text.length..minWidth) DO PutChar[Ascii.SP]; ENDLOOP;
    PutText[text];
    END;

  PutText: PUBLIC PROCEDURE [text: LONG STRING, minWidth: CARDINAL ← 0] =
    BEGIN
    Put.Text[DiagnosticsOps.toolData.fileSW, text];
    THROUGH [text.length..minWidth) DO
      Put.Char[DiagnosticsOps.toolData.fileSW, Ascii.SP]; ENDLOOP;
    END;

  PutTextCentered: PUBLIC PROCEDURE [text: LONG STRING, width: CARDINAL ← 0] =
    BEGIN
    leftBlanks: CARDINAL = (width - text.length)/2;
    rightBlanks: CARDINAL = width - text.length - leftBlanks;
    THROUGH [0..leftBlanks) DO PutChar[Ascii.SP]; ENDLOOP;
    PutText[text];
    THROUGH [0..rightBlanks) DO PutChar[Ascii.SP]; ENDLOOP;
    END;
    
  GetConfirmation: PUBLIC ENTRY OnlineDiagnostics.GetConfirmationProc =
    BEGIN
    ENABLE UNWIND => NULL;
    MakeConfirmsVisible[confirm, confirm];
    DiagnosticsOps.PutMessage[msg];
    PutLine["Please select Confirm! when this is done."L];
    WAIT DiagnosticsOps.confirmation;
    MakeConfirmsInvisible[];
    END;

  GetFloppyChoice: PUBLIC ENTRY OnlineDiagnostics.GetFloppyChoiceProc =
    BEGIN
    ENABLE UNWIND => NULL;
    MakeConfirmsVisible[continue, exit];
    PutLine["What do you want to do now?"L];
    WAIT DiagnosticsOps.confirmation;
    MakeConfirmsInvisible[];
    RETURN[
      SELECT DiagnosticsOps.toolData.latestConfirm FROM
        continue => OnlineDiagnostics.FloppyWhatToDoNext[continueToNextError],
        loop => OnlineDiagnostics.FloppyWhatToDoNext[loopOnThisError],
        display => OnlineDiagnostics.FloppyWhatToDoNext[displayStuff],
        ENDCASE => OnlineDiagnostics.FloppyWhatToDoNext[exit]];
    END;

  GetYesOrNo: PUBLIC ENTRY OnlineDiagnostics.GetYesOrNoProc =
    BEGIN
    ENABLE UNWIND => NULL;
    MakeConfirmsVisible[yes, no];
    DiagnosticsOps.PutMessage[msg];
    PutLine["Please select either Yes! or No! as appropriate."L];
    WAIT DiagnosticsOps.confirmation;
    MakeConfirmsInvisible[];
    RETURN[
      SELECT DiagnosticsOps.toolData.latestConfirm FROM
        yes => OnlineDiagnostics.YesOrNo[yes],
        ENDCASE => OnlineDiagnostics.YesOrNo[no]];
    END;

  MakeConfirmsVisible: PROCEDURE [low, high: DiagnosticsOps.ConfirmIndex] =
    BEGIN
    DiagnosticsOps.toolData.confirming ← TRUE;
    FOR i: DiagnosticsOps.ConfirmIndex IN [low..high] DO
      FormSW.FindItem[DiagnosticsOps.toolData.confirmSW, ORD[
      DiagnosticsOps.ConfirmIndex[i]]].flags.invisible ← FALSE;
      ENDLOOP;
    FormSW.Display[DiagnosticsOps.toolData.confirmSW];
    END;

  MakeConfirmsInvisible: PROCEDURE =
    BEGIN
    DiagnosticsOps.toolData.confirming ← FALSE;
    FOR i: DiagnosticsOps.ConfirmIndex IN DiagnosticsOps.ConfirmIndex DO
      FormSW.FindItem[DiagnosticsOps.toolData.confirmSW, ORD[
      DiagnosticsOps.ConfirmIndex[i]]].flags.invisible ← TRUE;
      ENDLOOP;
    FormSW.Display[DiagnosticsOps.toolData.confirmSW];
    END;

  CheckForAbort: PUBLIC PROCEDURE =
    BEGIN 
      IF UserInput.UserAbort[DiagnosticsOps.diagnosticwh] THEN ERROR ABORTED; 
    END;

  -- Append server trash, stolen from Diag1Pack.mesa

   AppendServers: PUBLIC PROCEDURE [
     strings: LONG DESCRIPTOR FOR ARRAY DiagnosticsOps.StringIndex OF LONG STRING,
      z:UNCOUNTED ZONE] =
    BEGIN  --AppendServers--
    found: BOOLEAN ← FALSE;
    foundThatID: BOOLEAN ← FALSE;
    pattern: CH.NamePattern;
    index: DiagnosticsOps.StringIndex;
    string: LONG POINTER TO LONG STRING;
    wildString: LONG STRING ← [5];

    GetAndAppendID: PROC [name: CH.Element] =
      BEGIN  --GetAndAppendID--

      AppendID: PROC [fullName: CH.Element, info: CHLookup.FileserverPt] =
        BEGIN  --AppendID--
        temp: LONG STRING ← [100];
        -- Append the decimal representation of info.address --
        AppendDashedNumberAndGrow[string, @info.address.host, 3, 10, z];
        -- Append a blank --
        String.AppendStringAndGrow[string, " "L, z];
        -- ****************************************************************** --
        -- NOTE!!!! - The octal & hex representations of the proc IDs are 
	-- not printed at this time. May be re-inserted at a future time.
        -- Append the octal representation of info.address
        -- AppendNumberAndGrow[string, @info.address.host, 3, 8, z];
        -- Append the string "B "
        -- String.AppendStringAndGrow[string, "B "L, z];
        -- Append the hexadecimal representation of info.address
        -- AppendNumberAndGrow[string, @info.address.host, 3, 16, z];
        -- Append the string "X "
        -- String.AppendStringAndGrow[string, "X "L, z];
        -- ****************************************************************** --
        -- Append the string " NET # "
        String.AppendStringAndGrow[string, " NET # "L, z];
        -- Append the net # --
        AppendDashedNumberAndGrow[string, @info.address.net, 2, 10, z];
        -- Append a blank --
        String.AppendStringAndGrow[string, " "L, z];
        -- Append the name of the server
        NSString.AppendToMesaString[temp, name.local];
        String.AppendStringAndGrow[string, temp, z];
        -- Append a CR --
        String.AppendStringAndGrow[string, "
    "L, z];
        found ← TRUE;
        END --AppendID-- ;

      SELECT index FROM
        listFS =>
          CHLookup.LookupFileserver[
            name, AppendID !
            CHLookup.Error => BEGIN found ← FALSE; CONTINUE; END; ];
        listPS =>
          CHLookup.LookupPrintserver[
            name, LOOPHOLE[AppendID] !
            CHLookup.Error => BEGIN found ← FALSE; CONTINUE; END; ];
        listMS =>
          CHLookup.LookupMailserver[
            name, LOOPHOLE[AppendID] !
            CHLookup.Error => BEGIN found ← FALSE; CONTINUE; END; ];
        ENDCASE => NULL;
      END --GetAndAppendID-- ;

    -- Set up the pattern to be used in the enumerations. --
    String.AppendChar[wildString, CH.wildCard];
    pattern ← [
      org: NSString.StringFromMesaString[strings[currOrganization]],
      domain: NSString.StringFromMesaString[strings[currDomain]],
      local: NSString.StringFromMesaString[wildString]];
    --The following code enumerates the servers found in the Clearinghouse,
    -- and appends their IDs to the appropriate strings.
    FOR index IN [listFS..listMS] DO
      string ← @strings[index];
      found ← CH.Enumerate[
        Authenticator.nullCredentials, Authenticator.firstVerifier, @pattern,
        (SELECT index FROM
           listFS => CHPIDs.ch3fileserver,
           listPS => CHPIDs.ch3printserver,
           ENDCASE => CHPIDs.ch3mailserver), GetAndAppendID].code = done;
      IF found THEN
        WHILE string[string↑.length - 1] = Ascii.SP
          OR string[string↑.length - 1] = Ascii.CR DO
          string↑.length ← string↑.length - 1; ENDLOOP  -- get rid of final CR
      ELSE String.AppendStringAndGrow[string, "none"L, z];
      ENDLOOP;
    END --AppendServers-- ;
    
  AppendDashedNumberAndGrow: PROCEDURE [
    string: LONG POINTER TO LONG STRING, field: LONG POINTER, size: CARDINAL,
    radix: CARDINAL, z: UNCOUNTED ZONE] =
    BEGIN  --AppendDashedNumberAndGrow--
    temp: LONG STRING ← [100];
    temp.length ← 0;
    ExtendedString.AppendNumber[field, size, radix, temp];
    FOR i: CARDINAL IN [0..temp.length) DO
      String.AppendCharAndGrow[string, temp[i], z];
      IF (temp.length - 1 - i) MOD 3 = 0 AND i # temp.length - 1 THEN
        String.AppendCharAndGrow[string, '-, z];
      ENDLOOP;
    END --AppendDashedNumberAndGrow-- ;

  AppendNumberAndGrow: PROCEDURE [
    string: LONG POINTER TO LONG STRING, field: LONG POINTER, size: CARDINAL,
    radix: CARDINAL, z: UNCOUNTED ZONE] =
    BEGIN  --AppendNumberAndGrow--
    temp: LONG STRING ← [100];
    temp.length ← 0;
    ExtendedString.AppendNumber[field, size, radix, temp];
    String.AppendStringAndGrow[string, temp, z];
    END --AppendNumberAndGrow-- ;
  
  END.