#include "ownincs/IBMconsole.h"


/* allowed globals.. */
struct	ExecBase			*SysBase;
struct	DosLibrary		*DOSBase;
struct	GfxBase			*GfxBase;
struct	IntuitionBase	*IntuitionBase;


                /* CSI Funktionen zu IBM Emulator.. */



VOID IBM_ignore(struct IBMConsole *con, UBYTE *args, ULONG argc)
{
	return;	/* ..(^: */
}


VOID IBM_insertchars(struct IBMConsole *con, UBYTE *args, ULONG argc)
{
	UBYTE cnt;

	cnt = args[0];
	if(!cnt)
		cnt = 1;

	if(con->col < con->columns)
		ScrollRaster(con->rp, -(cnt << 3), 0, (con->col - 1) << 3, ((con->row-1) << 3), con->width - 1, (con->row << 3) - 1);
}


VOID IBM_cursorright(struct IBMConsole *con, UBYTE *args, ULONG argc)
{
	UBYTE cnt;

	cnt = args[0];
	if(!cnt)
		cnt = 1;

	while(cnt--)
	{
		if(con->col >= con->columns)
		{
			if(con->stat & X_SCROLLCURSOR)
				IBM_cursornextline(con, "\001", 1);
			else
				break;
		}
		else
			con->col++;
	}
}


VOID IBM_cursorleft(struct IBMConsole *con, UBYTE *args, ULONG argc)
{
	UBYTE cnt;

	cnt = args[0];
	if(!cnt)
		cnt = 1;

	while(cnt--)
	{
		if(con->col <= 1)
		{
			if(con->stat & X_SCROLLCURSOR)
			{
				con->col = con->columns;
				IBM_cursorup(con, "\001", 1);
			}
			else
				break;
		}
		else
			con->col--;
	}
}


VOID IBM_cursorup(struct IBMConsole *con, UBYTE *args, ULONG argc)
{
	UBYTE cnt;

	cnt = args[0];

	if(!cnt)
		cnt = 1;

	if(con->stat & Y_SCROLLCURSOR)
	{
		if(con->row - cnt >= 1)
			con->row -= cnt;
		else
		{
			LONG ntimes;

			ntimes = (con->row > 1) ? (cnt - con->row) : cnt;
			con->row = 1;
			ScrollRaster(con->rp, 0, -8 * ntimes, 0, 0, con->width - 1, (con->lines << 3) - 1);
		}
	}

	else
	{
		if(con->row - cnt > 1)
			con->row -= cnt;
		else
			con->row = 1;
	}
}


VOID IBM_cursordown(struct IBMConsole *con, UBYTE *args, ULONG argc)
{
	UBYTE cnt;

	cnt = args[0];

	if(!cnt)
		cnt = 1;

	if(con->stat & Y_SCROLLCURSOR)
	{
		if(con->row + cnt <= con->lines)
			con->row += cnt;
		else
		{
			LONG ntimes;

			ntimes = con->row + cnt - con->lines;
			con->row = con->lines;
			ScrollRaster(con->rp, 0, +8 * ntimes, 0, 0, con->width - 1, (con->lines << 3) - 1);
		}
	}
	else
	{
		if(con->row + cnt < con->lines)
			con->row += cnt;
		else
			con->row = con->lines;
	}
}


VOID IBM_cursornextline(struct IBMConsole *con, UBYTE *args, ULONG argc)
{
	con->col = 1;
	IBM_cursordown(con, args, argc);
}


VOID IBM_cursoraboveline(struct IBMConsole *con, UBYTE *args, ULONG argc)
{
	con->col = 1;
	IBM_cursorup(con, args, argc);
}


VOID IBM_cursorposition(struct IBMConsole *con, UBYTE *args, ULONG argc)
{
	con->row = args[0];
	if(!con->row)
		con->row = 1;
	else
	{
		if(con->row > con->lines)
			con->row = con->lines;
	}

	con->col = args[1];
	if(!con->col)
		con->col = 1;
	else
	{
		if(con->col > con->columns)
			con->col = con->columns;
	}
}


/*
 CSI Ps J	ED		Erase in display:
				0 = cursor to end of screen, inclusive
				1 = start of screen to cursor, inclusive
				2 = entire screen, cursor home
*/
VOID IBM_eraseindisplay(struct IBMConsole *con, UBYTE *args, ULONG argc)
{
	switch(args[0])
	{
		case 0:
			if(con->row < con->lines)
			{
				con->row++;
				IBM_eraselines(con, con->lines - con->row);
				con->row--;
			}
			IBM_erasechars(con, con->columns + 1 - con->col);
		break;

		case 1:
			IBM_erasescrbeg(con);
			IBM_eraselinebeg(con);
		break;

		case 2:
			IBM_erasescreen(con);
	}
}


/*
 CSI Ps K	EL		Erase in line:
				0 = cursor to end of line, inclusive
				1 = start of line to cursor, inclusive
				2 = entire line, cursor does not move
*/
VOID IBM_eraseinline(struct IBMConsole *con, UBYTE *args, ULONG argc)
{
	switch(args[0])
	{
		case 0:
			IBM_erasechars(con, con->columns + 1 - con->col);
		break;

		case 1:
			IBM_eraselinebeg(con);
		break;

		case 2:
			IBM_eraselinebeg(con);
			IBM_erasechars(con, con->columns + 1 - con->col);
		break;
	}
}


/*
 CSI Pn L	IL		Insert Pn lines preceding current line.
*/
VOID IBM_insertlines(struct IBMConsole *con, UBYTE *args, ULONG argc)
{
	UBYTE cnt;

	cnt = args[0];
	if(!cnt)
		cnt = 1;

	if((con->row >= 1)  &&  (con->row <= con->lines))
	{
		if(cnt > (con->lines - con->row))
			cnt = (con->lines - con->row);

		ScrollRaster(con->rp, 0, -(cnt << 3), 0, (con->row - 1) << 3, con->width - 1, (con->lines << 3) - 1);
	}
}


/*
 CSI Pn M	DL		Delete Pn lines from current downward, incl.
*/
VOID IBM_deletelines(struct IBMConsole *con, UBYTE *args, ULONG argc)
{
	UBYTE cnt;

	cnt = args[0];
	if(!cnt)
		cnt = 1;

	if((con->row >= 1)  &&  (con->row <= con->lines))
	{
		if(cnt > (con->lines - con->row + 1))
			cnt = (con->lines - con->row + 1);

		ScrollRaster(con->rp, 0, +(cnt << 3), 0, (con->row - 1) << 3, con->width - 1, (con->lines << 3) - 1);
	}
}


/*
 CSI Pn P	DCH		Delete Pn chars from cursor to left, incl.
*/
VOID IBM_deletechars(struct IBMConsole *con, UBYTE *args, ULONG argc)
{
	UBYTE cnt;

	cnt = args[0];
	if(!cnt)
		cnt = 1;

	if(con->col < con->columns)
		ScrollRaster(con->rp, +(cnt << 3), 0, (con->col - 1) << 3, (con->row - 1) << 3, con->width - 1, (con->row << 3) - 1);
}


VOID IBM_scrollup(struct IBMConsole *con, UBYTE *args, ULONG argc)
{
	UBYTE cnt;

	cnt = args[0];
	if(!cnt)
		cnt = 1;

	ScrollRaster(con->rp, 0, -(cnt << 3), 0, 0, con->width - 1, (con->lines << 3) - 1);
}


VOID IBM_scrolldown(struct IBMConsole *con, UBYTE *args, ULONG argc)
{
	UBYTE cnt;

	cnt = args[0];
	if(!cnt)
		cnt = 1;

	ScrollRaster(con->rp, 0, -(cnt << 3), 0, 0, con->width - 1, (con->lines << 3) - 1);
}


VOID IBM_ANSIsetmodes(struct IBMConsole *con, UBYTE *args, ULONG argc)
{
	UWORD i;

	for(i=0; i<(argc+1); i++)
	{
		switch(con->inter[i])
		{
			case NUL:
				if(args[i] == 20)
					con->stat |= NEWLINE;
			break;

			case '>':
				if(args[i] == 1)
					con->stat |= Y_SCROLLCURSOR;
			break;

			case '?':
				if(args[i] == 7)
					con->stat |= X_SCROLLCURSOR;
			break;

		}
	}
}


VOID IBM_ANSIresetmodes(struct IBMConsole *con, UBYTE *args, ULONG argc)
{
	UWORD i;

	for(i=0; i<(argc+1); i++)
	{
		switch(con->inter[i])
		{
			case NUL:
				if(args[i] == 20)
					con->stat &= ~NEWLINE;
			break;

			case '>':
				if(args[i] == 1)
					con->stat &= ~Y_SCROLLCURSOR;
			break;

			case '?':
				if(args[i] == 7)
					con->stat &= ~X_SCROLLCURSOR;
			break;

		}
	}
}


VOID IBM_textmodes(struct IBMConsole *con, UBYTE *args, ULONG argc)
{
	BOOL setapen=FALSE, setbpen=FALSE, setattr=FALSE;
	UWORD i;
	UBYTE cnt;

	for(i=0; i<(argc+1); i++)
	{
		cnt = args[i];

		switch(cnt)
		{
			case 0:
				con->attr	= FS_NORMAL;
				con->apen	= con->foreground_pen;
				con->bpen	= BACKGROUND_PEN;
				setapen		= TRUE;
				setbpen		= TRUE;
				setattr		= TRUE;
			break;

			case 1:
				if(con->bold)
				{
					con->attr |= M_BOLD;
					setapen	= TRUE;
				}
			break;

			case 4:
				con->attr |= FSF_UNDERLINED;
				setattr = TRUE;
			break;

			case 7:
				con->attr |= M_INVERSID;
			break;

			case 30: case 31: case 32: case 33:
			case 34: case 35: case 36: case 37:
			case 39:
				if(con->mono == FALSE)
				{
					con->apen = cnt - 30;
					if(con->apen == 9)
						con->apen = con->foreground_pen;

					setapen = TRUE;
				}
			break;

			case 40: case 41: case 42: case 43:
			case 44: case 45: case 46: case 47:
			case 49:
				if(con->mono == FALSE)
				{
					con->bpen = cnt-40;
					if(con->bpen == 9  ||  con->bpen >= 1<<con->io->xem_screendepth)
						con->bpen = BACKGROUND_PEN;

					setbpen = TRUE;
				}
			break;

		}
	}

	if(con->apen == con->bpen  &&  con->bold == FALSE)
	{
		con->apen = con->foreground_pen;
		con->bpen = BACKGROUND_PEN;
		setapen = TRUE;
		setbpen = TRUE;
	}

	if(setapen)
	{
		if(con->attr & M_BOLD)	/* real BOLD */
		{
			if(con->mono)
				con->apen = 3;
			else
			{
				if(con->apen <= 7)
					con->apen |= 8;
			}
		}

		SetAPen(con->rp, con->apen);
	}


	if(setbpen)
		SetBPen(con->rp, con->bpen);

	if(setattr)
		SetSoftStyle(con->rp, (UWORD)con->attr, FSF_UNDERLINED);
}


VOID IBM_devicestatreport(struct IBMConsole *con, UBYTE *args, ULONG argc)
{
	UBYTE com[16], *answer=NULL;

	if(args[0] == 6)
	{
		sprintf(com, "\233%ld;%ldR", con->row, con->col);
		answer = com;
	}

	if(answer)
		con->io->xem_swrite(answer, -1);
}


VOID IBM_savecursor(struct IBMConsole *con, UBYTE *args, ULONG argc)
{
	con->s_row	= con->row;
	con->s_col	= con->col;
	con->s_attr	= con->attr;
	con->s_apen	= con->apen;
	con->s_bpen	= con->bpen;
	con->s_shift= con->shift;
	con->s_stat	= con->stat;
}


VOID IBM_restorecursor(struct IBMConsole *con, UBYTE *args, ULONG argc)
{
	con->row	 	= con->s_row;
	con->col		= con->s_col;
	con->attr	= con->s_attr;
	con->apen	= con->s_apen;
	con->bpen	= con->s_bpen;
	con->shift	= con->s_shift;
	con->stat	= con->s_stat;

	SetAPen(con->rp, con->apen);
	SetBPen(con->rp, con->bpen);
	SetSoftStyle(con->rp, (UWORD)con->attr, FSF_UNDERLINED);
}



/* end of source-code */
