-- Copyright (C) 1983  by Xerox Corporation. All rights reserved. 
-- FixLocalTimeParameters.mesa, HGM,  3-Dec-83 16:51:45

DIRECTORY
  Ascii USING [CR],
  CmFile USING [Handle, TableError],
  OthelloOps USING [GetTimeFromTimeServer, SetProcessorTime, TimeServerError],
  PilotMP USING [cTimeNotAvailable],
  ProcessorFace USING [SetMP, mp],
  Put USING [Text],
  String USING [AppendChar, AppendDecimal, AppendString],
  StringLookUp USING [noMatch, TableDesc],
  System USING [
    GetLocalTimeParameters, GreenwichMeanTime, LocalTimeParameters, LocalTimeParametersUnknown,
    SetLocalTimeParameters, WestEast],
  Token USING [Decimal],
  
  Indirect USING [Close, NextValue, OpenSection];

FixLocalTimeParameters: PROGRAM
  IMPORTS
    CmFile, OthelloOps, ProcessorFace, Put, String, System, Token,
    Indirect =
  BEGIN

  GetTimeFromNet: PROCEDURE =
    BEGIN
    timeTrys: CARDINAL ← 25;
    time: System.GreenwichMeanTime;
    lpt: System.LocalTimeParameters;
    timeFromServer: BOOLEAN ← TRUE;
    teMP: CARDINAL = ProcessorFace.mp;
    ProcessorFace.SetMP[PilotMP.cTimeNotAvailable+1000];
    [time, lpt] ← OthelloOps.GetTimeFromTimeServer[
      ! OthelloOps.TimeServerError =>
        SELECT error FROM
	  noResponse =>
	    BEGIN
            IF (timeTrys ← timeTrys-1)=0 THEN BEGIN timeFromServer ← FALSE; CONTINUE; END
	    ELSE RETRY;
	    END;
        noCommunicationFacilities => BEGIN timeFromServer ← FALSE; CONTINUE; END;
	ENDCASE => ERROR];
    IF timeFromServer THEN
      BEGIN
      System.SetLocalTimeParameters[lpt];
      OthelloOps.SetProcessorTime[time]; 
      END;
    ProcessorFace.SetMP[teMP];
    END;
    
  GetTimeParametersFromEERom: PROCEDURE =
    BEGIN
    dstSpecified, zoneSpecified: BOOLEAN ← FALSE;
    parms: System.LocalTimeParameters;
    cmFile: CmFile.Handle;
    known: BOOLEAN ← TRUE;
    Option: TYPE = MACHINE DEPENDENT{
      dst(0), zone, noMatch(StringLookUp.noMatch)};
    DefinedOption: TYPE = Option [dst..zone];
    CheckType: PROCEDURE [h: CmFile.Handle, table: StringLookUp.TableDesc]
      RETURNS [index: CARDINAL] = Indirect.NextValue;
    MyNextValue: PROCEDURE [
      h: CmFile.Handle,
      table: LONG DESCRIPTOR FOR ARRAY DefinedOption OF LONG STRING]
      RETURNS [index: Option] = LOOPHOLE[CheckType];
    optionTable: ARRAY DefinedOption OF LONG STRING ← [
      dst: "DST"L, zone: "Zone"L];
    parms ← System.GetLocalTimeParameters[ !
      System.LocalTimeParametersUnknown => BEGIN known ← FALSE; CONTINUE; END];
    IF known THEN RETURN;
    cmFile ← Indirect.OpenSection["TimeServer"L];
    IF cmFile = NIL THEN
      BEGIN
      Message["Can't find [TimeServer] section in parameter file"L];
      RETURN;
      END;
    DO
      text: STRING = [200];
      option: Option;
      option ← MyNextValue[cmFile, DESCRIPTOR[optionTable] ! CmFile.TableError => RETRY];
      SELECT option FROM
        noMatch => EXIT;
	dst =>  -- <begin day> <end day>
          BEGIN
          parms.beginDST ← Token.Decimal[cmFile];
          parms.endDST ← Token.Decimal[cmFile];
          String.AppendString[text, "DST: begin="L];
          String.AppendDecimal[text, parms.beginDST];
          String.AppendString[text, ", last="L];
          String.AppendDecimal[text, parms.endDST];
          Message[text];
          dstSpecified ← TRUE;
          END;
        zone =>  -- <sign> <hours>:<minutes>
          BEGIN
          hours: INTEGER ← Token.Decimal[cmFile];
          minutes: CARDINAL ← Token.Decimal[cmFile];
          westEast: System.WestEast ← IF hours < 0 THEN east ELSE west;
          parms.direction ← westEast;
          parms.zone ← ABS[hours];
          parms.zoneMinutes ← minutes;
          String.AppendString[text, "ZONE: hours="L];
          String.AppendDecimal[text, hours];
          String.AppendString[
            text, IF westEast = west THEN "(west)"L ELSE "(east)"L];
          String.AppendString[text, ", minutes="L];
          String.AppendDecimal[text, minutes];
          Message[text];
          zoneSpecified ← TRUE;
          END;
        ENDCASE => ERROR;
      ENDLOOP;
    Indirect.Close[cmFile];
    IF ~dstSpecified OR ~zoneSpecified THEN RETURN;
    System.SetLocalTimeParameters[parms];
    END;

  Message: PROCEDURE [one, two, three: LONG STRING ← NIL] =
    BEGIN
    text: STRING = [100];
    String.AppendString[text, "FixTimeParameters: "L];
    String.AppendString[text, one];
    IF two # NIL THEN String.AppendString[text, two];
    IF three # NIL THEN String.AppendString[text, three];
    LogString[text];
    END;
  
  LogString: PROCEDURE [text: LONG STRING] =
    BEGIN
    String.AppendChar[text, '.];
    String.AppendChar[text, Ascii.CR];
    Put.Text[NIL, text];
    END;

  GetTimeFromNet[];
  GetTimeParametersFromEERom[];
  END.