#define   ANSICOL

#include <exec/types.h>
#include <proto/exec.h>
#include <proto/dos.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <fcntl.h>
#include <dos.h>

#include <link/config.h>
#include <link/io.h>
#include <link/util.h>

#include <dlg/dlg.h>
#include <dlg/resman.h>
#include <dlg/user.h>
#include <dlg/input.h>
#include <dlg/portconfig.h>
#include <dlg/msg.h>
#include <dlg/log.h>

#include <proto/dlg.h>

#include <pragmas/dlg.h>

#include <private/Version.h>
#define  ObjRev "1"
const UBYTE version[]="\0$VER: DLGUUSend " BUILDVER "." ObjRev " ©" COPYRIGHT " by Digerati Dreams "__AMIGADATE__;

#define INSTACK     RStruct.Command_Stack[0]

void  main            (int, char **);
void  MyPrintSpace    (FILE *, UBYTE, int);
int   NewDisplayBuffer(FILE *, char *, int, int, UBYTE, UBYTE, int *, int , char *, char *);
void  HandleLineTermination(char *, int);
void  DoAbort(void);
void  CleanUp(char *);
void  Usage  (void);
void _CXBRK  (void);


struct Global_Settings Globals;
struct USER_DATA       UserDat;
struct Ram_File        RStruct;
struct UserInfo        ui      = {&UserDat, &RStruct};
struct Query           q       = {NULL, NULL, NULL, NULL, NULL, 0, 0, 0};

char                   Ext[4];

char                   bodyfile[15];
char                   outfile[15];
FILE                  *ofp;
BOOL                   vialine = TRUE;

struct Library    *DLGBase = NULL;
struct LangStruct *ls;
char             **SA;


void main(int argc, char **argv)
{
   int   pos = 0;
   ULONG size;
   long  zflag;

   char *buf;
   char *defgroups  = NULL;
   char *defaddress = NULL;
   char *repfile    = NULL;

   char  addbuf   [256];
   char  subject   [80];
   char  execbuf  [255];
   char  sigfile   [80];
   char  newsgroups[80];
   char  uname     [36];
   char  origin    [80];
   char  title     [72];
   char  headerfile[36];

   struct Msg_Header Header;

   UBYTE newsflag = FALSE;
   UBYTE autoflag = FALSE;


   if (!(DLGBase = OpenLibrary(DLGNAME, DLGVERSION)))  exit(5);

   if (GetDevName(Ext)==-1)               CleanUp("Unable To Identify Port");
   if (ReadGlobals(Ext,&Globals)==-1)     CleanUp("Unable to read globals");
   if (!(ls = GetLang(Ext)))              CleanUp("Unable to find language");
   SA = ls->strings;

   if (!ReadUser(&RStruct,&UserDat,Ext))   CleanUp(SA[3283]);

   sprintf(headerfile,"t:%s.header",Ext);

/// parse args
   while(--argc>0)
   {
      char *s;

      s = *++argv;
      if (*s++ == '-')
      {
         while(*s)
         {
            switch(toupper(*s))
            {
               case 'M':  newsflag = FALSE;
               break;

               case 'N':  newsflag = TRUE;
               break;

               case 'T':  if (!--argc)  break;
               defaddress = *++argv;
               break;

               case 'R':  if (!--argc)  break;
               repfile = *++argv;
               break; 

               case 'G':  if (!--argc)  break;
               defgroups = *++argv;
               break;

               case 'S':  if (!--argc)  break;
               strncpy(subject, *++argv, 79);
               subject[79] = 0;
               break;

               case 'A':  autoflag = TRUE;
               break;

               case 'V':  vialine = FALSE;
               break;

               default:  Usage();
               break;
            }

            s++;
         }
      }
   }
//-

/// auto only: get info from header of reply file
   if (!autoflag)
   {
      Clr(UserDat.Ansi_Flag);
      if (repfile)  GetFirstStruct(repfile,(char *)&Header,sizeof(Header));
   }
//-

/// for mail: get address to mail to. For news: get target newsgroup
   if (!newsflag)
   {
      if (autoflag)
      {
         strcpy(addbuf,defaddress);
      }
      else
      {
         if (defaddress && !(UserDat.Ansi_Flag&ANSI_POS))
         printf(SA[3284],defaddress);

         Chk_Abort();
         printf(SA[3285]);
         q.prompt     =  NULL;
         q.string     =  addbuf;
         q.defstring  = (defaddress)?defaddress:NULL;
         q.length     =  255;
         q.typelength =  255;
         if (!DLGQuery(&q, &ui))  DoAbort();
      }
   }
   else
   {
      if (autoflag)
      {
         strcpy(newsgroups,defgroups);
      }
      else
      {
         if (defgroups && !(UserDat.Ansi_Flag&ANSI_POS))  printf(SA[3286],defgroups);

         Chk_Abort();
         printf(SA[3287]);
         q.prompt     =  NULL;
         q.string     =  newsgroups;
         q.defstring  = (defgroups)?defgroups:NULL;
         q.length     =  79;
         q.typelength =  79;
         if (!DLGQuery(&q, &ui))  DoAbort();
      }
   }
//-

/// Get title
   if (!autoflag)
   {
      if (newsflag)
      {
         if (repfile && !(UserDat.Ansi_Flag&ANSI_POS))
         printf(SA[3288],Header.Title);
         printf(SA[3289]);

         if (Strnicmp(Header.Title,"RE:",3))
            sprintf(title,"Re: %-.67s",Header.Title);
         else
            strcpy(title,Header.Title);

         Chk_Abort();
         q.prompt     =  SA[3290];
         q.string     =  subject;
         q.defstring  = (repfile)?title:NULL;
         q.length     =  75;
         q.typelength =  75;
         if (!DLGQuery(&q, &ui))  DoAbort();
      }
      else
      {
         if (repfile && !(UserDat.Ansi_Flag&ANSI_POS))
         printf(SA[3288],Header.Title);
         printf(SA[3289]);

         if (Strnicmp(Header.Title,"RE:",3))
            sprintf(title,"Re: %-.67s",Header.Title);
         else
            strcpy(title,Header.Title);

         Chk_Abort();
         q.prompt     =  SA[3291];
         q.string     =  subject;
         q.defstring  = (repfile)?title:NULL;
         q.length     =  75;
         q.typelength =  75;
         if (!DLGQuery(&q, &ui))  DoAbort();
      }

      printf("\n");
   }
//-

/// Create body file.
   if (autoflag)
      strcpy(bodyfile, repfile);
   else
      sprintf(bodyfile,"T:%s.Body",Ext);

   sprintf(outfile,"T:%s.UUOut",Ext);
//-

/// Create message
   if (!autoflag)
   {
      strcpy(Header.Title, subject);
      strcpy(Header.From,  RStruct.Name);
      strncpy(Header.To,  (newsflag)?newsgroups:addbuf, 35);
      Header.To[35]    = 0;
      Header.TimesRead = UUCP_MSG;
      DeleteFile(headerfile);

      AddStruct(headerfile,(char *)&Header,sizeof(Header),1);
      if (CallEditor(repfile,headerfile,bodyfile,USENET_MSG,&UserDat,&RStruct,Ext)==-1)
      {
         DeleteFile(headerfile);
         CleanUp(SA[3292]);
      }

      GetFirstStruct(headerfile,(char *)&Header,sizeof(Header));
      DeleteFile(headerfile);
      strcpy(subject, Header.Title);
   }
//-

   if (FileSize(bodyfile,&size)==-1)  CleanUp(SA[3292]);

   if (!(ofp = fopen(outfile,"w")))
      CleanUp(SA[3293]);

   if (newsflag)
      fprintf(ofp, SA[3294],newsgroups);
   else
      fprintf(ofp,SA[3295],addbuf);

   fprintf(ofp,SA[3296],subject);

   if (newsflag)  fprintf(ofp,SA[3297]);
      fprintf(ofp,"\n");

   if (autoflag)  printf(SA[3298]);

   printf(SA[3299]);

   sprintf(sigfile,"USER:%s/signature.uucp",RStruct.Name);
   UnderScore(sigfile);
   
   if (vialine)
      sprintf(origin,SA[3300],DLGSHORTNAME);
   else
      origin[0]='\0';

   if (Exists(sigfile))
      size+=(long)Cat(bodyfile,sigfile,origin);
   else
   {
      int fp;
      if ((fp=open(bodyfile,O_RDWR))!=EOF)
      {
         lseek(fp,0,2);
         write(fp,origin,strlen(origin));
         close(fp);
      }

      size+=(long)strlen(origin);
   }

   buf = NULL;
   FileToBuf(&buf,bodyfile,size,1,0);
   HandleLineTermination(buf,size);

   NewDisplayBuffer(ofp,buf,75,9999,0,0,&pos,0,NULL,"");

   fclose(ofp);
   ofp = NULL;

   Capitalize(RStruct.Name);
   strcpy(uname,RStruct.Name);
   UnderScore(uname);

   if (!newsflag)
      sprintf(execbuf,"Sendmail <%s -f %s -R %c%s%c",outfile,uname,34,RStruct.Name,34);
   else
      sprintf(execbuf,"PostNews <%s -f %s -r %c%s%c",outfile,uname,34,RStruct.Name,34);

   Execute(execbuf,NULL,NULL);

   if (!autoflag) printf(SA[3301]);

/// mail only
   if (!newsflag)
   {
      unsigned char *body=NULL;

      strcpy(Header.Title,subject);
      strcpy(Header.From,RStruct.Name);
      strncpy(Header.To,addbuf,35);
      Header.To[35]='\0';      
      MDate(Header.Date);
      Header.TimesRead=UUCP_MSG;
      Header.DestNode=Header.OrigNode=Header.Cost=Header.OrigNet=Header.DestNet=0;
      Header.ReplyTo=Header.Attribute=Header.NextReply=0;

      if (FileToBuf(&body,bodyfile,size,1,0))
      {
         if (Globals.PrivateArea)
         {
            struct Msg_Area msgarea;

            if (ReadArea(Globals.PrivateArea,&msgarea,0))
            {
               struct MsgStruct ms;
               
               ms.header=&Header;
               ms.repheader=NULL;
               ms.body=body;
               ms.replyto=0;
               ms.areainfo=&msgarea;
               ms.flags=0;

               SendRawMsg(&ms,NULL,"dlguusend");
            }
         }

         zflag = BoolQuery(SA[3302], 0, &ui);
         if (!INSTACK)  printf("\n\n");
         if (zflag)
         {
            struct MsgStruct ms;

            Header.TimesRead=CC_MSG;
            
            ms.header=&Header;
            ms.repheader=NULL;
            ms.body=body;
            ms.replyto=0;
            ms.areainfo=NULL;
            ms.flags=0L;

            SendRawMsg(&ms,RStruct.Name,"dlguusend");
         }

         free(body);
      }
   }
//-

   if (newsflag)
      WriteLog(WROTE_MESSAGE,Header.From,Ext,"Newsgroup");
   else
      WriteLog(WROTE_MESSAGE,Header.From,Ext,"UUCP Mail");

   CleanUp(NULL);
}


void MyPrintSpace(FILE *fp,UBYTE ansi,int spaces)
{
   if (ansi & ANSI_POS)
      printf(SA[3303],spaces/10 + '0',spaces%10 + '0');
   else
      for(; spaces; spaces--)
         putc(' ', fp);
}


int NewDisplayBuffer(FILE *fp,char *buffer,int screenwidth,int screenlen,
                     UBYTE moreflag,UBYTE ansi,int *screenpos,int indent,
                     char *ibuf,char *breakbuf)
{
   UBYTE noprint=FALSE, firstime=TRUE;
   unsigned char wrap,inansi;
   int counter, realcount,linelen, pos;

   screenwidth-=indent;
   pos=0;
   wrap=1;
   inansi=FALSE;
   noprint=FALSE;

   do {
      /* If we had a hard return, strip leading spaces */

      if(wrap != 1) while(buffer[pos] == 32) pos++;

      wrap=0;
      realcount=0;

      for(counter = 0; realcount <= screenwidth; counter++) {
         /* Scan the line */
         if(inansi) {
            if(isalpha(buffer[pos+counter])) inansi=FALSE; /* End of sequence */
         }
         else {
            if(buffer[pos+counter]==27) inansi=TRUE; /* Esc */
            else realcount++;
         }

         if(buffer[pos+counter] == 1) noprint=TRUE;

         if(buffer[pos+counter] == 10) {
            /* CR */
            wrap=1;
            break;
         }

         if(buffer[pos+counter] == 0) {
            /* End of buffer */
            wrap=3;
            break;
         }
      }

      linelen=counter;

      if(wrap == 0) {
         /* If no hard return, do word wrap */
         for(counter--; counter; counter--) {
            if(buffer[pos+counter] == 32) {
               linelen=counter;
               wrap=2;
               break;
            }
         }
      }

      if(indent && !firstime && !noprint)
      if(ibuf) fwrite(ibuf,indent,1,fp);
      else MyPrintSpace(fp,ansi,indent);

      if(!noprint&&linelen) fwrite(buffer+pos,linelen,1,fp);
      
      if((wrap!=3)&&(!noprint)) putc('\n',fp);

      if(((wrap!=3)||firstime)&&(!noprint)) (*screenpos)++;

      noprint=FALSE;
      if(firstime) firstime=FALSE;
      pos += linelen;
      if(wrap) pos++;
   }
   while(wrap!=3);

   return(0);
}

void HandleLineTermination(char *buffer,int size)
{
   long  index;
   long  newindex;
   UBYTE crflag = FALSE;

   index    = 0;
   newindex = 0;

   for(;index<size;index++)
   {
      switch(buffer[index])
      {
         case 12:       /* Screen Clear */
         crflag = FALSE;
         continue;
         break;

         case 141:       /* Soft return */
         crflag = TRUE;
         continue;
         break;

         case 13:       /* Carriage Return */
         buffer[index]=10;
         crflag = TRUE;
         break;

         case 10:       /* Line Feed */
         if (!((!crflag) && (index==size-1L || buffer[index+1L]!=13))) 
         {
            crflag = FALSE;
            continue;
         }
         crflag = FALSE;
         break;

         default:       /* Any other character */
         crflag = FALSE;
         break;
      }

      buffer[newindex++]=buffer[index];
   }

   buffer[newindex]='\0';
}


void DoAbort(void)

{
   printf(SA[3304]);
   CleanUp(NULL);
}


void CleanUp(char *s)

{
   if (ofp)  fclose(ofp);

   DeleteFile(bodyfile);
   DeleteFile(outfile);

   WriteRam(&RStruct,Ext);
   if (s)  printf(SA[3305],s);
   CloseLibrary(DLGBase);

   exit(s?5:0);
}


void Usage(void)

{
   printf(SA[3306]);
   printf(SA[3307]);

   CleanUp(NULL);
}


void _CXBRK(void)

{
   CleanUp(NULL);
}
