/*ProfiPacket - packet radio terminal program
  Copyright (C) 1999  Alexander Feigl

  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; either version 2 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

  Author:

  Alexander Feigl
  Burachstraße 51

  D-88250 Weingarten

  Mail : Alexander.Feigl@gmx.de
*/


#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "global.h"
#include "QSO.h"
#include "GUIProtos.h"
#include "QSO/Filetrans.h"

#ifdef AmigaOS

#include <exec/memory.h>
#include <dos/exall.h>
#include <clib/exec_protos.h>
#include <clib/dos_protos.h>
#ifdef __GNUC__
extern void *SysBase;
extern void *DOSBase;
#include <inline/exec.h>
#include <inline/dos.h>
#endif /*__GNUC__*/

#else

#include "amigaemu.h"

#endif /*AmigaOS*/

#include <stdlib.h>
#include <stdio.h>

#ifdef __GNUC__
#define _storage_text_ __attribute__ ((section(".text")))
#else
#define _storage_text_
#endif

typedef const unsigned char *constr;

const constr _storage_text_ FileTypes[5]=
 {
  "AUTOBIN ",
  "BINARY  ",
  "7PLUS   ",
  "PCTEXT  ",
  "AMGTEXT ", 
 };
 
const _storage_text_ int FileType_Len[5]= {7,6,5,6,7};

int StartFiletransfer(int channel,int filetype,const unsigned char *filename)
 {
  unsigned char clinebuf[512];
  const unsigned char *servername;
  struct QSO *qso;
  int x;
  void *server;
  
  if (channel<1) return(TRANSERROR_NOTCONNECTED);
  if (channel>MaxChannel) return(TRANSERROR_NOTCONNECTED);
  
  if (filename[0]=='\0') return(TRANSERROR_NOTFOUND);
  
  
  qso=QSOs+(channel-1);  
  
  if (qso->Server==NULL) return(TRANSERROR_NOTCONNECTED);
  if (qso->TransferMode) return(TRANSERROR_ALREADYTRANSFER);
  clinebuf[0]=0x0d;
  clinebuf[1]=0x22;
  CopyString(clinebuf+2,filename);
  x=StringLength(clinebuf);
  clinebuf[x]=0x22;
  clinebuf[x+1]=0x00;
  
  switch (filetype)
   {
    case FILEFORMAT_AUTOBINARY:
     servername="RPRG"; 
     break;
    case FILEFORMAT_BINARY:
     servername="RB";
     break;
    case FILEFORMAT_7PLUS:
     servername="R7";
     break;
    case FILEFORMAT_TEXT:
     servername="R";
     break;
    case FILEFORMAT_TEXTAMIGA:
     servername="R";
     break;
    default:
     servername=NULL;
     break;  
   }

  if (servername==NULL) return (TRANSERROR_NOSERVER);
  
  server=QSO_SearchComServer(servername);
  
   {
    BPTR lock;
    lock=Lock((unsigned char *) filename,-2);
    if (lock==NULL) return(TRANSERROR_NOTFOUND);
    UnLock(lock);
   }
   
  if (server==NULL) return (TRANSERROR_NOSERVER);
  if (QSO_StartServer(channel,server,clinebuf)) return(TRANSERROR_NOSERVER);
  return(0);
 }

int StartFilereceive(int channel,int filetype,const unsigned char *filename)
 {
  unsigned char clinebuf[512];
  const unsigned char *servername;
  struct QSO *qso;
  int x;
  void *server;
  
  if (channel<1) return(TRANSERROR_NOTCONNECTED);
  if (channel>MaxChannel) return(TRANSERROR_NOTCONNECTED);
  
  qso=QSOs+(channel-1);  
  
  if (qso->Server==NULL) return(TRANSERROR_NOTCONNECTED);
  if (qso->TransferMode) return(TRANSERROR_ALREADYTRANSFER);
  clinebuf[0]=0x0d;
  clinebuf[1]=0x22;
  CopyString(clinebuf+2,filename);
  x=StringLength(clinebuf);
  clinebuf[x]=0x22;
  clinebuf[x+1]=0x00;
  
  switch (filetype)
   {
    case FILEFORMAT_AUTOBINARY:
     servername="WPRG"; 
     break;
    case FILEFORMAT_BINARY:
     servername="WB";
     break;
    case FILEFORMAT_7PLUS:
     servername="W7";
     break;
    case FILEFORMAT_TEXT:
     servername="W";
     break;
    case FILEFORMAT_TEXTAMIGA:
     servername="WTA";
     break;
    default:
     servername=NULL;
     break;  
   }

  if (servername==NULL) return (TRANSERROR_NOSERVER);
  
  server=QSO_SearchComServer(servername);
  
  if (server==NULL) return (TRANSERROR_NOSERVER);
  if (QSO_StartServer(channel,server,clinebuf)) return(TRANSERROR_NOSERVER);
  return(0);
 }
 
void PresetFileInfo(struct FileInfo *finfo)
 {
  finfo->callsign[0]='\0';
  finfo->filesize=0;
  finfo->fileformat=FILEFORMAT_AUTOBINARY;
  finfo->badcrc=0;
  finfo->incomplete=0;
  finfo->guessedformat=1;
  finfo->lftype=LFTYPE_LF;
  
 }

int GetFileInfo(const unsigned char *filename,struct FileInfo *finfo) 
 {
  BPTR lock;
  struct FileInfoBlock *fib;
  const unsigned char *commptr;
  unsigned char format[16];
  unsigned char originator[16];
  int i;
  unsigned char *dptr;
  
  PresetFileInfo(finfo);
  
  fib=AllocDosObject(DOS_FIB,NULL);
  if (fib==NULL) return(TRANSERROR_NOTFOUND);
  lock=Lock((unsigned char *) filename,SHARED_LOCK);
  if (lock==NULL)
  {
   FreeDosObject(DOS_FIB,fib);
   return(TRANSERROR_NOTFOUND);
  }

 if ((Examine(lock,fib))==FALSE)
  {
   FreeDosObject(DOS_FIB,fib);
   UnLock(lock);
   return(TRANSERROR_NOTFOUND);
  }
  UnLock(lock);

  finfo->filesize=fib->fib_Size;
  
  commptr=fib->fib_Comment;
  
  format[0]='\0';
  originator[0]='\0';
  
  i=0;
  dptr=format;
  
  while ( (i<15) && (*commptr!='\0') && (*commptr!=' ') )
   {
    i++;
    *(dptr++)=*(commptr++);
   }
  *dptr='\0';
  
  if ( CompareStringLimit(" de ",commptr,4))
   {
    ++commptr;
    i=0;
    dptr=originator;
    while ( (i<15) && (*commptr!='\0') && (*commptr!=' ') )
     {
      i++;
      *(dptr++)=*(commptr++);
     }
    *(dptr)='\0';
    
    while (*commptr!='\0')
     {
      if (CompareStringLimit(" BADCRC!",commptr,8))
       {
        commptr+=8;
        finfo->badcrc=1;  
        continue;
       } 
      if (CompareStringLimit(" INCOMP!",commptr,8))
       {
        commptr+=8;
        finfo->incomplete=1;
        continue;
      
       }
      commptr++;
     }    
   } 
  FreeDosObject(DOS_FIB,fib);
  
 
  if (originator[0]) CopyString(finfo->callsign,originator);
  
  for (i=0;i<5;++i)
   {
    if (CompareStringLimit(FileTypes[i],format,FileType_Len[i]))
     {
      finfo->fileformat=i;
      finfo->guessedformat=0;
      return(0);
     }
   }

   {
    unsigned char *filebuffer;
    FILE *tfile;
    unsigned long xlen,i,wascr;
    unsigned short history[256];
    
    
    wascr=0;
    filebuffer=malloc(1024);
    if (filebuffer==NULL) return(TRANSERROR_NOTFOUND);
    
    if ((tfile=fopen(filename,"rb"))==NULL)
     {
      free(filebuffer);
      return(TRANSERROR_NOTFOUND);  
     }     
   
    xlen=fread(filebuffer,1,1024,tfile);
    fclose(tfile);
    for (i=0;i<256;++i) history[i]=0;
    for (i=0;i<xlen;++i)
     {
      history[filebuffer[i]]++;
      if (filebuffer[i]=='\r')
       {
        if (wascr) finfo->lftype=LFTYPE_CR;
        wascr=1;
       } else if (filebuffer[i]=='\n')
       {
        if (wascr) 
          {
           finfo->lftype=LFTYPE_CRLF;
           wascr=0;
          }
          else
          {
           finfo->lftype=LFTYPE_LF;
          }
        } 
        else
        {
         if (wascr) finfo->lftype=LFTYPE_CR;
         wascr=0;
        }
            
     }
    free(filebuffer);
   }     
  finfo->fileformat=FILEFORMAT_AUTOBINARY;
  return(0);
 }

int SetFileInfo(const unsigned char *filename,struct FileInfo *finfo) 
 {
  unsigned char commentline[80];
  unsigned char *claddr;
  const unsigned char *sptr;
  
  
  
  claddr=commentline;
  sptr=FileTypes[finfo->fileformat];
  while (*sptr!='\0') *(claddr++)=*(sptr++);
  *(claddr++)=' ';
  *(claddr++)='d';
  *(claddr++)='e';
  *(claddr++)=' ';
  sptr=finfo->callsign;
  if (*sptr=='\0') sptr="??????";
  while (*sptr!='\0') *(claddr++)=*(sptr++);
  if (finfo->badcrc)
   {
    sptr=" BADCRC!";
	while (*sptr!='\0') *(claddr++)=*(sptr++);
   }
  if (finfo->incomplete)
   {
    sptr=" INCOMP!";
	while (*sptr!='\0') *(claddr++)=*(sptr++);
   }
  *claddr='\0';
  
  if (SetComment((unsigned char *) filename,commentline)==FALSE) {return (TRANSERROR_CANNOTWRITE);}
  
  return(0); 
 }
  
