// --------------------------------------------------------------------------
// Citadel: Down.CPP
//
// Code to bring Citadel down.

#include "ctdl.h"
#pragma hdrstop

#include "libovl.h"
#include "music.h"
#include "config.h"
#include "group.h"
#include "hall.h"
#include "scrlback.h"
#include "timer.h"
#include "cfgfiles.h"
#include "cwindows.h"
#include "mouse.h"
#include "events.h"
#include "term.h"


// --------------------------------------------------------------------------
// Contents
//
// crashout()			Fatal system error
// exitcitadel()		Done with cit, time to leave


// --------------------------------------------------------------------------
// crashout(): Fatal system error.

void cdecl crashout(const char *message, ...)
	{
	FILE *fd;			// Record some crash data
	char buf[256];
	va_list ap;

	va_start(ap, message);
	vsprintf(buf, message, ap);
	va_end(ap);

	Hangup();

	bufferedClose(msgfl);
	citClose(&TI()OC.PrintFile);
	citClose(&trapfl);
	citClose(&roomfl);
	citClose(&journalfl);

	fd = fopen(citfiles[C_CRASH_CIT], FO_W);
	fprintf(fd, pcts, buf);
	fclose(fd);

	cfg.attr = 7;	// exit with white letters
	cfg.battr = 0;	// and black border

	outstring(cfg.modunsetup);
	outstring(br);

	TI()SerialPort.DropDtr();
	TI()SerialPort.Deinit();

	freeTables();
	DestroyScrollBackBuffer();

#ifndef WINCIT
	position(0, 0);

	for (int i = 0; i < strlen(getmsg(785)); i++)
		{
		cPrintf(pctc, getmsg(785)[i]);
		doccr();
		}

	cPrintf(pcts, buf);
	doccr();

	(*deinitkbd)();
	(*close_sound)();
	deinitMouseHandler();
	deinit_internal_sound();

	delete [] vidDriver;
	delete [] comDriver;
	delete [] kbdDriver;

	curson();
#else
	MessageBox(NULL, buf, NULL, MB_ICONSTOP | MB_OK);
#endif

	DeinitializeTimer();
	critical(FALSE);
	exit(199);
	}


// --------------------------------------------------------------------------
// exitcitadel(): Done with cit, time to leave.

void exitcitadel(void)
	{
	static Bool ShutdownStarted;	// I just know someone will try to
									// #CALL ExitCitadel in a SHUTDOWN #EVENT

	if (!ShutdownStarted)
		{
		TI()ExitToMsdos = FALSE;	// Script processor aborts if TRUE
		ShutdownStarted = TRUE;
		doEvent(EVT_SHUTDOWN);
		TI()ExitToMsdos = TRUE; 	// Probably not needed
		}

	CITWINDOW *w = CitWindowsMsg(NULL, getmsg(1672));

	GroupData->Save();
	HallData->Save();

	writeTables();

	trap(getmsg(786), T_SYSOP);

	// close all files
	bufferedClose(msgfl);
	citClose(&TI()OC.PrintFile);
	citClose(&trapfl);
	citClose(&roomfl);
	citClose(&journalfl);

	if (!slv_door)
		{
		Hangup();
		outstring(cfg.modunsetup);
		outstring(br);

		TI()SerialPort.DropDtr();
		}

	TI()SerialPort.Deinit();

	if (w)
		{
		destroyCitWindow(w, FALSE);
		}

	deinitMouseHandler();

	cfg.attr = 7;	// exit with white letters
	cfg.battr = 0;	// and black border

	outPhys(TRUE);
	cls(SCROLL_NOSAVE);

	setdefaultTerm(2); // Not sure about this.
	char dtstr[80];
	strftime(dtstr, 79, cfg.vdatestamp, 0l);
	cPrintf(getmsg(509), spc, dtstr);
	doccr();

	cPrintf(getmsg(510), ns, diffstamp(uptimestamp));
	doccr();

	freeTables();
	DestroyScrollBackBuffer();

#ifndef WINCIT
	(*deinitkbd)();
	(*close_sound)();
	deinit_internal_sound();

	delete [] vidDriver;
	delete [] comDriver;
	delete [] kbdDriver;

	curson();

	DeinitializeTimer();
	critical(FALSE);
	exit(return_code);
#endif
	}
