#define UmsBase UMSBase

#include <exec/types.h>

#include <clib/exec_protos.h>
#ifdef _DCC
#include <proto/exec.h>
#else
#include <pragmas/exec_pragmas.h>
#endif

#include <libraries/ums.h>
#include <clib/ums_protos.h>
#ifdef _DCC
#include <proto/ums.h>
#else
#include <pragmas/ums_pragmas.h>
#endif

#include <libraries/dos.h>
#include <clib/dos_protos.h>
#ifdef _DCC
#include <proto/dos.h>
#else
#include <pragmas/dos_pragmas.h>
#include <dos.h>
#endif

#include <clib/locale_protos.h>
#ifdef _DCC
#include <proto/locale.h>
#else
#include <pragmas/locale_pragmas.h>
#endif


#include <dos/dos.h>
#include <dos/datetime.h>
#include <dos/rdargs.h>

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

#include "date.h"

/* SMAKE */

// Version String
// --------------

static char VersionString[] = "$VER: sumswrite 2.6a (13.2.94)";

static char UsageString[] = "\
  U=User      : user name.\n\
  P=Password  : user's password.\n\
  S=Server    : server name.\n\n\
Message will be read from standard input. See docs for file format.\n\n\
";


// Template
// --------

static char *TemplateString = "U=User/A,P=Password/A,S=Server/K";
enum opts {
	OPT_USER, OPT_PASSWORD, OPT_SERVER,
	OPT_COUNT};
static LONG opts[OPT_COUNT];


// Globals
// -------

extern struct Library *DOSBase;

struct Library *UMSBase = NULL;
UMSUserAccount acc = NULL;

#define KW_STRING  0
#define KW_NUMBER  1
#define KW_BOOLEAN 2
#define KW_DATE    3

struct Keyword
{
	char *name;
	LONG type;
	LONG tag;
	APTR data;
} Keywords[]=
{
	{ "MsgNum"      , KW_NUMBER , UMSTAG_WMsgNum      , NULL },
	{ "MsgDate"     , KW_DATE   , UMSTAG_WMsgDate     , NULL },
	{ "ChainUp"     , KW_NUMBER , UMSTAG_WChainUp     , NULL },
	{ "HardLink"    , KW_NUMBER , UMSTAG_WHardLink    , NULL },
	{ "SoftLink"    , KW_NUMBER , UMSTAG_WSoftLink    , NULL },
	{ "AutoBounce"  , KW_BOOLEAN, UMSTAG_WAutoBounce  , NULL },
	{ "HdrFill"     , KW_NUMBER , UMSTAG_WHdrFill     , NULL },
	{ "TxtFill"     , KW_NUMBER , UMSTAG_WTxtFill     , NULL },
	{ "NoUpdate"    , KW_BOOLEAN, UMSTAG_WNoUpdate    , NULL },
	{ "FromName"    , KW_STRING , UMSTAG_WFromName    , NULL },
	{ "FromAddr"    , KW_STRING , UMSTAG_WFromAddr    , NULL },
	{ "ToName"      , KW_STRING , UMSTAG_WToName      , NULL },
	{ "ToAddr"      , KW_STRING , UMSTAG_WToAddr      , NULL },
	{ "MsgID"       , KW_STRING , UMSTAG_WMsgID       , NULL },
	{ "CreationDate", KW_STRING , UMSTAG_WCreationDate, NULL },
	{ "ReceiveDate" , KW_STRING , UMSTAG_WReceiveDate , NULL },
	{ "ReferID"     , KW_STRING , UMSTAG_WReferID     , NULL },
	{ "Group"       , KW_STRING , UMSTAG_WGroup       , NULL },
	{ "Subject"     , KW_STRING , UMSTAG_WSubject     , NULL },
	{ "Attributes"  , KW_STRING , UMSTAG_WAttributes  , NULL },
	{ "Comments"    , KW_STRING , UMSTAG_WComments    , NULL },
	{ "Organization", KW_STRING , UMSTAG_WOrganization, NULL },
	{ "Distribution", KW_STRING , UMSTAG_WDistribution, NULL },
	{ "Folder"      , KW_STRING , UMSTAG_WFolder      , NULL },
	{ "FidoID"      , KW_STRING , UMSTAG_WFidoID      , NULL },
	{ "MausID"      , KW_STRING , UMSTAG_WMausID      , NULL },
	{ "ReplyGroup"  , KW_STRING , UMSTAG_WReplyGroup  , NULL },
	{ "ReplyName"   , KW_STRING , UMSTAG_WReplyName   , NULL },
	{ "ReplyAddr"   , KW_STRING , UMSTAG_WReplyAddr   , NULL },
	{ "FidoText"    , KW_STRING , UMSTAG_WFidoText    , NULL },
	{ "ErrorText"   , KW_STRING , UMSTAG_WErrorText   , NULL },
	{ "Newsreader"  , KW_STRING , UMSTAG_WNewsreader  , NULL },
	{ NULL,0,0,0 }
};


// CTRL-C Stuff
// ------------

VOID chkabort(VOID) {}
#define ABORTED (SetSignal(0,0) & SIGBREAKF_CTRL_C)


struct Keyword *FindKeyword(UBYTE *name)
{
	struct Keyword *k;
	for (k=Keywords;k->name;k++)
		if (!strnicmp(name,k->name,strlen(k->name))) return(k);
	return(NULL);
}


BOOL GetTrueFalse(char *str)
{
	if (!stricmp(str,"true") || !stricmp(str,"on") || !stricmp(str,"yes") || !stricmp(str,"ein") || !stricmp(str,"an") || !stricmp(str,"ja"))
		return(TRUE);
	else
		return(FALSE);
}


BOOL HandleLine(char *line)
{
	struct Keyword *k;
	int len=strlen(line);
	if (!len) return(TRUE);
	if (line[len-1]=='\n') line[len-1]=0;
	if (!(k=FindKeyword(line))) return(FALSE);
	line+=strlen(k->name);
	while (isspace(*line)) line++;
	if (*line=='=') line++;
	while (isspace(*line)) line++;
	if (!*line && k->type==KW_BOOLEAN) line="true";
	if (!*line) return(TRUE);
	switch (k->type)
	{
		case KW_STRING:	k->data = strdup(line);
								break;
		case KW_NUMBER:	k->data = (APTR)atol(line);
								break;
		case KW_BOOLEAN:	k->data = (APTR)(*line ? GetTrueFalse(line) : TRUE);
								break;
		case KW_DATE:		k->data = (APTR)DateToSeconds(line);
								break;
	}
	return(TRUE);
}


// Main Function
// -------------

int main(int argc,char *argv[])
{
	static char buffer[256];
	static struct TagItem Tags[30];
	int erg = RETURN_FAIL;
	BOOL text=FALSE;
	char *textbuf=NULL,*newbuf,*tptr;
	int textbufsize=0,textlen=0,c;
	struct RDArgs *args_ptr;

	if (argc<2 || *argv[1] == '?')
		fprintf(stderr,"\33[1m%s\33[0m, written by Stefan Stuntz, Public Domain\n\nTemplate: %s\n%s",&VersionString[6],TemplateString,UsageString);

	{
		int i;

		for (i=0; i<OPT_COUNT; i++)
		opts[i]=NULL;
	}

	if (args_ptr = ReadArgs(TemplateString, opts, NULL))
	{
		if (UMSBase = OpenLibrary("ums.library",10))
		{
			if (acc = UMSRLogin((char *)opts[OPT_SERVER],(char *)opts[OPT_USER],(char *)opts[OPT_PASSWORD]))
			{
				while (!feof(stdin))
				{
					if (text)
					{
						if ((c=fgetc(stdin))==EOF) break;
						if (textlen==textbufsize)
						{
							if (!(newbuf=malloc(textbufsize+10001))) { text=FALSE; break; }
							if (textbuf)
							{
								CopyMem(textbuf,newbuf,textbufsize);
								free(textbuf);
							}
							textbuf=newbuf;
							textbufsize+=10000;
							tptr=textbuf+textlen;
						}
						*tptr++=c;
						textlen++;
					}
					else
					{
						if (fgets(buffer,255,stdin))
						{
							if (buffer[0]=='-')
							{
								text=TRUE;
							}
							else if (!HandleLine(buffer))
							{
								fprintf(stderr,"\7Invalid line: \"%s\"\n",buffer);
							}
						}
					}
				}

				if (text)
				{
					struct Keyword *k;
					struct TagItem *t=Tags;
					for (k=Keywords;k->name;k++)
					{
						if (k->data)
						{
							t->ti_Tag  = k->tag;
							t->ti_Data = (LONG)((k->tag==UMSTAG_WGroup && k->data && !stricmp(k->data,"Netmail") ? NULL : (LONG)k->data));
							t++;
						}
					}
					t->ti_Tag  = UMSTAG_WMsgText;
					t->ti_Data = (LONG)textbuf;
					t++;
					t->ti_Tag = TAG_DONE;

					*tptr=0;

					if (WriteUMSMsg(acc,Tags))
					{
						printf("Message written.\n");
						erg=0;
					}
					else
						fprintf(stderr,"\7UMS-Error %ld: %s\n",UMSErrNum(acc),UMSErrTxt(acc));
				}
				else
					fprintf(stderr,"\7Missing message text.\n");

				UMSLogout(acc);
			}
			else printf("\7UMS-Login failed.\n");


			CloseLibrary(UMSBase);
		}
		else printf("\7Could not open ums.library V10.\n");

		FreeArgs(args_ptr);
	}
	else
	{
		PrintFault(IoErr(), NULL);
		return(RETURN_ERROR);
	}

	return(erg);
}
