/* $Id: render.c,v 1.2 1993/06/11 16:29:21 Rhialto Exp $
 * $Log: render.c,v $
 * Revision 1.2  1993/06/11  16:29:21  Rhialto
 * First real RCS checkin
 *
 */

/*
 *  RENDER.C
 *
 *  David Berezowski - March/88.
 *  Modified for DICE - May/91	Matthew Dillon
 *  Modified for ElCheapoFax April 1993 Olaf 'Rhialto' Seibert.
 *
 *  Copyright (c) 1988  Commodore-Amiga, Inc.
 *  (c)Copyright 1991 Matthew Dillon
 *  (c)Copyright 1993 Olaf Seibert
 */

#include <string.h>
#include <devices/printer.h>
#include <devices/prtbase.h>
#include <intuition/preferences.h>

#include "faxdefs.h"

#include <stdio.h>

extern struct PrinterData* PD;
extern struct PrinterExtendedData* PED;

extern void Transfer(PrtInfo *, UWORD, UBYTE *);
extern void OpenFaxFile(int);
extern void CloseFaxFile(void);
extern int endPageOnClose(void);
extern void setStatus(char*);
extern void setFileName(char*);

void finalizeDoChar(void);

char* pd_PrintBuf = 0;

int NoFormFeed;
int ped_NumRows = 16;
int currentPage = 1;
int FaxFine = 1;

void *FaxHandle = 0;

long Render(long ct, long x, long y, long status) {
    static long LineBufSize, TotalBufSize;
    static int XSize;

    long err;

    err = PDERR_NOERR;

    switch(status) {
    case 5: /* Pre-Master Initialization */
	/*
	 *	ct	- 0 or pointer to IODRPReq structure.
	 *	x	- io_Special flag from IODRPReq.
	 *	y	- 0.
	 */

	/* select density */
      /* SetDensity(x & SPECIAL_DENSITYMASK);*/
//      printf("Pre-Master Init\n");
	break;
    case 0:	/* Master Initialization */
	/*
	 *	ct	- pointer to IODRPReq structure.
	 *	x	- width of printed picture in pixels.
	 *	y	- height of printed picture in pixels.
	 */
	XSize = x;
	if (XSize != LINE_BITS) {
	    XSize = LINE_BITS;
	}
	NoFormFeed = (((struct IODRPReq *)ct)->io_Special & SPECIAL_NOFORMFEED)
		     != 0;
	pd_PrintBuf = NULL;

	LineBufSize = (XSize + 7) / 8;
	TotalBufSize = PED->ped_NumRows * LineBufSize;
	pd_PrintBuf = AllocMem(TotalBufSize, MEMF_PUBLIC);
	if (pd_PrintBuf == NULL) {
	  err = PDERR_BUFFERMEMORY;
	  break;
	}
	break;
    case 1: /* Scale, Dither and Render */
	    /*
	     *	    ct	    - pointer to PrtInfo structure.
	     *	    x	    - 0.
	     *	    y	    - row # (0 to Height - 1).
	     */
#define pi ((struct PrtInfo *)ct)
	if (pi->pi_xpos >= XSize) {
	    pi->pi_xpos = 0;
	}
	Transfer((struct PrtInfo *)ct, y, pd_PrintBuf + LineBufSize * (y % PED->ped_NumRows));
	break;
    case 2: /* Dump Buffer to Printer */
	/*
	 *	ct	- 0.
	 *	x	- 0.
	 *	y	- # of rows sent (1 to peMd_NumRows).
	 */
	{
	    int 	    offset;

	    if (!FaxHandle) {
	      /* only open fax file when someone tries to write to it */
	      OpenFaxFile(0);
	    }

	    if (FaxHandle) {
	      for (offset = 0; y > 0; offset += LineBufSize, y--) {
		tofax(FaxHandle, pd_PrintBuf + offset, XSize);
	      }
	    }
	}
	break;
    case 3:	/* Clear and Init Buffer */
	/*
	 *	ct	- 0.
	 *	x	- 0.
	 *	y	- 0.
	 */
	memset(pd_PrintBuf, 0, TotalBufSize);
	break;
    case 4: /* Close Down */
	/*
	 *	ct	- error code.
	 *	x	- io_Special flag from IODRPReq.
	 *	y	- 0.
	 */

	if (pd_PrintBuf != NULL) {
	    FreeMem(pd_PrintBuf, TotalBufSize);
	    pd_PrintBuf = NULL;
	}
        if (endPageOnClose()) {
	  CloseFaxFile();
	} else {
	  setStatus("Render Closed"); 
	}
	break;
    }
    return(err);
}

char lastFaxFile[256];
#define ESC	    "\33"
#define CSI	    "\233"

void OpenFaxFile(int startFromTextPrint) {
    char tmp[256];
    FILE* seq;
    static int sequence;
    char* filename = tmp;

    if (currentPage == 1) {
      /* only do these things once per session -- as signified by
	 an open printer */

      sequence = 1;

      seq = fopen("faxout:seq", "r");
      if (seq) {
	fscanf(seq, "%d", &sequence);
	fclose(seq);
      }
      
      sprintf(lastFaxFile, "fax%d", sequence);

      /* update sequence */
      seq = fopen("faxout:seq", "w");
      if (seq) {
	sequence++;
	fprintf(seq, "%d", sequence);
	fclose(seq);
      } else {
	/* danger!  couldn't write to sequence file! */
      }
    }

    sprintf(filename, "faxout:%s.%03d", lastFaxFile, currentPage);
    setFileName(filename);

    if (startFromTextPrint) {
      if (PD->pd_Preferences.PrintQuality & LETTER) {
	FaxFine = 1;
	setStatus("Opened page for text (Fine)");
      } else {
	FaxFine = 0;
	setStatus("Opened page for text (Standard)");
      }
    } else {
      FaxFine = PED->ped_YDotsInch > Y_DPI/2;
      if (FaxFine)
	setStatus("Opened page for graphics (Fine)");
      else
	setStatus("Opened page for graphics (Standard)");
    }
//    printf("FaxFine = %d\n", FaxFine);

    if (filename)
	FaxHandle = faxout_open(filename, 0 /* 0 == output header */);
    if (FaxHandle) {
//      printf("Opened %s\n", filename);
      /* this is generated by a program, so it is *clean* */
      
      faxout_begin_page(FaxHandle, FaxFine, 0);
    }

    /* reset, set x offset */
    sprintf(tmp, ESC"c" CSI"%dx", 0);
    WinWrite(tmp);
    return;
}

void DeleteLastFaxFile(void) {
//  printf("Deleting last faxfile %s\n", lastFaxFile);
  unlink(lastFaxFile);
}

void CloseFaxFile(void) {
  finalizeDoChar();
  if (FaxHandle) {
    setFileName("");
    setStatus("Closed page");
//    printf("Closed %s\n", lastFaxFile);
    faxout_end_page(FaxHandle);
    faxout_close(FaxHandle);
    FaxHandle = NULL;
    currentPage++;
  }
}

