/*

  PROGRAMMNAME:     ABC
  VERSION:          1.0
  DATUM:            15.3.1990
  PROGRAMMZWECK:    Hilft Kinder Lesen zu lernen und Begriffe besser zu
                    unterscheiden
  PROGRAMMAUTOR:    Thorsten Kuthe
                    Sonderburgerstr. 2a
                    5090 Leverkusen 1
                    FRG

  COMPILER:         Manx Aztec C 3.6a

  COMPILERAUFRUF:   CC +L ABC.c
  LINKERAUFRUF:     LN ABC.o Bilder.o -LARP -LC32
  BEMERKUNGEN:      Die Bilddaten sind in der Datei Bilder.o, die
                    hinzugelinkt wird.
*/


/*********************  Präprozessor Anweisungen  ********************/

#define UBP (UBYTE *)
#define RP  win->RPort
#define BRP Bed->RPort
#define ARP a_win->RPort
#define UP  win->UserPort
#define ANZAHL 1              5               /* Anzahl der Bilder */

#define makeintuitext(name,string,size,ypos, pen) struct IntuiText name={pen, 0, JAM1,\
    ( 1 + size - 8* (sizeof(string) - 1 ) )/2, ypos, NULL, (UBYTE*)string}

#define makebox(name,tname,width,height,off,pen) short tname[]={0,0,width,0,\
   width,1,0,1,0,height-1,width,height-1,width,height,0,height,width,height,\
   width,0};\
   struct Border name={off,off,pen,0,JAM2,10,tname}

#define makengadg(name,prev,xpos,ypos,text,ch, len, height, box) struct Gadget name={prev,\
   xpos,ypos, len, height,GADGHCOMP,RELVERIFY,BOOLGADGET,\
   (APTR)&box,NULL,&text,NULL,NULL,ch,NULL}

#define BGADS 120       /* Gadget-Breite1 */
#define WGADS 200       /* Gadget-Breite2 */
#define GADGH 30        /* Gadget-Höhe1   */
#define GH    20        /* Gadget-Höhe2   */
#define LINE2 100       /* Y-Koord Gadget */
#define COL1 30         /* X-Koord Gadget */
#define WIDTH 460       /* Fenster-Breite */
#define HEIGHT 256      /* Fenster-Höhe   */

/*********************           Libraries        ********************/

extern struct ArpBase *ArpBase;

/*********************         Grafikdaten        ********************/

USHORT Palette[8] =
{
        0x000, 0xeca, 0xc00, 0xf60, 0xff0, 0x3f1, 0x00f, 0x600
};

struct Image StImage =
{
        0,0, 0,0,3,
        NULL, 0x7,0x0, NULL
};

extern USHORT HausImageData[408];
extern USHORT StuhlImageData[351];
extern USHORT TischImageData[576];
extern USHORT AmigaImageData[1830];
extern USHORT SchweinImageData[1440];
extern USHORT NoteImageData[480];
extern USHORT BananeImageData[795];
extern USHORT SchereImageData[648];
extern USHORT KofferImageData[612];
extern USHORT BirneImageData[576];
extern USHORT BriefImageData[450];
extern USHORT HerzImageData[465];
extern USHORT SchleifeImageData[396];
extern USHORT TasseImageData[570];
extern USHORT GlockeImageData[396];

/*********************       Spieldaten          ********************/

struct Infos                        /* Informationen über die Bilder */
{
 char *T_1[2];                      /* Texte ( Engl./Ger. )          */
 char *T_2[2];
 char *T_3[2];
 SHORT  Right;                      /* Der richtige Ausdruck         */
 USHORT *Img;                       /* Bilddaten                     */
 SHORT x;                           /* X-Koordinate                  */
 SHORT y;                           /* Y-Koordinate                  */
 SHORT size;                        /* Größe der Bilddaten           */
} Inf[ANZAHL]  =
{
 "Flat",     "Wohnung", "House",      "Haus",      "Shop",      "Geschäft", 2, &HausImageData[0],     48, 45, sizeof(HausImageData),
 "Bed",      "Bett",    "Sofa",       "Sofa",      "Chair",     "Stuhl",    3, &StuhlImageData[0],    38, 39, sizeof(StuhlImageData),
 "Table",    "Tisch",   "Board",      "Brett",     "Box",       "Kiste",    1, &TischImageData[0],    86, 32, sizeof(TischImageData),
 "Camera",   "Kamera",  "Television", "Fernseher", "Computer",  "Computer", 3, &AmigaImageData[0],   145, 61, sizeof(AmigaImageData),
 "Pig",      "Schwein", "Horse",      "Pferd",     "Cow",       "Kuh",      1, &SchweinImageData[0], 149, 48, sizeof(SchweinImageData),
 "Number",   "Zahl",    "Note",       "Note",      "Balls",     "Baelle",   2, &NoteImageData[0],     57, 40, sizeof(NoteImageData),
 "Chery",    "Kirsche", "Banana",     "Banane",    "Appel",     "Apfel",    2, &BananeImageData[0],   80, 53, sizeof(BananeImageData),
 "Knife",    "Messer",  "Saw",        "Säge",      "Scissors",  "Schere",   3, &SchereImageData[0],   58, 54, sizeof(SchereImageData),
 "Suitcase", "Koffer",  "Bag",        "Tasche",    "Chest",     "Kiste",    1, &KofferImageData[0],   90, 34, sizeof(KofferImageData),
 "Lamp",     "Lampe",   "Fire",       "Feuer",     "Bulb",      "Birne",    3, &BirneImageData[0],    63, 48, sizeof(BirneImageData),
 "Parcel",   "Paket",   "Letter",     "Brief",     "Paper",     "Papier",   2, &BriefImageData[0],    87, 25, sizeof(BriefImageData),
 "Circle",   "Kreis",   "Ball",       "Ball",      "Heart",     "Herz",     3, &HerzImageData[0],     72, 31, sizeof(HerzImageData),
 "Cap",      "Mütze",   "Rope",       "Seil",      "Slip-Knot", "Schleife", 3, &SchleifeImageData[0], 86, 22, sizeof(SchleifeImageData),
 "Cup",      "Tasse",   "Beaker",     "Becher",    "Bottle",    "Flasche",  1, &TasseImageData[0],    75, 38, sizeof(TasseImageData),
 "Bell",     "Glocke",  "Church",     "Kirche",    "Horn",      "Horn",     1, &GlockeImageData[0],   63, 33, sizeof(GlockeImageData)
};

SHORT Wer;          /* Nummer des Bildes        */
BOOL  OK;           /* Richtiges Bild ?         */
SHORT Versuch;      /* Die Nummer des Versuches */
BOOL  Modus=TRUE;   /* Die Sprache              */


/*********************           Requester        ********************/

makeintuitext(Q_text,"Ende",    BGADS, 10, 1);
makeintuitext(A_text,"Autor",   BGADS, 10, 1);
makeintuitext(L_text,"Deutsch", BGADS, 10, 1);

makeintuitext(Text_1, "",  WGADS, 6, 3);
makeintuitext(Text_2, "",     WGADS, 6, 3);
makeintuitext(Text_3, "", WGADS, 6, 3);

makebox (nbox, tn1, BGADS-1, GADGH-1, 0, 3);
makebox (wbox, tn2, WGADS-1, GH-1, 0, 3);

makengadg(  Quit_G,    NULL, COL1, LINE2   , Q_text, 1, BGADS, GADGH, nbox);
makengadg(  Lang_G, &Quit_G, COL1, LINE2+40, L_text, 2, BGADS, GADGH, nbox);
makengadg( About_G, &Lang_G, COL1, LINE2+80, A_text, 3, BGADS, GADGH, nbox);

makengadg(  Gadg_1,    NULL,  200,      100, Text_1, 1, WGADS, GH,    wbox);
makengadg(  Gadg_2, &Gadg_1,  200,      130, Text_2, 2, WGADS, GH,    wbox);
makengadg(  Gadg_3, &Gadg_2,  200,      160, Text_3, 3, WGADS, GH,    wbox);

struct IntuiText EText  = { 7,0,JAM1,15,14,NULL,UBP""             ,NULL };
struct IntuiText RText  = { 7,0,JAM1,15, 4,NULL,UBP"ABC 1.0"     ,&EText};
struct IntuiText PText  = { 7,0,JAM1, 6, 4,NULL,UBP" abbrechen " ,NULL  };
struct IntuiText NText  = { 7,0,JAM1, 6, 4,NULL,UBP" weiter "    ,NULL  };



/*********************       Screens/Windows      ********************/

struct Screen    *screen;
struct Window    *win=NULL, *Bed;
struct IntuiMessage *wmes;

struct NewScreen ns = { 0, 0, 640, 256, 3, 0, 1,
                        HIRES, CUSTOMSCREEN, NULL,
                        UBP "ABC 1.0", NULL, NULL
                      };

struct NewWindow nw = { 460, 0, 180, 256, 0, 1,
                        GADGETUP, GIMMEZEROZERO,
                        &About_G ,NULL,UBP"",NULL,NULL,
                        460, 0, 460, 0, CUSTOMSCREEN
                      };

struct NewWindow nwin = { 0, 0, WIDTH, HEIGHT, 0, 1,
                          GADGETUP, GIMMEZEROZERO|ACTIVATE,
                          &Gadg_3 ,NULL,UBP"",NULL,NULL,
                          WIDTH, HEIGHT, WIDTH, HEIGHT, CUSTOMSCREEN
                        };


/*********************           Texte E/D        ********************/

char *Sprache[3][2]  = { "Quit", "Ende",    "About",  "Autor",   "English", "Deutsch"  };
char *Texte[3][2]    = { "Try",  "Versuch", "WRONG!", "FALSCH!", "RIGHT!",  "RICHTIG!" };
char *ER_texte[2][2] = { " stop ", " abbrechen ", " continue ", " weiter " };

char *Errors[2][2]    = { "Do you really want to leave ABC?", "Wollen Sie ABC beenden?",
                          "Not enough memory!",               "Nicht genug Speicher!"   };


/*********************************************************************/
VOID error()
/*********************************************************************/
{
 if (win)    CloseWindow(win);
 if (Bed)    CloseWindow(Bed);
 if (screen) CloseScreen(screen);
 ArpExit();
}


/*********************************************************************/
VOID BreakP(Meldung)          /* Ein Autorequester mit Schlußmeldung */
/*********************************************************************/
UBYTE *Meldung;
{
 EText.IText = Meldung;
 NText.IText = UBP ER_texte[1][Modus];
 PText.IText = UBP ER_texte[0][Modus];
 if (AutoRequest(win, &RText, &PText, &NText, 0, 0, 320, 65)) error(1);
}


/*********************************************************************/
VOID end_err(text)
/*********************************************************************/
STRPTR text;
{
 BreakP(text);
 error();
}

/***************************************************************************/
Print(R,text,col,x,y)                         /* Schreibt Text in RastPort */
/***************************************************************************/
struct RastPort *R;
STRPTR text;
SHORT col,x,y;
{
 SetAPen(R,col);
 Move(R, x, y);
 Text(R, text, strlen(text));
}

/***************************************************************************/
POut(R,text,xpos,ypos)                            /* Gibt Schönschrift aus */
/***************************************************************************/
struct RastPort *R;
STRPTR text;
SHORT xpos,ypos;
{
 SetDrMd(R,JAM1);
 Print(R, text,3,xpos-1,ypos-1);
 Print(R, text,7,xpos+1,ypos+1);
 Print(R, text,6,xpos,ypos);
}

/*********************************************************************/
VOID Feld(x2,y2)                           /* Zeichnet das Spielfeld */
/*********************************************************************/
SHORT x2,y2;
{
 LoadRGB4(&(screen->ViewPort),Palette,8);
 SetRast(RP,5);

 SetAPen(RP,0);
 RectFill(RP, 80+5,30+5,380+5,70+5);

 SetAPen(RP, 2);
 SetOPen(RP, 11);
 RectFill(RP, 80,30,380,70);
 BNDRYOFF(RP);

 SetDrMd(BRP, JAM1);
 SetRast(BRP, 5);
 SetAPen(BRP, 0);

 RectFill(BRP, COL1+5, LINE2+5,    COL1+BGADS+3, LINE2+GADGH+3);
 RectFill(BRP, COL1+5, LINE2+40+5, COL1+BGADS+3, LINE2+GADGH+40+3);
 RectFill(BRP, COL1+5, LINE2+80+5, COL1+BGADS+3, LINE2+GADGH+80+3);

 RectFill(BRP, COL1+1, LINE2,    COL1+BGADS-2, LINE2+GADGH-3);
 RectFill(BRP, COL1+1, LINE2+40, COL1+BGADS-2, LINE2+GADGH+40-3);
 RectFill(BRP, COL1+1, LINE2+80, COL1+BGADS-2, LINE2+GADGH+80-3);

 RefreshGadgets(&About_G, Bed, NULL);


 Print(BRP, "ABC V1.0",0,58+2,30+2);
 Print(BRP, "(C) 1990 BY",0,42+2,50+2);
 Print(BRP, "Thorsten Kuthe",0,34+2,70+2);

 POut(BRP, "ABC V1.0",58,30);
 POut(BRP, "(C) 1990 BY",42,50);
 POut(BRP, "Thorsten Kuthe",34,70);

}


/*********************************************************************/
Number()                      /* Die die Nummer des Versuches aus    */
/*********************************************************************/
{
 char pr[20];
 SetAPen(RP,2);
 RectFill(RP, 166, 40, 282, 61);
 sprintf(pr,"%d. %s:", Versuch, Texte[0][Modus]);
 POut(RP,pr,230 - (strlen(pr)*4) ,50);
}


/*********************************************************************/
SHORT Calc_Pos(size,string)   /* Berechnet die Position eines String */
/*********************************************************************/
SHORT size;
STRPTR string;
{
 return ( ( 1 + size - ( (strlen(string) - 1) << 3 )) / 2 );
}


/*********************************************************************/
VOID OpenAll()
/*********************************************************************/
{
 if (!(screen=OpenScreen(&ns))) end_err("Cannot create screen!");
 nw.Screen   = screen;
 nwin.Screen = screen;
 if (!(Bed=OpenWindow(&nw)))   end_err("Cannot open the window!");
 if (!(win=OpenWindow(&nwin))) end_err("Cannot open the window!");
 Feld (WIDTH-20, HEIGHT-20);
}

/*********************************************************************/
VOID Load_Pic()                           /* Zeichnet ein neues Bild */
/*********************************************************************/
{
 USHORT *CD;

 if (!(CD=AllocMem( Inf[Wer].size, MEMF_CHIP))) end_err(Errors[1][Modus]);
 CopyMem( Inf[Wer].Img, CD, Inf[Wer].size );
 SetAPen(RP,5);

 if (!Wer)
 {
  RectFill(RP, 100 - (Inf[ANZAHL - 1].x / 2), 131-(Inf[ANZAHL - 1].y / 2), 100+(Inf[ANZAHL - 1].x / 2), 131 + (Inf[ANZAHL - 1].y / 2) );
 }
 else
 {
  RectFill(RP, 100 - (Inf[Wer    - 1].x / 2), 131-(Inf[Wer    - 1].y / 2), 100+(Inf[Wer    - 1].x / 2), 131 + (Inf[Wer    - 1].y / 2) );
 }

 StImage.ImageData = CD;
 StImage.Width     = Inf[Wer].x;
 StImage.Height    = Inf[Wer].y;
 StImage.LeftEdge  = 100 - (StImage.Width/2);
 StImage.TopEdge   = 131 - (StImage.Height/2);

 DrawImage(RP,&StImage,0,0);
 FreeMem(CD,Inf[Wer].size);
}


/*********************************************************************/
VOID Draw_Req()                          /* Zeichnet die Gadgets neu */
/*********************************************************************/
{
 SHORT er;
 Text_1.IText    = UBP Inf[Wer].T_1[Modus];
 Text_2.IText    = UBP Inf[Wer].T_2[Modus];
 Text_3.IText    = UBP Inf[Wer].T_3[Modus];
 Text_1.LeftEdge = Calc_Pos(WGADS, Inf[Wer].T_1[Modus]);
 Text_2.LeftEdge = Calc_Pos(WGADS, Inf[Wer].T_2[Modus]);
 Text_3.LeftEdge = Calc_Pos(WGADS, Inf[Wer].T_3[Modus]);
 SetAPen(RP,5);
 RectFill(RP, 200, 100, 400, 190);
 RefreshGadgets(&Gadg_3, win, NULL);
}


/*********************************************************************/
VOID Change_L()                      /* Ändert die Sprache der Texte */
/*********************************************************************/
{
 SHORT i;
 Modus = !Modus;
 L_text.IText = UBP Sprache[2][Modus];
 A_text.IText = UBP Sprache[1][Modus];
 Q_text.IText = UBP Sprache[0][Modus];
 SetAPen(BRP, 0);
 for (i=0;i<120;i+=40) RectFill(BRP, COL1+2, LINE2+i, COL1+BGADS-2, LINE2+GADGH-3+i);
 RefreshGadgets(&About_G, Bed, NULL);
 Draw_Req();
}


/*********************************************************************/
Message(w)                     /* Beantwortet eine Intuition-Message */
/*********************************************************************/
struct Window *w;
{
 struct IntuiMessage *nach;

 if (!w) return(0);
 nach = (struct IntuiMessage *)GetMsg(w->UserPort);
 if (nach)
 {
  wmes=nach;
  ReplyMsg(nach);
  return(1);
 }
 return(0);
}


/*********************************************************************/
SHORT Gadgetid()            /* Gibt die Gadget Identifikation zurück */
/*********************************************************************/
{
 struct Gadget *gad;

 gad = (struct Gadget *)wmes->IAddress;
 return (gad->GadgetID);
}

/*********************************************************************/
Bed_Auswerten()                  /* Wertet die Wahl eines Gagets aus */
/*********************************************************************/
{
 SHORT id;

 if (wmes->Class==GADGETUP)
 {
  id=Gadgetid();
  switch (id)
  {
   case 1 : BreakP(Errors[0][Modus]); break;
   case 2 : Change_L();               break;
   case 3 : About();                  break;
   default: DisplayBeep(0);           break;
  }
 }
}

/*********************************************************************/
Auswerten(zahl)               /* Wertet die Auswahl eines Bildes aus */
/*********************************************************************/
SHORT zahl;
{
 Number();
 if (zahl==Inf[Wer].Right)
 {
  POut(RP, Texte[2][Modus], 230-(strlen(Texte[2][Modus])*4) ,60);
  DisplayBeep(0);
  OK=TRUE;
 }
 else POut(RP, Texte[1][Modus], 230-(strlen(Texte[1][Modus])*4), 60);
}

/*********************************************************************/
VOID HandleMes()                  /* Reagiert auf Intuition-Messages */
/*********************************************************************/
{
 SHORT class=0, id;
 LONG WMask;
 while (class != GADGETUP)
 {
  WMask= Wait ( 1L<< UP->mp_SigBit | 1L << Bed->UserPort->mp_SigBit);
  if (WMask & 1L << Bed->UserPort->mp_SigBit)
  {
   while (Message(Bed));
   Bed_Auswerten();
  }
  else
  {
   while (Message(win));
   class=wmes->Class;
   Auswerten(Gadgetid());
  }
 }
}

/*********************************************************************/
About()                            /* Gibt eine Copyrightmeldung aus */
/*********************************************************************/
{
 struct Window *a_win;

 nw.LeftEdge    = 150;
 nw.TopEdge     =  50;
 nw.Width       = 340;
 nw.Height      =  90;
 nw.IDCMPFlags  = MOUSEBUTTONS|RAWKEY;
 nw.Flags       = GIMMEZEROZERO|ACTIVATE;
 nw.FirstGadget = NULL;
 nw.Title       = UBP "About";

 if (!(a_win = OpenWindow(&nw)))
 {
  BreakP("Kann das Fenster nicht öffnen!");
  return();
 }
 SetRast(ARP, 2);
 SetAPen(ARP, 5);
 SetDrMd(ARP, JAM1);
 Print (ARP, ">> A B C  1.0 <<",    5, 106, 15);
 Print (ARP, "(C) 1990 BY",         5, 126, 25);
 Print (ARP, "Thorsten Kuthe",      5, 114, 35);
 Print (ARP, "Sonderburgerstr. 2A", 5,  94, 45);
 Print (ARP, "5090 Leverkusen 1",   5, 102, 55);
 Print (ARP, "West-Germany",        5, 118, 65);
 WaitPort(a_win->UserPort);
 while (Message(a_win));
 CloseWindow(a_win);
}


/*********************************************************************/
VOID _main()                           /* Weder CLI, noch WB-Parsing */
/*********************************************************************/
{
 OpenAll();
 FOREVER
 {
  for ( Wer=0; Wer < ANZAHL; Wer++)
  {
   Load_Pic();
   Draw_Req();

   OK=FALSE;
   Versuch=0;
   while (OK==FALSE)
   {
    Versuch++;
    HandleMes();
   }
   Delay(50);
   SetAPen(RP,2);
   RectFill(RP, 180, 40, 282, 61);
  }
 }
}
