/* -*- Mode:Text -*- */
/*
 * Deal w/ amiga console screen stuff.
 *
 * 					-- luis soltero, 5/12/88 --
 *
 *
 */
#include <stdio.h>
#include <fcntl.h>

/*------------------------------------------------------------------------
 * amiga console suport routines
 */

#include <exec/types.h>
#include <exec/exec.h>
#include <intuition/intuition.h>
#include <graphics/gfx.h>
#include <libraries/dos.h>
#include <libraries/dosextens.h>

/* console colors */
#define WHITE_ON_BLACK	0
#define WHITE_ON_BLUE	1
#define BLACK_ON_WHITE	2
#define BLUE_ON_WHITE	3
#define ORANGE_ON_BLUE	4

#define SETCOLORS(k,x)	(setcolors(k, colors[x].style, colors[x].frw, colors[x].bak))

struct colortype {
    char *style;
    char *frw;
    char *bak;
} colors[5] = {
    {"0", "31", "42"},		/* white on black */
    {"0", "31", "40"},		/* white on blue  */
    {"0", "32", "41"},		/* black on white */
    {"0", "30", "41"},		/* blue on white  */
    {"0", "33", "40"}		/* orange_on_blue */
};

insert_line(rq)
struct IOStdReq *rq;
{
     printc(rq,"%c%c",0x9b, 0x4c);
}

scroll_up(rq, nl)
struct IOStdReq *rq;
int nl;
{
    char buf[10];
    sprintf(buf,"%d",(short)nl);
    printc(rq,"%c%s%c",0x9b, buf, 0x53);
}

scroll_down(rq, nl)
struct IOStdReq *rq;
int nl;
{
    char buf[10];
    sprintf(buf,"%d",(short)nl);
    printc(rq,"%c%s%c",0x9b, buf, 0x54);
}

cursor_off(rq)
struct IOStdReq *rq;
{
     printc(rq,"%c%c%c%c",0x9b,0x30,0x20,0x70);
}

cursor_on(rq)
struct IOStdReq *rq;
{
    printf(rq,"%c%c%c",0x9b,0x20,0x70);
}

beep(rq)
struct IOStdReq *rq;
{
    printc(rq,"%c",0x7);
}

con_set_line(rq,offset,len)
struct IOStdReq *rq;
int offset,		/* in raster col, dist from left of win */
    len;		/* number of chars		        */
{
    char buf[10];
    sprintf(buf,"%d",(short)offset);
    printc(rq,"%c%s%c",0x9b,buf,0x78);

    sprintf(buf,"%d",(short)len);
    printc(rq,"%c%s%c",0x9b,buf,0x75);
}

con_set_pagelen(rq)
struct IOStdReq *rq;
{
    printc(rq,"%c%c",0x9b,0x74);
}

Open_Console(rq,win)
  struct IOStdReq 	*rq;
  struct Window		*win;
{
	rq->io_Data = (APTR) win;
	rq->io_Length = sizeof(*win);
	if (OpenDevice("console.device",0,rq,0))
	  return(FALSE);	/* could not get device */	  
	return(TRUE);	/* device opened successfully */
}

GotoXY(rq,x,y)
  struct IOStdReq	*rq;
  ULONG			x,y;
{
    char buf[10];
    sprintf(buf,"%c%d%c%d%c",0x9b,y,0x3b,x,0x48);
    putcon(rq,buf);
}

ClrScr(rq)
  struct IOStdReq	*rq;
{
	char buf[10];
	sprintf(buf,"%c",0x0c);
	putcon(rq,buf);
}

setcolors(rq,style,fg,bg)
struct IOStdReq *rq;
char *style, *fg, *bg;
{
    char buf[10];
    sprintf(buf,"%c%s%c%s%c%s%c",0x9b,style,0x3b,fg,0x3b,bg,0x6d);
    putcon(rq,buf);
}

putcon(rq,str)
struct IOStdReq *rq;
char *str;
{
    /* in case the console has not been initialized */
    if ( rq == NULL ) {
        fprintf(stderr,"%s",str);
	return;
    }
    rq->io_Command = CMD_WRITE;
    rq->io_Data = (APTR) str;
    rq->io_Length = -1;	
    DoIO(rq);    
}

printc(rq,fmt,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12)
struct  IOStdReq	*rq;
ULONG	  fmt,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12;
{
	char	pbuff[256];
	sprintf(pbuff,fmt,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12);
	putcon(rq,pbuff);
}

struct NewWindow NewWin = {
    0, 0,		/* left, top edge    */
    0, 0,		/* width, hight      */
    0, 1,		/* detail, block pen */
    CLOSEWINDOW   | NEWSIZE,      /* IDCMP flags */
    SMART_REFRESH | ACTIVATE    | /* flags       */
    WINDOWCLOSE   | WINDOWDRAG  | 
    WINDOWSIZING  | WINDOWDEPTH | 
    GIMMEZEROZERO,
    NULL, NULL,		/* gadget, check mark    */
    NULL,		/* title	         */
    NULL, NULL,		/* screen, bitmap        */
    200, 15,		/* min width, min height */
    640, 200,		/* max width, max height */
    WBENCHSCREEN	/* type			 */
};

Make_Window(w_ptr, title, x0, y0, x1, y1)
  struct	Window	**w_ptr;
  UBYTE		*title;
  int		x0,y0,x1,y1;	/* upper left & lower right corners */

{
	struct  Window 		*OpenWindow();
	
	/* define the window in Amiga Intuition terms */

	NewWin.LeftEdge = x0;
	NewWin.TopEdge = y0;
	NewWin.Width = (x1 - x0);
	NewWin.Height = (y1 - y0);
	NewWin.Title = title;

	if ((*w_ptr = OpenWindow(&NewWin)) == NULL)
	  return(FALSE);	/* problem... return false */

	return(TRUE);	/* window opened okay... return true */

}	/* Make_Window() */

struct IntuitionBase *IntuitionBase;

/* open a 25x80 nondescript win to scroll text in */
init_win(ApplWin, applname, ApplIOrq)
struct Window   **ApplWin;
char *applname;
struct IOStdReq *ApplIOrq;
{
	struct IntuitionBase *OpenLibrary();
        struct GfxBase *gfb;

	IntuitionBase = OpenLibrary("intuition.library",LIBRARY_VERSION);
	if (IntuitionBase == NULL)
	  exit(FALSE);

	gfb = (struct GfxBase *)OpenLibrary("graphics.library",LIBRARY_VERSION);
	if (gfb == NULL)
	  exit(FALSE);

	if (!(Make_Window(ApplWin,applname,0L,0L,640L,200L)))
	  exit (FALSE);
	  
	ModifyIDCMP((*ApplWin), CLOSEWINDOW | NEWSIZE | ACTIVEWINDOW | 
			     VANILLAKEY  | MENUPICK);
	
	if (! Open_Console(ApplIOrq,(*ApplWin) )){
	   CloseWindow((*ApplWin));
	   exit(FALSE);
 	}
        con_set_line(ApplIOrq,0,130);
	SETCOLORS(ApplIOrq,WHITE_ON_BLACK);
}

/* terminate win opened by init_win() */
close_win(ApplWin, ApplIOrq)
struct Window   *ApplWin;
struct IOStdReq *ApplIOrq;
{
    CloseWindow(ApplWin);
    CloseDevice(ApplIOrq);
}

/* get input from user and tokenize it */ 
getevent(ApplWin) 
struct Window *ApplWin;
{
    struct IntuiMessage *mess, *GetMsg();
    int retval = -1;

    /* wait for an intuition event */
    while( !(mess = GetMsg(ApplWin->UserPort)) )
        Wait(1 << ApplWin->UserPort->mp_SigBit);
 
    switch(mess->Class) {
	case CLOSEWINDOW:
	    retval = 'q';
	    break;
	case VANILLAKEY: 
	    retval = mess->Code;
	    break;
	case NEWSIZE : 
	    retval = 0x0c;
	    break;
	case MENUPICK:
	case ACTIVEWINDOW:
	default:
	    break;
    }
    ReplyMsg(mess);
    return(retval);
}

/*
 * end of amiga console support.
 *-----------------------------------------------------------------------*/


/*-------------------------------------------------------------------------
 * terminal handling entry points
 */

#include <sgtty.h>
#include <signal.h>
#include "ispell.h"

struct Window *scr_w = NULL;
struct IOStdReq *scr_rq = NULL, _scr_rq;

printcon(fmt,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12)
ULONG	  fmt,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12;
{
	char	pbuff[256];
	sprintf(pbuff,fmt,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12);
	putcon(scr_rq, pbuff);
}

putccon(ch)
char ch;
{
    printc(scr_rq,"%c", ch);
}

getccon()
{
    int ch;

    while ( (ch=getevent(scr_w)) == -1 )
        ;
    if ( ch == '\b' || ch == 0x7f )
        erasechar = ch;
    return( ch );
}

/* open a console window for spell */
terminit ()
{
    erasechar = '\b';
    scr_rq = &_scr_rq;
    init_win(&scr_w, "ISpell", scr_rq);
}

done ()
{
    unlink(tempfile);
    close_win(scr_w, scr_rq);
    exit(0);
}

/* clear the screen */
erase ()
{
    ClrScr(scr_rq);
}

/* move to row, col */
move (row, col)
{
    GotoXY(scr_rq, col, row);
}

/* do stand out mode */
inverse ()
{
    SETCOLORS(scr_rq, ORANGE_ON_BLUE); 
}

/* do stand end mode */
normal ()
{
    SETCOLORS(scr_rq, WHITE_ON_BLACK);
}

/* do a back space */
backup ()
{
    putch((int)'\b');
}

putch (c)
{
    printc (scr_rq,"%c", c);
}

/* not implemented on the amiga */
onstop(signo) {}
stop () {}

#define CLI	"NewCli"
#define CLINAME "\"con:20/30/600/100/ISpell Cli\""

shellescape (buf)
char *buf;
{
    fexecl(CLI,CLI,CLINAME,0);
}

/*
 * end of terminal control entry points
 *-----------------------------------------------------------------------*/

/*-----------------------------------------------------------------------
 * misc missing and broken stuff.
 *
 */

/* the manx access routine is broken, here is a brain damaged one
   that works for this applications. */
access(name)
char *name;
{
    int in = open(name, O_RDWR);
    if ( in == -1 ) 
        return( -1 );
    close (in);
    return(0);
}

/* i really do not understant why sleep is used in i spell. Here is
   a null function used soley to keep ispell happy. */
sleep(n) int n; {}

link(from, to)
char *from, *to;
{
    FILE *f, *t;
    int  ch;
    if ( (f=fopen(from,"r")) == NULL )
        return(-1);
    if ( (t=fopen(to,"w")) == NULL ) {
        fclose(f);
	return(-1);
    }
    while((ch=getc(f)) != EOF )
	putc(ch, t);
    fclose(f);
    fclose(t);
}

