/*

  ***********************************************************************

     InterActive Status door for DayDream BBS V1.00 By Hydra!

     Note that the code is not optimized to the maximum, because i
     wanted to make it easy to read. I think this demonstrates well enough
     how to use dreamdoor.library when coding doors for DayDream BBS.

     Sas/C 6.50 tells warnings because of those time_t things. I was
     unable to fix them, sorry..

  ***********************************************************************

*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <proto/dddoor.h>
#include <libraries/dddoor.h>
#include <proto/exec.h>
#include <proto/dos.h>
#include <daydream.h>
#include <exec/memory.h>
#include <dos.h>

struct	Library	*DDBase;
struct	DIFace	*d;
struct	DDPointers *Pointers;

void ClearEntry(ULONG Suuda);
void UpdateEntry(ULONG updateme);
void HandleCAccess(ULONG, char *);
ULONG CountNodes(struct NodeStruct *);

char BUFFER[2048];

int main(int argc, char *argv[])
{
UWORD CurrSelect=NULL;
UWORD Exit=NULL;
ULONG Answer=NULL;

	DDBase=(struct Library *)OpenLibrary("dreamdoor.library",1);
	if(DDBase==NULL)
	{
		printf("Needs DreamDoor.library V1.00+ to run\n");
		exit(10);
	}
	d=InitDoor(argv[1]);		/* Establish link with DD */

	if(d==NULL)
		{
		printf("Hey Asswipe, this program requires DayDream BBS!\n");
		CloseLibrary(DDBase);
		exit(10);
		}

	Pointers = AllocMem(sizeof(struct DDPointers),MEMF_PUBLIC|MEMF_CLEAR);
	InquirePointers(d,Pointers);

	if (!strcmp("?",Pointers->dp_DoorParams)) {
	SendString(d,"[36m          Selleri Statusdoor V1.0 for DayDream BBS by Hydra/Selleri!\n[34m          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n[32m                              Humanoid Invasion\n                               +358-81-5409139\n                                     24h	\n");
	} else {

	SendString(d,"[0 p[36m.--------------------.  .--------------------------------------------------.\n");
	SendString(d,"[36m|[35m 1) General Info    [0;34m|  [36m|                                                  [34m|\n");
	SendString(d,"[36m|[35m 2) File Stats      [34m|  [36m|                                                 [34m |\n");
	SendString(d,"[36m|[35m 3) Msg Stats       [34m|  [36m|                                                 [34m |\n");
	SendString(d,"[36m|[35m 4) Board Info      [34m|  [36m|                                                 [34m |\n");
	SendString(d,"[36m`[34m--------------------'  [36m|                                                  [34m|\n");
	SendString(d,"                        [36m|                                                  [34m|\n");
	SendString(d,"[33m DD-Stats V1.0 By Hydra [36m|                                                  [34m|\n");
	SendString(d,"[33m Cursor keys to select. [36m|                                                  [34m|\n");
	SendString(d,"                        [36m|                                                  [34m|\n");
	SendString(d,"[33m Q => Quit         [36m     |                                                  [34m|\n");
	SendString(d,"                        [36m|                                                  [34m|\n");
	SendString(d,"                        [36m|                                                  [34m|\n");
	SendString(d,"                        [36m|                                                  [34m|\n");
	SendString(d,"                        [36m|                                                  [34m|\n");
	SendString(d,"                        [36m|                                                  [34m|\n");
	SendString(d,"                        [36m|                                                  [34m|\n");
	SendString(d,"                        [36m|                                                  [34m|\n");
	SendString(d,"                        [36m|                                                  [34m|\n");
	SendString(d,"                        [36m`[34m--------------------------------------------------'\n");
	UpdateEntry(0);

        while (Exit==0)
        {
         Answer=GetKey(d,HOTKEY_CURSOR);
         switch (Answer)
         {
         case 0:
         case 'q': /* q */
	 case 'Q': /* Q */
	 case 27:
         Exit=1;
	 break;
         case 251: /* Cursor down */
           ClearEntry(CurrSelect);
	   CurrSelect++;
  	   if (CurrSelect==4) CurrSelect=0;
           UpdateEntry(CurrSelect);
           break;
         case 250: /* Cursor up */
           ClearEntry(CurrSelect);
	   CurrSelect--;
  	   if (CurrSelect==-1) CurrSelect=3;
           UpdateEntry(CurrSelect);
           break;
	 case '1': /* one */
	 if (CurrSelect==0) break;
           ClearEntry(CurrSelect);
	   CurrSelect=0;
           UpdateEntry(CurrSelect);
           break;
	 case '2': /* two */
	 if (CurrSelect==1) break;
           ClearEntry(CurrSelect);
	   CurrSelect=1;
           UpdateEntry(CurrSelect);
           break;
	 case '3': /* three */
	 if (CurrSelect==2) break;
           ClearEntry(CurrSelect);
	   CurrSelect=2;
           UpdateEntry(CurrSelect);
           break;
	 case '4': /* four */
	 if (CurrSelect==3) break;
           ClearEntry(CurrSelect);
	   CurrSelect=3;
           UpdateEntry(CurrSelect);
           break;
	}

         if (Answer==0) Exit=1;

        }
	SendString(d,"[1 p");
}
        FreeMem(Pointers,sizeof(struct DDPointers));
	CloseDoor(d);
	CloseLibrary(DDBase);
 	exit(0);
}

void ClearEntry(ULONG clearme)
{
  if (clearme==0) SendString(d,"[2;2H[0;35m 1) General Info    ");
  if (clearme==1) SendString(d,"[3;2H[0;35m 2) File Stats      ");
  if (clearme==2) SendString(d,"[4;2H[0;35m 3) Msg Stats       ");
  if (clearme==3) SendString(d,"[5;2H[0;35m 4) Board Info      ");
}

void UpdateEntry(ULONG updateme)
{
char confbuf[48];
char buffer2[48];
char clean[2]=" ";
time_t callinfo;
struct InfoData info;
struct DayDream_User *UserOnLine;
ULONG lrp;
ULONG freefast;
UserOnLine=Pointers->dp_CurrUser;

  if (updateme==0) 
  {
	SendString(d,"[2;2H[0;44m 1) GENERAL INFO    [0m");
        sprintf(BUFFER,"[2;27H[0;33mReal Name [34m: [32m%-36.36s[3;27H[33mHandle    [34m: [32m%-36.36s",UserOnLine->user_realname,UserOnLine->user_handle);
	SendString(d,BUFFER);
        sprintf(BUFFER,"[4;27H[0;33mLocation  [34m: [32m%-36.36s[5;27H[33mOrganizat.[34m: [32m%-36.36s",UserOnLine->user_zipcity,UserOnLine->user_organization);
	SendString(d,BUFFER);
        sprintf(BUFFER,"[6;27H[0;33mPhone     [34m: [32m%-36.36s[7;27H%-48.48s",UserOnLine->user_voicephone,clean);
	SendString(d,BUFFER);
	callinfo=UserOnLine->user_firstcall+252460800;
	sprintf(BUFFER,"[8;27H[0;33mFirst Call     [34m: [32m%s[8;68H       ",(ULONG)ctime((time_t)&callinfo));
	SendString(d,BUFFER);
	callinfo=Pointers->dp_Lastcall+252460800;
	sprintf(BUFFER,"[9;27H[0;33mLast Call      [34m: [32m%s[9;68H       [10;27H[0;33mCalls          [34m: [32m%-30d",(ULONG)ctime((time_t)&callinfo),(UWORD)UserOnLine->user_connections);
	SendString(d,BUFFER);
	sprintf(BUFFER,"[11;27H%-48.48s[12;27H[33mTime Left/Limit[34m: [32m%4d [34m/ [32m%4d [34mmins            [13;27H%-48.48s",clean,UserOnLine->user_timeremaining,UserOnLine->user_dailytimelimit,clean);
	SendString(d,BUFFER);
	sprintf(BUFFER,"[14;27H[33mBPS Rate   [34m: [32m%-36d[15;27H%-48.48s[16;27H[33mConf Access[34m :%-36.36s",Pointers->dp_BpsRate,clean,clean);
	SendString(d,BUFFER);
	HandleCAccess(UserOnLine->user_conferenceacc1,confbuf);
	sprintf(BUFFER,"[17;27H[32m%-48.48s",confbuf);
	SendString(d,BUFFER);
	HandleCAccess(UserOnLine->user_conferenceacc2,confbuf);
	sprintf(BUFFER,"[18;27H[32m%-48.48s",confbuf);
	SendString(d,BUFFER);
  }
 
  if (updateme==1)
  {
	 SendString(d,"[3;2H[0;44m 2) FILE STATS      [0m");
	 if (UserOnLine->user_fileratio==0) { strcpy(confbuf,"None"); } else { sprintf(confbuf,"1:%ld",(ULONG)UserOnLine->user_fileratio); }
	 if (UserOnLine->user_byteratio==0) { strcpy(buffer2,"None"); } else { sprintf(buffer2,"1:%ld",(ULONG)UserOnLine->user_byteratio); }
         sprintf(BUFFER,"[2;27H[0;33mFile Ratio[34m: [32m%-36s[3;27H[33mByte ratio[34m: [32m%-36s[4;27H%-48.48s",confbuf,buffer2,clean);
         SendString(d,BUFFER);
	 sprintf(confbuf,"%d [34mfiles, [32m%ld [34mbytes",UserOnLine->user_ulfiles,UserOnLine->user_ulbytes);
	 sprintf(buffer2,"%d [34mfiles, [32m%ld [34mbytes",UserOnLine->user_dlfiles,UserOnLine->user_dlbytes);
         sprintf(BUFFER,"[5;27H[0;33mUploads   [34m: [32m%-36s[6;27H[33mDownloads [34m: [32m%-36s[7;27H%-48.48s",confbuf,buffer2,clean);
         SendString(d,BUFFER);
	 sprintf(confbuf,"%d [34mfiles, [32m%ld [34mbytes",UserOnLine->user_freedlfiles,UserOnLine->user_freedlbytes);
         sprintf(BUFFER,"[8;27H%-48.48s[8;27H[0;33mFree dl's [34m: [32m%-32s    [9;27H%-48s",clean,confbuf,clean);
         SendString(d,BUFFER);
	 if (UserOnLine->user_fileratio==0) { strcpy(confbuf,"Unlimited"); } else { sprintf(confbuf,"%ld",(ULONG)(UserOnLine->user_fileratio*UserOnLine->user_ulfiles)-UserOnLine->user_dlfiles+UserOnLine->user_freedlfiles); }
	 if (UserOnLine->user_byteratio==0) { strcpy(buffer2,"Unlimited"); } else { sprintf(buffer2,"%ld",(ULONG)(UserOnLine->user_byteratio*UserOnLine->user_ulbytes)-UserOnLine->user_dlbytes+UserOnLine->user_freedlbytes); }
         sprintf(BUFFER,"[10;27H[0;33mFiles left[34m: [32m%-36s[11;27H[33mBytes left[34m: [32m%-36s[12;27H%-48.48s",confbuf,buffer2,clean);
         SendString(d,BUFFER);
	 sprintf(confbuf,"%d [34mfiles, [32m%ld [34mbytes",UserOnLine->user_fakedfiles,UserOnLine->user_fakedbytes);
         sprintf(BUFFER,"[13;27H[0;33mFakes     [34m: [32m%-36s[14;27H%-48.48s",confbuf,clean);
         SendString(d,BUFFER);

         getdfs(Pointers->dp_CurrentNode->ns_Currnode->MULTI_TEMPORARY,&info);
	 sprintf(BUFFER,"[15;27H[33mFree space on temp directory [34m: [32m%11ld [33mbytes",(info.id_NumBlocks - info.id_NumBlocksUsed)* info.id_BytesPerBlock);
         SendString(d,BUFFER);
         getdfs(Pointers->dp_CurrConf->CONF_ULPATH,&info);
	 sprintf(BUFFER,"[16;27H[33mFree space on ul directory   [34m: [32m%11ld [33mbytes[17;27H%-48.48s[18;27H%-48.48s",(info.id_NumBlocks - info.id_NumBlocksUsed)* info.id_BytesPerBlock,clean,clean);
         SendString(d,BUFFER);

  }
  if (updateme==2) 
  {
	lrp=GetLrp(d,Pointers->dp_CurrConf->CONF_NUMBER,Pointers->dp_CurrBase->MSGBASE_NUMBER);

	SendString(d,"[4;2H[0;44m 3) MSG STATS       [0m");
        sprintf(BUFFER,"[2;27H[0;33mPub msgs  [34m: [32m%-36d[3;27H[33mPrv msgs  [34m: [32m%-36d[4;27H%-48s[5;27H[33mBase Information%-30s[6;27H[34m~~~~~~~~~~~~~~~~%-30s",UserOnLine->user_pubmessages,UserOnLine->user_pvtmessages,clean,clean,clean);
	SendString(d,BUFFER);
        sprintf(BUFFER,"[7;27H[0;33mTotal Messages [34m: [32m%-32d",Pointers->dp_CurrBase->MSGBASE_HIGHEST-Pointers->dp_CurrBase->MSGBASE_LOWEST);
	SendString(d,BUFFER);
        sprintf(confbuf,"%ld [34m([32m%ld [34munread)",lrp,Pointers->dp_CurrBase->MSGBASE_HIGHEST-lrp);
	sprintf(BUFFER,"[8;27H%-48s[8;27H[0;33mYour last read [34m: [32m%-32s[9;27H%-48s",clean,confbuf,clean);
	SendString(d,BUFFER);
        sprintf(confbuf,"[32m%5d [34m/ [32m%5d",Pointers->dp_CurrBase->MSGBASE_LOWEST,Pointers->dp_CurrBase->MSGBASE_HIGHEST);
	sprintf(BUFFER,"[10;27H%-48s[10;27H[0;33mLowest/Highest [34m: [32m%-32s[11;27H%-48s",clean,confbuf,clean);
	SendString(d,BUFFER);
	if (Pointers->dp_CurrBase->MSGBASE_FN_TAG[0]==0) { strcpy(confbuf,"-"); } else { strcpy(confbuf,Pointers->dp_CurrBase->MSGBASE_FN_TAG); }
	if (Pointers->dp_CurrBase->MSGBASE_FN_ZONE==0) { strcpy(buffer2,"-"); } else { sprintf(buffer2,"%d:%d/%d.%d",Pointers->dp_CurrBase->MSGBASE_FN_ZONE,Pointers->dp_CurrBase->MSGBASE_FN_NET,Pointers->dp_CurrBase->MSGBASE_FN_NODE,Pointers->dp_CurrBase->MSGBASE_FN_POINT); }
        sprintf(BUFFER,"[12;27H[0;33mFidoTag   [34m: [32m%-36s[13;27H[33mFidoAddr. [34m: [32m%-36s[14;27H%-48.48s",confbuf,buffer2,clean);
	SendString(d,BUFFER);
	if (Pointers->dp_CurrBase->MSGBASE_FN_ORIGIN[0]==0) { strcpy(confbuf,"-"); } else { strcpy(confbuf,Pointers->dp_CurrBase->MSGBASE_FN_ORIGIN); }
        sprintf(BUFFER,"[15;27H[0;33mOrigin    [34m: %-36s[16;27H[32m%-48.48s[17;27H%-48.48s[18;27H%-48.48s",clean,confbuf,clean,clean);
	SendString(d,BUFFER);
  }
  if (updateme==3) { SendString(d,"[5;2H[0;44m 4) BOARD INFO      [0m");
        sprintf(BUFFER,"[2;27H[0;33mBBS Name  [34m: [32m%-36s[3;27H[33mSysOp     [34m: [32m%-36s[4;27H%-48s[5;27H[33mNode Information%-30s[6;27H[34m~~~~~~~~~~~~~~~~%-30s",Pointers->dp_DayDream->CFG_BOARDNAME,Pointers->dp_DayDream->CFG_SYSOPNAME,clean,clean,clean);
	SendString(d,BUFFER);
	sprintf(BUFFER,"[7;27H[0;33mDTE Rate  [34m: [32m%-8ld [33mNode Number [34m: [32m%2d [34m/ [32m%2d       ",Pointers->dp_Iodev->IOD_DTERATE,(UWORD)Pointers->dp_CurrentNode->ns_Nodenumber,(UWORD)CountNodes(Pointers->dp_NodeStructure));
	SendString(d,BUFFER);
	sprintf(BUFFER,"[8;27H[0;33mUnit      [34m: [32m%-8ld [33mDriver      [34m: [32m%-13.13s",Pointers->dp_Iodev->IOD_UNIT,Pointers->dp_Iodev->IOD_NAME);
	SendString(d,BUFFER);
        sprintf(confbuf,"[32m%ld [34msecs",Pointers->dp_DayDream->CFG_IDLETIMEOUT);
	sprintf(BUFFER,"[9;27H[0;33mTimeout   [34m: [32m%-36s      [10;27H%-48s",confbuf,clean);
	SendString(d,BUFFER);
	SendString(d,"[11;27H[33mFree Memory                                     [12;27H[34m~~~~~~~~~~~                                     [13;27H[33mChip           Fast            Total            ");
	lrp=AvailMem(MEMF_CHIP); freefast=AvailMem(MEMF_FAST);
	sprintf(BUFFER,"[14;27H[32m%-15ld%-16ld%-17ld[15;27H%-48.48s",lrp,freefast,lrp+freefast,clean);
	SendString(d,BUFFER);
	sprintf(BUFFER,"[16;27H[33mCurrent Conference[34m: [32m%-28s[17;27H%-48.48s[18;27H%-48.48s",Pointers->dp_CurrConf->CONF_NAME,clean,clean);
	SendString(d,BUFFER);
 }
}



void HandleCAccess(ULONG Access, char * Destbuf)
{
UWORD i = 0;
while (i!=32)
 {
  if (Access&(1L<<i)) { Destbuf[i]='X'; } else { Destbuf[i]='_'; }
  i++;
 }
 Destbuf[i]=0;
}

ULONG CountNodes(struct NodeStruct *Nodet)
{
struct NodeStruct *Node;
ULONG i = 0;
UWORD j = 0;
Node=Nodet->ns_Next;
while (j==0)
 {
   i++;
   if (Node==0) j=1;
   Node=Node->ns_Next;
 }
 return(i);
}
