--ILTSetProfileImpl.mesa
--Created by
--   JFung.PASA	  	15-Nov-83 15:44:26

--last edited by
--   JFung.PASA	   	23-Jan-84 11:10:41 



DIRECTORY
     CmFile,
     Cursor,
     Event,
     EventTypes,
     Exec,
     Format,
     FormSW,
     Heap,
     LispToolOps,
     MFile,
     MStream,
     Process,
     Put,
     Runtime,
     Stream,
     String,
     StringLookUp,
     Supervisor,
     Time,
     Token,
     Tool,
     ToolDriver,
     ToolWindow,
     UserInput,
     Version,
     Window;



ILTSetProfileImpl: PROGRAM
     IMPORTS
          CmFile, Cursor, Event, Exec, FormSW, Heap, LispToolOps, MFile, MStream,
          Process, Put, Runtime, Stream, String, StringLookUp, Supervisor, Time,
          Token, Tool, ToolDriver, ToolWindow, Version, Window

     EXPORTS LispToolOps =


     BEGIN OPEN ILT: LispToolOps;
     ServerType: TYPE = {IFS, NS};

     DataHandle: TYPE = LONG POINTER TO Data;
     Data: TYPE = MACHINE DEPENDENT RECORD [
          -- Message subwindow stuff
          msgSW(0): Window.Handle ← NIL,
          -- File subwindow stuff
          fileSW(2): Window.Handle ← NIL,

          -- Form subwindow stuff
          -- Note: enumerateds and booleans must be word boundary
          -- aligned as addresses for them must be generated
          --formSW: Window.Handle ← NIL,
          paramSW(4): Window.Handle ← NIL,
          commandSW(6): Window.Handle ← NIL,

          busy(8): BOOLEAN ← FALSE,  -- command is running
          userName(9): LONG STRING ← NIL,
          password(11): LONG STRING ← NIL,
          domainName(13): LONG STRING ← NIL,
          organizationName(15): LONG STRING ← NIL,
          filePathName(17): LONG STRING ← NIL,
          volName(19): LONG STRING ← NIL,
          fileServerProtocol(21): LONG STRING ← NIL,
          NSLisp(23): LONG STRING ← NIL,
          PUPLisp(25): LONG STRING ← NIL,
          fileServer(27): ServerType ← NS];


     debug: BOOLEAN ← FALSE;
     toolData: DataHandle ← NIL;
     profileWindow: Window.Handle ← NIL;

     active: BOOLEAN ← FALSE;
     agent: Supervisor.SubsystemHandle = Supervisor.CreateSubsystem[
          CheckDeactivate];

     formDisplay: ToolWindow.DisplayProcType ← NIL;
     heraldName: STRING ← [80];


     CheckDeactivate: Supervisor.AgentProcedure =
          BEGIN
          IF event = EventTypes.deactivate AND profileWindow # NIL
               AND profileWindow = eventData AND toolData.busy THEN
               BEGIN
               Put.Line[
                    toolData.msgSW, "The tool is busy:  aborting deactivation"L];
               ERROR Supervisor.EnumerationAborted;
               END;
          END;  --CheckDeactivate



     ClearCommandSubwindow: PROCEDURE =
          BEGIN
          item: FormSW.ItemHandle;

          FOR i: CARDINAL ← 0, i + 1 UNTIL
               (item ← FormSW.FindItem[toolData.commandSW, i]) = NIL DO
               item.flags.invisible ← TRUE ENDLOOP;
          FormSW.Display[toolData.commandSW];
          END;



     ClearFileSubwindow: PROCEDURE =
          BEGIN
          item: FormSW.ItemHandle;

          FOR i: CARDINAL ← 0, i + 1 UNTIL
               (item ← FormSW.FindItem[toolData.fileSW, i]) = NIL DO
               item.flags.invisible ← TRUE ENDLOOP;
          FormSW.Display[toolData.fileSW];
          formDisplay ← Window.GetDisplayProc[toolData.fileSW];
          END;



     ClearMsgSubwindow: PROCEDURE =
          BEGIN
          item: FormSW.ItemHandle;

          FOR i: CARDINAL ← 0, i + 1 UNTIL
               (item ← FormSW.FindItem[toolData.msgSW, i]) = NIL DO
               item.flags.invisible ← TRUE ENDLOOP;
          FormSW.Display[toolData.msgSW];
          formDisplay ← Window.GetDisplayProc[toolData.msgSW];
          END;



     ClearSubWindows: PROCEDURE =
          BEGIN
          --ClearFileSubwindow;
          ClearMsgSubwindow;
          END;


     ClientTransition: ToolWindow.TransitionProcType =
          -- This procedure is called whenever the system determines that this
          -- Tool's state is undergoing a user invoked transition.
          -- In this Example we demonstrate a technique that minimizes the memory
          -- requirements for a Tool that is inactive.
          BEGIN
          SELECT TRUE FROM
               old = inactive =>
                    BEGIN
                    IF toolData = NIL THEN
                         toolData ← Heap.systemZone.NEW[Data ← []];
                    ProcessUserDotCM[];
                    active ← TRUE;
                    END;
               new = inactive =>
                    BEGIN
                    Supervisor.RemoveDependency[
                         client: agent, implementor: Event.toolWindow];
                    IF toolData # NIL THEN
                         BEGIN
                         FormSW.Destroy[toolData.paramSW];
                         FormSW.Destroy[toolData.commandSW];
                         Heap.systemZone.FREE[@toolData];
                         END;
                    --ToolDriver.RemoveSWs[tool: "LispTool"L];
                    active ← FALSE;
                    END;
               ENDCASE
          END;



     FormSWMakeUserCM: FormSW.ProcType =
          BEGIN
          toolData.busy ← TRUE;
          ClearSubWindows;
          IF ILT.Confirm[] THEN ILT.MakeUserCM[];
          toolData.busy ← FALSE;
          END;  --FormSWMakeUserCM


     FormSWQuitProc: FormSW.ProcType =
          BEGIN
          IF debug THEN {
               Put.Line[toolData.fileSW, "Quit Proc..."L];
               --Process.Pause[Process.SecondsToTicks[5]];
               };
          [] ← ToolWindow.Deactivate[profileWindow];
          END;  --FormSWQuitProc



     Init: PROCEDURE =
          BEGIN
          --h: Exec.Handle;
          --execWrite: Format.StringProc ← Exec.OutputProc[h];
          --execWrite["Creating tool window.."L]; 
          --Process.Pause[Process.SecondsToTicks[5]];
          Exec.AddCommand["SetDomain.~"L, ProfileExec, Unload];
          --IF (profileWindow # NIL) AND ~active THEN
          -- ToolWindow.Activate[profileWindow]
          --ELSE profileWindow ← MakeTool[];
          END;



     MakeCommands: FormSW.ClientItemsProcType =
          BEGIN OPEN FormSW;

          tabs: ARRAY [0..3) OF CARDINAL ← [0, 30, 60];
          nItems: CARDINAL = 2;
          items ← AllocateItemDescriptor[nItems];

          items[0] ← CommandItem[
               tag: "Set Profile"L, place: newLine, proc: FormSWMakeUserCM];
          -- newLine is required, else will get 915 trap

          items[1] ← CommandItem[tag: "Quit"L, proc: FormSWQuitProc];

          SetTagPlaces[items, DESCRIPTOR[tabs], FALSE];
          RETURN[items, TRUE];
          END;



     MakeParams: FormSW.ClientItemsProcType =
          BEGIN OPEN FormSW;

          tabs: ARRAY [0..7) OF CARDINAL ← [0, 28, 52, 56, 60, 68, 75];
          nItems: CARDINAL = 7;

          serverForm: ARRAY [0..2) OF Enumerated ← [
               ["IFS"L, ServerType[IFS]], ["NS"L, ServerType[NS]]];

          items ← AllocateItemDescriptor[nItems];

          items[0] ← StringItem[
               tag: "User"L, string: @toolData.userName, inHeap: TRUE,
               place: newLine];
          items[1] ← StringItem[
               tag: "Password"L, string: @toolData.password, inHeap: TRUE,
               feedback: password];
          items[2] ← StringItem[
               tag: "Domain"L, place: newLine, string: @toolData.domainName,
               inHeap: TRUE];
          items[3] ← StringItem[
               tag: "Organization"L, string: @toolData.organizationName,
               inHeap: TRUE];
          items[4] ← EnumeratedItem[
               tag: "File Server"L, z: Heap.systemZone, feedback: all,
               value: @toolData.fileServer, copyChoices: TRUE,
               proc: ServerNotifyProc, choices: DESCRIPTOR[serverForm]];
          items[5] ← StringItem[
               tag: "NSLisp"L, place: newLine, string: @toolData.NSLisp,
               inHeap: TRUE];
          items[6] ← StringItem[
               tag: "PUPLisp"L, place: newLine, string: @toolData.PUPLisp,
               inHeap: TRUE];

          SetTagPlaces[items, DESCRIPTOR[tabs], FALSE];
          RETURN[items, TRUE]
          END;



     MakeSWs: Tool.MakeSWsProc =
          BEGIN
          logName: STRING ← [40];
          addresses: ARRAY [0..4) OF ToolDriver.Address;

          Tool.UnusedLogName[unused: logName, root: "SetProfile.log"L];
          toolData.msgSW ← Tool.MakeMsgSW[window: window, lines: 1];
          toolData.paramSW ← Tool.MakeFormSW[window: window, formProc: MakeParams];
          toolData.commandSW ← Tool.MakeFormSW[
               window: window, formProc: MakeCommands];
          toolData.fileSW ← Tool.MakeFileSW[window: window, name: logName];
          Supervisor.AddDependency[client: agent, implementor: Event.toolWindow];

          -- do the ToolDriver stuff
          addresses ← [
               [name: "msgSW"L, sw: toolData.msgSW], [
               name: "ParamSW"L, sw: toolData.paramSW], [
               name: "CmdSW"L, sw: toolData.commandSW], [
               name: "fileSW"L, sw: toolData.fileSW]];
          ToolDriver.NoteSWs[
               tool: "SetProfile"L, subwindows: DESCRIPTOR[addresses]];

          END;



     MakeTool: PROCEDURE RETURNS [wh: Window.Handle] =
          BEGIN

          String.AppendString[heraldName, "XSIS:Xerox Profile Tool "L];
          String.AppendString[heraldName, " of "L];
          Time.Append[heraldName, Time.Unpack[Runtime.GetBcdTime[]]];
          heraldName.length ← heraldName.length - 3;
          String.AppendString[heraldName, " on Pilot Version "L];
          Version.Append[heraldName];

          RETURN[
               Tool.Create[
                    makeSWsProc: MakeSWs, initialState: default,
                    clientTransition: ClientTransition, name: heraldName,
                    tinyName1: "Profile"L, tinyName2: "Tool"L]]
          END;




     MakeUserCM: PUBLIC PROCEDURE[] =
          BEGIN

          name: LONG STRING ← "User.cm"L;
          myFile: MFile.Handle ← NIL;
          --readS: MStream.Handle ← NIL;
          writeS: MStream.Handle ← NIL;

          IF debug THEN {
               Put.Line[toolData.fileSW, "Enter MakeUserCM..."L];
               Process.Pause[Process.SecondsToTicks[5]];
               };
          IF ~MFile.ValidFilename[name] THEN {
               Put.Line[toolData.msgSW, "Invalid file name"L]; RETURN; };

          IF debug THEN {
               Put.Line[toolData.fileSW, "Acquire..."L];
               Process.Pause[Process.SecondsToTicks[5]];
               };
          myFile ← MFile.Acquire[
               name, anchor, MFile.dontRelease !
               MFile.Error => {myFile ← NIL; CONTINUE}];

          IF debug THEN {
               Put.Line[toolData.fileSW, "Set hourGlass..."L];
               Process.Pause[Process.SecondsToTicks[5]];
               };
          Cursor.Set[hourGlass];
          --IF myFile # NIL THEN MFile.Release[myFile];

          BEGIN
          ENABLE MFile.Error => GOTO problem;
          --ENABLE MFile.Error  => {MFile.Release[myFile]; CONTINUE;};

          IF myFile # NIL THEN
               BEGIN
               IF debug THEN {
                    Put.Line[toolData.fileSW, "SetAccess..."L];
                    Process.Pause[Process.SecondsToTicks[5]];
                    };
               MFile.SetAccess[myFile, readWrite];
               END
          ELSE
               BEGIN
               IF debug THEN {
                    Put.Line[toolData.fileSW, "ReadWrite..."L];
                    Process.Pause[Process.SecondsToTicks[5]];
                    };
               myFile ← MFile.ReadWrite[name, MFile.dontRelease, text];
               END;

          --myFile ← MFile.ReadWrite[name, MFile.dontRelease, text];
          -- myFile is ReadWrite so can Copy handle with read later
          IF debug THEN {
               Put.Line[toolData.fileSW, "Create..."L];
               Process.Pause[Process.SecondsToTicks[5]];
               };
          writeS ← MStream.Create[myFile, []];

          IF debug THEN {
               Put.Line[toolData.fileSW, "SetLength..."L];
               Process.Pause[Process.SecondsToTicks[5]];
               };
          MStream.SetLength[writeS, 0];

          IF debug THEN {
               Put.Line[toolData.fileSW, "fileServer..."L];
               Process.Pause[Process.SecondsToTicks[5]];
               };
          IF toolData.fileServer = NS THEN
               toolData.fileServerProtocol ← String.CopyToNewString[
                    s: "NS"L, z: Heap.systemZone]
          ELSE
               toolData.fileServerProtocol ← String.CopyToNewString[
                    s: "IFS"L, z: Heap.systemZone];

          writeS.PutString["[User.cm]\n"];
          writeS.PutString["[System]\n"];
          writeS.PutString["User: "];
          writeS.PutString[toolData.userName];
          writeS.PutString["\n"];
          writeS.PutString["Password: "];
          writeS.PutString[toolData.password];
          writeS.PutString["\n"];
          writeS.PutString["Domain: "];
          writeS.PutString[toolData.domainName];
          writeS.PutString["\n"];
          writeS.PutString["Organization: "];
          writeS.PutString[toolData.organizationName];
          writeS.PutString["\n"];
          writeS.PutString["fileServerProtocol: "];
          writeS.PutString[toolData.fileServerProtocol];
          writeS.PutString["\n"];
          writeS.PutString["NSLisp: "];
          writeS.PutString[toolData.NSLisp];
          writeS.PutString["\n"];
          writeS.PutString["PUPLisp: "];
          writeS.PutString[toolData.PUPLisp];
          writeS.PutString["\n"];
          writeS.PutString["Screen: White\n"];
          writeS.PutString["Debug: No\n"];
          writeS.PutString["[Diagnostics:System]\n"];
          writeS.PutString["InitialCommand: InstallLispTool\n"];

          IF debug THEN {
               Put.Line[toolData.fileSW, "SendNow..."L];
               Process.Pause[Process.SecondsToTicks[5]];
               };
          writeS.SendNow;

          IF debug THEN {
               Put.Line[toolData.fileSW, "CopyFileHandle..."L];
               Process.Pause[Process.SecondsToTicks[5]];
               };
          myFile ← MFile.CopyFileHandle[
               MStream.GetFile[writeS], MFile.dontRelease, readOnly];

          IF debug THEN {
               Put.Line[toolData.fileSW, "Delete..."L];
               Process.Pause[Process.SecondsToTicks[5]];
               };
          EXITS
               problem => {
                    IF debug THEN Put.Line[toolData.fileSW, "problem..."L];

                    IF myFile # NIL THEN
                         BEGIN
                         Put.Line[toolData.msgSW, "Error in auquiring file"L];
                         MFile.Release[myFile];
                         END;
                    }
          END;
          writeS.Delete;
          IF myFile # NIL THEN MFile.Release[myFile];

          Cursor.Set[textPointer];
          Put.Line[toolData.fileSW, " Done"L];
          END;  --MakeUserCM



     ProcessUserDotCM: PROCEDURE =
          BEGIN
          CMOption: TYPE = MACHINE DEPENDENT{
               Domain, User, Password, NSFile, IFSFile, Protocol, Org,
               noMatch(StringLookUp.noMatch)};
          DefinedOption: TYPE = CMOption [Domain..Org];
          cmOptionTable: ARRAY DefinedOption OF LONG STRING ← [
               Domain: "Domain"L, User: "User"L, Password: "Password"L,
               Org: "Organization"L, NSFile: "NSLisp"L, IFSFile: "PUPLisp"L,
               Protocol: "FileServerProtocol"L];
          cmIndex: CMOption;

          CheckType: PROCEDURE [h: CmFile.Handle, table: StringLookUp.TableDesc]
               RETURNS [index: CARDINAL] = CmFile.NextValue;

          MyNextValue: PROCEDURE [
               h: CmFile.Handle,
               table: LONG DESCRIPTOR FOR ARRAY DefinedOption OF LONG STRING]
               RETURNS [index: CMOption] = LOOPHOLE[CheckType];

          cmFile: CmFile.Handle ← CmFile.UserDotCmOpen[
               ! CmFile.Error => IF code = fileNotFound THEN GOTO return];

          IF CmFile.FindSection[cmFile, "System"L] THEN
               DO
                    SELECT
                    (cmIndex ← MyNextValue[
                         h: cmFile, table: DESCRIPTOR[cmOptionTable] !
                         CmFile.TableError => RESUME ]) FROM
                         noMatch => EXIT;

                         User =>
                              BEGIN
                              value: LONG STRING = Token.Item[cmFile];
                              toolData.userName ← String.CopyToNewString[
                                   s: value, z: Heap.systemZone];
                              [] ← Token.FreeTokenString[value];
                              END;

                         Password =>
                              BEGIN
                              value: LONG STRING = Token.Item[cmFile];
                              toolData.password ← String.CopyToNewString[
                                   s: value, z: Heap.systemZone];
                              [] ← Token.FreeTokenString[value];
                              END;

                         Domain =>
                              BEGIN
                              value: LONG STRING = Token.Item[cmFile];
                              toolData.domainName ← String.CopyToNewString[
                                   s: value, z: Heap.systemZone];
                              [] ← Token.FreeTokenString[value];
                              END;

                         Org =>
                              BEGIN
                              value: LONG STRING ← Token.Item[cmFile];
                              toolData.organizationName ← String.CopyToNewString[
                                   s: value, z: Heap.systemZone];
                              [] ← Token.FreeTokenString[value];
                              END;

                         NSFile =>
                              BEGIN
                              value: LONG STRING ← Token.Item[cmFile];
                              Put.Line[toolData.fileSW, value];
                              toolData.NSLisp ← String.CopyToNewString[
                                   s: value, z: Heap.systemZone];
                              [] ← Token.FreeTokenString[value];
                              END;

                         IFSFile =>
                              BEGIN
                              value: LONG STRING ← Token.Item[cmFile];
                              toolData.PUPLisp ← String.CopyToNewString[
                                   s: value, z: Heap.systemZone];
                              [] ← Token.FreeTokenString[value];
                              END;

                         Protocol =>
                              BEGIN
                              value: LONG STRING ← Token.Item[cmFile];
                              IF String.Equivalent[value, "NS"] THEN
                                   toolData.fileServer ← NS
                              ELSE toolData.fileServer ← IFS;
                              [] ← Token.FreeTokenString[value];
                              END;


                         ENDCASE;
                    ENDLOOP;

          [] ← CmFile.Close[cmFile];
          EXITS return => NULL;
          END;  --ProcessUserDotCM




     ProfileExec: Exec.ExecProc =
          BEGIN
          execWrite: Format.StringProc ← Exec.OutputProc[h];
          --execWrite["Creating tool window.."L]; 
          --Process.Pause[Process.SecondsToTicks[5]];
          IF (profileWindow # NIL) AND ~active THEN
               ToolWindow.Activate[profileWindow]
          ELSE profileWindow ← MakeTool[];
          END;  --ProfileExec




     ProfileToolActivate: PUBLIC PROCEDURE =
          BEGIN
          IF profileWindow = NIL THEN profileWindow ← MakeTool[];
          ToolWindow.Activate[profileWindow];
          Window.Stack[
               profileWindow, Window.GetChild[Window.GetParent[profileWindow]]];  -- top me
          Window.ValidateTree[];
          END;  --ProfileToolActivate


     ServerNotifyProc: FormSW.EnumeratedNotifyProcType =
          BEGIN
          IF debug THEN {
               Put.Line[toolData.fileSW, "ServerNotifyProc...."L];
               Process.Pause[Process.SecondsToTicks[5]];
               };

          --DisplayFile[];
          END;  --ServerNotifyProc


     Unload: Exec.ExecProc =
          BEGIN
          IF profileWindow # NIL THEN Tool.Destroy[profileWindow];
          profileWindow ← NIL;
          [] ← Exec.RemoveCommand[h, "SetProfile.~"L];
          END;


     ---- ---- ---- ---- ---- ---- ---- ---- ----  --
     -- Mainline code

     Init[];

     END...