/****************************************************************/
/*                                                              */
/*           SayError package  -  version 31.12.88              */
/*                                                              */
/****************************************************************/


#include "comal/comal.h"
#include "exec/ports.h"
#include "devices/narrator.h"
                                       /* Exec library        */
extern APTR OpenLibrary();
extern LONG OpenDevice();
extern void BeginIO(),WaitIO();
extern void CloseLibrary(),CloseDevice();

                                      /* Exec support library */
extern struct MsgPort *CreatePort();
extern void DeletePort();

struct package *SayError;
struct MsgPort *ReplyPort;
struct narrator_rb narrat;
UBYTE amaps[] = {3,5,10,12};

void CleanUp();

int busy;
LONG nar_flag;
APTR TranslatorBase;           /* Address of translator lib   */

void ErrorText(wrkspc,wrktop)  /* Say error function          */
struct valparam *wrkspc,*wrktop; /* workspace pointers        */
{
  struct valparam *p;          /* String parameter structure  */
  STRPTR outtxt;               /* Pointer to translated text  */

  outtxt = (STRPTR)wrkspc;     /* Point to output buffer      */
  p = (--wrkspc);              /* p = pointer to text         */
  Translate(p->d2,(ULONG)p->d3,outtxt,256);
  if ( busy )
    {
     WaitIO(&narrat);
     busy = 0;
    } 
  narrat.message.io_Command = CMD_WRITE;
  if ((narrat.message.io_Length = strlen(outtxt)) != 0 )
   {
    narrat.message.io_Data = (APTR)outtxt;
    SendIO(&narrat);
    busy = 1;
   }
}

int strlen(s)
STRPTR s;
{
  int i;

  for (i=0; *s != '\0'; s++) i++ ;
  return i;
}

/* Signal-routine                                            */
void signal(s)
short s;             /* Signal number as parameter           */
{
  switch(s)
  {
    case 0:
    case 1: break;
    case 2: CleanUp();
    case 3:
    case 4:
    case 5:
    case 6:
    case 7:
    case 8:
    case 9:  break;
    case 10: CleanUp();
  };
}

topptr topnode = NULL;       /* No pocedures or functions      */

void init(pck)
struct package *pck;
{
  SayError = pck; 
  pck->var = &topnode;     /* Initialise top-id link           */
  pck->signal = &signal;   /* .. and address of signal routine */

  nar_flag=-1;
  if ((TranslatorBase=OpenLibrary("translator.library",0))==NULL)
    RetStat(199);
  if ((ReplyPort = CreatePort(0,0)) == NULL)
    {
      CleanUp();
      RetStat(199);
    };
  narrat.message.io_Message.mn_ReplyPort = ReplyPort;
  if (nar_flag = OpenDevice("narrator.device",0,&narrat,0))
    {
      CleanUp();
      RetStat(199);
    };
  pck->Flags |= ErrOutFlag;
  pck->ErrOut = &ErrorText;
  narrat.ch_masks = amaps;
  narrat.nm_masks = 4;
  busy = 0;
}

void CleanUp()
{
  if (busy)
   {
    WaitIO(&narrat);
    busy = 0;
   }
  if ( ReplyPort ) DeletePort(ReplyPort);
  if ( nar_flag == 0L ) CloseDevice(&narrat);
  if ( TranslatorBase ) CloseLibrary(TranslatorBase);
  SayError->Flags &= (~ErrOutFlag);
}
