
#include <intuition/intuition.h>
#include <exec/memory.h>

struct GameData
{
   UBYTE  TeamA[12], TeamB[12];
   ULONG  pl1_score, pl2_score;
};

struct PlayerData
{
   UBYTE  pl_num;
   UBYTE  pl_name[12];
   UWORD  gw, gd, gl;
   ULONG  gf, ga;
};

struct DataSeg
{
   UBYTE  pl_entered;
   UBYTE  games_played;
   struct GameData  LastResults[8];
   struct PlayerData  Player[8];
};

struct NameGadget
{
   struct Gadget  ResetGadget, Pl1Gadget, Pl2Gadget;
   struct StringInfo  SInfo;
   struct Gadget  StringGadget;
};

struct NG2     /* for easy copying of structure */
{
   struct NameGadget  NG;
};

#define NGSIZE sizeof(struct NameGadget)

struct DataSeg  Temp;
extern struct DataSeg  Data;

extern struct IntuitionBase  *IntuitionBase;
struct Window *RWindow;
struct RastPort  *RRPort;
struct IntuiMessage *Rmessage, *mes2;
void  *OpenLibrary();
void  *AllocMem();
struct NameGadget  *Gptr[8];
UBYTE  Pl1_selected, Pl2_selected;
UBYTE  Result[37];
extern struct Window  *Window;

#define R_pl1_pos 0
#define R_vs_pos  12
#define R_pl2_pos 15
#define R_sc1_pos 30
#define R_ln_pos  32
#define R_sc2_pos 35
#define R_end_pos 36

extern struct TextAttr  Style;

struct IntuiText
Sure_text = {  0, 1, JAM2, 10, 10, &Style,
   (UBYTE *)"Warning: all player data will be lost!", NULL },
Yes_text = {  0, 1, JAM2, 5, 3, &Style, (UBYTE *)"Continue", NULL },
No_text = {  0, 1, JAM2, 5, 3, &Style, (UBYTE *)"Cancel", NULL },
Result_text = {  2, 3, JAM2, 0, 0, &Style, Result, NULL },
plscore_txt = {  1, 0, JAM2, -6, -12, &Style, (UBYTE *)"Score", NULL },
OK_text = {  1, 0, JAM2, 6, 2, &Style, (UBYTE *)"Accept", NULL },
Cancel_text = {  1, 0, JAM2, 6, 2, &Style, (UBYTE *)"Cancel", NULL },
Reset_text = {  1, 0, JAM2, -14, -12, &Style, (UBYTE *)"Reset", NULL },
TmA_text = {  1, 0, JAM2, -14, -12, &Style, (UBYTE *)"Team A", NULL },
TmB_text = {  1, 0, JAM2, -14, -12, &Style, (UBYTE *)"Team B", NULL },
plus   = {  1, 0, JAM2, 2, 2, &Style, (UBYTE *)"+", NULL },
minus  = {  1, 0, JAM2, 2, 2, &Style, (UBYTE *)"-", NULL };

WORD  OKPairs[] =
{  60, 1, 60, 11, 0, 11   };
WORD  OKPairsa[] =
{  0, 10, 0, 0, 60, 0   };

struct Border  OKBoxa =
{  0, 0, 2, 0, JAM1, 3, OKPairsa, NULL  };
struct Border  OKBox =
{  0, 0, 1, 0, JAM1, 3, OKPairs, &OKBoxa  };

WORD  RGadgetPairs3[] =
{  99, 1, 99, 11, 0, 11   };
WORD  RGadgetPairs3a[] =
{  0, 10, 0, 0, 99, 0   };

struct Border  RGadgetBorder3a =
{  -2, -2, 2, 0, JAM1, 3, RGadgetPairs3a, NULL  };
struct Border  RGadgetBorder3 =
{  -2, -2, 1, 0, JAM1, 3, RGadgetPairs3, &RGadgetBorder3a  };

WORD  sbPairs[] =
{  12, 1, 12, 11, 0, 11   };
WORD  sbPairsa[] =
{  0, 10, 0, 0, 12, 0   };

struct Border  squareboxa =
{  0, 0, 2, 0, JAM1, 3, sbPairsa, NULL  };
struct Border  squarebox =
{  0, 0, 1, 0, JAM1, 3, sbPairs, &squareboxa  };

WORD  ResPairs[] =
{  293, 1, 293, 11, 0, 11   };
WORD  ResPairsa[] =
{  0, 10, 0, 0, 293, 0   };
WORD  ResPairsb[] =
{  1, 1, 292, 1, 292, 10, 1, 10, 1, 1  };

struct Border  ResBorderb =
{  -3, -2, 3, 0, JAM1, 5, ResPairsb, NULL  };
struct Border  ResBordera =
{  -3, -2, 1, 0, JAM1, 3, ResPairsa, &ResBorderb  };
struct Border  ResBorder =
{  -3, -2, 2, 0, JAM1, 3, ResPairs, &ResBordera  };

WORD  IntPairs[] =
{  27, 1, 27, 11, 0, 11   };
WORD  IntPairsa[] =
{  0, 10, 0, 0, 27, 0   };

struct Border  IntBordera =
{  -2, -2, 2, 0, JAM1, 3, IntPairsa, NULL  };
struct Border  IntBorder =
{  -2, -2, 1, 0, JAM1, 3, IntPairs, &IntBordera  };

struct NameGadget  OneNameGadget =
{
   NULL, 0, 0, 13, 12, GADGHCOMP, RELVERIFY,   /* ResetGadget */
   BOOLGADGET, &squarebox, NULL, NULL, NULL, NULL, 0, NULL,
   NULL, 0, 0, 13, 12, GADGHCOMP, TOGGLESELECT | GADGIMMEDIATE,   /* Pl1Gadget */
   BOOLGADGET, (APTR)&squarebox, NULL, NULL, NULL, NULL, 0, NULL,
   NULL, 0, 0, 13, 12, GADGHCOMP, TOGGLESELECT | GADGIMMEDIATE,   /* Pl2Gadget */
   BOOLGADGET, (APTR)&squarebox, NULL, NULL, NULL, NULL, 0, NULL,
   NULL, NULL, 0, 12, 0, 0, 0, 0, 0, 0,   /* SInfo */
   NULL, 0, NULL,
   NULL, 0, 0, 100, 12, GADGHCOMP, RELVERIFY, STRGADGET,   /* StrGadget */
   (APTR)&RGadgetBorder3, NULL, NULL, NULL, NULL, 0, NULL
};

UBYTE  pl1score_buf[3] = "0", pl2score_buf[3] = "0";

struct StringInfo  pl2score_SInfo =
{
   pl2score_buf, NULL, 0, 3, 0, 0, 0, 0, 0, 0,
   NULL, 0, NULL
};

struct StringInfo  pl1score_SInfo =
{
   pl1score_buf, NULL, 0, 3, 0, 0, 0, 0, 0, 0,
   NULL, 0, NULL
};

#define g_Pl1     20
#define g_Pl2     30
#define g_Reset   40
#define g_String  50
#define g_OK      10
#define g_Cancel  11
#define g_minus2   7
#define g_plus2    6
#define g_pl2score 2
#define g_minus1   5
#define g_plus1    4
#define g_pl1score 1

struct Gadget  Cancel_gadget =
{
   NULL, 48, 142, 61, 12, GADGHCOMP, RELVERIFY, BOOLGADGET,
   (APTR)&OKBox, NULL, (APTR)&Cancel_text, NULL, NULL, g_Cancel, NULL
};

struct Gadget  OK_gadget =
{
   &Cancel_gadget, 48, 128, 61, 12, GADGHCOMP, RELVERIFY, BOOLGADGET,
   (APTR)&OKBox, NULL, (APTR)&OK_text, NULL, NULL, g_OK, NULL
};

struct Gadget  Minus_gadget2 =
{
   &OK_gadget, 245, 138, 13, 12, GADGHCOMP, RELVERIFY | GADGIMMEDIATE, BOOLGADGET,
   (APTR)&squarebox, NULL, (APTR)&minus, NULL, NULL, g_minus2, NULL
};

struct Gadget  Plus_gadget2 =
{
   &Minus_gadget2, 286, 138, 13, 12, GADGHCOMP, RELVERIFY | GADGIMMEDIATE,
   BOOLGADGET, (APTR)&squarebox, NULL, (APTR)&plus, NULL, NULL, g_plus2, NULL
};

struct Gadget  pl2score_gadget =
{
   &Plus_gadget2, 260, 140, 27, 14, GADGHCOMP, RELVERIFY | LONGINT | STRINGRIGHT,
   STRGADGET, (APTR)&IntBorder, NULL, &plscore_txt, NULL, &pl2score_SInfo,
   g_pl2score, NULL
};

struct Gadget  Minus_gadget1 =
{
   &pl2score_gadget, 155, 138, 13, 12, GADGHCOMP, RELVERIFY | GADGIMMEDIATE,
   BOOLGADGET, (APTR)&squarebox, NULL, (APTR)&minus, NULL, NULL, g_minus1, NULL
};

struct Gadget  Plus_gadget1 =
{
   &Minus_gadget1, 196, 138, 13, 12, GADGHCOMP, RELVERIFY | GADGIMMEDIATE,
   BOOLGADGET, (APTR)&squarebox, NULL, (APTR)&plus, NULL, NULL, g_plus1, NULL
};

struct Gadget  pl1score_gadget =
{
   &Plus_gadget1, 170, 140, 27, 14, GADGHCOMP, RELVERIFY | LONGINT | STRINGRIGHT,
   STRGADGET, (APTR)&IntBorder, NULL, &plscore_txt, NULL, &pl1score_SInfo,
   g_pl1score, NULL
};


struct NewWindow NewRWindow =
{
   120, 10, 322, 177, -1, -1,
   GADGETDOWN | GADGETUP,
   WINDOWDEPTH | WINDOWDRAG | SMART_REFRESH | ACTIVATE,
   &pl1score_gadget, NULL, (UBYTE *)"Match results",
   NULL, NULL, 0, 0, 0, 0, WBENCHSCREEN,
};

BOOL  GetResult()
{
   ULONG  MessageClass;
   UWORD  code, GadgetNr;
   struct Gadget *GadgetPtr;
   struct Message  *GetMsg();
   struct PlayerData  *Pptr;
   ULONG  sc1, sc2;
   int  i;

   Temp = Data;
   pl1score_SInfo.LongInt = 0;
   pl2score_SInfo.LongInt = 0;
   strcpy(pl1score_buf, "0");
   strcpy(pl2score_buf, "0");
   DoGadgets();
   ROpen_All();
   MakeResString();

   FOREVER
   {
      if (!(Rmessage = (struct IntuiMessage *)
          GetMsg(RWindow->UserPort)))
      {
         Wait(1L << RWindow->UserPort->mp_SigBit);
         continue;
      }
      MessageClass = Rmessage->Class;
      code = Rmessage->Code;
      GadgetPtr = (struct Gadget *) Rmessage->IAddress;
      GadgetNr = GadgetPtr->GadgetID;
      ReplyMsg(Rmessage);
      switch(MessageClass)
      {
         case GADGETUP:
            if ((GadgetNr >= g_Reset) && (GadgetNr < g_Reset + 8))
            {
               if (AutoRequest(RWindow, &Sure_text, &Yes_text, &No_text,
                  0L, 0L, IntuiTextLength(&Sure_text) + 60L, 60L))
               {
                  Pptr = &Temp.Player[GadgetNr - g_Reset];
                  Pptr->gw = 0;
                  Pptr->gd = 0;
                  Pptr->gl = 0;
                  Pptr->gf = 0;
                  Pptr->ga = 0;
                  strcpy(Pptr->pl_name, "Player x");
                  Pptr->pl_name[7] = '1' + Pptr->pl_num;
                  RefreshGList(&Gptr[GadgetNr - g_Reset]->StringGadget,
                     RWindow, NULL, 1L);
                  MakeResString();
               }
            }
            else if ((GadgetNr >= g_String) && (GadgetNr < g_String + 8))
               MakeResString();
            else switch (GadgetNr)
            {
               case g_OK:
                  sc1 = pl1score_SInfo.LongInt;
                  sc2 = pl2score_SInfo.LongInt;
                  Temp.Player[Pl1_selected].gf += sc1;
                  Temp.Player[Pl1_selected].ga += sc2;
                  Temp.Player[Pl2_selected].gf += sc2;
                  Temp.Player[Pl2_selected].ga += sc1;
                  if (sc1 > sc2)
                  {
                     Temp.Player[Pl1_selected].gw++;
                     Temp.Player[Pl2_selected].gl++;
                  }
                  else if (sc1 == sc2)
                  {
                     Temp.Player[Pl1_selected].gd++;
                     Temp.Player[Pl2_selected].gd++;
                  }
                  else
                  {
                     Temp.Player[Pl1_selected].gl++;
                     Temp.Player[Pl2_selected].gw++;
                  }
                  if (Temp.games_played < 8)
                  {
                     strcpy(Temp.LastResults[Temp.games_played].TeamA,
                        Temp.Player[Pl1_selected].pl_name);
                     strcpy(Temp.LastResults[Temp.games_played].TeamB,
                        Temp.Player[Pl2_selected].pl_name);
                     Temp.LastResults[Temp.games_played].pl1_score = sc1;
                     Temp.LastResults[Temp.games_played].pl2_score = sc2;
                     Temp.games_played++;
                  }
                  else
                  {
                     for (i = 0; i < 7; i++)
                        Temp.LastResults[i] = Temp.LastResults[i + 1];
                     strcpy(Temp.LastResults[7].TeamA,
                        Temp.Player[Pl1_selected].pl_name);
                     strcpy(Temp.LastResults[7].TeamB,
                        Temp.Player[Pl2_selected].pl_name);
                     Temp.LastResults[7].pl1_score = sc1;
                     Temp.LastResults[7].pl2_score = sc2;
                  }
                  Data = Temp;
                  RClose_All();
                  while (mes2 = (struct IntuiMessage *) GetMsg(Window->UserPort))
                     ReplyMsg(mes2);
                  return(TRUE);
                  break;

               case g_Cancel:
                  RClose_All();
                  while (mes2 = (struct IntuiMessage *) GetMsg(Window->UserPort))
                     ReplyMsg(mes2);
                  return(FALSE);
                  break;

               case g_pl1score:
                  MakeResString();
                  break;

               case g_pl2score:
                  MakeResString();
                  break;
            }
            break;

         case GADGETDOWN:
            if ((GadgetNr >= g_Pl1) && (GadgetNr < g_Pl1 + 8))
            {
               if (GadgetNr - g_Pl1 != Pl2_selected)
               {
                  ToggleGadget(&Gptr[Pl1_selected]->Pl1Gadget);
                  Pl1_selected = GadgetNr - g_Pl1;
               }
               else ToggleGadget(&Gptr[GadgetNr - g_Pl1]->Pl1Gadget);
            }
            else if ((GadgetNr >= g_Pl2) && (GadgetNr < g_Pl2 + 8))
            {
               if (GadgetNr - g_Pl2 != Pl1_selected)
               {
                  ToggleGadget(&Gptr[Pl2_selected]->Pl2Gadget);
                  Pl2_selected = GadgetNr - g_Pl2;
               }
               else ToggleGadget(&Gptr[GadgetNr - g_Pl2]->Pl2Gadget);
            }
            else switch(GadgetNr)
            {
               case g_plus1:
                  if (pl1score_SInfo.LongInt < 99)
                     UpdateGadg(&pl1score_gadget, ++pl1score_SInfo.LongInt);
                  break;

               case g_minus1:
                  if (pl1score_SInfo.LongInt > 0)
                     UpdateGadg(&pl1score_gadget, --pl1score_SInfo.LongInt);
                  break;

               case g_plus2:
                  if (pl2score_SInfo.LongInt < 99)
                     UpdateGadg(&pl2score_gadget, ++pl2score_SInfo.LongInt);
                  break;

               case g_minus2:
                  if (pl2score_SInfo.LongInt > 0)
                     UpdateGadg(&pl2score_gadget, --pl2score_SInfo.LongInt);
                  break;
            }
            MakeResString();
            break;
      }
   }
}

ROpen_All()
{
   struct Window  *OpenWindow();

   if (!(RWindow = (struct Window *)
       OpenWindow(&NewRWindow)))
   {
      puts(NULL, "Fout bij openen venster", NULL);
      RClose_All();
      return(FALSE);
   }
   RRPort = RWindow->RPort;
   DrawBorder(RRPort, &ResBorder, 16L, 163L);
}

RClose_All()
{
   int  i;

   if (RWindow) CloseWindow(RWindow);
   for (i = 0; i < 8; i++) if (Gptr[i]) FreeMem(Gptr[i], NGSIZE);
}

DoGadgets()
{
   int  i, j;
   struct NG2  *G2ptr;


   for (i= 0; i < 8; i++)
   {
      Gptr[i] =  (struct NameGadget *) AllocMem(NGSIZE, MEMF_PUBLIC | MEMF_CLEAR);
      if (!Gptr[i]) puts("no memory!");
      else
      {
         G2ptr = (struct NG2 *) Gptr[i];
         G2ptr->NG = OneNameGadget;
         if (i > 0) Gptr[i]->ResetGadget.NextGadget = &Gptr[i-1]->StringGadget;
         else Gptr[i]->ResetGadget.NextGadget = NULL;
         Gptr[i]->ResetGadget.LeftEdge = 20;
         Gptr[i]->ResetGadget.TopEdge = 26 + 12*i;
         Gptr[i]->ResetGadget.GadgetID = g_Reset + i;
         Gptr[i]->Pl1Gadget.NextGadget = &Gptr[i]->ResetGadget;
         Gptr[i]->Pl1Gadget.LeftEdge = 180;
         Gptr[i]->Pl1Gadget.TopEdge = 26 + 12*i;
         Gptr[i]->Pl1Gadget.GadgetID = g_Pl1 + i;
         Gptr[i]->Pl2Gadget.NextGadget = &Gptr[i]->Pl1Gadget;
         Gptr[i]->Pl2Gadget.LeftEdge = 270;
         Gptr[i]->Pl2Gadget.TopEdge = 26 + 12*i;
         Gptr[i]->Pl2Gadget.GadgetID = g_Pl2 + i;
         Gptr[i]->StringGadget.NextGadget = &Gptr[i]->Pl2Gadget;
         Gptr[i]->StringGadget.LeftEdge = 45;
         Gptr[i]->StringGadget.TopEdge = 28 + 12*i;
         Gptr[i]->StringGadget.SpecialInfo = &Gptr[i]->SInfo;
         Gptr[i]->StringGadget.GadgetID = g_String + i;
         Gptr[i]->SInfo.Buffer = Temp.Player[i].pl_name;
      }
      Gptr[0]->Pl1Gadget.Flags |= SELECTED;
      Gptr[1]->Pl2Gadget.Flags |= SELECTED;
      Pl1_selected = 0;
      Pl2_selected = 1;
      Gptr[0]->Pl1Gadget.GadgetText = &TmA_text;
      Gptr[0]->Pl2Gadget.GadgetText = &TmB_text;
      Gptr[0]->ResetGadget.GadgetText = &Reset_text;
      Cancel_gadget.NextGadget = &Gptr[7]->StringGadget;
   }
}

UpdateGadg(gadg, LI)
struct Gadget  *gadg;
LONG  LI;
{
   struct StringInfo  *SIP;
   UBYTE  *buf;

   SIP = (struct StringInfo *) gadg->SpecialInfo;
   buf = SIP->Buffer;

   if (LI > 9)
   {
      buf[0] = '0' + LI / 10;
      buf[1] = '0' + LI % 10;
      buf[2] = 0;
   }
   else
   {
      buf[0] = '0' + LI;
      buf[1] = 0;
   }
   RefreshGList(gadg, RWindow, NULL, 1L);
}

ToggleGadget(gadg)
struct Gadget  *gadg;
{
   RemoveGadget(RWindow, gadg);
   RefreshGList(gadg, RWindow, NULL, 1L);
   gadg->Flags ^= SELECTED;
   AddGadget(RWindow, gadg, RWindow, -1L);
   RefreshGList(gadg, RWindow, NULL, 1L);
}

MakeResString()
{
   int  i;

   for (i = 0; i < R_end_pos; i++) Result[i] = ' ';
   strcpynz(&Result[R_pl1_pos], Temp.Player[Pl1_selected].pl_name);
   strcpynz(&Result[R_vs_pos], "vs");
   strcpynz(&Result[R_pl2_pos], Temp.Player[Pl2_selected].pl_name);
   longcpynz(&Result[R_sc1_pos], pl1score_SInfo.LongInt);
   Result[R_ln_pos] = '-';
   longcpynz(&Result[R_sc2_pos],  pl2score_SInfo.LongInt);
   Result[R_end_pos] = 0;
   PrintIText(RRPort, &Result_text, 16L, 163L);
}
