// Print RTF files from the command line
// (without a connection to the Window Server!)
// Eric P. Scott, San Francisco State University, November 1993
// + for NS 2.1 and 3.1
// cc -o rtf2ps -s -O rtf2ps.m -lNeXT_s

/*
 * enhanced to handle multiple files (both .rtf and .rtfd)
 * and to emit postscript to stdout instead of printing it.
 *
 * Steve Hayman
 * February  1994
 * shayman@Objectario.com
 */
 

#ifdef NX_COMPILER_RELEASE_3_0
#include <ansi/stdio.h>
#import <defaults/defaults.h>
#else
#include <stdio.h>
#import <appkit/defaults.h>
#endif
#import <streams/streams.h>
#import <objc/Object.h>
#import <objc/Storage.h>
#import <appkit/PrintInfo.h>
#import <appkit/Text.h>
#import <dpsclient/dpsclient.h>
#import <dpsclient/psops.h>

@interface FakeApp:Object
{
    id	_focusStack;
    id	printInfo;
}

+ initialize;
- init;
- printInfo;
- (BOOL)shouldRunPrintPanel:aView;
- (const char *)appName;
- (const char *const *)systemLanguages;
- _focusStack;
- (DPSContext)context;
#ifdef NX_COMPILER_RELEASE_3_0
- (BOOL)_calibratedColorOK;
#endif

@end

@implementation FakeApp

+ initialize
{
    static NXDefaultsVector PRDefaults = {
	{ "NXFont", "Helvetica" },
	{ "NXFontSize", "12" },
	{ "NXMargins", "72 72 90 90" },
	{ "NXPaperType", "Letter" },
#ifdef NX_COMPILER_RELEASE_3_0
	{ "NXBoldSystemFonts", "Helvetica" },
	{ "NXSystemFonts", "Helvetica-Bold" },
#endif
        { (char *)NULL, (char *)NULL }
    };
    NXRegisterDefaults("rtf2ps", PRDefaults);
    return self;
}
 
- init
{
    [super init];
    _focusStack=[[Storage allocFromZone:[self zone]]
	initCount:0 elementSize:10 description:"@*c"];
    return self;
}

- printInfo
{
    if (!printInfo) printInfo=[[PrintInfo allocFromZone:[self zone]] init];
    return printInfo;
}

- (BOOL)shouldRunPrintPanel:aView
{
    return NO;
}

- (const char *)appName
{
    return "rtf2ps";
}

- (const char *const *)systemLanguages
{
    return (const char *const *)NULL;
}

- _focusStack
{
    return _focusStack;
}

- (DPSContext)context
{
    return (DPSContext)NULL;
}

#ifdef NX_COMPILER_RELEASE_3_0
- (BOOL)_calibratedColorOK
{
    return YES;
}
#endif


@end

@interface Text(printrtf)

- (BOOL)lockFocus;
- unlockFocus;
- (BOOL)getVisibleRect:(NXRect *)theRect;
#ifndef NX_COMPILER_RELEASE_3_0
- beginPSOutput;
#endif
- display:(const NXRect *)rects :(int)rectCount :(BOOL)clipFlag;
- spoolFile:(const char *)filename;

@end

@implementation Text(printrtf)

- (BOOL)lockFocus
{
    return (NXDrawingStatus==NX_PRINTING) ? NO : [super lockFocus];
}

- unlockFocus
{
    return (NXDrawingStatus==NX_PRINTING) ? self : [super unlockFocus];
}

- (BOOL)getVisibleRect:(NXRect *)theRect
{
    if (NXDrawingStatus!=NX_PRINTING) return [super getVisibleRect:theRect];
    [self getBounds:theRect];
    return YES;
}

#ifndef NX_COMPILER_RELEASE_3_0
- beginPSOutput
{
    extern id NXApp;

    [[NXApp printInfo] setPageOrder:NX_ASCENDINGORDER];
    return [super beginPSOutput];
}
#endif

- display:(const NXRect *)rects :(int)rectCount :(BOOL)clipFlag
{
    if (NXDrawingStatus!=NX_PRINTING)
	return [super display:rects:rectCount:clipFlag];
    PSgsave();
    PStranslate(0.0, -frame.size.height+
	(rects[0].size.height+rects[0].origin.y)*2.0);
    PSscale(1.0, -1.0);
    [self drawSelf:rects:rectCount];
    PSgrestore();
    return self;
}

- spoolFile:(const char *)filename
{
    extern id NXApp;
    id pi;
    const char *pn;
    int cp;
    char cmd[256];
    
    pi=[NXApp printInfo];
    (void)strcpy(cmd, "exec lpr");
#ifdef NX_COMPILER_RELEASE_3_0
    if ((pn=[[pi printer] name])&&*pn) {
#else
    if ((pn=[pi printerName])&&*pn) {
#endif
	(void)strcat(cmd, " -P");
	(void)strcat(cmd, pn);
    }
    if ((cp=[pi copies])>1) (void)sprintf(&cmd[strlen(cmd)], " -#%d", cp);
    (void)strcat(cmd, " -r -s ");
    (void)strcat(cmd, filename);
    
    /*
     * forget all that, just ship it to stdout ...sah 
     */
    sprintf(cmd, "cat %s", filename);
    (void)system(cmd);	/* really should check status here! */
    return self;
}


@end

main(int argc, char *argv[])
{
    extern id NXApp;
    register int i;
    NXStream *f;
    Text *t;
    int errs;
    NXRect fr;
    char *streambuf;
    int len, maxlen;
    id pi;
    char path[24];

    errs=0;
    [Text excludeFromServicesMenu:YES];
    NXApp=[[FakeApp alloc] init];
    pi=[NXApp printInfo];
    [pi setHorizCentered:NO];
    [pi setVertCentered:NO];
#ifdef NX_COMPILER_RELEASE_3_0
    [pi setReversePageOrder:YES];
#endif
    for (i=1;i<argc;i++) {
	const NXSize large={ 504.0, 1.0e38 };
	char *extension;
	char *rindex();
	BOOL isRTFD;
	

	extension = rindex( argv[i], '.' );
	
	isRTFD = (extension && (strcmp(extension, ".rtfd") == 0));
		    
	
    	if (!isRTFD && !(f=NXMapFile(argv[i], NX_READONLY))) {
	    perror(argv[i]);
	    errs++;
	    continue;
	}
	
	if ( !isRTFD )
	    NXGetMemoryBuffer(f, &streambuf, &len, &maxlen);
	NXSetRect(&fr, 0.0, 0.0, 504.0, 21.0);
	t=[[Text alloc] initFrame:&fr];
	[t setMaxSize:&large];
	[t setVertResizable:YES];
	if ( isRTFD ) {
	    [t setMonoFont:NO];
	    [t openRTFDFrom:argv[i]];
	} else if (streambuf&&!strncmp(streambuf, "{\\rtf0\\", 7)) {
	    [t setMonoFont:NO];
	    [t readRichText:f];
	}
	else [t readText:f];
	[t sizeToFit];
	(void)strcpy(path, "/tmp/.printrtfXXXXXX.ps");
	(void)NXGetTempFilename(path, 14);
	[pi setOutputFile:path];

#if 0
	if ( isRTFD ){
	    NXStream *s = NXOpenMemory(NULL, 0L, NX_READWRITE);
	    int c;
	    [t writeRTFDTo:s];
	    NXSeek(s, 0L, NX_FROMSTART);
	    while ((c = NXGetc(s)) >= 0 ) 
		printf("%c",c);
	}
#endif
	[t printPSCode:NXApp];
	unlink( path );	// sah
	
	    
	if ( !isRTFD )
	    NXCloseMemory(f, NX_FREEBUFFER);
    }
    exit(errs);
}
