/* event.c */
#include<exec/types.h>
#include<intuition/intuition.h>
#include "golf.h"

int event(ULONG class,USHORT code,CPTR iaddr)
{
   struct Gadget *gad;
   gad = (struct Gadget *)iaddr;
   switch (class) {
      case CLOSEWINDOW :   return(0);
                           break;
      case GADGETUP    :   /* hier die Karten verschieben und anzeigen */
#ifdef DEBUG
                           printf("Stapel %d angeklickt.\n",gad->GadgetID);
#endif
                           karteVon(gad->GadgetID);
                           break;
      case MENUPICK    :   switch(MENUNUM(code)) {
                              case 0: /* Project */
                                       switch(ITEMNUM(code)) {
                                          case 0: /* new */
                                                   karteVon(20);
                                                   break;
                                          case 1: /* about */
                                                   displayHelp(1);
                                                   break;
                                          case 2: /* quit */
                                                   return(0);
                                                   break;
                                       }
                                       break;
                              case 1: /* edit */
                                       switch(ITEMNUM(code)) {
                                          case 0: /* undo */
                                                   karteVon(1);
                                                   break;
                                       }
                                       break;
                              case 2: /* settings */
                                       switch(ITEMNUM(code)) {
                                          case 0: /* BackImg */
                                                   selectBack();
                                                   break;
                                          case 1: /* columns */
                                                   getSpalten();
                                                   karteVon(20); /* new */
#if 0
                                                   SetAPen(PlayRastPort,0);
                                                   RectFill(PlayRastPort,0,12,320,149);
                                                   SetAPen(PlayRastPort,9);
                                                   Move(PlayRastPort,120,80);
                                                   Text(PlayRastPort,"Bäh!",4);
                                                   /* PrintIText("Bäh!"); */
                                                   Delay(150);
                                                   SetAPen(PlayRastPort,0);
                                                   RectFill(PlayRastPort,0,12,320,149);
                                                   DrawAllCards();
#endif
                                                   break;
                                          case 2: /* palette */
                                                   if (showPalette(1) == -1)
                                                      showRequest("Can't find Requester.Lib",0);
                                                   break;
                                       }
                                       break;
                              case 3: /* cards */
                                       switch(ITEMNUM(code)) {
                                          case 0: /* rules */
                                                   karteVon(21);
                                                   break;
                                       }
                                       break;
                           }
                           break;
      default          :   /* sollte eigentlich nicht vorkommen */
                           printf("event : class = %lx ???\n",class);
                           break;
   }
   return(1);
}

void ClrImg(int x,int y)
{
   SetAPen(PlayRastPort,0);
   RectFill(PlayRastPort,x,y,x+SPALTENDX-1,y+37);
}

static void pr_st1(int n)
{
   if (n < 53) pr_st1(Karten[n].letzte);
   printf("%d ",n);
}

static void pr_st(int n)
{
   if (n < 53) pr_st(Karten[n].vor);
   printf("%d ",n);
}

void printStapel(int n)
{
   printf("Stapel %d: ",n);
   if (n == 1) pr_st1(stapel[1]);
   else pr_st(stapel[n]);
   printf(":\n");
}

void karteVon(int stapelnr)
{
   static int abgelegt = 0;
   /* wenn stapel null angeklickt: */
   /*   wenn stapel 0 nicht leer, karte auf stapel 1 packen. */
   /*     wenn stapel 0 dann leer, backimg löschen */
   /* wenn stapel 1 angeklickt : */
   /*   wenn stapel 1 mindestens 2 karten, oberste karte zurück ( wohin */
   /*     steht in der struktur) stapel[] aktualisieren */
   /*     bei bedarf Backimg zeichnen */
   /* wenn stapel >= 2 angeklickt: */
   /*   wenn noch mindestens 1 karte auf dem stapel, sonst displaybeep */
   /*     prüfen, ob die karte auf stapel 1 passt, sonst displaybeep */
   /*     karte auf stapel 1 packen ( hier alte karte auf altem stapel */
   /*     löschen, darunter liegende karte neu zeichnen, verschobene karte */
   /*     auf stapel 1 zeichnen (oben bei stapel 1 das gleiche )) */
   switch(stapelnr) {
      case 0 : /* stapel der restlichen karten */
               if (stapel[0] < 53) { /* alles andere Quatsch oder 255 für leer */
                  abgelegt++;
#ifdef DEBUG
                  printf("Karte %d auf st 1, darunter %d, abgelegt %d\n",stapel[0],Karten[stapel[0]].vor,abgelegt);
#endif
                  Karten[stapel[0]].letzte = stapel[1]; /* auf stapel 1 */
                  stapel[1] = stapel[0];
                  stapel[0] = Karten[stapel[0]].vor;
                  DrawImage(PlayRastPort,Karten[stapel[1]].img,bottImageX+BOTTOMDX*abgelegt,bottImageY);
                  /* neue oberste Karte von Stapel 1 zeichnen */
                  if (stapel[0] == 255) ClrImg(bottImageX-SPALTENDX,bottImageY);
                  /* BackImg löschen */
               } else DisplayBeep(PlayScreen);
               break;
      case 1 : /* ablagestapel */
               if (stapel[1] < 53 && Karten[stapel[1]].letzte < 53) {
                  /* oberste karte auf stapel 1 löschen und die darunter neu zeichnen */
                  ClrImg(bottImageX+BOTTOMDX*abgelegt,bottImageY);
                  abgelegt--;
#ifdef DEBUG
                  printf("alte karte gelöscht, neue karte = %d aus Spalte %d\n",stapel[1],Karten[stapel[1]].spalte);
#endif
                  DrawImage(PlayRastPort,Karten[Karten[stapel[1]].letzte].img,bottImageX+BOTTOMDX*abgelegt,bottImageY);
                  if (Karten[stapel[1]].spalte)
                     DrawImage(PlayRastPort,Karten[stapel[1]].img,leftImageX+SPALTENDX*(Karten[stapel[1]].spalte-2),leftImageY+SPALTENDY*Karten[stapel[1]].zeile);
                  else
                     if (stapel[0] == 255) DrawImage(PlayRastPort,BackImage,bottImageX-SPALTENDX,bottImageY);
                  stapel[Karten[stapel[1]].spalte] = stapel[1];
                  stapel[1] = Karten[stapel[1]].letzte;
               } else DisplayBeep(PlayScreen);
               break;
      case 2 :
      case 3 :
      case 4 :
      case 5 :
      case 6 :
      case 7 :
      case 8 :
      case 9 :
      case 10:
      case 11:
      case 12: /* stapel der karten, die heruntergelegt werden sollen */
               if (stapelnr > AnzStapel+1) break; /* den Stapel gibts nich */
               if (stapel[stapelnr] < 53 && passtAuf(stapel[1],stapel[stapelnr])) {
                  abgelegt++;
                  /* erstmal Karte vom oberen Stapel holen */
                  ClrImg(leftImageX+SPALTENDX*(stapelnr-2),leftImageY+SPALTENDY*Karten[stapel[stapelnr]].zeile);
                  /* jetzt die Karte auf Stapel 1 */
                  Karten[stapel[stapelnr]].letzte = stapel[1];
                  stapel[1] = stapel[stapelnr];
                  stapel[stapelnr] = Karten[stapel[stapelnr]].vor;
                  if (stapel[stapelnr] < 53) {
                     DrawImage(PlayRastPort,Karten[stapel[stapelnr]].img,leftImageX+SPALTENDX*(stapelnr-2),leftImageY+SPALTENDY*Karten[stapel[stapelnr]].zeile);
                  } else testGewonnen();
                  /* jetzt die Karte auf Stapel 1 neu zeichnen */
                  DrawImage(PlayRastPort,Karten[stapel[1]].img,bottImageX+BOTTOMDX*abgelegt,bottImageY);
               } else DisplayBeep(PlayScreen);
/* Fehlt noch ein Test auf Gewonnenes Spiel */
/* Vielleicht, sobald ein Stapel aufgelöst wurde (alle Stapel == 255) */
               break;
      case 20: /* restart */ /* falsch, eher ein NEW */
               SetAPen(PlayRastPort,0);
               RectFill(PlayRastPort,0,12,320,149);
               initCards(AnzStapel,AnzZeilen);
               DrawAllCards();
               abgelegt = 0;
               break;
      case 21: /* help */
               displayHelp(0);
               break;
      case 22: /* echtes restart */
               if (Karten[stapel[1]].letzte > 51) break;
               /* wenn noch nichts abgelegt wurde */
               SetAPen(PlayRastPort,0);
               RectFill(PlayRastPort,0,12,320,149);
               while (Karten[stapel[1]].letzte < 53) {
                  stapel[Karten[stapel[1]].spalte] = stapel[1];
                  stapel[1] = Karten[stapel[1]].letzte;
               }
               abgelegt = 0;
               DrawAllCards();
               break;
      default: /* sollte eigentlich nicht vorkommen */
               printf("karteVon: Stapelnr %d unbekannt\n",stapelnr);
               break;
   }
   if (stapel[0] > 51 && passtNix()) endeSpiel();
}

int passtAuf(int liegt,int soll)
{
   /* testet,ob die ausgewählte Karte oben auf den Stapel darf, nach den Regeln */
   /* :auf eine karte, darf eine mit größerem oder kleinerem Wert */
   /* :Ausnahme, auf einen König darf nix mehr */
   /* die Nummerierung : */
   /* 0 - As, 1 - die zwei, 2 - die drei,...,9 - die zehn, 10 der Bube */
   /* 11 - die Dame, 12 - der König */
   if (Karten[liegt].karte == 0) {
      /* auf As darf Zwei oder König */
      return((Karten[soll].karte == 1 || Karten[soll].karte == 12)? 1 : 0);
   }
   if (Karten[liegt].karte == 12) {
      /* auf König nix mehr */
      return(0);
   }
   if (Karten[liegt].karte+1 == Karten[soll].karte) return(1);
   if (Karten[liegt].karte-1 == Karten[soll].karte) return(1);
   return(0);
}

int passtNix(void)
{
   int i;
   
   for (i=2;i<AnzStapel+2;i++)
      if (passtAuf(stapel[1],stapel[i])) return(0);
   return(1);
}

extern struct TextAttr topaz;
static char text[16];
static struct IntuiText itex = {
   1, 0, JAM1, 230, 20, &topaz, text, NULL
};

void endeSpiel(void)
{
   int i,j,k; /* 2 x laufvar, anzahl der übriggebliebenen karten */
   /* sollte eigentlich einen Requester oder so zeigen */
   /* oder gewisse Gadgets an- oder abschalten */
#ifdef DEBUG
   puts("nix geht mehr, nur noch zurück");
#endif
   for (k=0,i=2;i<AnzStapel+2;i++) {
      j = stapel[i];
      while (j < 53) {
         k++;
         j = Karten[j].vor;
      }
   }
   if (!k) {
      puts("endeSpiel : gewonnen !");
      return;
   }
   sprintf(text,"%2d cards",k); /* 11 Zeichen */
   PrintIText(PlayRastPort,&itex,0,0);
   sprintf(text,"left");
   PrintIText(PlayRastPort,&itex,8,11);
}

void testGewonnen(void)
{
   int i;
   
   for(i=2;i<AnzStapel+2;i++) {
#ifdef DEBUG
      printf("stapel[%d] = %d\n",i,stapel[i]);
#endif
      if (stapel[i] < 53) return; /* da liegt noch was */
   }
#ifdef DEBUG
   puts("da hat er also gewonnen!");
#endif
   sprintf(text,"YOU WIN!");
   PrintIText(PlayRastPort,&itex,0,0);
}
