/* UserList.c - Zeus UserList replacement
 *
 *
 * To Do:  - Add (press any key to abort list)
 *         ? Add computer type
 *
 */

#include <exec/types.h>
#include <proto/exec.h>
#include <proto/dos.h>

#define	USE_DOORLIB

#include <proto/pipeline.h>
#include <proto/pipeutil.h>

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

/* #define DEBUG 1 */

struct Library *PipelineBase;
struct Library *PipeUtilBase;
struct User		 *u;
struct UserKey *uk;
long					 LineNumber;
ULONG					 WriteFlags;

typedef struct tuser
{
	UBYTE ur_Alias[40];
	UBYTE ur_Name[40];
	UBYTE Age;
	UBYTE ur_Access;
	UBYTE	ur_Computer;
	UBYTE ur_Town[20];
	UBYTE ur_County[20];
	UBYTE ur_Country[20];
};

BOOL		printit;

int CalcAge ( struct tm *t, struct User *user );
int __saveds MatchFunc ( ULONG Number, ULONG SecondArg );

static UBYTE   *VersTag = "\0$VER: UserList 1.4 "__AMIGADATE__;

/* Zeus routine to calculate user age from a time struct (as returned by GMTime()) */
int
CalcAge ( struct tm *t, struct User *user )
{
	signed	int	Age;
	signed	int	Mon;

	Age = t->tm_year - (user->ur_DOB_Year - 1900) ;

	Mon = (t->tm_mon + 1) - user->ur_DOB_Mon;
	if ( Mon < 0 )
	{
		Age --;
	} else
	if ( ! Mon )
	{
		Mon = t->tm_mday - user->ur_DOB_Day;
		if ( Mon < 0 )
		{
			Age --;
		}
	}
	return ( Age ) ;
}


int __saveds
MatchFunc ( ULONG Number, ULONG SecondArg )
{
#ifdef DEBUG
sprintf(obuff, "%lu:%lu ", Number, SecondArg);
LPuts(obuff);
#endif
	if(Number == SecondArg)
	{
		printit = TRUE;
		
		/* Returning 0 tells ParseNum() to quit */
		
		return(0);
	}

	return ( 1 ) ;
}


int main(int argc, char **argv)
{
	struct	Line		*le;
	UBYTE					 buff[80], obuff[256];
	struct	tm	t;
	struct	parsekey	 Key;
	struct tuser TUser;
	struct tuser *tu;

	char match[7][41], tmatch[2][51];

	int  		c;

	BOOL 		ok;
	BOOL		printall;

	if( argc != 2 )
	{
		Printf( "This door must be run as a ZDOOR!\n\n" );
		Printf( "Usage: %s <Line Number>\n\n", argv[0] );
		return(11);
	}

	tu = &TUser;

	for(c=0;c<6;c++)
		strcpy(match[c], "[Not Set]");

	if (PipelineBase = OpenLibrary("zeus.library", 0))
	{
		LineNumber = atol( argv[1] );
		le = GetLine( LineNumber );

		if( !le )
		{
			Printf( "Illegal line number!\n\n" );
			CloseLibrary( PipelineBase );
			return(10);
		}

		WriteFlags = NULL;

		if ( PipeUtilBase = OpenLibrary ( "zmf.library", 0 ) )
		{
			LPuts ( "\n[1;37mZeus Userlist Utility v1.3 (c)1995-1996 by Rod Schnell\n\n" ) ;
			sprintf( obuff, "[0;32mMatch Patterns\n\n"
							"[1;37m1[0;32m) Alias    : [1;37m%s\n"
							"[1;37m2[0;32m) RealName : [1;37m%s\n"
							"[1;37m3[0;32m) Age      : [1;37m%s\n"
							"[1;37m4[0;32m) Access   : [1;37m%s\n"
							"[1;37m5[0;32m) City     : [1;37m%s\n"
							"[1;37m6[0;32m) Prov     : [1;37m%s\n\n",
							match[0],
							match[1],
							match[2],
							match[3],
							match[4],
							match[5]);
			LPuts(obuff);

			Menu:

			LPuts("[0;32mEnter match # to change (return to continue): [K[1;37m");
			ReadLineTags( LineNumber, buff, RLT_MakeUpper, TRUE, RLT_Opts, "Q123456\r", TAG_DONE );
			
			c = buff[0];
		
			switch(c)
			{
			case '1': /* Alias */
				sprintf( obuff, "[8A[K[1;37m1[0;32m) Alias    : [1;33m%s", "");
				LPuts(obuff);
				ReadLineTags( LineNumber, match[6], RLT_MaxLen, 40,  TAG_DONE );
				if( match[6] )
				{
					strcpy(match[0], match[6]);
					sprintf( obuff, "[6B", NULL);
					LPuts(obuff);
				}
				else
				{
					sprintf( obuff, "[1A[K[1;37m1[0;32m) Alias    : [1;37m[Not Set][6B\n", NULL);
					LPuts(obuff);
				}
				goto Menu;
				break;
			case '2': /* RealName */
				sprintf(obuff, "[7A[K[1;37m2[0;32m) RealName : [1;33m%s", "");
				LPuts(obuff);
				ReadLineTags( LineNumber, match[6], RLT_MaxLen, 40,  TAG_DONE );
				if( match[6] )
				{
					strcpy(match[1], match[6]);
					LPuts("[5B");
				}
				else
				{
					sprintf(obuff, "[1A[K[1;37m2[0;32m) RealName : [1;37m[Not Set][5B\n", NULL);
					LPuts(obuff);
				}
				goto Menu;
				break;
			case '3': /* Age */
				sprintf(obuff, "[6A[K[1;37m3[0;32m) Age      : [1;33m%s", "");
				LPuts(obuff);
				ReadLineTags( LineNumber, match[6], RLT_MaxLen, 40,  TAG_DONE );
				if( match[6] )
				{
					strcpy(match[2], match[6]);
					LPuts("[4B");
				}
				else
				{
					sprintf(obuff, "[1A[K[1;37m3[0;32m) Age      : [1;37m[Not Set][4B\n", NULL);
					LPuts(obuff);
				}
				goto Menu;
				break;
			case '4': /* Access */
				sprintf(obuff, "[5A[K[1;37m4[0;32m) Access   : [1;33m%s", "");
				LPuts(obuff);
				ReadLineTags( LineNumber, match[6], RLT_MaxLen, 40,  TAG_DONE );
				if( match[6] )
				{
					strcpy(match[3], match[6]);
					LPuts("[3B");
				}
				else
				{
					sprintf(obuff, "[1A[K[1;37m4[0;32m) Access   : [1;37m[Not Set][3B\n", NULL);
					LPuts(obuff);
				}
				goto Menu;
				break;
			case '5': /* City */
				sprintf(obuff, "[4A[K[1;37m5[0;32m) City     : [1;33m%s", "");
				LPuts(obuff);
				ReadLineTags( LineNumber, match[6], RLT_MaxLen, 40,  TAG_DONE );
				if( match[6] )
				{
					strcpy(match[4], match[6]);
					LPuts("[2B");
				}
				else
				{
					sprintf(obuff, "[1A[K[1;37m5[0;32m) City     : [1;37m[Not Set][2B\n", NULL);
					LPuts(obuff);
				}
				goto Menu;
				break;
			case '6': /* Prov */
				sprintf(obuff, "[3A[K[1;37m6[0;32m) Prov     : [1;33m%s", "");
				LPuts(obuff);
				ReadLineTags( LineNumber, match[6], RLT_MaxLen, 40,  TAG_DONE );
				if( match[6] )
				{
					strcpy(match[5], match[6]);
					LPuts("[1B");
				}
				else
				{
					sprintf(obuff, "[1A[K[1;37m6[0;32m) Prov     : [1;37m[Not Set][1B\n", NULL);
					LPuts(obuff);
				}
				goto Menu;
				break;
			default:
				LPuts("\n");
				break;
			}
						
			GMTime ( Time ( NULL ), &t ) ;
		
			printall = TRUE;

			/* convert match strings to lower case */

			for(c = 0;c < 6;c++)
			{
				if(strlen(match[c]) && strcmp(match[c], "[Not Set]"))
				printall = FALSE;
				strlwr(match[c]);
			}

			/* add leading 1 and/or trailing 255 to unterminated ranges */
			/* Workaround for zmf.library bug in ParseNum() function    */
			tmatch[0][0] = NULL;
			tmatch[1][0] = NULL;
			if(match[2][0] == '-') strcpy(tmatch[0], "1");
			strcat(tmatch[0], match[2]);
			if(match[2][strlen(match[2])-1] == '-') strcat(tmatch[0], "255");
			if(match[3][0] == '-') strcpy(tmatch[1], "1");
			strcat(tmatch[1], match[3]);
			if(match[3][strlen(match[3])-1] == '-') strcat(tmatch[1], "255");
#ifdef DEBUG
sprintf(obuff, "\n%s   %s\n\n", tmatch[0], tmatch[1]);
LPuts(obuff);
#endif

			if (uk = InitUserKey(KEY_ALPHAFORWARD))
			{
				ok = TRUE;
				if( le->le_User->ur_Flags & UF_CLRSCR)
					LPuts("[2J[H");
				LPuts("[0;32mAlias                RealName             Age Acc Location\n");
				while( ok )
				{
					u = LoadUserFromKey( uk );

	/* Use a temp user struct to hold the data we need, so we can make changes */
  /* (strlwr, etc.) without affecting/changing any of the original data.     */

					tu->Age = CalcAge ( &t, u ) ;
					if(!printall)
					{
						printit = FALSE;

						/* Copy necessary user data to temp buffer */

						strcpy(tu->ur_Alias, u->ur_Alias);
						strcpy(tu->ur_Name, u->ur_Name);
						strcpy(tu->ur_Town, u->ur_Town);
						strcpy(tu->ur_County, u->ur_County);

						/* convert temp strings to lower case */

						strlwr(tu->ur_Alias);
						strlwr(tu->ur_Name);
						strlwr(tu->ur_Town);
						strlwr(tu->ur_County);

						if(strstr(tu->ur_Alias, match[0])) printit = TRUE;
						if(strstr(tu->ur_Name, match[1])) printit = TRUE;

						/* Age and ur_Access (numeric range strings) need special treatment */

						if(strlen(match[2]))
						{
							InitParse ( &Key, tmatch[0] );
							Key.firstnum = 1;
							Key.endno = 255;
							ParseNum ( &Key, MatchFunc, tu->Age );
						}
						if(strlen(match[3]))
						{
							InitParse ( &Key, tmatch[1] );
							Key.firstnum = 1;
							Key.endno = 255;
							ParseNum ( &Key, MatchFunc, u->ur_Access );
						}

						if(strstr(tu->ur_Town, match[4])) printit = TRUE;
						if(strstr(tu->ur_County, match[5])) printit = TRUE;
					}
					if(printit || printall)
					{
						/* takes 84 chars */
						sprintf( obuff,	"[1;37m%-20.20s %-20.20s %3d %3d %.15s, %.5s, %.10s[0m\n",
										u->ur_Alias,
										u->ur_Name,
										tu->Age,
										u->ur_Access,
										u->ur_Town,
										u->ur_County,
										u->ur_Country);
						LPuts(obuff);
					}
					ok = NextUserKey( uk );
					/* Use GetHotChar instead of ReadLineTags RLT_NoWait because *
           * ReadLineTags messes up Press any key prompts.             */
					if( c = GetHotChar(LineNumber, TRUE))
						ok = FALSE;
				}
			
				EndUserKey(uk);
			}
			CloseLibrary(PipeUtilBase);
		}
		else
		{
			CloseLibrary( PipelineBase );
			LPuts("Could not open zmf.library!\n");
			return(20);
		}
		CloseLibrary(PipelineBase);
	}
	else
	{
		printf("Zeus is not running!\n", NULL);
		return(40);
	}
}

