-- NSPrintAgentImpl.mesa
-- Copyright (C) 1985 by Xerox Corporation.  All rights reserved.
-- Bill Jackson, June 23, 1985 2:22:53 am PDT


DIRECTORY
  CedarNSPrintRpcControl,
  CedarNSPrintUtilsRpcControl,
  NSPrint,
  CedarNSPrint,
  CedarNSPrintUtils,

  AddressTranslation USING [Error, PrintError, StringToNetworkAddress],
  Filer USING [File],
  Format USING [StringProc],
  MStream USING [Copy, Error, Handle, ReadOnly],
  NSDataStream USING [Aborted, SinkStream],
  Stream USING [Delete, SetPosition];

NSPrintAgentImpl: MONITOR
  IMPORTS
    NSPrint, CedarNSPrintRpcControl, CedarNSPrintUtilsRpcControl,
    AddressTranslation, Filer, MStream, NSDataStream, Stream
  EXPORTS CedarNSPrint, CedarNSPrintUtils =
  BEGIN OPEN CedarNSPrint, CedarNSPrintUtils;

  -- This should be much more careful than this!

  error: PROCEDURE [x: NSPrint.ErrorRecord]
    RETURNS [y: CedarNSPrint.ErrorRecord] = {
    RETURN[LOOPHOLE[x, CedarNSPrint.ErrorRecord]]; };
  pa: PROCEDURE [x: PrintAttributes] RETURNS [y: NSPrint.PrintAttributes] = {
    RETURN[LOOPHOLE[x, NSPrint.PrintAttributes]]; };
  po: PROCEDURE [x: PrintOptions] RETURNS [y: NSPrint.PrintOptions] = {
    RETURN[LOOPHOLE[x, NSPrint.PrintOptions]]; };
  se: PROCEDURE [x: SystemElement] RETURNS [y: NSPrint.SystemElement] = {
    RETURN[LOOPHOLE[x, NSPrint.SystemElement]]; };
  cse: PROCEDURE [x: NSPrint.SystemElement] RETURNS [y: SystemElement] = {
    RETURN[LOOPHOLE[x, SystemElement]]; };
  rid: PROCEDURE [x: RequestID] RETURNS [y: NSPrint.RequestID] = {
    RETURN[LOOPHOLE[x, NSPrint.RequestID]]; };
  crid: PROCEDURE [x: NSPrint.RequestID] RETURNS [y: CedarNSPrint.RequestID] = {
    RETURN[LOOPHOLE[x, CedarNSPrint.RequestID]]; };
  pp: PROCEDURE [x: NSPrint.PrinterProperties]
    RETURNS [y: CedarNSPrint.PrinterProperties] = {
    RETURN[LOOPHOLE[x, CedarNSPrint.PrinterProperties]]; };
  ps: PROCEDURE [x: NSPrint.PrinterStatus]
    RETURNS [y: CedarNSPrint.PrinterStatus] = {
    RETURN[LOOPHOLE[x, CedarNSPrint.PrinterStatus]]; };
  rs: PROCEDURE [x: NSPrint.RequestStatus]
    RETURNS [y: CedarNSPrintUtils.RequestStatus] = {
    RETURN[LOOPHOLE[x, CedarNSPrint.RequestStatus]]; };

  Error: PUBLIC ERROR [why: ErrorRecord] = CODE;


  Print: PUBLIC PROCEDURE [
    master: Source, printAttributes: PrintAttributes,
    printOptions: PrintOptions, systemElement: SystemElement]
    RETURNS [printRequestID: RequestID] = {
    localStream: MStream.Handle;
    foo: NSPrint.RequestID;
    basename: LONG STRING = "$PrintAgent.tmp$";
    SendStream: PROCEDURE [sink: NSDataStream.SinkStream] = {
      [] ← MStream.Copy[
        from: localStream, to: sink, bytes: LAST[LONG CARDINAL] !
        NSDataStream.Aborted => CONTINUE;
        UNWIND => Stream.Delete[sink ! NSDataStream.Aborted => CONTINUE]];
      Stream.Delete[sink ! NSDataStream.Aborted => CONTINUE]};

    -- Here is where we have to FTP over the file from Cedar STPServer
    -- and open an appropriate stream (NSStream) on the local file

    Filer.File[from: master, to: basename];
    localStream ← MStream.ReadOnly[
      name: basename, release: [NIL, NIL] ! MStream.Error => {NULL}];
    foo ← NSPrint.Print[
      [proc[SendStream]], pa[printAttributes], po[printOptions], se[
      systemElement] !
      NSPrint.Error =>
        SELECT why.errorType FROM
          busy, tooManyClients => {
            Error[error[why]]; Stream.SetPosition[localStream, 0]; RETRY};
          spoolingDisabled => {
            Error[error[why]]; Stream.SetPosition[localStream, 0]; RETRY};
          ENDCASE => {Error[error[why]]}];

    RETURN[crid[foo]];
    };

  GetPrinterProperties: PUBLIC PROCEDURE [systemElement: SystemElement]
    RETURNS [properties: PrinterProperties] = {
    RETURN[pp[NSPrint.GetPrinterProperties[se[systemElement]]]]; };

  GetPrinterStatus: PUBLIC PROCEDURE [systemElement: SystemElement]
    RETURNS [status: PrinterStatus] = {
    RETURN[ps[NSPrint.GetPrinterStatus[se[systemElement]]]]; };

  GetPrintRequestStatus: PUBLIC PROCEDURE [
    printRequestID: RequestID, systemElement: SystemElement]
    RETURNS [status: RequestStatus] = {
    RETURN[
      rs[
        NSPrint.GetPrintRequestStatus[rid[printRequestID], se[systemElement]]]];
    };

  AddressTranslationStringToNetworkAddress: PUBLIC PROCEDURE [name: LONG STRING]
    RETURNS [systemElement: SystemElement, chUsed: BOOLEAN] = {
    element: NSPrint.SystemElement;
    cacheMiss: BOOLEAN;
    errorString: LONG STRING ← [128];
    stringProc: Format.StringProc = {errorString ← s};

    [element, cacheMiss] ← AddressTranslation.StringToNetworkAddress[
      name !
      AddressTranslation.Error => {
        AddressTranslation.PrintError[errorRecord, stringProc]}];
    RETURN[cse[element], cacheMiss];
    };

  FreeString: PUBLIC PROCEDURE [string: LONG POINTER] = {
    NSPrint.FreeString[string]; };

  FreeMedia: PUBLIC PROCEDURE [media: LONG POINTER] = {
    NSPrint.FreeMedia[media]; };

  FreePrinterProperties: PUBLIC PROCEDURE [printerProperties: LONG POINTER] = {
    NSPrint.FreePrinterProperties[printerProperties]; };

  FreePrinterStatus: PUBLIC PROCEDURE [printerStatus: LONG POINTER] = {
    NSPrint.FreePrinterStatus[printerStatus]; };

  FreeRequestStatus: PUBLIC PROCEDURE [requestStatus: LONG POINTER] = {
    NSPrint.FreeRequestStatus[requestStatus]; };

  Init: PROCEDURE = {
    CedarNSPrintRpcControl.ExportInterface[user: NIL, password: TRASH];
    CedarNSPrintUtilsRpcControl.ExportInterface[user: NIL, password: TRASH];
    };

  Init[];

  END. .. -- NSPrintAgentImpl.