#define UmsBase UMSBase

#include <exec/types.h>

#include <clib/exec_protos.h>
#ifdef _DCC
#include <proto/exec.h>
#else
#include <pragmas/exec_pragmas.h>
#include <dos.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 <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.h>	 woher stammt das eigentlich? es gibt doch nur libraries/dos.h und dos/dos.h?!? [to be deleted] */

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

#include "date.h"


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

static char VersionString[] = "$VER: sumswrite 2.3 (03.11.93)";

static char UsageString[] = "\
 Usage: sumswrite <user> <password>\n\
  <user>    : user name.\n\
  <password>: user's password.\n\
  Message will be read from standard input. See docs for file format.\n\
";


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

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;

	if (argc<3 || argv[1][0]=='?')
	{
		fprintf(stderr,"\33[1m%s\33[0m, written by Stefan Stuntz, Public Domain\n%s",&VersionString[6],UsageString);
		return(RETURN_WARN);
	}

	if (UMSBase = OpenLibrary("ums.library",10))
	{
		if (acc = UMSLogin(argv[1],argv[2]))
		{
			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");

	return(erg);
}
