#include <exec/types.h>

#include <libraries/dos.h>
#include <libraries/dosextens.h>

#include <intuition/intuition.h>

#include <proto/exec.h>
#include <proto/dos.h>
#include <proto/intuition.h>
#include <proto/dlg.h>
#include <proto/diskfont.h>
#include <proto/graphics.h>

#include <graphics/gfxbase.h>
#include <graphics/text.h>

#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <ctype.h>
#include <dos.h>

#include <dlg/dlg.h>
#include <dlg/portconfig.h>
#include <dlg/resman.h>

#include <link/io.h>

#include <clib/alib_protos.h>

#include <pragmas/dlg.h>

#include <private/privs.h>

#include "DLGScreen.h"

void CleanUp(int errorcode);
void OutputString(struct IntuiText *toprint, long left, long top);
int  CheckSerialNumber(void);
void ErrorText(char *text);

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

struct Library   *DLGBase;

struct Window    *w;
struct Screen    *sc;
struct TextAttr   ta;
struct IntuiText  it;

char              DLGCW = 0;        // DLG capability word
char              DLGSERIAL[10];    // DLG Serial Number
char              OWNER[128];       // Owner name

/// struct Image
struct Image     im =
{
   WINXOFF,WINYOFF,        // Left & top edge
   WINX,WINY,              // Width & height
   2,                      // depth
   &dlgpro[0],             // image data
   3,0,                    // Planepick, PlaneOff
   NULL,                   // NextImage
};
//-
/// struct NewWindow
struct NewWindow nw =
{
   WINXOFF,WINYOFF,        // Left edge, top edge
   WINX,WINY,              // Width, Height
   1,2,                    // Detailpen, blockpen
   0,                      // IDCMP flags
   WFLG_BORDERLESS,        // Flags (window struct)
   0,                      // First gadget
   NULL,                   // Image for checkmark
   NULL,                   // Window title
   0,                      // Pointer to custom screen
   0,                      // SuperBitMap image
   0,0,0,0,                // Min/max dimensions
   PUBLICSCREEN            // Open on workbench screen
};
//-

/// main
void main(int argc,char **argv)
{
   char                 t[256];

   long                 tlen;
   long                 tleft;
   long                 ttop;

   struct   RMMessage   rm;


   DLGBase = OpenLibrary("dlg.library",4L);

   // Lock default public screen
   sc = LockPubScreen(NULL);
   if(sc == NULL) CleanUp(10);

   // Figure out window origin
   nw.LeftEdge = nw.LeftEdge + ((sc->Width - WINX) / 2);
   nw.TopEdge = nw.TopEdge + ((sc->Height - WINY) / 2);

   // Open window
   w = OpenWindow(&nw);
   if(w == NULL) CleanUp(10);

   // We're done with the public screen info, so we unlock it
   // We won't lose it until possibly after we close our window.
   UnlockPubScreen(NULL,sc); sc = NULL;

   // Set up font info
   ta.ta_Name  = "topaz.font";
   ta.ta_YSize = 8;
   ta.ta_Style = 0;
   ta.ta_Flags = FPB_ROMFONT;

   // set up IntuiText info
   it.FrontPen  = 1;
   it.BackPen   = 2;
   it.DrawMode  = JAM1;
   it.LeftEdge  = 0;
   it.TopEdge   = 0;
   it.ITextFont = &ta;
   it.NextText  = NULL;

   // Draw our splash screen
   DrawImage(w->RPort,&im,0,0);

   DLGCW = CheckSerialNumber();

   if(DLGCW < 0)
   {
      ErrorText("Error decoding DLGSerial!");
      CleanUp(10);
   }

   if(DLGCW == 0)
      ASPrintf(NULL,t,"Unregistered");
   else
      ASPrintf(NULL,t,"Serial Number: %s",DLGSERIAL);

   it.IText     = t;
   tlen = IntuiTextLength(&it);
   tleft =  (WINX / 2) - (tlen / 2);
   ttop = WINY - ((ta.ta_YSize + 2) * 4);
   OutputString(&it,tleft,ttop);

   if(DLGCW == 0)
      ASPrintf(NULL,t,"Demo Mode");
   else
      ASPrintf(NULL,t,"Registered to: %s",OWNER);

   it.IText     = t;
   tlen = IntuiTextLength(&it);
   tleft =  (WINX / 2) - (tlen / 2);
   ttop = ttop + ta.ta_YSize + 2;
   OutputString(&it,tleft,ttop);

   it.IText     = "Release " BUILDVER " ("__DATE__")";
   tlen = IntuiTextLength(&it);
   tleft =  (WINX / 2) - (tlen / 2);
   ttop = ttop + ta.ta_YSize + 2;
   OutputString(&it,tleft,ttop);

   rm.type     =  99;
   rm.priority =  DLGCW;
   rm.passwd   =  strdup(DLGSERIAL);
   rm.reason   =  strdup(OWNER);
   ResourceMsg(&rm);

   Delay(200L);

   CleanUp(0);
}
//-
/// CleanUp
void CleanUp(int errorcode)
{
   if(w)    CloseWindow(w);
   if(sc)   UnlockPubScreen(NULL,sc);

   if(DLGBase) CloseLibrary(DLGBase);

   exit(errorcode);
}
//-
/// OutputString()
void OutputString(struct IntuiText *toprint, long left, long top)
{
   toprint->FrontPen = 1;

   PrintIText(w->RPort,toprint,left, top - 1);
   PrintIText(w->RPort,toprint,left, top + 1);
   PrintIText(w->RPort,toprint,left - 1, top - 1);
   PrintIText(w->RPort,toprint,left - 1, top);
   PrintIText(w->RPort,toprint,left - 1, top + 1);
   PrintIText(w->RPort,toprint,left + 1, top - 1);
   PrintIText(w->RPort,toprint,left + 1, top);
   PrintIText(w->RPort,toprint,left + 1, top + 1);

   toprint->FrontPen = 2;

   PrintIText(w->RPort,toprint,left,top);

   return;
}
//-
/// ErrorText()
void ErrorText(char *text)
{
   long  tlen;
   long  tleft;
   long  ttop;

   it.IText     = text;
   tlen = IntuiTextLength(&it);
   tleft =  (WINX / 2) - (tlen / 2);
   ttop = WINY - ((ta.ta_YSize + 2) * 3);
   OutputString(&it,tleft,ttop);
   Delay(200);
}
//-
/// CheckSerialNumber
int  CheckSerialNumber(void)
{
   BPTR  fh   =  NULL;

   BOOL  SerialFound =  FALSE;
   BOOL  OwnerFound  =  FALSE;

   int   ln   =  0;
   int   StartLine = 0;
   int   TotalLines = 0;
   int   TotalGroups = 0;
   int   CharsPerGroup = 0;
   int   FirstChar = 0;
   int   LastFour = 0;
   int   i = 0;
   int   _SERIAL = 0;
   int   CW = 0;

   char  t[1024];
   char  SERIAL[12];
   char *p;
   char *q;

   fh =  Open("DLGConfig:Misc/DLGSerial",MODE_OLDFILE);

   if(!fh)  return( -1 );

   while(FGets(fh,t,1024))
   {
      ln++;

      strcpy(t, stpblk(t));                  // strip blanks

      if (strlen(t) == 0)  continue;         // Skip empty lines

      if (!Strnicmp(t, ";", 1)) continue;    // Skip comments

      if(!SerialFound)  {  strcpy(SERIAL,t); SerialFound = TRUE;  continue;}

      if(!Strnicmp(t,"OWNER",5))
      {
         char *s;

         OwnerFound = TRUE;
         StripSpaces(t);
         s = strtok(t,"\r\n");
         strcpy(OWNER,s+6);
         continue;
      }

      if(SerialFound && OwnerFound)
      {
         StartLine = ln;
         break;
      }
   }

   if(!SerialFound || !OwnerFound)
   {
      ErrorText("DLGSerial is mangled! Setting up demo.");
      Close(fh);
      return( 0 );
   }

   // start 1000's (lines)

   Seek(fh,0,OFFSET_BEGINNING);

   for(ln = 0; ln < StartLine; ln++)
      FGets(fh,t,1024);

   while(FGets(fh,t,1024)) TotalLines++;
   TotalLines++;

//printf("Total lines (1000's + 2) = %ld\n",TotalLines);

   // end 1000's (lines)

   // start 100's (groups)
   Seek(fh,0,OFFSET_BEGINNING);

   for(ln = 0; ln < StartLine; ln++)
      FGets(fh,t,1024);

   q = strdup(strtok(t,"\n"));
   StripSpaces(q);

//printf(".%s.\n",q);

   for(i = 0; i < strlen(q); i++)
      if(q[i] == ' ') TotalGroups++;

   TotalGroups++;

//printf("Total groups (100's +2) = %ld\n",TotalGroups);

   // End 100's (groups)

   // start 10's (chars per group)

   for(i = (strlen(t)-1); i > 1; i--)  // isolate first group
      if(t[i] == ' ') t[i]=0;

   CharsPerGroup = strlen(t);

   // end 10's (chars per group)

//printf("Total chars per group (10's + 2) = %ld\n",CharsPerGroup);

   // start 1's (first char)

   t[1] = 0;
//printf(".%s.\n",t);
   stch_i(t,&FirstChar);

   // end 1's (first char)

//printf("First char (1's + 2) = %ld\n",FirstChar);

   // start checking of serial number integrity. We don't care about the first two digits.

   LastFour =  ((TotalLines-2)*1000) + ((TotalGroups-2)*100) + ((CharsPerGroup-2)*10) + (FirstChar-2);

   p = SERIAL+2;
   _SERIAL = atol(p);

   if(LastFour != _SERIAL)
   {
      ErrorText("Keyfile tampered with -- Demo mode!");
      Close(fh);
      return( 0 );
   }

   ASPrintf(NULL,DLGSERIAL,"%06ld",_SERIAL);

   // end serial number integrity check.

   // start capability word parse

   if(!FGets(fh,t,1024)) { Close(fh); return(0);}
   if(fh)   {  Close(fh); fh = NULL;   }

   t[1] = 0;
   stch_i(t,&CW);
   // end capability word parse

   return( CW );
}
//-


