/****************************************************************************
 *
 *        IFF_Printer driver.
 */

#include <exec/types.h>
#include <exec/nodes.h>
#include <exec/lists.h>
#include <exec/memory.h>
#include <devices/prtbase.h>
#include <devices/printer.h>
#include <iffp/packer.h>

#include <clib/exec_protos.h>

#include "task.h"

extern struct Library *AbsExecBase;

extern struct PrinterData *PD;
extern struct PrinterExtendedData *PED;
extern void SetDensity(ULONG);
extern void Transfer(struct PrtInfo *PInfo, UWORD y, BYTE *ptr, UWORD colors[]);
extern int SendMyMsg(int i);

#define MAXCOLORBUFS 3

void Eject(void);

	BYTE *PackBuf;
        UWORD BufSize, ColorSize;
        UBYTE *ptr;
	UWORD colors[MAXCOLORBUFS];

int Render(long ct, long x, long y, long status)
{
        int i, err;

        err=PDERR_NOERR;
        switch(status) {
                case 0 : /* Master Initialization */
                        /*
                                ct      - pointer to IODRPReq structure.
                                x       - width of printed picture in pixels.
                                y       - height of printed picture in pixels.
                        */
                        BufSize = ((PED->ped_MaxXDots + 15) / 16) * 2;
			ColorSize = BufSize;
			if (PD->pd_Preferences.PrintShade == SHADE_COLOR)
				BufSize *= 3;
			colors[0] = ColorSize * 0; /* Black or yellow */
			colors[1] = ColorSize * 1; /* Magenta */
			colors[2] = ColorSize * 2; /* Cyan */
                        PD->pd_PrintBuf = AllocMem(BufSize, MEMF_ANY);
                        if (PD->pd_PrintBuf == NULL) {
                                err = PDERR_BUFFERMEMORY; /* no mem */
                        }
                        else {
				PackBuf = AllocMem(MaxPackedSize(BufSize),
					MEMF_ANY);
				if (PackBuf == NULL) {
					err = PDERR_BUFFERMEMORY;
					FreeMem(PD->pd_PrintBuf, BufSize);
					PD->pd_PrintBuf = NULL;
				}
				else if (SendMyMsg(myCode_OpenFile)
					== NULL) err = PDERR_BUFFERMEMORY;
			}
                        break;

                case 1 : /* Scale, Dither and Render */
                        /*
                                ct      - pointer to PrtInfo structure.
                                x       - 0.
                                y       - row # (0 to Height - 1).
                        */
                        Transfer((struct PrtInfo *)ct, y, PD->pd_PrintBuf,
				colors);
                        err = PDERR_NOERR; /* all ok */
                        break;

                case 2 : /* Dump Buffer to Printer */
                        /*
                                ct      - 0.
                                x       - 0.
                                y       - # of rows sent (1 to NumRows).
                        */
			if (SendMyMsg(myCode_WriteLine) == NULL) {
				err = PDERR_CANCEL;
			}
                        break;

                case 3 : /* Clear and Init Buffer */
                        /*
                                ct      - 0.
                                x       - 0.
                                y       - 0.
                        */
                        ptr = PD->pd_PrintBuf;
                        i = BufSize;
                        do {
                                *ptr++ = 0;
                        } while (--i);
                        break;

                case 4 : /* Close Down */
                        /*
                                ct      - error code.
                                x       - io_Special flag from IODRPReq struct
                                y       - 0.
                        */
                        err = PDERR_NOERR; /* assume all ok */
                        /* if user did not cancel the print */
                        if (ct != PDERR_CANCEL) {
                        	/* if want to unload paper */
                        	if (!(x & SPECIAL_NOFORMFEED)) {
                        		/* eject paper */
					Eject();
                                }
                        }
                        if (PD->pd_PrintBuf != NULL) {
                                FreeMem(PD->pd_PrintBuf, BufSize);
                        }
			if (PackBuf != NULL) {
				FreeMem(PackBuf, MaxPackedSize(BufSize));
				PackBuf = NULL;
			}
                        break;

                case 5 : /* Pre-Master Initialization */
                        /*
                                ct      - 0 or pointer to IODRPReq structure.
                                x       - io_Special flag from IODRPReq struct
                                y       - 0.
                        */
                        /* select density */
                        SetDensity(x & SPECIAL_DENSITYMASK);
                        break;
        }
        return(err);
}

void Eject(void) {
	SendMyMsg(myCode_CloseFile);
}

