/* PR-QWK - QWK Importer for UMS
 * Copyright (C) 1998 J.Ross Nicoll
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */

#include <dos/dostags.h>
#include <exec/memory.h>
#include <exec/types.h>
#include <libraries/locale.h>
#include <utility/tagitem.h>
#include <utility/utility.h>
#include <workbench/icon.h>
#include <workbench/startup.h>
#include <workbench/workbench.h>

#include <proto/alib.h>
#include <proto/dos.h>
#include <proto/exec.h>
#include <proto/icon.h>
#include <proto/intuition.h>
#include <proto/locale.h>
#include <proto/ums.h>
#include <proto/utility.h>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define CATCOMP_NUMBERS

#include "locale.h"
#include "pr-qwk.h"

static const TEXT UserDefault[] = {"qwk.default"};
static const TEXT ServerDefault[] = {"default"};

#define Local static
#define Prototype extern
#include "PR-QWK-protos.h"

Local BOOL CLIParseArgs(void);
Local BOOL GetMailConfigs(void);
Local BOOL GetShowConfigs(void);
Local BOOL Init(void);
Local BOOL WBParseIcon(void);
Local struct Library *OpenALibrary(STRPTR, ULONG);

Prototype BOOL CheckConfig(void);
Prototype BOOL CLIinit(void);
Prototype BOOL GetConfig(void);
Prototype BOOL WBInit(void);

BOOL CheckConfig(void)
{
	ULONG allocation;

	InboundDirLock = Lock(Inbound, ACCESS_READ);
	if(InboundDirLock == NULL)
	{
		SPrintF(FormatBuffer, GetString(ERRMSG_INBOUND_NOT_EXIST), Inbound);
		PutStr(FormatBuffer);

		return(FALSE);
	}

	TempDirLock = CreateDir(TempDir);
	if(TempDirLock != NULL)
	{
		UnLock(TempDirLock);
	}
	TempDirLock = Lock(TempDir, ACCESS_READ);
	if(TempDirLock == NULL)
	{
		SPrintF(FormatBuffer, GetString(ERRMSG_CANNOT_CREATE_TEMPDIR), TempDir);
		PutStr(FormatBuffer);

		return(FALSE);
	}

	if((NoExport == 0) ||
		(NoImport == 0))
	{
		allocation = (strlen(Site) + 7);
		BaseGroup = AllocPoolVec(allocation);
		if(BaseGroup != NULL)
		{
			SPrintF(BaseGroup, "qwk.%s.", Site);
			BaseGroupLen = strlen(BaseGroup);
			return(TRUE);
		}
		else
		{
			HandleMemoryError(allocation, MISCMSG_BASE_GROUP_NAME);
		}
	}
	else
	{
		DisplayError(GetString(REQMSG_SHIT_HAPPENS_TEXT_FORMAT), REQMSG_MISC_GADGET_FORMAT, REQMSG_SHIT_HAPPENS_TITLE);
	}

	return(FALSE);
}

/* ---------------------------------------------------------------------- */

BOOL CLIinit(void)
{
	InputHandle = Input();
	OutputHandle = Output();

	if(Init() == FALSE) return(FALSE);

	if(CLIParseArgs() == FALSE) return(FALSE);

	return(TRUE);
}

/* ---------------------------------------------------------------------- */

BOOL CLIParseArgs(void)
{
	struct RDArgs *RDArgs;
	ULONG allocation;
	ULONG RDArray[7] = {0,0,0,0,0,0,0};

	RDArgs = AllocDosObject(DOS_RDARGS, &BlankTag);
	if(RDArgs != NULL)
	{
		memset(RDArray, 0, sizeof(STRPTR) * 3);

		RDArgs -> RDA_ExtHelp = GetString(HELPMSG_RDARGS_HELP);

		if(ReadArgs(GetString(HELPMSG_RDARGS_TEMPLATE), RDArray, RDArgs) != NULL)
		{
			if(RDArray[0] == NULL)
			{
				User = strdupPoolVec(UserDefault);
				allocation = strlen(UserDefault) + 1;
			}
			else
			{
				User = strdupPoolVec((STRPTR)RDArray[0]);
				allocation = strlen((STRPTR)RDArray[0]) + 1;
			}
			if(User != NULL)
			{
				if(RDArray[1] == NULL)
				{
					Password = strdupPoolVec(&Blank);
					allocation = 2;
				}
				else
				{
					Password = strdupPoolVec((STRPTR)RDArray[1]);
					allocation = strlen((STRPTR)RDArray[1]);
				}
				if(Password != NULL)
				{
					if(RDArray[2] == NULL)
					{
						Server = strdupPoolVec(ServerDefault);
						allocation = strlen(ServerDefault) + 1;
					}
					else
					{
						Server = strdupPoolVec((STRPTR)RDArray[2]);
						allocation = strlen((STRPTR)RDArray[2]) + 1;
					}
					if(Server != NULL)
					{
						NoExport = RDArray[3];
						NoImport = RDArray[4];
						Keep = RDArray[5];
						ShowDebug = RDArray[6];

						FreeArgs(RDArgs);
						FreeDosObject(DOS_RDARGS, RDArgs);

						return(TRUE);
					}
					else
					{
						HandleMemoryError(allocation, MISCMSG_ARGUMENT_STORAGE);
					}
				}
				else
				{
					HandleMemoryError(allocation, MISCMSG_ARGUMENT_STORAGE);
				}
			}
			else
			{
				HandleMemoryError(allocation, MISCMSG_ARGUMENT_STORAGE);
			}
			FreeArgs(RDArgs);
		}
		else
		{
			DisplayError(GetString(REQMSG_READARGS_TEXT_FORMAT), REQMSG_MISC_GADGET_FORMAT, REQMSG_READARGS_TITLE);
		}
		FreeDosObject(DOS_RDARGS, RDArgs);
	}
	else
	{
		HandleMemoryError(-1, MISCMSG_ARGUMENT_STORAGE);
	}

	return(FALSE);
}

/* ---------------------------------------------------------------------- */

BOOL GetConfig(void)
{
	STRPTR tempStore;
	ULONG allocation;

	ArcCmd = ReadConfig("qwk.arcCmd", "lha a %d %s", MISCMSG_ARCHIVE_COMMAND);
	if(ArcCmd != NULL)
	{
		DearcCmd = ReadConfig("qwk.dearcCmd", "lha x %s", MISCMSG_DEARCHIVE_COMMAND);
		if(DearcCmd != NULL)
		{
			Inbound = ReadConfig("qwk.inbound", "DOWNLOADS:", MISCMSG_INBOUND_PATH);
			if(Inbound != NULL)
			{
				MailFolder = ReadConfig("qwk.mailFolder", "", MISCMSG_MAIL_FOLDER);
				if(MailFolder != NULL)
				{
					MailTo = ReadConfig("qwk.mailTo", NULL, MISCMSG_MAIL_TO);
					if(FatalUMSError == FALSE)
					{
						Outbound = ReadConfig("qwk.outbound", "UPLOADS:", MISCMSG_OUTBOUND_PATH);
						if(Outbound != NULL)
						{
							Site = ReadConfig("qwk.site", "QWK", MISCMSG_SITE_NAME);
							if(Site != NULL)
							{
								if(strlen(Site) <= MAX_SITE_LENGTH)
								{
									UpperCase(Site);

									TempDir = ReadConfig("qwk.tempdir", "T:", MISCMSG_TEMP_STORE_PATH);
									if(TempDir != NULL)
									{
										tempStore = ReadConfig("qwk.bufferSize", "16384", MISCMSG_BUFFER_SIZE);
										if(tempStore != NULL)
										{
											BufferSize = atoi(tempStore);
											FreePoolVec(tempStore);

											if(GetMailConfigs() != FALSE)
											{
												PacketName = ReadConfig("qwk.pktName", "", MISCMSG_PACKET_NAME);
												if(FatalUMSError == FALSE)
												{
													if(GetShowConfigs() != FALSE)
													{
														allocation = (strlen(Site) + 5);
														SiteAddr = AllocPoolVec(allocation);
														if(SiteAddr != NULL)
														{
															strcpy(SiteAddr, Site);
															strcat(SiteAddr, "@qwk");

															return(TRUE);
														}
														else
														{
															HandleMemoryError(allocation, MISCMSG_SITE_ADDRESS);
														}
													}
												}
											}
										}
									}
								}
								else
								{
									PutStr(GetString(ERRMSG_SITE_NAME_LONG));
								}
							}
						}
					}
				}
			}
		}
	}

	return(FALSE);
}

/* ---------------------------------------------------------------------- */

BOOL GetMailConfigs(void)
{
	MailBulletins = ReadBoolConfig("qwk.MailBulletins", TRUE);
	if(FatalUMSError == FALSE)
	{
		MailGoodbye = ReadBoolConfig("qwk.MailGoodbye", FALSE);
		if(FatalUMSError == FALSE)
		{
			MailNews = ReadBoolConfig("qwk.MailNews", TRUE);
			if(FatalUMSError == FALSE)
			{
				MailNewFiles = ReadBoolConfig("qwk.MailNewFiles", TRUE);
				if(FatalUMSError == FALSE)
				{
					MailSession = ReadBoolConfig("qwk.MailSession", FALSE);
					if(FatalUMSError == FALSE)
					{
						MailWelcome = ReadBoolConfig("qwk.MailWelcome", FALSE);
						if(FatalUMSError == FALSE)
						{
							return(TRUE);
						}
					}
				}
			}
		}
	}

	return(FALSE);
}

/* ---------------------------------------------------------------------- */

BOOL GetShowConfigs(void)
{
	ShowBulletins = ReadBoolConfig("qwk.ShowBulletins", FALSE);
	if(FatalUMSError == FALSE)
	{
		ShowGoodbye = ReadBoolConfig("qwk.ShowGoodbye", TRUE);
		if(FatalUMSError == FALSE)
		{
			ShowNews = ReadBoolConfig("qwk.ShowNews", FALSE);
			if(FatalUMSError == FALSE)
			{
				ShowNewFiles = ReadBoolConfig("qwk.ShowNewFiles", FALSE);
				if(FatalUMSError == FALSE)
				{
					ShowSession = ReadBoolConfig("qwk.ShowSession", FALSE);
					if(FatalUMSError == FALSE)
					{
						ShowWelcome = ReadBoolConfig("qwk.ShowWelcome", TRUE);
						if(FatalUMSError == FALSE)
						{
							return(TRUE);
						}
					}
				}
			}	
		}
	}

	return(FALSE);
}

/* ---------------------------------------------------------------------- */

BOOL Init(void)
{
	TEXT text_English[] = {"english"};

	MainPool = LibCreatePool((MEMF_PUBLIC | MEMF_CLEAR), 16384, 4096);
	if(MainPool != NULL)
	{
		LocaleBase = OpenLibrary("locale.library", 38);
		if(LocaleBase != NULL)
		{
			Locale = OpenLocale(NULL);
			Catalog = OpenCatalog(Locale, "PR-QWK",
				OC_BuiltInLanguage, (ULONG)text_English,
				TAG_DONE);
		}

		IntuitionBase = OpenALibrary("intuition.library", 37);
		if(IntuitionBase != NULL)
		{
			AsyncIOBase = OpenALibrary("asyncio.library", 39);
			if(AsyncIOBase != NULL)
			{
				IconBase = OpenALibrary("icon.library", 37);
				if(IconBase != NULL)
				{
					UtilityBase = OpenALibrary("utility.library", 37);
					if(UtilityBase != NULL)
					{
						UMSBase = OpenALibrary(UMSNAME, UMSVERSION);
						if(UMSBase != NULL)
						{
							FileInfoBlock = AllocDosObject(DOS_FIB, &BlankTag);
							if(FileInfoBlock != NULL)
							{
								ioSystemTags[0].ti_Data = InputHandle;
								ioSystemTags[1].ti_Data = OutputHandle;

								return(TRUE);
							}
							else
							{
								HandleMemoryError(-1, MISCMSG_FILE_INFO);
								FreeDosObject(DOS_FIB, FileInfoBlock);
							}
						}
					}
				}
			}
		}
	}

	return(FALSE);
}

/* ---------------------------------------------------------------------- */

BOOL WBInit(void)
{
	InputHandle = Open("CON:////PR-QWK Output/AUTO", MODE_NEWFILE);
	OutputHandle = InputHandle;
	if(OutputHandle == NULL) return(FALSE);
	OldOutputHandle = SelectOutput(OutputHandle);

	if(Init() == FALSE) return(FALSE);

	if(WBParseIcon() == FALSE) return(FALSE);

	return(TRUE);
}

/* ---------------------------------------------------------------------- */

BOOL WBParseIcon(void)
{
	struct DiskObject *obj;
	ULONG maxDirNameLength;

	maxDirNameLength = (FORMAT_BUFFER_SIZE - 2) - strlen(WBStartup -> sm_ArgList -> wa_Name);
	if(NameFromLock(WBStartup -> sm_ArgList -> wa_Lock, FormatBuffer, maxDirNameLength) != FALSE)
	{
		strcat(FormatBuffer, "/");
		strcat(FormatBuffer, WBStartup -> sm_ArgList -> wa_Name);

		obj = GetDiskObject(FormatBuffer);
		if(obj != NULL)
		{
			User = ReadTool(obj, "NAME", UserDefault);
			if(User != NULL)
			{
				Password = ReadTool(obj, "PASSWORD", &Blank);
				if(Password != NULL)
				{
					Server = ReadTool(obj, "SERVER", ServerDefault);
					if(Server != NULL)
					{
						NoExport = ReadBoolTool(obj, "NOEXPORT", FALSE);
						NoImport = ReadBoolTool(obj, "NOIMPORT", FALSE);
						Keep = ReadBoolTool(obj, "KEEP", FALSE);
						ShowDebug = ReadBoolTool(obj, "DEBUG", FALSE);
	
						FreeDiskObject(obj);

						return(TRUE);
					}
				}
			}
			FreeDiskObject(obj);
		}
	}

	return(FALSE);
}

/* ---------------------------------------------------------------------- */

/* This opens a library, reports an error if it can't, then returns
 * either a pointer to the library or NULL.
 *
 * BUG!!!: Because this is run before reading arguments, there is no
 * way for the user to indicate that the program shouldn't display
 * errors, and so if run by a script or similar, it would block the
 * script indefinately.
 * Best solution would be to implement a timer. May move to ReqTools.library
 * later.
 */
struct Library *OpenALibrary(STRPTR Name, ULONG Version)
{
	struct Library *library;

	library = OpenLibrary(Name, Version);
	if(library == NULL)
	{
		SPrintF(FormatBuffer, GetString(REQMSG_OPENLIBRARY_TEXT_FORMAT), Name, Version);
		DisplayError(FormatBuffer, REQMSG_MISC_GADGET_FORMAT, REQMSG_OPENLIBRARY_LIBRARY_ERROR);
	}

	return(library);
}
