/* special.c */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <exec/types.h>
#include <exec/exec.h>
#include <exec/ports.h>
#include <intuition/intuition.h>

#include "globals.h"
#include "special.h"
#include "bitmap.h"

#include "globals.i"
#include "amscreen.i"

#ifdef LATTICE
#  include <proto/exec.h>
#endif


extern long  hh;                        /* current h on device */
extern long  vv;                        /* current v on device */
extern struct bitmap map;
extern long upper_limit;
extern long lower_limit;


static struct MsgPort *special_port, *reply_port;
static struct special_msg message;
static struct driver_map dmap;



static int  open_port(void);
static void setup_dmap(struct driver_map *dmap);



struct special_map *send_special(char *sp_string)
{
  struct special_msg *reply_msg;

  if (open_port()) {	/* Fehler? */
    return NULL;
  }

  setup_dmap(&dmap);

  message.msg.mn_Node.ln_Type	= NT_MESSAGE;
  message.msg.mn_ReplyPort	= reply_port;
  message.msg.mn_Length		= sizeof(message);
  message.action		= AC_SEND_SPECIAL;
  message.ret			= 0;
  message.special_string	= sp_string;
  message.hresolution		= hconvresolution;
  message.vresolution		= vconvresolution;
  message.bmap			= NULL;
  message.tpic			= NULL;
  message.dmap			= &dmap;
  
  Message("wait for picture...");

  PutMsg(special_port,&(message.msg));
  WaitPort(reply_port);
  reply_msg = (struct special_msg *)GetMsg(reply_port);
  if (reply_msg->action != AC_REPLY_SPECIAL) {
    Warning("I have expected AC_REPLY_SPECIAL, I found %d!",reply_msg->action);
    return NULL;
  }
  if (reply_msg->ret != 0) {
    Warning("Return from \"special\" program: %d!",reply_msg->ret);
  }

  return reply_msg->bmap;
}


void send_tpic(struct tpic_msg *tp)
{
  struct special_msg *reply_msg;

  if (open_port()) {	/* Fehler? */
    return;
  }

  setup_dmap(&dmap);

  message.msg.mn_Node.ln_Type	= NT_MESSAGE;
  message.msg.mn_ReplyPort	= reply_port;
  message.msg.mn_Length		= sizeof(message);
  message.action		= AC_SEND_TPIC;
  message.ret			= 0;
  message.special_string	= NULL;
  message.hresolution		= hconvresolution;
  message.vresolution		= vconvresolution;
  message.bmap			= NULL;
  message.tpic			= tp;
  message.dmap			= &dmap;
  
  PutMsg(special_port,&(message.msg));
  WaitPort(reply_port);
  reply_msg = (struct special_msg *)GetMsg(reply_port);
  if (reply_msg->action != AC_REPLY_TPIC) {
    Warning("I expected AC_REPLY_TPIC, I found %d!",reply_msg->action);
    return;
  }
  if (reply_msg->ret != 0) {
    Warning("Return from \"special\" program: %d!",reply_msg->ret);
  }

  DeletePort(reply_port);

  special_port = NULL;
  reply_port   = NULL;
}


void special_ok(void)
{
  struct special_msg *reply_msg;

  if (special_port == NULL || reply_port == NULL) {
    special_port = NULL;
    reply_port = NULL;
    return;
  }

  setup_dmap(&dmap);

  message.msg.mn_Node.ln_Type	= NT_MESSAGE;
  message.msg.mn_ReplyPort	= reply_port;
  message.action		= AC_OK_BITMAP;
  message.ret			= 0;
  message.tpic			= NULL;
  message.dmap			= &dmap;
  message.special_string	= NULL;
  message.hresolution		= hconvresolution;
  message.vresolution		= vconvresolution;

  PutMsg(special_port,&(message.msg));
  
  WaitPort(reply_port);
  reply_msg = (struct special_msg *)GetMsg(reply_port);
  if (reply_msg->action != AC_REPLY_BITMAP) {
    Warning("I expected AC_REPLY_BITMAP, I found %d!",reply_msg->action);
  }
  else {
    if (reply_msg->ret != 0) {
      Warning("Return from \"special\" program: %d!",reply_msg->ret);
    }
  }

  DeletePort(reply_port);

  special_port = NULL;
  reply_port   = NULL;
  
  Message("picture received");
}



static int open_port(void)
{
  special_port = NULL;
  reply_port   = NULL;

  special_port = FindPort(SPECIAL_PORT);
  if (special_port == NULL) {
    /* no special port */
    Warning("Found no \"special\" program!");
    return TRUE;
  }

  reply_port = CreatePort(SPECIAL_REPLY,0L);
  if (reply_port == NULL) {
    /* no reply port */
    Warning("Can't create \"special\" reply-port!");
    return TRUE;
  }
  return FALSE;		/* kein Fehler */
}


static void setup_dmap(struct driver_map *dmap)
{
  dmap->x		 = hh + (long)hoffset;
  dmap->y		 = vv + (long)voffset;
  dmap->width		 = map.width;
  dmap->height		 = map.height;
  dmap->lower_limit	 = lower_limit;
  dmap->upper_limit	 = upper_limit;
  dmap->pixptr		 = map.pixptr;
}
