#include  "defs.h"
#include  <devices/parallel.h>
#include  <exec/devices.h>

Prototype           BOOL  is_nec(void);
Prototype __regargs BOOL  init_par(PE *);   /* send printer setup codes */
Prototype           void  close_prt(void);  /* close prt:  */
Prototype           BOOL  init_prt(void);

Prototype FH *prt;       /* prt:    */

FH    *prt;              /* prt:    */


/***********************  get_prefs()  **************************/

const UBYTE nec_pin[] = "Nec_Pinwriter";

BOOL
is_nec(void)
{
  SHORT nec = TRUE;
  PREF *prefs;
  if  (prefs  = (PREF *)AllocMem(sizeof(PREF), MPC))
  {
    GetPrefs(prefs, sizeof(PREF));

    if  (!(stricmp(prefs->PrinterFilename, nec_pin) == 0))
      nec = FALSE;

    FreeMem(prefs, sizeof(PREF));
  }
  else
  {
    quit  = TRUE;
    autom = TRUE;
  }

  return (nec);
}

/***********************  init_prt(void)  ****************************/
const UBYTE printerror[] = "***Error : can't access printer !";
const UBYTE prtstr[]     = "prt:";

BOOL
init_prt(void)
{
  if (!prt)
    if (!(prt = (FH *) Open(prtstr, MODE_NEWFILE)))
    {
      do_request(printerror, resume, 0);
      return (FALSE);                   /* no printer  */
    }
  return (TRUE);
}

/***********************  close_prt(void)  **************************/
void
close_prt(void)
{
  Close(prt);
  prt = NULL;
}

/***********************  init_par(PE *)  **************************/

                    /* RESET USA      */
#define RESET       "\x1C\x40\x1B\x52\x00"
#define SIXSIX      "\x1B\x32"
#define EIGHTEIGHT  "\x1B\x30"
                    /* PICA  NLQ LM RM */
#define EIGHTZERO   "\x1B\x50\x1B\x78\x01\x1B\x6C\x00\x1B\x51\x50"
                    /* ELITE DRAFT LM RM FAST */
#define NINESIX     "\x1B\x4D\x1B\x78\x00\x1B\x6C\x10\x1B\x51\x60\x1C\x53\x01"
                    /* COND DRAFT LM RM */
#define ONETHREETWO "\x1B\x50\x0F\x1B\x78\x00\x1B\x6C\x20\x1B\x51\x90"


const UBYTE parname[]     = "parallel.device";
const UBYTE erroronline[] = "***Error : printer not online !";
const UBYTE retry[]       = "retry";

const UBYTE reset[]       = RESET;
const UBYTE *lines[2]     = { SIXSIX, EIGHTEIGHT };
const UBYTE *chars[3]     = { EIGHTZERO, NINESIX, ONETHREETWO };

__regargs BOOL
init_par(PE *pe)
{
  if (prt)                              /* otherwise gurus !   */
    close_prt();

  struct MsgPort  *pardev_port = NULL;
  struct IOExtPar *pardev_req  = NULL;
  BOOL   init = FALSE;

  if (pardev_port = (struct MsgPort *) CreatePort(NULL, NULL))
  {
    if (pardev_req = (struct IOExtPar *) CreateExtIO(pardev_port,
                                                sizeof(struct IOExtPar)))
    {
      if (!(init = OpenDevice(parname, NULL, pardev_req, NULL)))
      {
        for (int i = 1; i <= 3; ++i)       /* three times request "online" */
        {
          pardev_req->IOPar.io_Command = PDCMD_QUERY;   /* is it online ?? */
          DoIO(pardev_req);
                                        /* must be selected and not busy */
          if ((((UBYTE) pardev_req->io_Status & (UBYTE) IOPTF_PARSEL) ==
               (UBYTE) IOPTF_PARSEL) &&
              (((UBYTE) pardev_req->io_Status & (UBYTE) IOPTF_PARBUSY) !=
               (UBYTE) IOPTF_PARBUSY))
          {
            pardev_req->IOPar.io_Command = CMD_WRITE;
            for (int com = 1; com <= 3; ++com)    /*  collect command string  */
            {
              switch(com)
              {
              case 1:
                pardev_req->IOPar.io_Data   = reset;
                pardev_req->IOPar.io_Length = 5;
                break;

              case 2:
                pardev_req->IOPar.io_Data   = lines[pe->pagesize];
                pardev_req->IOPar.io_Length = 2;
                break;

              case 3:
                pardev_req->IOPar.io_Data   = chars[pe->linelength];
                if ((pe->linelength == 1) && is_nec()) /* highspeed */
                  pardev_req->IOPar.io_Length = 14;
                else
                {
                  if (pe->linelength == 2)
                    pardev_req->IOPar.io_Length = 12;
                  else
                    pardev_req->IOPar.io_Length = 11;
                }

              default:
                break;
              }               /*  switch com */

              DoIO(pardev_req);
              Delay(10);      /*  wait for mechanicsm */
            }                 /*  ... end of for (com) loop  */
            init = TRUE;
            break;            /*  ... out of for (i) loop */
          }
          else
            do_request(erroronline, retry, 0);
        }                     /*  ... end of for (i) loop */
        CloseDevice(pardev_req);
      }
      DeleteExtIO(pardev_req);
    }
    DeletePort(pardev_port);
  }
  return (init);
}


