/*

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

              Request Door for DayDream BBS V1.10 By Hydra!

        Experienced C-programmers may find some parts lamely coded,
                          as I'm not a C-Guru :)

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

*/

#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>
#include <dos/dostags.h>

struct Requ {
        char req_what[50];
        char req_by[32];
        char req_when[10];
	};

struct Muisti {
	char BUFFER[2048];
	char BUFFER2[2048];
	char Dataname[100];
	char Listpath[100];
	UWORD conf;
	UWORD base;
	char MsgOutput[100];
        char Receiver[100];
        };

void ReDraw(void);
void ClearEntry(ULONG Suuda);
ULONG CountNodes(struct NodeStruct *);
void UpdateEntry(ULONG);
int AddRequest(char *);
void RemoveLF(char *);
int ReadConfig(void);
int WriteList(void);
int mycpy(char *, char *, int);
int HandleCode(char *, char *, int, int, struct Requ *);
void ListRequests(int);
int DeleteRequest(char *);

struct Muisti *Vars;
struct Library	*DDBase;
struct DIFace	*d;
struct DDPointers *Pointers;
UWORD CurrSelect;

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

	Vars=AllocMem(sizeof(struct Muisti),0);
	DDBase=(struct Library *)OpenLibrary("dreamdoor.library",4);
	if(DDBase==NULL)
	{
		printf("Needs DreamDoor.library V4.0+ 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 (ReadConfig()) {

	ChangeActivity(d,"DD-Request");

	ReDraw();
        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) {
           ClearEntry(CurrSelect);
	   CurrSelect=0;
           UpdateEntry(CurrSelect);
           }
             sodma=AddRequest(argv[1]);
             ReDraw();
             if (sodma==0) Exit=1;
           break;
	 case '2': /* two */
	 if (CurrSelect!=1) {
           ClearEntry(CurrSelect);
	   CurrSelect=1;
           UpdateEntry(CurrSelect);
           }
             ListRequests(1);
             ReDraw();
             break;
	 case '3': /* three */
	 if (CurrSelect!=2) {
           ClearEntry(CurrSelect);
	   CurrSelect=2;
           UpdateEntry(CurrSelect);
           }
             sodma=DeleteRequest(argv[1]);
             ReDraw();
             break;
	 case '4': 
	 if (CurrSelect!=3) {
           ClearEntry(CurrSelect);
	   CurrSelect=3;
           UpdateEntry(CurrSelect); }
           Exit=1;
           break;
         case 13:
         case 10:
           switch (CurrSelect)
           {
             case 3:
             Exit=1;
             break;
             case 0:
             sodma=AddRequest(argv[1]);
	     ReDraw();
             if (sodma==0) Exit=1;
             break;
             case 1:
             ListRequests(1);
             ReDraw();
             break;
             case 2:
             sodma=DeleteRequest(argv[1]);
             ReDraw();
             break;
           }

	}
        if (Answer==0) Exit=1;
        }
        SendString(d,"[0mThank you for using DD-Request V1.1!\n\n");
        }
        else
        {
	SendString(d,"Error while reading configfile!\n\n");
        }        
        FreeMem(Pointers,sizeof(struct DDPointers));
	CloseDoor(d);
	CloseLibrary(DDBase);
	FreeMem(Vars,sizeof(struct Muisti));
}

void ClearEntry(ULONG clearme)
{
  if (clearme==0) SendString(d,"[4A[74D                          [36m1[35m) [0mAdd request                                   [4B[1C");
  if (clearme==1) SendString(d,"[3A[74D                          [36m2[35m) [0mList requests                                 [3B[1C");
  if (clearme==2) SendString(d,"[2A[74D                          [36m3[35m) [0mDelete Request                                [2B[1C");
  if (clearme==3) SendString(d,"[A[74D                          [36m4[35m) [0mQuit to BBS                                   [B[1C");
}

int AddRequest(char *mynode)
{
   struct Requ requesti;
   struct DateStamp dates;
   struct DateTime datet;
   int resultti;
   LONG sihi;
   BPTR Handle;
   BPTR Handle2;
   register int pos;
   register int pos2;
   int kili;
   char Puskuri[300];

   SendString(d,"\n[36mDescribe request: [44m                                                    [52D[36m");
   resultti=Prompt(d,requesti.req_what,49,0,0);
   if (resultti==1)
   {
     if (requesti.req_what[0]!=0)
      {
     DateStamp(&dates);
     datet.dat_Stamp=dates;
     datet.dat_Format=FORMAT_CDN;
     datet.dat_Flags=0;
     datet.dat_StrDay=0;
     datet.dat_StrDate=requesti.req_when;
     datet.dat_StrTime=0;
     DateToStr(&datet);
     strcpy(requesti.req_by,Pointers->dp_CurrUser->user_handle);
     SendString(d,"[0;36mAre you sure? ([0mYes[36m/[0mno[36m)?: [35m");
     sihi=YesNo(d,1);
     if (sihi==-1) return(0);
     if (sihi==0) return(1);
     Handle=Open(Vars->Dataname,MODE_READWRITE);
     if (Handle==0) { SendString(d,"\n[36mError in writing!\n"); return(1); }
     Seek(Handle,0,OFFSET_END);
     Write(Handle,&requesti,sizeof(struct Requ));
     Close(Handle);
     WriteList();
     if (Vars->conf)
     {
       SendString(d,"[0;36m\nLeave message? ([0mYes[36m/[0mno[36m)?: [35m");
       sihi=YesNo(d,1);
       if (sihi==-1) return(0);
       if (sihi==0) return(1);
       Handle=Open(Vars->MsgOutput,MODE_OLDFILE);
       if (Handle==0) { SendString(d,"\n[36mCan't find Msg-Design!\n"); return(1); }
       sprintf(Puskuri,"T:DDReq-Temp.%s",mynode);
       if (Handle2=Open(Puskuri,MODE_NEWFILE))
       {
          while(FGets(Handle,Vars->BUFFER,2000))
          {
            pos=0;
            pos2=0;
            while(Vars->BUFFER[pos]!=0)
            {
              if (Vars->BUFFER[pos]=='%') { kili=HandleCode(Vars->BUFFER,Vars->BUFFER2,pos,pos2,&requesti); pos=pos+2; pos2=pos2+kili; } else {
              Vars->BUFFER2[pos2]=Vars->BUFFER[pos];
              pos2++;pos++; }
            }           
            Vars->BUFFER2[pos2]=0;
            FPuts(Handle2,Vars->BUFFER2);
          }
        Close(Handle2);
        sprintf(Vars->BUFFER,"RoboWriter CONF %d BASE %d MESSAGE %s FROM \"%s\" TO \"%s\" SUBJECT Request",Vars->conf,Vars->base,Puskuri,requesti.req_by,Vars->Receiver);
        SystemTags(Vars->BUFFER,SYS_Input,0,SYS_Output,0);
       }
       Close(Handle);

     }
      }
   }
   SendString(d,"[0m");
   return(resultti);
}

/* Sorry if this string formatting routine is lame, but I'm not a C-Guru :-) */

int HandleCode(char *perse, char *perse1, int pos1, int pos2, struct Requ *myreq)
{
  int kili;

  pos1++;
  if (perse[pos1]=='r') kili=mycpy(perse1,myreq->req_what,pos2);
  if (perse[pos1]=='a') kili=mycpy(perse1,myreq->req_by,pos2);
  if (perse[pos1]=='d') kili=mycpy(perse1,myreq->req_when,pos2);
  perse1[kili+pos2]=0;

  return(kili);
}

int mycpy(char *perse, char *perse1, int sod)
{
  register int p=0;
  
  while(perse1[p]!=0)
  {
   perse[sod]=perse1[p]; p++; sod++;
  }
  return(p);
}

int WriteList(void)
{
   struct Requ requesti;
   BPTR Handle;
   BPTR THandle=0;
   BPTR GHandle=0;
   char Puskuri[300];
   int reqcount=1;

   Handle=Open(Vars->Dataname,MODE_OLDFILE);
   if (Handle==0) return(0);
   sprintf(Puskuri,"%s.TXT",Vars->Listpath);
   if (THandle=Open(Puskuri,MODE_NEWFILE))
   {
    sprintf(Puskuri,"%s.GFX",Vars->Listpath);
    if (GHandle=Open(Puskuri,MODE_NEWFILE))
    {
     FPuts(THandle,".----.------------------------------------------.-----------------.----------.\n|  # | Description                              | Requester       | Date     |\n)----+------------------------------------------+-----------------+----------(\n");
     FPuts(GHandle,"[0;34m.----.------------------------------------------.-----------------.----------.\n| [36;44m #[0;34m | [36;44mDescription                             [0;34m | [36;44mRequester      [0;34m | [36;44mDate    [0;34m |\n)----+------------------------------------------+-----------------+----------(\n");
     
     while(Read(Handle,&requesti,sizeof(struct Requ)))
     {
      sprintf(Vars->BUFFER,"| %02d | %-40.40s | %-15.15s | %s |\n",reqcount,requesti.req_what,requesti.req_by,requesti.req_when);
      FPuts(THandle,Vars->BUFFER);
      sprintf(Vars->BUFFER,"| [35m%02d [34m|[36m %-40.40s [34m| [33m%-15.15s [34m| [32m%s [34m|\n",reqcount,requesti.req_what,requesti.req_by,requesti.req_when);
      FPuts(GHandle,Vars->BUFFER);
      reqcount++;
     }
     FPuts(THandle,"`----^------------------------------------------^--[DD-Req by Hydra/Insane]--'\n");
     FPuts(GHandle,"[34m`----^------------------------------------------^--[[35mDD-Req by Hydra/Insane[34m]--'\n");
     Close(GHandle);
    }
    Close(THandle);
   }
   Close(Handle);

}

void UpdateEntry(ULONG updateme)
{
  if (updateme==0) SendString(d,"[4A[76D[44m                          [36m1[35m) [37mADD REQUEST                                   [0m[4B[D");
  if (updateme==1) SendString(d,"[3A[76D[44m                          [36m2[35m) [37mLIST REQUESTS                                 [0m[3B[D");
  if (updateme==2) SendString(d,"[2A[76D[44m                          [36m3[35m) [37mDELETE REQUEST                                [0m[2B[D");
  if (updateme==3) SendString(d,"[A[76D[44m                          [36m4[35m) [37mQUIT TO BBS                                   [0m[B[D");
}

int ReadConfig(void)
{
char Puskuri[300];
register BPTR CFGHandle;
int poro;

	CFGHandle = Open("ENV:Dreamutils",MODE_OLDFILE);
	if (!CFGHandle) return(0);
        poro=Read(CFGHandle,Puskuri,260);
	Puskuri[poro]=0;
	Close(CFGHandle);

	sprintf(Vars->BUFFER,"%sDDRequest.CFG",Puskuri);
	CFGHandle=Open(Vars->BUFFER,MODE_OLDFILE);
	if (!CFGHandle) return(0);

	FGets(CFGHandle,Puskuri,250);
	RemoveLF(Puskuri);
	strcpy(Vars->Dataname,Puskuri);

	FGets(CFGHandle,Puskuri,250);
	RemoveLF(Puskuri);
	strcpy(Vars->Listpath,Puskuri);

	FGets(CFGHandle,Puskuri,250);
	RemoveLF(Puskuri);
	Vars->conf=atoi(Puskuri);

	FGets(CFGHandle,Puskuri,250);
	RemoveLF(Puskuri);
	Vars->base=atoi(Puskuri);

	FGets(CFGHandle,Puskuri,250);
	RemoveLF(Puskuri);
	strcpy(Vars->MsgOutput,Puskuri);

	FGets(CFGHandle,Puskuri,250);
	RemoveLF(Puskuri);
	strcpy(Vars->Receiver,Puskuri);

	Close(CFGHandle); return(1);
}

void RemoveLF(char *stringi)
{
register int kohta=0;
register int keepon=0;

  while (keepon==0)
  {
    if (stringi[kohta]==0) { keepon=1; } else {
     if (stringi[kohta]==10) { stringi[kohta]=0 ; keepon=1; } else {
       kohta++;
      }
     }
  }
}

void ReDraw(void)
{
	DisplayFile(d,"DD-Request",DDF_ADDEXTENSION);
	SendString(d,"[34m.---------------------------------------------------------------------------.\n");
SendString(d,"|                          [36m1[35m) [0mAdd request                                   [34m|\n");
SendString(d,"|                          [36m2[35m) [0mList requests                                 [34m|\n");
SendString(d,"|                          [36m3[35m) [0mDelete Request                                [34m|\n");
SendString(d,"|                          [36m4[35m) [0mQuit to BBS                                   [34m|\n");
SendString(d,"`----------------------------------------[[33m DD-Request V1.1 By Hydra/Insane [34m]'");

	CurrSelect=3;
	UpdateEntry(3);
}

void ListRequests(int more)
{
  WriteList();
  
  SendString(d,"\n");
  if (Pointers->dp_CurrDisplay->DISPLAY_ATTRIBUTES&(1L<<0))
  { sprintf(Vars->BUFFER,"%s.GFX",Vars->Listpath); } else {
    sprintf(Vars->BUFFER,"%s.TXT",Vars->Listpath); }
  DisplayFile(d,Vars->BUFFER,0);
  if (more) {
  Pause(d);
  }
}

int DeleteRequest(char *mynode)
{
 struct Requ requesti;
 int resultti;
 BPTR Handle;
 BPTR Handle2;
 char Puskuri[300];
 int snikkei=0;
 int delthis;
 int count=1;
 int delacc=0;
 int del;
 int match=0;

 while (snikkei==0)
 { SendString(d,"[36m\nDelete request # (L for list) :");
   resultti=Prompt(d,Puskuri,2,0,0);
   if (resultti==0) return(0);
   if (Puskuri[0]==0) return(1);
   if (Puskuri[0]=='l' || Puskuri[0]=='L' ) { ListRequests(0); } else {
     delthis=atoi(Puskuri);
     if (Handle=Open(Vars->Dataname,MODE_OLDFILE))
     {
       sprintf(Puskuri,"%s.%s",Vars->Dataname,mynode);
       if (Handle2=Open(Puskuri,MODE_NEWFILE))
       {
         while(Read(Handle,&requesti,sizeof(struct Requ)))
         {
           if (count==delthis) {
            match=1;
            if (Pointers->dp_CurrUser->user_securitylevel==255) delacc=1;
            del=strcmp(Pointers->dp_CurrUser->user_handle,requesti.req_by);
            if (del==0) delacc=1;
            if (delacc==0) { SendString(d,"[0mYou have are not allowed to delete that request! [34m<[33mResume[34m> ");
                             GetKey(d,0); count++; Write(Handle2,&requesti,sizeof(struct Requ)); } else
            {
              count++; match=2;
           } 
            } else {
            Write(Handle2,&requesti,sizeof(struct Requ));
            count++;
           }
         }
       if (match==0) { SendString(d,"[0mRequest # not found! [34m<[33mResume[34m> "); GetKey(d,0); }
       Close(Handle2);
       }
     Close(Handle);
     if (match==2) { DeleteFile(Vars->Dataname); Rename(Puskuri,Vars->Dataname); } else
      {
        DeleteFile(Puskuri);
     }
     snikkei=1;
  }

 }
}
}
