/*************************************************************************/
/*                  VChat interactive IP-level chat system               */
/*-----------------------------------------------------------------------*/
/*  (c) '93/'94 by Andreas S. Wetzel (mickey@deadline.bln.sub.org)       */
/*                 All rights reserverd.                                 */ 
/*-----------------------------------------------------------------------*/
/* See the file COPYRIGHT in the top level directory of VChat for        */
/* copyright notices and further disclaimers.                            */ 
/*************************************************************************/

#include "../config.h"
#include "../global.h"
#include <stdio.h>
#include <stdarg.h>
#include <sys/ioctl.h>
#include "proto.h"

/********* Globals **********/

int sqpos = 0;

	static char *col_code[] = { 
		"","1","4","5","7",
		"30","31","32","33","34","35","36","37",
		"40","41","42","43","44","45","46","47",
		"","","","","","","","","","",""};

/*********** Code ***********/

void screen_init(void)
{
	extern int t_cols;
	extern int t_rows;
	extern int reverse;
	extern char *emulation;

	if(reverse)
		scr_mode(WHITE);
	else
		scr_mode(BLACK);

	cls();
	mv(1, (t_rows-1));
	printf("%s=== VChat === Type \".h\" to get help ===%*s%7s %3dx%-3d %s",
		vt(REVERSE | BOLD | FG_WHITE | BG_BLUE),
		t_cols-56, " ", emulation, t_cols, t_rows,
		vt(OFF));
	scroll_reg(1, (t_rows-2));

	mv(1,t_rows);

	printf("%s%s", vt(OFF), vt(BOLD));

	fflush(stdout);
}

void mv(int x, int y)
{
	extern char csi[];

	printf("%s%d;%dH", csi, y, x);
	fflush(stdout);
}

void cls(void)
{
	extern char csi[];

	printf("%s2J", csi);
	fflush(stdout);
}

void scr_mode(int sw)
{
	extern char csi[];

	printf("%s?5%c", csi, (sw == 1) ? 'l' : 'h');
	fflush(stdout);
}

void scroll_reg(int start, int ende)
{
	extern char csi[];

	printf("%s%d;%dr", csi, start, ende);
	fflush(stdout);
}

void cprintf(int win, char *fmt, ...)
{
	extern char csi[];
	extern int t_rows;
	extern int txcol;

	char tmp[512];
	static char line[1024];

	register int i = 0;
	register int n = 0;
	register char c;
	register long attr;

	va_list(ap);
	va_start(ap, fmt);

	vsprintf(tmp, fmt, ap);

	bzero(line, sizeof(line));

	/* Convert server color control codes to ansi codes */

	for(i = 0; i < strlen(tmp); i++)
	{
		if((((c = tmp[i]) & 0x80) == 0x80) && txcol)		/* Bit 7 = Colorctl. code */
		{
			attr = ((c & 0x20) == 0x20) ? BOLD : 0;

			if((c & 0x10) == 0x10)		/* Background	*/
			{
				switch(c & 0x8F)	/* Exclude bits 6,5,4 */
				{
					case BLK:	attr |= BG_BLACK;
							break;
					case RED:	attr |= BG_RED;
							break;
					case GRN:	attr |= BG_GREEN;
							break;
					case YEL:	attr |= BG_YELLOW;
							break;
					case BLU:	attr |= BG_BLUE;
							break;
					case MAG:	attr |= BG_MAGENTA;
							break;
					case CYN:	attr |= BG_CYAN;
							break;
					case WHT:	attr |= BG_WHITE;
							break;
					case XXX:	attr |= OFF;
							break;
				}
			}
			else				/* Foreground   */
			{
				switch(c & 0x8F)
				{
					case BLK:	attr |= FG_BLACK;
							break;
					case RED:	attr |= FG_RED;
							break;
					case GRN:	attr |= FG_GREEN;
							break;
					case YEL:	attr |= FG_YELLOW;
							break;
					case BLU:	attr |= FG_BLUE;
							break;
					case MAG:	attr |= FG_MAGENTA;
							break;
					case CYN:	attr |= FG_CYAN;
							break;
					case WHT:	attr |= FG_WHITE;
							break;
					case XXX:	attr |= OFF;
							break;
				}
			}

			if(attr)
			{
				attr = (txcol) ? attr : (attr & 0x1f);
				strcat(line, vt(attr));

				if(attr == OFF)
					strcat(line, vt(BOLD));

				n = strlen(line);
			}
		}
		else
		{
			bcopy(&tmp[i], &line[n++], 1);
		}
	}

	if(win == 0)					/* Output window */
	{
		printf("\0337%s%d;1H%s%s%s\n\0338", csi, (t_rows-2),
		line, vt(OFF), vt(BOLD));
	}
	else if(win == 1)				/* Statusline    */
	{
		printf("\0337%s%d;1H%s\0338", csi, (t_rows-1), line);
	}
	else if(win == 2)				/* Input window  */
	{
		printf("%s%d;1H%sK%s", csi, t_rows, csi, line);
	}
	else if(win == 3)
	{
		printf("\0337%s%d;1H%s%s%s\n", csi, (t_rows - 2),
		line, vt(OFF), vt(BOLD));
	}
	else if(win == 4)
	{
		printf("%s%s%s\n", line, vt(OFF), vt(BOLD));
	}
	else if(win == 5)
	{
		printf("%s%s%s\n\0338", line, vt(OFF), vt(BOLD));
	}

	fflush(stdout);
	va_end(ap);
}

char *vt(unsigned long attr)
{
	extern int color;
	extern char csi[];

	int i, maxattr;
	int n = 0;
	char *sq;
	static char seq[800];

#define BUFFERS 20

	extern int sqpos;

	maxattr = (color == 0xff) ? 21 : 5;

	sqpos++;

	if(sqpos >= BUFFERS)
		sqpos = 0;

	sq = &seq[sqpos * 40];

	for(i=0; i < maxattr; i++)
	{
		if(((attr >> i) & 1) && ((color == 0xff && i != 4) || color == 0))
		{
			n++;

			if(n > 1)
			{
				strcat(sq, ";");
			}
			else
			{
				sprintf(sq, "%s", csi);	
			}

			strcat(sq, col_code[i]);
		}
	}

	if(n)
		strcat(sq, "m");

	return((char *)sq);
}

void winch(void)
{
	extern int t_cols;
	extern int t_rows;
	extern int reverse;
	extern char csi[];
	extern char *emulation;

#ifdef Linux
	struct winsize tsiz;

	if(ioctl(0, TIOCGWINSZ, &tsiz) == 0)
	{
		t_cols = (tsiz.ws_col == 0) ? 80 : tsiz.ws_col;
		t_rows = (tsiz.ws_row == 0) ? 80 : tsiz.ws_row;
	}
#else
	struct ttysize tsiz;

	if(ioctl(0, TIOCGSIZE, &tsiz) == NULL)
	{
		t_cols = (tsiz.ts_cols == 0) ? 80 : tsiz.ts_cols;
		t_rows = (tsiz.ts_lines == 0) ? 24 : tsiz.ts_lines;
	}
#endif
	else
	{
		t_cols = 80;
		t_rows = 24;
	}
	scroll_reg(1, t_rows-2);
	cprintf(1,"%s=== VChat === Type \".h\" to get help ===%*s%7s %3dx%-3d %s",
		vt(REVERSE | BOLD | FG_WHITE | BG_BLUE),
		t_cols-55, " ", emulation, t_cols, t_rows,
		vt(OFF));

	mv(1,t_rows);

	printf("%s%s", vt(OFF), vt(BOLD));

	fflush(stdout);
}
