// --------------------------------------------------------------------------
// Citadel: TermOvl.CPP
//
// Overlayed terminal emulation stuff.

#include "ctdl.h"
#pragma hdrstop

#include "log.h"
#include "blurbs.h"
#include "term.h"


// --------------------------------------------------------------------------
// Contents
//
// autoansi()			Handles auto ansi detect.


// --------------------------------------------------------------------------
// autoansi(): This sets term at according to cfg.autoansi or does actual
//	auto ansi detect.

void autoansi(void)
	{
	char x;
	char inch;
	char detected = 0;
	long t;

	if (cfg.autoansi == 0)
		{
		setdefaultTerm(0);
		}
	else if (cfg.autoansi == 2)
		{
		setdefaultTerm(2);
		TI()CurrentUser->SetIBMANSI(TRUE);
		TI()CurrentUser->SetIBMColor(TRUE);
		}
	else
		{
		if (TI()modStat)
			{
			mPrintf(pctss, getmsg(85));

			TI()SerialPort.Flush();

			for (x = 0; x < 3 && !TI()SerialPort.IsInputReady(); x++)
				{
				outstring("[6n");
				pause(50);
				}

			if (TI()SerialPort.IsInputReady())
				{
				inch = (char)TI()SerialPort.Input();

				if (inch == ESC)
					{
					detected = TRUE;
					mPrintfCR(getmsg(87));
					doCR();
					setdefaultTerm(2);
					TI()CurrentUser->SetIBMANSI(TRUE);
					TI()CurrentUser->SetIBMColor(TRUE);
					}
				}

			if (!detected)
				{
				mPrintfCR(getmsg(88));
				CRmPrintf(getmsg(89));

				t = time(NULL);

				TI()SerialPort.Flush();

				inch = 0;

				do
					{
					if (TI()SerialPort.IsInputReady())
						{
						inch = (char)TI()SerialPort.Input();
						}

					if (KBReady())
						{
						inch = (char) ciChar();
						}

					inch = toupper(inch);
					} while (SerialPort.HaveCarrier() && (inch != ' ') &&
							(inch != 'A') && (inch != 'S') &&
							(inch != ESC) && ((uint) (time(NULL) - t) < 5));

				doCR();

				if (toupper(inch) == 'A')
					{
					setdefaultTerm(2);
					TI()CurrentUser->SetIBMANSI(TRUE);
					TI()CurrentUser->SetIBMColor(TRUE);
					}
				else
					{
					setdefaultTerm(0);
					}
				}
			}
		else
			{
			setdefaultTerm(2);
			TI()CurrentUser->SetIBMANSI(TRUE);
			TI()CurrentUser->SetIBMColor(TRUE);
			}
		}

	TI()SerialPort.Flush();
	}


// --------------------------------------------------------------------------
// setdefaultcolors(): Sets default colors.

void setdefaultcolors(void)
	{
	if (TI()CurrentUser->IsIBMColor())
		{
		TI()CurrentUser->SetAttribute(ATTR_BOLD, 14);
		TI()CurrentUser->SetAttribute(ATTR_BLINK, 128);
		TI()CurrentUser->SetAttribute(ATTR_NORMAL, 15);
		TI()CurrentUser->SetAttribute(ATTR_REVERSE, 78);
		TI()CurrentUser->SetAttribute(ATTR_UNDERLINE, 13);
		}
	else
		{
		TI()CurrentUser->SetAttribute(ATTR_BOLD, 8);
		TI()CurrentUser->SetAttribute(ATTR_BLINK, 128);
		TI()CurrentUser->SetAttribute(ATTR_NORMAL, 7);
		TI()CurrentUser->SetAttribute(ATTR_REVERSE, 112);
		TI()CurrentUser->SetAttribute(ATTR_UNDERLINE, 1);
		}
	}


// --------------------------------------------------------------------------
// setdefaultTerm(): Setup the terminal
//
// 0=tty, 1=mono, 2=color, 3=vt100

void setdefaultTerm(char t)
	{
	switch (t)
		{
		case 0: // TTY
			{
			TI()term.bold[0] = 0;
			TI()term.ibmAnsi = 0;
			TI()term.blink[0] = 0;
			TI()term.under[0] = 0;
			TI()term.ibmColor = 0;
			TI()term.normal[0] = 0;
			TI()term.inverse[0] = 0;
			break;
			}

		case 1: // Mono
			{
			strcpy(TI()term.normal, "[0m");
			strcpy(TI()term.bold,	"[1m");
			strcpy(TI()term.inverse,"[7m");
			strcpy(TI()term.blink,	"[5m");
			strcpy(TI()term.under,	"[4m");
			TI()term.ibmAnsi = 1;
			TI()term.ibmColor = 0;
			break;
			}

		case 2: // Color
			{
			strcpy(TI()term.normal, "[0;1;37;40m");
			strcpy(TI()term.bold,	"[1;33;40m");
			strcpy(TI()term.inverse,"[1;33;41m");
			strcpy(TI()term.blink,	"[5m");
			strcpy(TI()term.under,	"[1;35;40m");
			TI()term.ibmAnsi = 1;
			TI()term.ibmColor = 1;
			break;
			}

		case 3: // VT100
			{
			strcpy(TI()term.normal, "[0m");
			strcpy(TI()term.bold,	"[1m");
			strcpy(TI()term.inverse,"[7m");
			strcpy(TI()term.blink,	"[5m");
			strcpy(TI()term.under,	"[4m");
			TI()term.ibmAnsi = 0;
			TI()term.ibmColor = 0;
			break;
			}
		}
	}


// --------------------------------------------------------------------------
// setlogTerm(): Setup the terminal according to TI()CurrentUser.

void setlogTerm(void)
	{
	if (TI()CurrentUser->IsIBMANSI())
		{
		strcpy(TI()term.normal, 
				attrtoansi(TI()CurrentUser->GetAttribute(ATTR_NORMAL), 1));

		strcpy(TI()term.bold, 
				attrtoansi(TI()CurrentUser->GetAttribute(ATTR_BOLD), 0));

		strcpy(TI()term.inverse, 
				attrtoansi(TI()CurrentUser->GetAttribute(ATTR_REVERSE), 0));

		strcpy(TI()term.blink, 
				attrtoansi(TI()CurrentUser->GetAttribute(ATTR_BLINK), 0));

		strcpy(TI()term.under, 
				attrtoansi(TI()CurrentUser->GetAttribute(ATTR_UNDERLINE), 0));
		}
	else
		{
		TI()term.normal[0] = 0;
		TI()term.bold[0] = 0;
		TI()term.inverse[0] = 0;
		TI()term.blink[0] = 0;
		TI()term.under[0] = 0;
		}

	TI()term.ibmAnsi = TI()CurrentUser->IsIBMGraph();
	TI()term.ibmColor = TI()CurrentUser->IsIBMColor();
	}


// --------------------------------------------------------------------------
// askAttributes(): Lets the user config own colors.

void askAttributes(LogEntry1 *EditLog)
	{
	doCR();

	EditLog->SetAttribute(ATTR_NORMAL, (int) GetNumberWithBlurb(getmsg(94),
			0L, 255L, EditLog->GetAttribute(ATTR_NORMAL), B_COLORS));

	EditLog->SetAttribute(ATTR_BLINK, (int) GetNumberWithBlurb(getmsg(95),
			0L, 255L, EditLog->GetAttribute(ATTR_BLINK), B_COLORS));

	EditLog->SetAttribute(ATTR_REVERSE, (int) GetNumberWithBlurb(getmsg(96),
			0L, 255L, EditLog->GetAttribute(ATTR_REVERSE), B_COLORS));

	EditLog->SetAttribute(ATTR_BOLD, (int) GetNumberWithBlurb(getmsg(98),
			0L, 255L, EditLog->GetAttribute(ATTR_BOLD), B_COLORS));

	EditLog->SetAttribute(ATTR_UNDERLINE, (int) GetNumberWithBlurb(getmsg(99),
			0L, 255L, EditLog->GetAttribute(ATTR_UNDERLINE), B_COLORS));

	setlogTerm();
	}

// This function is a bit ugly. Oh well.
Bool IsColorOrFormattingOnly(const char *Code)
	{
	return (isdigit(*Code) ||
			(toupper(*Code) >= 'A' && toupper(*Code) <= 'H') ||
			toupper(*Code) == 'R');
	}
