/* This is an example program which shows how to work with the
   coder.library in C.
   It opens a file and decodes it if it was coded with MasterCoder.
   Morover it decodes protected AmigaBasic files to the binary format
   of AmigaBasic.

   MasterCoder and coder.library are FREEWARE!
   ©1994 by N.Tausch, Karlstr. 30, D-90763 Fuerth
   See docs for further information!
   All codes done in 1994 by N.Tausch
*/


#include <exec/types.h>
#include <exec/memory.h>
#include <dos/dos.h>
#include <coder/coder.h>

struct CoderBase *CoderBase;

extern char *AllocMem();
extern long *OpenLibrary();

extern struct FileHandle *Open();
extern long Read(),Seek(),Write();

extern long UnknownDeCode();
extern char *LibVersion();
extern struct FuncTable *FuncInfo();

void GotoXY(x,y)
   int x,y;
   {
      printf("\033[%d;%dH",y,x);
   }

void Color(Style,Front,Back)
   int Style,Front,Back;
   {
      Front+=30;
      Back+=40;
      printf("\033[%d;%d;%dm",Style,Front,Back);
   }

main()
{
   char *InfoPointer,*Memory,Letter;
   char Source[81],Destination[81],Codeword[161];
   struct FileHandle *SHandle1,*SHandle2;
   struct CoderIDStruc CoderID;
   struct FuncTable *FuncTable;
   long FileLength,Bytes,Status;
   int ErrorFlag,Counter;

   CoderBase=(struct CoderBase *)OpenLibrary("coder.library",0);
   if(CoderBase==NULL) exit(FALSE);

   printf("\f");

   /* LibVersion return a pointer to a string contenting information
      about version and release date.
   */

   InfoPointer=LibVersion();
   GotoXY(2,2); printf("This program decodes crypted files of the MasterCoder");
   GotoXY(2,3); printf("using coder.library %s",InfoPointer);

   GotoXY(4,5); printf("Please enter the name of a coded file: ");
   scanf("%s",Source);

   SHandle1=Open(Source,MODE_OLDFILE);

   if(SHandle1!=0)
   {
      /* Get length of file */
      FileLength=Seek(SHandle1,0,OFFSET_END);
      FileLength=Seek(SHandle1,0,OFFSET_BEGINNING);

      Memory=AllocMem(FileLength,MEMF_CLEAR+MEMF_PUBLIC);

      if(Memory!=0)
      {
         GotoXY(4,6); printf("Loading file...");
         Bytes=Read(SHandle1,Memory,FileLength);

         if(Bytes==FileLength)
         {
            /* If the first character of file is 244, the file
               is a protected AmigaBasic file
            */

            if(*Memory==AMIGABASIC_PROTECTED)
            {
               GotoXY(4,7); printf("Decoding protected AmigaBasic file! Please wait...");

               /* Change first character of file to 245 (=binary) */
               *Memory=AMIGABASIC_BINARY;

               /* ABasDeCode decodes the protected datas to the
                  binary format of AmigaBasic.
               */
               ABasDeCode(Memory+1,Memory+1,FileLength-1);
               ErrorFlag=1;
            }
            else
            {
               /* TestCoderID tests if the file was coded with MasterCoder
                  and returns the number of the algorithm and the length
                  of the MasterCoder fileheader in the CoderID-Structure.
               */
               TestCoderID(Memory,&CoderID);

               if(CoderID.Status==1)
               {
                  GotoXY(4,7); printf("Please enter codeword: ");
                  scanf("%s",Codeword);
                  GotoXY(4,8);

                  /* FuncInfo returns a pointer to a table including
                     information about the algorithms of the
                     coder.library.
                  */
                  FuncTable=FuncInfo();

                  if(FuncTable!=0)
                  {
                     printf("Decoding file with ");

                     for(Counter=0;Counter<=7;Counter++)
                     {
                        Letter=FuncTable->Routine[CoderID.Recog].Name[Counter];
                        if(Letter!=(char)(32) && Letter!=(char)(0)) printf("%c",Letter);
                     }

                     printf("Code! Please wait...");
                     FreeMem(FuncTable,FuncTable->Length);
                  }
                  else printf("Decoding file! Please wait...");

                  /* UnknownDeCode decodes the coded datas. The algorithm
                     number (=CoderID.Recog) says which algorithm is used
                     for decoding
                  */
                  Status=UnknownDeCode(Memory+CoderID.Length,Memory+CoderID.Length,Codeword,FileLength-CoderID.Length,CoderID.Recog);

                  if(Status==1)
                  {
                     ErrorFlag=1;
                     printf("OK!\n");
                  }
                  else
                  {
                     ErrorFlag=0;
                     printf("ERROR!\n");
                  }
               }
               else
               {
                  GotoXY(6,7); Color(1,3,2);
                  if(CoderID.Status==-1) printf("File is of a higher version!\n");
                  if(CoderID.Status==0) printf("This file isn\'t a file of MasterCoder!\n");
                  ErrorFlag=0;
               }
            }

            if(ErrorFlag==1)
            {
               GotoXY(4,10); printf("Please enter name of destination file: ");
               scanf("%s",Destination);

               SHandle2=Open(Destination,MODE_NEWFILE);

               if(SHandle2!=0)
               {
                  GotoXY(4,11); printf("Writing...");
                  Bytes=Write(SHandle2,Memory+CoderID.Length,FileLength-CoderID.Length);

                  if(Bytes==FileLength-CoderID.Length)
                  {
                     GotoXY(4,12); printf("Datas were saved!\n");
                  }
                  else
                  {
                     GotoXY(6,12); Color(1,3,2);
                     printf("Error while writing!\n");
                  }
               }
               else
               {
                  GotoXY(6,11); Color(1,3,2);
                  printf("Error! I can\'t open destination file!\n");
               }

               Close(SHandle2);
            }
            else
            {
               GotoXY(6,10); Color(1,3,2);
               printf("Datas weren\'t saved!\n");
            }
         }
         else
         {
            GotoXY(6,7); Color(1,3,2);
            printf("Error while reading!\n");
         }

         FreeMem(Memory,FileLength);
      }
      else
      {
         GotoXY(6,6); Color(1,3,2);
         printf("Not enough memory to load file!\n");
      }

      Close(SHandle1);
   }
   else
   {
      GotoXY(6,6); Color(1,3,2);
      printf("Error: I can\'t open file!\n");
   }

   Color(0,1,0);
   CloseLibrary(CoderBase);
   printf("\n");
}
