-- Copyright (C) Xerox Corporation 1984, 1985. All rights reserved.
-- TargetPSImpl.mesa
-- Last edited by Jacks 24-Sep-85 14:00:32

DIRECTORY
  NSDataStream USING [Aborted, Error, SourceStream],
  NSFile USING [
    Attributes, Error, GetAttributes, GetAttributesRecord, Handle, InterpretedSelections, nullTime, ReleaseAttributesRecord, Retrieve, Session, Time],
  NSPrint USING [
    Error, ErrorRecord, GetPrinterProperties, GetPrinterStatus, GetPrintRequestStatus, Print, PrintAttribute, PrintAttributeType, PrintAttributesIndex, PrinterProperties, PrinterStatus, PrintOption, PrintOptionType, PrintOptionsIndex, RequestStatus],
  NSString USING [nullString, String],
  MiscUtilities USING [NSPrintPaperToPaperTypes, PaperTypesToNSPrintPaper],
  PaperTypes USING [Paper],
  PaperTypesExtras USING [nullPaper],
  PrintQueue USING [Priority],
  PSVolume USING [GetDefaultSession],
  System USING [NetworkAddress, nullID, UniversalID],
  TargetPS,
  TargetPSStatus USING [Communication, Current, Properties, Request];

TargetPSImpl: PROGRAM
  IMPORTS NSDataStream, NSFile, NSPrint, MiscUtilities, PSVolume
  EXPORTS TargetPS =
  BEGIN

  
  Error: PUBLIC ERROR [why: TargetPSStatus.Communication] = CODE;
  

  -- PROCEDURES:
  
  GetPrinterProperties: PUBLIC PROCEDURE [target: System.NetworkAddress]
    RETURNS [properties: TargetPSStatus.Properties ← []] =
    BEGIN
    printerProperties: NSPrint.PrinterProperties ← 
      NSPrint.GetPrinterProperties [systemElement: target
        ! NSPrint.Error => RaiseTargetPSError[why]];
	
    FOR i: CARDINAL IN [0..LENGTH[printerProperties]) DO
      WITH printerProperties[i] SELECT FROM
	staple => properties.staple ← staple;
	twoSided => properties.twoSided ← twoSided;
        media => FOR mediaCount: CARDINAL IN [0..LENGTH[media]) DO 
	  WITH media[mediaCount] SELECT FROM
	    paper => SELECT mediaCount FROM
	      0 => properties.paperSupply.size1 ← MiscUtilities.NSPrintPaperToPaperTypes[paper].knownSize;
	      1 => properties.paperSupply.size2 ← MiscUtilities.NSPrintPaperToPaperTypes[paper].knownSize;
	      ENDCASE => NULL; --only recognize first two paper sizes
	    ENDCASE;
	  ENDLOOP;
	ENDCASE;
      ENDLOOP;
    
    END; --GetPrinterProperties
    
    
  GetPrinterStatus: PUBLIC PROCEDURE [target: System.NetworkAddress]
    RETURNS [status: TargetPSStatus.Current ← []] =
    BEGIN
    printerStatus: NSPrint.PrinterStatus ← NSPrint.GetPrinterStatus [
      systemElement: target ! NSPrint.Error => RaiseTargetPSError[why]];
	
    FOR statusType: CARDINAL IN [0..LENGTH[printerStatus]) DO
      WITH printerStatus[statusType] SELECT FROM
        spooler => status.spooler ← LOOPHOLE[spooler];
	formatter => status.formatter ← LOOPHOLE[formatter];
	printer => status.printer ← LOOPHOLE[printer];
	media => FOR mediaCount: CARDINAL IN [0..LENGTH[media]) DO 
	  WITH media[mediaCount] SELECT FROM
	    paper => SELECT mediaCount FROM
	      0 => status.paperSupply.size1 ← MiscUtilities.NSPrintPaperToPaperTypes[paper].knownSize;
	      1 => status.paperSupply.size2 ← MiscUtilities.NSPrintPaperToPaperTypes[paper].knownSize;
	      ENDCASE => NULL; --only recognize first two paper sizes
	    ENDCASE;
	  ENDLOOP;
	ENDCASE;
      ENDLOOP;
    END; --GetPrinterStatus
    
    
  GetPrintRequestStatus: PUBLIC PROCEDURE [
    printRequestID: System.UniversalID, target: System.NetworkAddress]
    RETURNS [requestStatus: TargetPSStatus.Request ← unknown] =
    BEGIN
    printRequestStatus: NSPrint.RequestStatus ← 
      NSPrint.GetPrintRequestStatus [
        printRequestID: printRequestID, systemElement: target
          ! NSPrint.Error => RaiseTargetPSError[why]];
    
    FOR i: CARDINAL IN [0..LENGTH[printRequestStatus]) DO
      WITH printRequestStatus[i] SELECT FROM
        status => requestStatus ← LOOPHOLE[status];
	ENDCASE;
      ENDLOOP;
    END; --GetPrintRequestStatus
    
    
  ForwardDocument: PUBLIC PROCEDURE [
    target: System.NetworkAddress,
    master: NSFile.Handle,
    docName: NSString.String ← NSString.nullString,
    sender: NSString.String ← NSString.nullString,
    recipient: NSString.String ← NSString.nullString,
    message: NSString.String ← NSString.nullString,
    paper: PaperTypes.Paper ← [],
    copies: CARDINAL ← 1,
    staple: BOOLEAN ← FALSE,
    twoSided: BOOLEAN ← FALSE,
    docCreateDate: NSFile.Time ← NSFile.nullTime,
    priority: PrintQueue.Priority ← normal,
    releaseKey: CARDINAL ← LAST[CARDINAL]
    ] RETURNS [printRequestID: System.UniversalID ← System.nullID] =
    BEGIN
    session: NSFile.Session = PSVolume.GetDefaultSession[];
    options: ARRAY NSPrint.PrintOptionsIndex OF NSPrint.PrintOption;
    attributes: ARRAY NSPrint.PrintAttributesIndex OF NSPrint.PrintAttribute;
    optionCounter: CARDINAL ← 0;
    attributeCounter: CARDINAL ← 0;
    
    SendData: PROCEDURE [sourceDS: NSDataStream.SourceStream] =
      BEGIN
      printRequestID ← NSPrint.Print [
        master: [stream[sourceDS]],
	printAttributes: DESCRIPTOR[BASE[attributes], attributeCounter],
	printOptions: DESCRIPTOR[BASE[options], optionCounter],
	systemElement: target
	! NSPrint.Error => RaiseTargetPSError[why];
          NSDataStream.Aborted => ERROR Error [transferAborted];
	  NSDataStream.Error => ERROR Error [transferError];
	  NSFile.Error => WITH error SELECT FROM
	    transfer => SELECT problem FROM
	      aborted => ERROR Error [transferAborted];
	      ENDCASE => ERROR Error [transferError];
	    ENDCASE => ERROR;
	  ];
      END; --SendData
      
    FOR o: NSPrint.PrintOptionType IN NSPrint.PrintOptionType DO
      SELECT o FROM
        printObjectSize => BEGIN
          attribute: NSFile.Attributes ← NSFile.GetAttributesRecord[];
          selections: NSFile.InterpretedSelections;
          selections[dataSize] ← TRUE;
          NSFile.GetAttributes [master, [interpreted: selections], attribute, session
            ! NSFile.Error => GOTO NoPrintObjectSize];
	  options[optionCounter] ← [printObjectSize[attribute.dataSize]];
	  NSFile.ReleaseAttributesRecord[attribute];
	  optionCounter ← optionCounter + 1;
	  EXITS NoPrintObjectSize => NULL;
	  END;
	recipientName => IF recipient # NSString.nullString THEN BEGIN
	  options[optionCounter] ← [recipientName[recipient]];
	  optionCounter ← optionCounter + 1;
	  END;
	message => IF message # NSString.nullString THEN BEGIN
	  options[optionCounter] ← [message[message]];
	  optionCounter ← optionCounter + 1;
	  END;
	copyCount => BEGIN
	  options[optionCounter] ← [copyCount[copies]];
	  optionCounter ← optionCounter + 1;
	  END;
	pagesToPrint => BEGIN
	  options[optionCounter] ← [pagesToPrint[[beginningPageNumber: 1, endingPageNumber: LAST[CARDINAL]]]];
	  optionCounter ← optionCounter + 1;
	  END;
	mediumHint => IF NOT paper = PaperTypesExtras.nullPaper THEN BEGIN
	  options[optionCounter] ← [mediumHint[[paper[
	    MiscUtilities.PaperTypesToNSPrintPaper[paper]]]]];
	  optionCounter ← optionCounter + 1;
	  END;
	priorityHint => BEGIN
	  options[optionCounter] ← [priorityHint[LOOPHOLE[priority]]];
	  optionCounter ← optionCounter + 1;
	  END;
	releaseKey => IF releaseKey # LAST[CARDINAL] THEN BEGIN
	  options[optionCounter] ← [releaseKey[releaseKey]];
	  optionCounter ← optionCounter + 1;
	  END;
	staple => IF staple THEN BEGIN
	  options[optionCounter] ← [staple[TRUE]];
	  optionCounter ← optionCounter + 1;
	  END;
	twoSided => IF twoSided THEN BEGIN
	  options[optionCounter] ← [twoSided[TRUE]];
	  optionCounter ← optionCounter + 1;
	  END;
	ENDCASE;
      ENDLOOP;
      
    FOR a: NSPrint.PrintAttributeType IN NSPrint.PrintAttributeType DO
      SELECT a FROM
        printObjectName => IF docName # NSString.nullString THEN BEGIN
	  attributes[attributeCounter] ← [printObjectName[docName]];
	  attributeCounter ← attributeCounter + 1;
	  END;
	printObjectCreateDate => IF docCreateDate # NSFile.nullTime THEN BEGIN
	  attributes[attributeCounter] ← [printObjectCreateDate[docCreateDate]];
	  attributeCounter ← attributeCounter + 1;
	  END;
	senderName => IF sender # NSString.nullString THEN BEGIN
	  attributes[attributeCounter] ← [senderName[sender]];
	  attributeCounter ← attributeCounter + 1;
	  END;
	ENDCASE;
      ENDLOOP;
	
    NSFile.Retrieve [file: master, sink: [proc[SendData]], session: session];
    END; --ForwardDocument
    
    
  -- Private procedures:
  
  RaiseTargetPSError: PROCEDURE [error: NSPrint.ErrorRecord] =
    BEGIN
    --Raises TargetPS.Error based on NSPrint.Error raised.
    WITH e: error SELECT FROM
      busy => ERROR Error [busy];
      insufficientSpoolSpace => ERROR Error [insufficientSpoolSpace];
      invalidPrintParameters => ERROR Error [systemError]; --implementation error
      masterTooLarge => ERROR Error [masterTooLarge];
      mediumUnavailable => ERROR Error [mediumUnavailable];
      serviceUnavailable => ERROR Error [serviceUnavailable];
      spoolingDisabled => ERROR Error [spoolingDisabled];
      spoolingQueueFull => ERROR Error [spoolingQueueFull];
      systemError => ERROR Error [systemError];
      tooManyClients => ERROR Error [tooManyClients];
      undefinedError => ERROR Error [undefinedError];
      connectionError => SELECT e.connection FROM
        noRoute => ERROR Error [noRouteToSystemElement];
	noResponse => ERROR Error [remoteSystemElementNotResponding];
	transmissionHardware => ERROR Error [transmissionMediumProblem];
	returnTimedOut => ERROR Error [returnTimedOut];
	parameterInconsistency, invalidMessage => ERROR Error [systemError]; --implementation error
	ENDCASE => ERROR Error [connectionError];
      transferError => ERROR Error [transferError];
      courier => SELECT e.courier FROM
        transmissionMediumHardwareProblem, transmissionMediumUnavailable,
	transmissionMediumNotReady => ERROR Error [transmissionMediumProblem];
	noRouteToSystemElement => ERROR Error [noRouteToSystemElement];
	remoteSystemElementNotResponding => ERROR Error [remoteSystemElementNotResponding];
	returnTimedOut => ERROR Error [returnTimedOut];
	streamNotYours, parameterInconsistency, 
	invalidArguments, invalidMessage => ERROR Error [systemError]; --implementation error
	ENDCASE => ERROR Error [courierError];
      ENDCASE => ERROR Error [undefinedError];
    END; --RaiseTargetPSError
    
  END. -- of TargesPSImpl
  
LOG when/who/what
26-Oct-84 10:49:36 - Jacks - Created.
31-Oct-84 13:24:57 - Jacks - Update to TargetPS type definitions.
 9-Nov-84 14:50:07 - Jacks - Updated to second round of 9.0 ps interfaces.
12-Dec-84 15:19:39 - Jacks - GetPrinterStatus returns TargetPS.Status instead of StatusTypes.TargetPrintService.
27-Feb-85 14:38:33 - Jacks - Corrected some of the errors raised in RaiseTargetPSError.
17-Jun-85 15:37:04 - Jacks - Added copyright notice; updated to PS Euclid interfaces.
17-Jul-85 15:13:56 - Jacks - Updated to Euclid Services interfaces.
 7-Aug-85 11:04:53 - Jacks - Made use of NSFile.GetAttributesRecord.
24-Sep-85 13:46:19 - Jacks - Changed to new MiscUtilities procs: NSPrintPaperToPaperTypes and PaperTypesToNSPrintPaper.