#include "ascsend.h"

UBYTE          *version = ASCSEND_VERSION; 
LONG            values[10] = {0L,0L,0L,0L,0L,0L,0L,0L,0L,0L};
struct  RDArgs *args;
ULONG           verzoegerung = 12;
ULONG           v_char;
long          __OSlibversion = 37;
ULONG          filesize;
ULONG          filepos;
UBYTE         *filename;
UBYTE          windowname[STRINGSIZE];
UBYTE         *screenname;
ULONG          waits;
LONG           do_it = FALSE;

void __stdargs main(int argc,char **argv)
{
 {
  if(args = ReadArgs("FILE/A,WINDOW/K/M,SCREEN/K,WAIT/K/N,DELAY/K/N,DELAYCHAR/K/N,",values,NULL))
  {
   filename   = (UBYTE *)(values[0]);
   if(values[1])
   {
    UBYTE **p;
    p = (UBYTE **)values[1];
    while(*p)
    {
     strcat(windowname,*p);strcat(windowname," ");
     p++;
    }
    windowname[strlen(windowname)-1] = 0;
   }
   if(values[2])screenname = (UBYTE *)values[2];
   if(values[3]){ LONG *n = (LONG *)values[3];waits = ((LONG)*n > 0) ? (LONG)*n : 0 ;}
   if(values[4]){ LONG *n = (LONG *)values[4];verzoegerung = ((LONG)*n > 0) ? (LONG)*n : 0 ;}
   if(values[5]){ LONG *n = (LONG *)values[5];v_char = ((LONG)*n > 0) ? (LONG)*n : 0 ;}

   if(screenname && windowname[0])printf("*ASCSEND FEHLER* SCREEN und WINDOW Parameter geht nicht !\n");  
   else
   {
    if(!(screenname || windowname[0]))do_it = TRUE;
    if(waits)Delay(waits);
    if(screenname)   activate_screen(screenname);
    if(windowname[0])activate_window(windowname);
    if(do_it)Sendfile(filename,GET_A_FILE);
   }
  }
  FreeArgs(args);
 }
 exit(0);
}

long __regargs Sendfile(UBYTE *filename,ULONG mode)
{
 int rc = TRUE;
 struct InputEvent *ie;
 UBYTE buffer[STRINGSIZE];
 UBYTE *filebuffer;
 int Ldelay     = FALSE;
 ULONG           stop = FALSE;
 ULONG           v_line;
 ULONG           v_z;
 ULONG           fpm;
 v_line = verzoegerung;
 v_z = v_char;
 filepos = 0;
 if(filebuffer = getfilebuffer(filename,mode))
 {
  while((getnextchar(filebuffer,buffer)) && (!stop))
  {
   *(buffer + 1) = 0;
   switch(*buffer)
   {
    case '\n' : Ldelay = TRUE;
                strcpy(buffer,"\\n");
                break;
    case '\r' : Ldelay = TRUE;
                strcpy(buffer,"\\r");
                break;
    case '\t' : strcpy(buffer,"\\t");
                break;
    case '\\' : fpm = filepos;
                getnextchar(filebuffer,buffer + 1);
                *(buffer + 2) = 0;
                {
                 int end = FALSE;
                 int p = 2;
                 ULONG v;
                 if((*(buffer + 1)=='d')||(*(buffer + 1)=='l')||(*(buffer + 1)=='c')||
                    (*(buffer + 1)=='n')||(*(buffer + 1)=='r')||(*(buffer + 1)=='t'))
                 {
                  do
                  {
                   if( (*(buffer + 1)=='n')||(*(buffer + 1)=='r')||(*(buffer + 1)=='t'))
                   {
                    end = TRUE;
                   }
                   else
                   {
                    getnextchar(filebuffer,buffer + p);
                    if(!(isdigit(*(buffer + p))) || (p >= 6))
                    {
                     end = TRUE;
                     *(buffer + p + 1) = 0;
                     v = atol(buffer + 2);
                     switch(*(buffer + 1))
                     {
                      case 'd' : Delay(v);
                                 break;
                      case 'l' : v_line = v;
                                 break;
                      case 'c' : v_z = v;
                                 break;
                      default  : break;
                     }
                     *buffer = 0;
                     filepos -= 1;
                    }
                    p++;
                    if(p >= (STRINGSIZE - 2))end = TRUE;
                   }
                  }
                  while(!end); 
                 }
                 else
                 {
                  UBYTE t[2] = {0,0}; 
                  struct InputEvent ev;
                  if(*(buffer + 1) == '(')
                  {
                   getnextchar(filebuffer,buffer + 2);
                   getnextchar(filebuffer,buffer + 3);
                   getnextchar(filebuffer,buffer + 4);
                   getnextchar(filebuffer,buffer + 5);
                   if((*(buffer + 3) == 'm')&&(*(buffer + 5)==':'))
                   {
                    int p = 6;
                    int py;
                    int end = FALSE;
                    while(!end)
                    {
                     getnextchar(filebuffer,buffer + p);
                     if(!(isdigit(*(buffer + p))))
                     {
                      end = TRUE;
                     }
                     p++;
                    }
                    --p;
                    if(*(buffer + p) == ',')
                    {
                     p++;
                     py = p;
                     end = FALSE;
                     while(!end)
                     {
                      getnextchar(filebuffer,buffer + p);
                      if(!(isdigit(*(buffer + p))))
                      {
                       end = TRUE;
                      }
                      p++;
                     }
                     --p;
                     if(*(buffer + p) == ')')
                     {
                      ev.ie_Class = IECLASS_POINTERPOS;
                      ev.ie_NextEvent = NULL;
                      ev.ie_Qualifier = 0;
                      ev.ie_SubClass  = 0;
                      ev.ie_TimeStamp.tv_secs = 0;
                      ev.ie_TimeStamp.tv_micro = 0;
                      ev.ie_Y = (WORD)atol(buffer + py);
                      ev.ie_X = (WORD)atol(buffer + 6);
                      switch(*(buffer + 2))
                      {
                       case 'l' : if(*(buffer + 4) == 'd')
                                   ev.ie_Code      = IECODE_LBUTTON ;
                                  else
                                    ev.ie_Code      = IECODE_LBUTTON | IECODE_UP_PREFIX;
                                  AddIEvents(&ev);
                                  break;
                       case 'r' : if(*(buffer + 4) == 'd')
                                   ev.ie_Code      = IECODE_RBUTTON ;
                                  else
                                    ev.ie_Code      = IECODE_RBUTTON | IECODE_UP_PREFIX;
                                  AddIEvents(&ev);
                                  break;
                        case 'm' : if(*(buffer + 4) == 'd')
                                   ev.ie_Code      = IECODE_MBUTTON ;
                                  else
                                    ev.ie_Code      = IECODE_MBUTTON | IECODE_UP_PREFIX;
                                  AddIEvents(&ev);
                                  break;
                      }
                      *buffer = 0;
                     }
                     else
                     {
                      filepos =fpm;
                      strcpy(buffer,"\\\\");
                      if(ie = InvertString(buffer,NULL))
                      {
                       AddIEvents(ie);
                       FreeIEvents(ie);
                       *buffer = 0;
                      }
                     }
                    }
                    else
                    {
                     filepos = fpm;
                     strcpy(buffer,"\\\\");
                     if(ie = InvertString(buffer,NULL))
                     {
                      AddIEvents(ie);
                      FreeIEvents(ie);
                      *buffer = 0;
                     }
                    }
                   }
                   else
                   {
                    filepos = fpm;
                    strcpy(buffer,"\\\\");
                    if(ie = InvertString(buffer,NULL))
                    {
                     AddIEvents(ie);
                     FreeIEvents(ie);
                     *buffer = 0;
                    }
                   }
                  }
                  else
                  {
                   t[0] = *(buffer + 1);
                   strcpy(buffer,"\\\\");
                   if(ie = InvertString(buffer,NULL))
                   {
                    AddIEvents(ie);
                    FreeIEvents(ie);
                   }
                  }
                  strcpy(buffer,t);
                  switch(*buffer)
                  {
                   case '\n' : strcpy(buffer,"\\n");
                               break;
                   case '\r' : strcpy(buffer,"\\r");
                               break;
                   case '<'  : *buffer = 0;filepos -= 1;
                               break;
                  }
                 }
                }
                break;
    case '<'  : {
                 int end;
                 int p;
                 end = FALSE;
                 p = 1;
                 fpm = filepos;
                 do
                 {
                  getnextchar(filebuffer,buffer + p);
                  switch(*(buffer + p))
                  {
                   case '\r': 
                   case '\n': if(ie = InvertString("\\<",NULL))
                              {
                               AddIEvents(ie); 
                               FreeIEvents(ie);
                              }
                              filepos = fpm;
                              *buffer = 0;
                              end = TRUE;
                              break;
                   case '>' : *(buffer + p + 1) = 0;
                              if(ie = InvertString(buffer,NULL))
                              {
                               AddIEvents(ie); 
                               FreeIEvents(ie);
                              }
                              else
                              {
                               if(ie = InvertString("\\<",NULL))
                               {
                                AddIEvents(ie); 
                                FreeIEvents(ie);
                               }
                               filepos = fpm;
                              }
                              *buffer = 0;
                              end = TRUE;
                              break;
                   default  : break;
                  }
                  p++;
                  if(p >= (STRINGSIZE - 2))end = TRUE;
                 }
                 while(!end);
                 break;
                }
    
    case '>'  : if(ie = InvertString(buffer,NULL))
                {
                 AddIEvents(ie); 
                 FreeIEvents(ie);
                }
                strcpy(buffer,"\\>");
                break;
    default   : *(buffer + 1) = 0;
                break;
   }
   if(ie = InvertString(buffer,NULL))
   {
    if(v_z)Delay(v_z);
    AddIEvents(ie);
    if(Ldelay)
    {
     Delay(v_line);
     Ldelay = FALSE;    
    }
    FreeIEvents(ie);
   }
  }
 }
 return rc;
}

UBYTE __regargs *makemem(ULONG size)
{
 return((UBYTE *)AllocVec(size,MEMF_PUBLIC | MEMF_CLEAR));   
}

void releasemem(void *mem)
{
 FreeVec(mem);   
}

UBYTE __regargs *getfilebuffer(UBYTE *filename,ULONG mode)
{
 struct FileInfoBlock *fib;
 BPTR lock,fh;
 UBYTE *buffer;
 switch( mode )
 {
  case GET_A_FILE: 
  if(lock = Lock(filename,ACCESS_READ))
  {
   if(fib = AllocDosObject(DOS_FIB,TAG_DONE))
   {
    Examine(lock,fib);
    filesize = fib->fib_Size;
    FreeDosObject(DOS_FIB,fib);
    if(buffer = (UBYTE *)makemem(filesize))
    {
     if(fh = OpenFromLock(lock))
     {
      FRead(fh,buffer,filesize,1);
      Close(fh);
      return buffer;
     }
     else UnLock(lock);
    }
   }
  }
  return NULL;
  break;
  case GET_A_STRING :
  filesize = strlen(filename + 1);
  if(buffer = (UBYTE *)makemem(filesize))
  {
   strcpy(buffer,filename);
   return buffer;
  }
  else return NULL;
  break;
 }    
 return NULL;
}

void __regargs freefilebuffer(UBYTE *buffer,ULONG size)
{
 releasemem(buffer);   
}

BOOL __regargs getnextchar(UBYTE *buffer,UBYTE *where)
{
 if(filepos >= filesize)return FALSE;
 *where = *(buffer + filepos);
 filepos++;   
 return TRUE;
}

void activate_screen(UBYTE *screen)
{
 ULONG i_lock;
 struct Window *wd;
 struct Screen *cs;
 int end = FALSE;
 i_lock = LockIBase(0);
 cs = IntuitionBase->FirstScreen;
 while(cs && !end)
 {
  if(!strnicmp(screen,cs->Title,strlen(screen)))
  {
   end = TRUE;
   ScreenToFront(cs);
   if(wd = cs->FirstWindow)
   {
    do_it = TRUE;
   }
  }
  cs = cs->NextScreen;
 }
 UnlockIBase(i_lock);
 if(do_it == TRUE) ActivateWindow(wd);
}

void activate_window(UBYTE *wnd)
{
 struct Window *wd;
 struct Screen *sc;
 int end = FALSE;
 sc = IntuitionBase->FirstScreen;
 while(sc && !end)
 {
  wd = sc->FirstWindow;
  while(wd && !end)
  {
   if(!strnicmp(wnd,wd->Title,strlen(wnd)))
   {
    end = TRUE;
    do_it = TRUE;
    ScreenToFront(sc);
    ActivateWindow(wd);
   }
   wd = wd->NextWindow;
  }
  sc = sc->NextScreen;
 }
}
