/*******************************************************/
/* MULTITASK                                           */
/* Exemple de gestions de plusieurs fenêtres           */
/*                                                     */
/* Code                Jean-Pierre Rivière             */
/* Modifiée par        Pierre Philippe Launay          */
/* Copyright © 1993 by Pierre Philippe Launay          */
/*******************************************************/

/*-----------------------------------------------------*/
/* Include many system files                           */
/* Chargement des fichiers systèmes nécessaires        */
/*-----------------------------------------------------*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <intuition/intuition.h>
#include <exec/exec.h>

extern struct NewWindow NW_FenPrinc, NewWindow1, NewWindow2, NewWindow3;
extern struct NewScreen NewScreen;
extern struct Menu MenuStrip [];
extern UWORD ColorMapEntry [];


*/------------------------------------------------------*/
*/ PROGRAMME PRINCIPAL                                  */
*/ MAIN CODE                                            */
*/------------------------------------------------------*/
void main (void)
{
 struct Window * fenPrinc, * fille0, * fille1, * fille2;
 struct Screen * ecran;
 struct ViewPort * vp;
 struct RastPort * rp;
 struct EIControl * eic;
 ULONG bits;
 fenPrinc = fille0 = fille1 = fille2 = NULL;
 if (!(ecran = (struct Screen *) OpenScreen(&NewScreen)))
   QUITTER(20, "impossible d'ouvrir l'écran\n");
  vp = &(ecran->ViewPort);
  /* met les couleurs comme il faut */
  LoadRGB4(vp, ColorMapEntry, 4);
  /* recopie de l'info dans les descriptions de fenêtres */
  ShowTitle(ecran, (BOOL) 0);
  NW_FenPrinc.Screen = NewWindow1.Screen = NewWindow2.Screen = NewWindow3.Screen = ecran;
  /* ouverture de la fenêtre principale */
  if (!(fenPrinc = (struct Window *) OpenWindow(&NW_FenPrinc)))
    QUITTER(20, "impossible d'ouvrir la fenêtre principale\n");
  if (!SetMenuStrip(fenPrinc, MenuStrip))
  {
    CloseWindow(fenPrinc);
    fenPrinc = NULL;
    QUITTER(15, "impossible de mettre le menu en place\n");
   }
   rp = fenPrinc->RPort;
   SetAPen(rp, 2);
   Move(rp, 150, 24);
   Text(rp, "Origine", 7);
   Move(rp, 150, 56);
   Text(rp, "Evênement", 9);
   SetAPen(rp, 1);
   /* marquer les gadgets */
   MarquerGadget(fenPrinc);
   /* gerer le bazar */
   bits = 1 << fenPrinc->UserPort->mp_SigBit;
   for (;;)
   {
    struct IntuiMessage * imess;
    ULONG class;
    USHORT code;
    APTR address;
    struct Window * fenor;
    SHORT mouseX, mouseY;
    struct Window * fen;
    struct MsgPort * port;
    char * origine;
    char tampon[128];
    char tampon2 [20];
    ULONG recu, secondes, micros;
    recu = Wait(bits);
    if (recu == EICtrl[0].bit)
      port = EICtrl[0].Port;
    else if (recu == EICtrl[1].bit)
      port = EICtrl[1].Port;
    else if (recu == EICtrl[2].bit)
      port = EICtrl[2].Port;
    else
      port = fenPrinc->UserPort;
    while (imess = (struct IntuiMessage *) GetMsg(port)) {
      class = imess->Class;
      code = imess->Code;
      address = imess->IAddress;
      mouseX = imess->MouseX;
      mouseY = imess->MouseY;
      fen = imess->IDCMPWindow;
      secondes = imess->Seconds;
      micros = imess->Micros;
      ReplyMsg(imess);
      fenor = (struct Window *) address;
      switch (class) {
      /* gadgets */
      case GADGETDOWN :
       fenor = (struct Window *) ((struct Gadget *) address)->UserData;
       sprintf(tampon, "Gadget \"%s\" enfoncé", ((struct Gadget *) address)->GadgetText->IText);
       break;
      case GADGETUP :
       fenor = (struct Window *) ((struct Gadget *) address)->UserData;
       sprintf(tampon, "Gadget \"%s\" relevé", ((struct Gadget *) address)->GadgetText->IText);
       if (fenor == fenPrinc)
       {
       eic = Bascule(ecran, (struct Gadget *) address, &fille0, &fille1, &fille2);
       if (eic != NULL)
         bits ^= eic->bit;
       }
       break;
     /* fenêtre */
     case CLOSEWINDOW :
       if (fen == fenPrinc)
       QUITTER(0, NULL);
       /* manque une fonction pour traiter la fermeture locale */
       strcpy(tampon, "Fermer avec gadget fenêtre ppale");
       break;
     case MOUSEBUTTONS :
       switch (code)
       {
       case SELECTDOWN :
         strcpy(tampon, "bouton gauche pressé");
         break;
       case SELECTUP :
         strcpy(tampon, "bouton gauche relevé");
         break;
       case MENUDOWN :
         strcpy(tampon, "bouton droit pressé");
         break;
       case MENUUP :
         strcpy(tampon, "bouton droit relevé");
         break;
       }
       break;
     case MOUSEMOVE :
       sprintf(tampon, "pointeur en %d,%d", mouseX, mouseY);
       break;
     case VANILLAKEY :
       sprintf(tampon, "caractère \"%c\" reçu", (char) code);
       break;
     case  MENUPICK :
       if (code != MENUNULL)
       { /* on ne soucie pas de la sel. multiple */
         struct MenuItem * mi;
         UBYTE * it;
         mi = (struct MenuItem *) ItemAddress(MenuStrip, code);
         it = ((struct IntuiText *) mi->ItemFill)->IText;
         sprintf(tampon, "menu %d:%d \"%s\"", MENUNUM(code), ITEMNUM(code), it);
       }
       else
         strcpy(tampon, "aucun item du menu en fait");
         break;
    case INTUITICKS : /* uniquement sur fenêtre active ! */
      {
      ULONG heures, minutes;
      static ULONG sec = 0;
      if (sec != secondes)
        {
        heures = (minutes = secondes / 60) / 60;
        heures %= 24;
        minutes %= 60;
        secondes %= 60;
        sprintf(tampon, "%2d:%2d:%2d", heures, minutes, secondes);
        Move(rp, 150, 86);
        Text(rp, tampon, strlen(tampon));
        }
        continue;
      }
    default : /* pour WBENCHMESSAGE et pour mes oublis */
      strcpy(tampon, "sans intérêt");
      break;
    }
    if (fen == fenPrinc)
      origine = "fenêtre principale";
    else if (fen == fille0)
      origine = "fenêtre fille n°1";
    else if (fen == fille1)
      origine = "fenêtre fille n°2";
    else if (fen == fille2)
      origine = "fenêtre fille n°3";
    else
      origine = "tel le roi Leo...";
      Move(rp, 150, 36);
      Text(rp, Efface, sizeof(Efface) - 1);
      Move(rp, 150, 68);
      Text(rp, Efface, sizeof(Efface) - 1);
      Move(rp, 150, 36);
      Text(rp, origine, strlen(origine));
      Move(rp, 150, 68);
      Text(rp, tampon, strlen(tampon));
    }
   }
/* OH NO. */
}

*/*******************************************************/
*/ PROCEDURES                                           */
*/ PROCEDURES                                           */
*/*******************************************************/

struct EIControl
{
 ULONG bit;
 struct MsgPort * Port;
};

UBYTE Efface [] = "                ";

void MarquerGadget (struct Window * fenetre)
{
  struct Gadget * gadget;
  gadget = fenetre->FirstGadget;
  gadget = fenetre->FirstGadget->NextGadget;
  while (gadget)
  {
    gadget->UserData = fenetre;
    gadget = gadget->NextGadget;
  }
  return;
}

static struct EIControl EICtrl[3];

struct EIControl * Bascule (struct Screen * ecran, struct Gadget * gadget ,
       struct Window ** fille0, ** fille1,  ** fille2)
{
   struct Window ** pfen;
   struct NewWindow * nfen;
   ULONG id;

   switch (id = gadget->GadgetID) {
   default :
      break;
   case 0 :
      pfen = fille0;
      nfen = &NewWindow1;
      break;
   case 1 :
      pfen = fille1;
      nfen = &NewWindow2;
      break;
   case 2 :
      pfen = fille2;
      nfen = &NewWindow3;
      break;
   }
   if (*pfen == NULL)
     if (*pfen = (struct Window *) OpenWindow(nfen))
     {
      if (!SetMenuStrip(*pfen, MenuStrip))
      {
        CloseWindow(*pfen);
        DisplayBeep(ecran);
        return NULL;
       }
     MarquerGadget(*pfen);
     EICtrl[id].bit = 1 << (*pfen)->UserPort->mp_SigBit;
     EICtrl[id].Port = (*pfen)->UserPort;
      }
   else {
     DisplayBeep(ecran);
     return NULL;
   }
   else {
      CloseWindow(*pfen);
      *pfen = NULL;
   }
   return EICtrl + id;
}

void quitter (int code,
 char * message,
 struct Screen * ecran,
 struct Window * fenPrinc, * fille0, * fille1, * fille2
 )

{
 if (fille2)
 {
   ClearMenuStrip(fille2);
   CloseWindow(fille2);
 }
 if (fille1)
 {
   ClearMenuStrip(fille1);
   CloseWindow(fille1);
 }
 if (fille0)
 {
   ClearMenuStrip(fille0);
   CloseWindow(fille0);
 }
 if (fenPrinc)
 {
   ClearMenuStrip(fenPrinc);
   CloseWindow(fenPrinc);
 }
 if (ecran)
   CloseScreen(ecran);
 if(message)
   fprintf(stderr, message);
 exit(code);
}

/* Oh it's no good. Mais tant pis */
#define QUITTER(c,m) quitter((c), (m), ecran, fenPrinc, fille0, fille1, fille2)
