#include <proto/dos.h>
#include <proto/exec.h>
#include <exec/memory.h>
#include <exec/types.h>
#include <exec/execbase.h>
#include <exec/exec.h>
#include <dos/dostags.h>
#include <dos/stdio.h>
#include <dos/dos.h>
#include <dos/dosextens.h>
#include <dos/var.h>
#include <string.h>
#include <ctype.h>
#include <stdarg.h>
#include <stdio.h>

char user[80];
char node[80];
char nomeraw[200];

#define WWBBSCHATPARSER "STARTMSG,ABORTMSG,ENDMSG,WINDOW"
enum typeconfig {PSTARTMSG=0,PABORTMSG,PENDMSG,PWINDOW,PCFGMAX};

struct DosLibrary *DOSBase=NULL;

__inline static LONG MyFPrintf(BPTR fh, STRPTR format, ... )
{
	va_list argptr;

	va_start(argptr,format);
	return VFPrintf(fh,format,argptr);
}

LONG __stdargs __saveds Start(void)
{
	struct Process *p;
	struct RDArgs *RDA;
	LONG error=RETURN_OK;
	LONG argd[PCFGMAX];
	BPTR SRaw,FIn,FOut;
	LONG c,tm;
	short col;
	char *t;

	if((p=(struct Process *)((*((struct ExecBase **) 4L))->ThisTask))->pr_CLI!=NULL){
		if((*((struct ExecBase **) 4L))->LibNode.lib_Version>=36 &&
			(DOSBase=(struct DosLibrary *)OpenLibrary(DOSNAME,0))!=NULL){
			memset(argd,0,sizeof(LONG)*PCFGMAX);
			if((RDA=ReadArgs(WWBBSCHATPARSER,&(argd[0]),NULL))!=NULL){
				GetVar("NODE",node,79,GVF_LOCAL_ONLY|GVF_BINARY_VAR);
				GetVar("REALNAME",user,79,GVF_LOCAL_ONLY|GVF_BINARY_VAR);
				t=nomeraw;
				if(argd[PWINDOW]==NULL)
					strcpy(t,"RAW:///128/Chat ");
				else
					strcpy(t,(char *)argd[PWINDOW]);
				while(*t!='\0')t++;
				strcpy(t,user);
				while(*t!='\0')t++;
				*t++=' ';
				strcpy(t,node);
				if((SRaw=Open(nomeraw,MODE_READWRITE))!=NULL){
					MyFPrintf(SRaw,"Chat Request from %s node %s\n",user,node);
					FOut=Output();
					FIn=Input();
					SetMode(FIn,1);
					FPuts(FOut,"\r\n~sWWBBSChat v1.0\r\nby Giuseppe Vicari\r\n\r\n");
					if(argd[PSTARTMSG]==NULL)
						FPuts(FOut,"Please wait, I am calling Sysop ");
					else
						FPuts(FOut,(char *)argd[PSTARTMSG]);
					for(c=10;c!=0;c--){
						FPuts(SRaw,".\a");
						FPuts(FOut,".\a");
						Flush(FOut);Flush(SRaw);
						if(WaitForChar(SRaw,2000000L) && FGetC(SRaw)=='\r')
							break;
						if(WaitForChar(FIn,1000L) && FGetC(FIn)==3){
							c=0;
							break;
						}
					}
					if(c!=0){
						FPuts(SRaw,"\n\n");
						FPuts(FOut,"\r\n\r\n~pChat Sysop\r\n\r\n");
						col=-1;
						tm=1L;
						for(;;){
							if(WaitForChar(SRaw,tm)){
								c=FGetC(SRaw);
								if(c=='\033' || c==EOF)
									break;
								if(c=='\r'){
									FPuts(FOut,"\r\n");
									FPuts(SRaw,"\n");
								} else if(c=='\b'){
									FPuts(FOut,"\b \b");
									FPuts(SRaw,"\b \b");
									Flush(FOut);Flush(SRaw);
								} else if(isprint(c)){
									if(col!=1){
										FPuts(FOut,"~o");
										FPuts(SRaw,"\033[31m");
									}
									FPutC(FOut,c);
									FPutC(SRaw,c);
									Flush(FOut);Flush(SRaw);
									col=1;
								}
								tm=1000L;
							} else
								tm=100000L;
							if(WaitForChar(FIn,tm)){
								c=FGetC(FIn);
								if(c=='\033' || c==EOF)
									break;
								if(c=='\r'){
									FPuts(FOut,"\r\n");
									FPuts(SRaw,"\n");
								} else if(c=='\b'){
									FPuts(FOut,"\b \b");
									FPuts(SRaw,"\b \b");
									Flush(FOut);Flush(SRaw);
								} else if(isprint(c)){
									if(col!=0){
										FPuts(FOut,"~i");
										FPuts(SRaw,"\033[32m");
									}
									FPutC(FOut,c);
									FPutC(SRaw,c);
									Flush(FOut);Flush(SRaw);
									col=0;
								}
								tm=1000L;
							} else
								tm=100000L;
						}
						if(argd[PENDMSG]==NULL)
							FPuts(FOut,"\r\n\r\n~pEnd Chat Sysop\r\n");
						else
							FPuts(FOut,(char *)argd[PENDMSG]);
					} else {
						FPuts(SRaw,"\n\n");
						if(argd[PABORTMSG]==NULL)
							FPuts(FOut,"\r\n\r\nAbort\r\n");
						else
							FPuts(FOut,(char *)argd[PABORTMSG]);
					}
					Flush(FOut);
					SetMode(FIn,0);
					Close(SRaw);
				}
				FreeArgs(RDA);
			} else {
				PrintFault(IoErr(),NULL);
				error=RETURN_ERROR;
			}
			CloseLibrary((struct Library *)DOSBase);
		}
	} else {
		WaitPort(&(p->pr_MsgPort));
		Forbid();
		ReplyMsg(GetMsg(&(p->pr_MsgPort)));
		error=RETURN_FAIL;
	}
	return error;
}
