
/*** includes ***/

#include "mui_support.h"
#define MAXNAMELEN 256

#include <exec/memory.h>
#include <workbench/workbench.h>
#include <clib/icon_protos.h>
#include <stdio.h>
#include <stdlib.h>

#include <devices/printer.h>
#include <devices/prtbase.h>

#include "version.h"
#include "simplerexx.h"

struct PrtMsg {
    struct Message  pm_Msg;
    long	    pm_Type;
#define PM_RENDER   1
#define PM_INIT     2
#define PM_EXPUNGE  3
};
#define pm_rc	    pm_Type

extern long Render(long ct, long x, long y, long status);
void initializeDoChar(void);

struct RenderMsg {
    struct PrtMsg   rm_PrtMsg;
    long	    rm_ct;
    long	    rm_x;
    long	    rm_y;
    long	    rm_status;
};

struct PrinterData* PD;
struct PrinterExtendedData* PED;

int cannotClose = 0;

extern char lastFaxFile[];

#undef VER
#define VER "1.01"

static struct MsgPort* localPort = 0;
AREXXCONTEXT OutgoingRexx = 0;

/*** ids ***/

enum ids {
	ID_DUMMY,
	ID_ABOUT,
	ID_QUIT
};

/*** variables ***/

static APTR app = 0;
static APTR wi_main;
static APTR cm_endpageonclose;
static APTR bt_quit;
static APTR tx_status = 0;
static APTR tx_filename = 0;

void setStatus(char* s) {
  set(tx_status, MUIA_Text_Contents, s);
}

void setFileName(char* s) {
  set(tx_filename, MUIA_Text_Contents, s);
}

int endPageOnClose(void) {
  int temp;
  get(cm_endpageonclose, MUIA_Selected, &temp);

  return temp;
}

/*** arexx list ***/

static struct MUI_Command arexx_list[] =
{
	{NULL,			NULL,				NULL,				NULL}
};

void CloseFaxFile(void);
extern int currentPage;

void processArexxMessages(void) {
  void* ret;
  while (ret = GetReplyARexxMsg(OutgoingRexx)) {
    if (ret != REXX_RETURN_ERROR) {
    }
  }
}

static void processLocalPortMessages(void) {
  struct RenderMsg* dlMsg;
  int pos;
  char buf[100];
  char* tmp = buf;

  while (dlMsg = (struct RenderMsg*)GetMsg(localPort)) {
    switch (dlMsg->rm_PrtMsg.pm_Type) {
    case 1:
      dlMsg->pm_rc = Render(dlMsg->rm_ct, dlMsg->rm_x, dlMsg->rm_y, dlMsg->rm_status);
      break;
    case 2: /* open -- do nothing */
      setStatus("Opened Printer");
      cannotClose = 1;
      PED = (struct PrinterExtendedData*)dlMsg->rm_ct;
      PD = (struct PrinterData*)dlMsg->rm_status;
      currentPage = 1;
      strcpy(lastFaxFile, "");
      WinWriteInit();
      initializeDoChar();
      break;
    case 3: /* close -- end of page also */
      CloseFaxFile();
      /* do avm specific thing here */
      if (strcmp(lastFaxFile, "") != 0) {
	sprintf(buf, "CreateFax %s", lastFaxFile);
	SendARexxMsg(OutgoingRexx, buf, FALSE);
      }
      setStatus("Closed Printer");
      cannotClose = 0;
      break;
    case 4: /* DoSpecial */
      dlMsg->pm_rc = 0;
      if (getenv("AVMFCIIREL1HACK"))
	dlMsg->pm_rc = 1;
      switch (dlMsg->rm_status) {
      case 0:
	/* fallthrough */
      case 1:
	DoCtrl("\033c");
	break;
      case 5:
	DoCtrl("\033[0m");
	break;
      case 6:
	DoCtrl("\033[3m");
	break;
      case 7:
	DoCtrl("\033[23m");
	break;
      case 8:
	DoCtrl("\033[4m");
	break;
      case 9:
	DoCtrl("\033[24m");
	break;
      case 10:
	DoCtrl("\033[1m");
	break;
      case 11:
	DoCtrl("\033[22m");
	break;
      }
/*      printf("DoSpecial %d\n", dlMsg->rm_status); */
      break;
    case 5: /* ConvFunc */
      if (dlMsg->rm_status == 12) {
	setStatus("End of page");
	/* trap end of page */
	CloseFaxFile();
      } else {
	dochar(dlMsg->rm_status);
      }
      break;
    }

    dlMsg->rm_PrtMsg.pm_Msg.mn_Node.ln_Type = NT_REPLYMSG;
    Signal((struct Task *)dlMsg->rm_PrtMsg.pm_Msg.mn_ReplyPort, SIGF_SINGLE);

  }
}

void releaseResources(void) {
  if (localPort) DeletePort(localPort);
  cleanup();
  FreeARexx(OutgoingRexx);
}

SAVEDS ASM APTR doublestart_func(
	REG(a0) struct Hook *hook,
	REG(a2) Object *appl,
	REG(a1) ULONG *arg)
{
  set(app, MUIA_Application_Iconified, FALSE);
  DoMethod(wi_main, MUIM_Window_ToFront);
  return(RETURN_OK);
}

static const struct Hook doublestart_hook = {
  {NULL, NULL},
  (void *)doublestart_func,
  NULL,NULL
};

/*** main ***/

int main(int argc, char *argv[])
{
	/*** init ***/
	BOOL not_end = TRUE;
	ULONG localPortSignal, signalReceived = 0;

	atexit(releaseResources);

	if (chdir("avmrexx:")) {
	  fail(app, "Couldn't get into avmrexx:");
	}

	localPort = CreatePort("FAXPRINTERMP", 0); /* local port which we get
						    debugger output from, aside
						    from the arexx port */
	if (!localPort)
		fail(app, "Creating FAXPRINTERMP failed!");

	OutgoingRexx=InitARexx("AVMOPORT","avm");
	if (!OutgoingRexx) fail(app, "Couldn't open outgoing rexx port\n");

	openall();

	init(argc, argv);

	/*** create mui-application ***/
	app = ApplicationObject,
		MUIA_Application_Title,				"AVM FaxPrinter",
		MUIA_Application_Version,			"$VER: FaxPrinter " VER,
		MUIA_Application_Copyright,			"© 1994 by Al Villarica",
		MUIA_Application_Author,			"Al Villarica",
		MUIA_Application_Description,		"FaxPrinter",
		MUIA_Application_Base,				"AVMFAXPRINTER",
		MUIA_Application_SingleTask,		TRUE,
		MUIA_Application_Commands,			arexx_list,
	        MUIA_Application_DiskObject,		AVM_DiskObject,
	        MUIA_HelpFile, "avm:avm.guide",

		SubWindow, wi_main = WindowObject,
                        MUIA_HelpNode, "Faxing",
			MUIA_Window_ID, 'MAIN',
			MUIA_Window_Title, "AVM FaxPrinter",
	                WindowContents, VGroup,
	                  Child, HGroup,
	                    Child, Label2("Filename"),
                            Child, tx_filename = TextObject,
                              MUIA_Text_Contents, "",
                              TextFrame,
                            End,
                          End,

	                  Child, HGroup,
	                    Child, Label2("Status"),
                            Child, tx_status = TextObject,
                              MUIA_Text_Contents, "",
                              TextFrame,
                            End,
                          End,

                          Child, HGroup,
                          Child, Label2("End Page on Render Close"),
                            Child, HGroup,
                              Child, cm_endpageonclose = CheckMark(0),
                              Child, HSpace(0),
                            End,
                          End,

                          Child, bt_quit	= KeyButton("Quit",'q'),
			End, // VGroup
                        End, // WindowObject
	End;


	/*** application failed ? ***/
	if (!app)
		fail(app, "Creating application failed !");

	

	/*** connections & cycle ***/
	DoMethod(wi_main,		MUIM_Notify,	MUIA_Window_CloseRequest,	TRUE,	app,	2,	MUIM_Application_ReturnID,	ID_QUIT			);
	DoMethod(bt_quit, MUIM_Notify,	MUIA_Pressed,	FALSE,		app,	2,	MUIM_Application_ReturnID,	ID_QUIT);

  DoMethod(wi_main, MUIM_Window_SetCycleChain, bt_quit, NULL);

  DoMethod(app, MUIM_Notify, MUIA_Application_DoubleStart, TRUE, app, 2, MUIM_CallHook, &doublestart_hook);

	/*** open window ***/
	set(wi_main, MUIA_Window_Open,			TRUE);

	localPortSignal = (1L << localPort->mp_SigBit);

	/*** main-loop ***/
	while (not_end)
	{
		ULONG signal, id;

		if (signalReceived & localPortSignal) processLocalPortMessages();

		processArexxMessages();

		switch (id = DoMethod(app, MUIM_Application_Input, &signal))
		{
			case MUIV_Application_ReturnID_Quit:
			case ID_QUIT:
				if (!cannotClose) not_end = FALSE;
				else setStatus("I'm busy!");
				break;

			/*** default ***/

			default:
				if (id)
					printf("ID: %d = %08lx\n", id, id);
			break;
		}

		if (not_end && signal)
			signalReceived = Wait(signal | localPortSignal | ARexxSignal(OutgoingRexx));
	}

	fail(app, NULL);
}


/*** workbench ***/

int wbmain(struct WBStartup *wb_startup)
{
	return (main(0, NULL));
}


