#include "/Mailbox.h"
#include "/protos.h"
#include <libraries/zbbs.h>
#include"globals.c"

#define ARGTEMPLATE "C=CONFIG/K"
#define TITLE "Z-BBS System Editor v1.004 © by Michael Neuweiler"

enum { ARG_CONFIG, ARGS };

enum { GD_sys_name, GD_sysop, GD_netzname, GD_sys_passwort,	GD_chat_level,
		GD_bell, GD_screen_front, GD_faxcommand, GD_font, GD_font_size, GD_pri,
		GD_backdrop, GD_interlace, GD_pfade, GD_modem, GD_bretter, GD_users,
		GD_points, GD_daten, GD_ansi, GD_save, GD_quit };

VOID error(STRPTR);
VOID GetSystemGList(VOID);
BOOL CheckFont(VOID);
WORD __stdargs MyEasyRequest(UBYTE *, UBYTE *, ...);

LONG __saveds main()
{
	char configfile[256];
	BPTR FH;

	SysBase = *(struct ExecBase **)4;
	ThisProcess = (struct Process *)SysBase->ThisTask;

	if(!ThisProcess->pr_CLI)
	{
		WaitPort(&ThisProcess->pr_MsgPort);
		WBenchMsg = (struct WBStartup *)GetMsg(&ThisProcess->pr_MsgPort);
	}
	else	WBenchMsg = NULL;

	if(SysBase->LibNode.lib_Version < 36)
	{
		if(ThisProcess->pr_CLI)
		{
			if(DOSBase = OpenLibrary("dos.library", 0))
			{
				Write(ThisProcess->pr_COS, "Kickstart 2.0 or higher required.\a\n", 35);
				ThisProcess->pr_Result2 = ERROR_INVALID_RESIDENT_LIBRARY;
				CloseLibrary(DOSBase);
			}
		}
		else
		{
			if(IntuitionBase = OpenLibrary("intuition.library", 0))
			{
				STATIC struct IntuiText BodyText =  {0, 1, JAM1, 5, 3, NULL, (UBYTE *)"Kickstart 2.0 or higher required.", NULL};
				STATIC struct IntuiText OkayText = {0, 1, JAM1, 6, 3, NULL, (UBYTE *)"Okay", NULL};
				struct Window *Window;

				if(Window = (struct Window *)BuildSysRequest(NULL, &BodyText, NULL, &OkayText, GADGETUP, 301, 46))
				{
					struct IntuiMessage *Message;

					ScreenToFront(Window->WScreen);
					DisplayBeep(Window->WScreen);

					WaitPort(Window->UserPort);
					if(Message = GetMsg(Window->UserPort))
						ReplyMsg(Message);

					FreeSysRequest(Window);
				}

				CloseLibrary(IntuitionBase);
			}
		}

		if(WBenchMsg)
		{
			Forbid();
			ReplyMsg((struct Message *)WBenchMsg);
		}

		return(RETURN_FAIL);
	}

	if(!(DOSBase = OpenLibrary("dos.library", 36)))
		error("dos.library");

	strcpy(configfile, "BBS:Config");
	if(ThisProcess -> pr_CLI)
	{
		UBYTE **ArgArray;

		if(ArgArray = (UBYTE **)AllocVec(sizeof(UBYTE *) * ARGS, MEMF_ANY | MEMF_CLEAR))
		{
			struct RDArgs *ArgsPtr;
			if(ArgsPtr = (struct RDArgs *)AllocVec(sizeof(struct RDArgs), MEMF_ANY | MEMF_CLEAR))
			{
				if(ReadArgs(ARGTEMPLATE, (LONG *)ArgArray, ArgsPtr))
				{
					if(ArgArray[ARG_CONFIG]) strcpy(configfile, ArgArray[ARG_CONFIG]);
				}
				else
				{
					PrintFault(IoErr(),"SysEd");

					FreeArgs(ArgsPtr);
					FreeVec(ArgsPtr);
					FreeVec(ArgArray);
					CloseLibrary(DOSBase);

					return(RETURN_ERROR);
				}
				FreeVec(ArgsPtr);
			}
			FreeVec(ArgArray);
		}
	}
	else
	{
		CurrentDir(WBenchMsg->sm_ArgList->wa_Lock);
	}

	if(!(ZBBSBase = OpenLibrary("zbbs.library", 0)))
		error("zbbs.library");

	if(!(IntuitionBase = OpenLibrary("intuition.library", 36)))
		error("intuition.library");

	if(!(GfxBase = OpenLibrary("graphics.library", 0)))
		error("graphics.library");

	if(!(DiskfontBase = OpenLibrary("diskfont.library", 0)))
		error("diskfont.library");

	if(!(GadToolsBase = OpenLibrary("gadtools.library", 0)))
		error("gadtools.library");

	if(!(Font = OpenDiskFont(&FontAttr)))
		error("topaz.font 8");

	if(!(Scr = OpenScreenTags(NULL,
		SA_Type,			CUSTOMSCREEN,
		SA_DisplayID,	DEFAULT_MONITOR_ID | HIRES_KEY,
		SA_Depth,		2,
		SA_AutoScroll,	TRUE,
		SA_Pens,			&DriPens[0],
		SA_Title,		TITLE,
		TAG_END)))	error("screen");

	if(!(VisualInfo = GetVisualInfo(Scr, TAG_DONE)))
        error("visual-info");

	if(!(Win = OpenWindowTags(NULL,
		WA_Top,				1,
		WA_Left,				0,
		WA_Width,			Scr->Width,
		WA_Height,			Scr->Height - 1,
		WA_AutoAdjust,		TRUE,
		WA_IDCMP, 			BUTTONIDCMP | STRINGIDCMP | IDCMP_MENUPICK |
								IDCMP_REFRESHWINDOW | SLIDERIDCMP | LISTVIEWIDCMP ,
		WA_SmartRefresh,	TRUE,
		WA_GimmeZeroZero,	TRUE,
		WA_Activate,		TRUE,
		WA_CustomScreen,	Scr,
		WA_Title,			TITLE,
		TAG_DONE)))	error("window");

	if(FH = Open(configfile, MODE_OLDFILE))
	{
		char file[256];

		Seek(FH, 0, OFFSET_END);
		if(Seek(FH, 0, OFFSET_BEGINNING) == sizeof(struct Config))
			Read(FH, (UBYTE *)&Config, sizeof(struct Config));
		else
		{
			MyEasyRequest("ERROR: Invalid config file.\nUse converter first.", "Okay");
			Close(FH);
			error(NULL);
		}
		Close(FH);

		SPrintf(file, "%lsStatus", Config.system);
		if(FH = Open(file, MODE_OLDFILE))
		{
			Seek(FH, 0, OFFSET_END);
			if(Seek(FH, 0, OFFSET_BEGINNING) == sizeof(struct Status))
				Read(FH, (UBYTE *)&Status, sizeof(struct Status));
			else
			{
				MyEasyRequest("ERROR: Invalid status file\nUse converter first.", "Okay");
				Close(FH);
				error(NULL);
			}
			Close(FH);
		}
		else
		{
			MyEasyRequest("WARNING: Status file not found.\n Creating new file.", "Okay");
		}
	}
	else
	{
		MyEasyRequest("WARNING: Config file not found.\n Creating new file.", "Okay");
	}

	GetSystemGList();

	while(TRUE)
	{
		Wait(1L << Win->UserPort->mp_SigBit);

		while(imsg = GT_GetIMsg(Win->UserPort))
		{
			class	= imsg->Class;
			code	= imsg->Code;
			g		= imsg->IAddress;

			GT_ReplyIMsg(imsg);

			if(class == IDCMP_GADGETUP)
			{
				switch(g->GadgetID)
				{
					case GD_sys_name:
						strcpy(Config.box_name ,((struct StringInfo *)g->SpecialInfo)->Buffer);
						ActivateGadget(systemGadgets[GD_sysop], Win, NULL);
						break;

					case GD_sysop:
						strcpy(Config.sysop_name ,((struct StringInfo *)g->SpecialInfo)->Buffer);
						ActivateGadget(systemGadgets[GD_netzname], Win, NULL);
						break;

					case GD_netzname:
						strupr(((struct StringInfo *)g->SpecialInfo)->Buffer);
						strcpy(Config.netz_name ,((struct StringInfo *)g->SpecialInfo)->Buffer);
						RefreshGList(g, Win, NULL, 1);
						GT_RefreshWindow(Win, NULL);
						ActivateGadget(systemGadgets[GD_sys_passwort], Win, NULL);
						break;

					case GD_sys_passwort:
						strcpy(Config.system_passwort ,((struct StringInfo *)g->SpecialInfo)->Buffer);
						ActivateGadget(systemGadgets[GD_chat_level], Win, NULL);
						break;

					case GD_chat_level:
						Config.chat_level = ((struct StringInfo *)g->SpecialInfo)->LongInt;
						ActivateGadget(systemGadgets[GD_faxcommand], Win, NULL);
						break;

					case GD_bell:
						Config.bell = (g->Flags & SELECTED);
						break;

					case GD_screen_front:
						Config.screen_front = (g->Flags & SELECTED);
						break;

					case GD_faxcommand:
						strcpy(Config.fax_command ,((struct StringInfo *)g->SpecialInfo)->Buffer);
						ActivateGadget(systemGadgets[GD_font], Win, NULL);
						break;

					case GD_font:
						strcpy(Config.fontname ,((struct StringInfo *)g->SpecialInfo)->Buffer);
						ActivateGadget(systemGadgets[GD_font_size], Win, NULL);
						break;

					case GD_font_size:
						Config.fontsize = ((struct StringInfo *)g->SpecialInfo)->LongInt;
						ActivateGadget(systemGadgets[GD_pri], Win, NULL);
						break;

					case GD_pri:
						Config.priority = ((struct StringInfo *)g->SpecialInfo)->LongInt;
						ActivateGadget(systemGadgets[GD_sys_name], Win, NULL);
						break;

					case GD_backdrop:
						Config.backdrop = (g->Flags & SELECTED);
						break;

					case GD_interlace:
						Config.interlaced = (g->Flags & SELECTED);
						break;

					case GD_pfade:
						Pfade();
						GetSystemGList();
						break;

					case GD_modem:
						Modem();
						GetSystemGList();
						break;

					case GD_daten:
						Daten();
						GetSystemGList();
						break;

					case GD_users:
						Users();
						GetSystemGList();
						break;

					case GD_points:
						Points();
						GetSystemGList();
						break;

					case GD_bretter:
						Brett();
						GetSystemGList();
						break;

					case GD_ansi:
						Ansi();
						GetSystemGList();
						break;

					case GD_save:
						if(!AllPaths())
							MyEasyRequest("Die Konfiguration kann nicht gespeichert werden,\nwenn nicht alle Pfade angegeben wurden.", "Okay");
						else
						{
							if(!CheckFont())
								MyEasyRequest("Die Konfiguration kann nicht gespeichert werden,\nwenn kein gültiger Font angeben wurde.", "Okay");
							else
							{
								if(!CheckSerial())
									MyEasyRequest("Die Konfiguration kann nicht gespeichert werden,\nwenn die Modemeinstellungen nicht stimmen.", "Okay");
								else
								{
									char file[256];

									if(FH = Open(configfile, MODE_NEWFILE))
									{
										Write(FH, (UBYTE *)&Config, sizeof(struct Config));
										Close(FH);
									}
									else
									{
										DisplayBeep(NULL);
										MyEasyRequest("ERROR : Couldn't save config-file !", "Okay");
									}

									SPrintf(file, "%lsStatus", Config.system);
									if(FH = Open(file, MODE_NEWFILE))
									{
										Write(FH, (UBYTE *)&Status, sizeof(struct Status));
										Close(FH);
									}
									else
									{
										DisplayBeep(NULL);
										MyEasyRequest("ERROR : Couldn't save status-file !", "Okay");
									}
									error(NULL);
								}
							}
						}
						break;

					case GD_quit:
						error(NULL);
						break;
				}
			}
		}
	}
	error(NULL);
}

VOID error(STRPTR meldung)
{
	if(meldung)
	{
		if(IntuitionBase)
		{
			MyEasyRequest("ERROR : Couldn't open %ls", "Okay", meldung);
		}
		else	Printf("\nERROR: Couldn't open %ls\n\n", meldung);
	}

	if(Font)			CloseFont(Font);
	if(Win)			CloseWindow(Win);
	if(VisualInfo)	FreeVisualInfo(VisualInfo);
	if(Scr)			CloseScreen(Scr);
	if(glist)		FreeGadgets(glist);

   if(GadToolsBase)  CloseLibrary(GadToolsBase);
	if(DiskfontBase)	CloseLibrary(DiskfontBase);
	if(GfxBase)			CloseLibrary(GfxBase);
	if(IntuitionBase)	CloseLibrary(IntuitionBase);
	if(ZBBSBase)		CloseLibrary(ZBBSBase);
	if(DOSBase)			CloseLibrary(DOSBase);

	Exit(NULL);
}

BOOL CheckFont()
{
	struct TextFont *Font;
	struct TextAttr FontAttr = {NULL, NULL, NULL, NULL};

	FontAttr.ta_Name	= Config.fontname;
	FontAttr.ta_YSize	= Config.fontsize;

	if(!(Font = OpenDiskFont(&FontAttr)))
		return(FALSE);

	CloseFont(Font);
	return(TRUE);
}

VOID GetSystemGList()
{
	if(glist)
	{
		RemoveGList(Win, glist, -1);
		FreeGadgets(glist);
		glist = NULL;
		SetRast(Win->RPort, 0);
	}

    if(!(g = CreateContext(&glist)))
		error("system context");

	ng.ng_LeftEdge		= 148;
	ng.ng_TopEdge		= 30;
	ng.ng_Width			= 160;
	ng.ng_Height		= 14;
	ng.ng_TextAttr		= &FontAttr;
	ng.ng_GadgetText	= "Systemname....:";
	ng.ng_GadgetID		= GD_sys_name;
	ng.ng_Flags			= PLACETEXT_LEFT|NG_HIGHLABEL;
	ng.ng_VisualInfo	= VisualInfo;

	systemGadgets[GD_sys_name] =
	g = CreateGadget(STRING_KIND, g, &ng,
		GTST_String,	Config.box_name,
		GTST_MaxChars,	40,
		TAG_DONE);

	ng.ng_TopEdge		= 47;
	ng.ng_GadgetText	= "Sysopname.....:";
	ng.ng_GadgetID		= GD_sysop;

	systemGadgets[GD_sysop] =
	g = CreateGadget(STRING_KIND, g, &ng,
		GTST_String,	Config.sysop_name,
		GTST_MaxChars,	40,
		TAG_DONE);

	ng.ng_TopEdge		= 64;
	ng.ng_GadgetText	= "Netzname......:";
	ng.ng_GadgetID		= GD_netzname;

	systemGadgets[GD_netzname] =
	g = CreateGadget(STRING_KIND, g, &ng,
		GTST_String,	Config.netz_name,
		GTST_MaxChars,	40,
		TAG_DONE);

	ng.ng_TopEdge		= 81;
	ng.ng_GadgetText	= "Systempasswort:";
	ng.ng_GadgetID		= GD_sys_passwort;

	systemGadgets[GD_sys_passwort] =
	g = CreateGadget(STRING_KIND, g, &ng,
		GTST_String,	Config.system_passwort,
		GTST_MaxChars,	40,
		TAG_DONE);

	ng.ng_TopEdge		= 98;
	ng.ng_Width     	= 37;
	ng.ng_GadgetText	= "Chat-Level....:";
	ng.ng_GadgetID		= GD_chat_level;

	systemGadgets[GD_chat_level] =
	g = CreateGadget(INTEGER_KIND, g, &ng,
		GTIN_Number,	Config.chat_level,
		GTIN_MaxChars,	3,
		TAG_DONE);

	ng.ng_TopEdge		= 115;
	ng.ng_GadgetText	= "Bell..........:";
	ng.ng_GadgetID		= GD_bell;

	systemGadgets[GD_bell] =
	g = CreateGadget(CHECKBOX_KIND, g, &ng,
		GTCB_Checked,	Config.bell,
		TAG_DONE);

	ng.ng_TopEdge		= 129;
	ng.ng_GadgetText	= "Scr to front..:";
	ng.ng_GadgetID		= GD_screen_front;

	systemGadgets[GD_screen_front] =
	g = CreateGadget(CHECKBOX_KIND, g, &ng,
		GTCB_Checked,	Config.screen_front,
		TAG_DONE);

	ng.ng_LeftEdge		= 460;
	ng.ng_TopEdge   	= 30;
	ng.ng_Width   		= 160;
	ng.ng_GadgetText	= "Fax Command:";
	ng.ng_GadgetID		= GD_faxcommand;

	systemGadgets[GD_faxcommand] =
	g = CreateGadget(STRING_KIND, g, &ng,
		GTST_String,	Config.fax_command,
		GTST_MaxChars,	80,
		TAG_DONE);

	ng.ng_TopEdge		= 47;
	ng.ng_GadgetText	= "Font.......:";
	ng.ng_GadgetID		= GD_font;

	systemGadgets[GD_font] =
	g = CreateGadget(STRING_KIND, g, &ng,
		GTST_String,	Config.fontname,
		GTST_MaxChars,	40,
		TAG_DONE);

	ng.ng_TopEdge		= 64;
	ng.ng_Width     	= 37;
	ng.ng_GadgetText	= "Font Grösse:";
	ng.ng_GadgetID		= GD_font_size;

	systemGadgets[GD_font_size] =
	g = CreateGadget(INTEGER_KIND, g, &ng,
		GTIN_Number,	Config.fontsize,
		GTIN_MaxChars,	3,
		TAG_DONE);

	ng.ng_TopEdge		= 81;
	ng.ng_GadgetText	= "Priorität..:";
	ng.ng_GadgetID		= GD_pri;

	systemGadgets[GD_pri] =
	g = CreateGadget(INTEGER_KIND, g, &ng,
		GTIN_Number,	Config.priority,
		GTIN_MaxChars,	3,
		TAG_DONE);

	ng.ng_TopEdge		= 98;
	ng.ng_GadgetText	= "Backdrop...:";
	ng.ng_GadgetID		= GD_backdrop;
	ng.ng_Flags			= PLACETEXT_LEFT|NG_HIGHLABEL;

	systemGadgets[GD_backdrop] =
	g = CreateGadget(CHECKBOX_KIND, g, &ng,
		GTCB_Checked,	Config.backdrop,
		TAG_DONE);

	ng.ng_TopEdge		= 112;
	ng.ng_GadgetText	= "Interlaced.:";
	ng.ng_GadgetID		= GD_interlace;
	ng.ng_Flags			=	PLACETEXT_LEFT|NG_HIGHLABEL;

	systemGadgets[GD_interlace] =
	g = CreateGadget(CHECKBOX_KIND, g, &ng,
		GTCB_Checked,	Config.interlaced,
		TAG_DONE);

	ng.ng_LeftEdge		= 20;
	ng.ng_TopEdge   	= 170;
	ng.ng_Width   		= 80;
	ng.ng_Height 		= 15;
	ng.ng_GadgetText	= "Pfade";
	ng.ng_GadgetID		= GD_pfade;
	ng.ng_Flags			= PLACETEXT_IN;

	systemGadgets[GD_pfade] =
	g = CreateGadget(BUTTON_KIND, g, &ng, TAG_DONE);

	ng.ng_LeftEdge		= 110;
	ng.ng_GadgetText	= "Modem";
	ng.ng_GadgetID		= GD_modem;

	systemGadgets[GD_modem] =
	g = CreateGadget(BUTTON_KIND, g, &ng, TAG_DONE);

	ng.ng_LeftEdge		= 200;
	ng.ng_GadgetText	= "Bretter";
	ng.ng_GadgetID		= GD_bretter;

	systemGadgets[GD_bretter] =
	g = CreateGadget(BUTTON_KIND, g, &ng, TAG_DONE);

	ng.ng_LeftEdge		= 290;
	ng.ng_GadgetText	= "User";
	ng.ng_GadgetID		= GD_users;

	systemGadgets[GD_users] =
	g = CreateGadget(BUTTON_KIND, g, &ng, TAG_DONE);

	ng.ng_LeftEdge		= 20;
	ng.ng_TopEdge   	= 190;
	ng.ng_GadgetText	= "Points";
	ng.ng_GadgetID		= GD_points;

	systemGadgets[GD_points] =
	g = CreateGadget(BUTTON_KIND, g, &ng, TAG_DONE);

	ng.ng_LeftEdge		= 110;
	ng.ng_GadgetText	= "Daten";
	ng.ng_GadgetID		= GD_daten;

	systemGadgets[GD_points] =
	g = CreateGadget(BUTTON_KIND, g, &ng, TAG_DONE);

	ng.ng_LeftEdge		= 290;
	ng.ng_GadgetText	= "Ansi";
	ng.ng_GadgetID		= GD_ansi;

	systemGadgets[GD_ansi] =
	g = CreateGadget(BUTTON_KIND, g, &ng, TAG_DONE);

	ng.ng_LeftEdge		= 480;
	ng.ng_Width     	= 60;
	ng.ng_GadgetText	= "SAVE";
	ng.ng_GadgetID		= GD_save;

	systemGadgets[GD_save] =
	g = CreateGadget(BUTTON_KIND, g, &ng, TAG_DONE);

	ng.ng_LeftEdge		= 550;
	ng.ng_GadgetText	= "QUIT";
	ng.ng_GadgetID		= GD_quit;

	systemGadgets[GD_quit] =
	g = CreateGadget(BUTTON_KIND, g, &ng, TAG_DONE);

	if(!g)	error("system glist");

	AddGList(Win, glist, 0, -1, NULL);
	RefreshGList(glist, Win, NULL, -1);
	GT_RefreshWindow(Win, NULL);

	PrintIText(Win->RPort, systemIText, Win->BorderLeft, Win->BorderTop);
	ActivateGadget(systemGadgets[GD_sys_name], Win, NULL);
}

WORD __stdargs MyEasyRequest(UBYTE *Text, UBYTE *Gadgets, ...)
{
	struct	EasyStruct	Easy;
	struct	Window *window;
	ULONG		IDCMP = NULL;

	if(!Win)
	{
		ULONG lock;

		lock = LockIBase(0);
		window = IntuitionBase->ActiveWindow;
		UnlockIBase(lock);
	}
	else	window = Win;

	Easy.es_StructSize	= sizeof(struct EasyStruct);
	Easy.es_Flags			= NULL;
	Easy.es_Title			= "SysEd Request";
	Easy.es_TextFormat	= Text;
	Easy.es_GadgetFormat	= Gadgets;

	return(EasyRequestArgs(window, &Easy, &IDCMP, (STRPTR)(&Gadgets + 1)));
}

BOOL LoadLine(STRPTR file, LONG line, STRPTR buff)
{
	LONG size;
	STRPTR ptr, buf, buffer;

	line--;
	buff[0] = 0;

	if(buffer = GetFile(file, &size))
	{
		buf = buffer;
		if(ptr = strchr(buf, '\n'))	*ptr = 0;
		while(line-- && buf < buffer + size && ptr)
		{
			buf = ptr + 1;
			if(ptr = strchr(buf, '\n'))	*ptr = 0;
		}

		if(line == -1 && buf < buffer + size)
		{
			strcpy(buff, buf);
			FreeVec(buffer);
			return(TRUE);
		}
		FreeVec(buffer);
	}

	return(FALSE);
}

BOOL OpenWaitWindow()
{
	if(WaitWin)	return(TRUE);

	if(!(WaitWin = OpenWindowTags(NULL,
		WA_Width,			140,
		WA_Height,			30,
		WA_Top,				80,
		WA_Left,				(Scr->Width - 140) / 2,
		WA_Activate,		TRUE,
		WA_SmartRefresh,	TRUE,
		WA_CustomScreen,	Scr,
		TAG_DONE)))	return(FALSE);
	PrintIText(WaitWin->RPort, WaitIText, WaitWin->BorderLeft, WaitWin->BorderTop);

	return(TRUE);
}

VOID CloseWaitWindow()
{
	if(WaitWin)	CloseWindow(WaitWin);
	WaitWin = NULL;
}
