/***********************************************************
 *
 *  gadgets.c
 *
 *  Dynamische Erzeugung und Pflege der Gadgets zum "Calc"
 *
 *  Peter Gober, 06-Nov-88
 *
 ***********************************************************/


#include <exec/types.h>
#include <exec/memory.h>
#include <intuition/intuition.h>
#include <functions.h>
#include "calc.h"


/*
 *  Texte, die normalerweise in und unter den Gadgets stehen
 *  (2 = ohne und mit f, 5 = Anz. Zeichen)
 */

char gadnames[LINS][ROWS][2][5] =
{
{{"f"   ,""    },{"ln"  ,"e^x" },{"lg"  ,"10^x"},{"y^x" ,""    },{"sqr" ,"x²"  }},
{{"sin" ,"asin"},{"cos" ,"acos"},{"tan" ,"atan"},{"¶"   ,""    },{"x<>y",""    }},
{{"1/x" ,""    },{"+/-" ,"AND" },{"("   ,"OR"  },{")"   ,"XOR" },{"<-"  ,"NOT" }},
{{"E"   ,""    },{"7"   ,""    },{"8"   ,""    },{"9"   ,""    },{"÷"   ,""    }},
{{"M+"  ,"CM"  },{"4"   ,""    },{"5"   ,""    },{"6"   ,""    },{"×"   ,""    }},
{{"RM"  ,""    },{"1"   ,""    },{"2"   ,""    },{"3"   ,""    },{"-"   ,""    }},
{{"C"   ,""    },{"0"   ,""    },{"."   ,""    },{"="   ,""    },{"+"   ,""    }}
};


/*
 *  Adressen der Gadget-Strukturen werrd aufbewahrt für später
 */

struct Gadget *lastgad, *gad[LINS][ROWS];


/*
 *  Die Umrandung für alle Gadgets, die f-Taste bekommt eine Extrawurst
 *  (orange Umrandung)
 */

SHORT gadrendxy[] =
{
   0, 0,
   GADWIDTH - 1, 0,
   GADWIDTH - 1, GADHEIGHT - 1,
   0,  GADHEIGHT - 1,
   0,  0
};

struct Border gadrend =
{
   0, 0,                               /* LeftEdge, TopEdge */
   1, 0, JAM1,                         /* FrontPen, BackPen, DrawMode */
   5,                                  /* Count */
   gadrendxy,                          /* XY */
   NULL                                /* NextBorder */
};

struct Border fkeygadrend =
{
   0, 0,                               /* LeftEdge, TopEdge */
   3, 0, JAM1,                         /* FrontPen, BackPen, DrawMode */
   5,                                  /* Count */
   gadrendxy,                          /* XY */
   NULL                                /* NextBorder */
};


/*
 *  makegads() produziert die Gadgets
 */

makegads()
{
   register int line, row;

   register struct Gadget *thisgad;
   register struct IntuiText *thistext0, *thistext1;
                                        /* thistext1 ist für den Alternativtext mit "f" */


   lastgad = NULL;

   for (line = 0; line < LINS; line++)
   {
      for (row = 0; row < ROWS; row++)
      {
         /*
          *  Die ganzen Strukturen allokieren und füllen
          */

         if (!(thistext0 = (struct IntuiText *)
               AllocRemember(remkey, (long) sizeof(struct IntuiText),
                             MEMF_PUBLIC | MEMF_CLEAR)))
            cleanup();

         thistext0->FrontPen = 1;
         thistext0->DrawMode = JAM1;
         thistext0->LeftEdge =
            (GADWIDTH - 8 * strlen(gadnames[line][row][0])) / 2;
         thistext0->TopEdge = 1;
         thistext0->ITextFont = &textattr;
         thistext0->IText = (UBYTE *) gadnames[line][row][0];

         if (!(thistext1 = (struct IntuiText *)
               AllocRemember(remkey, (long) sizeof(struct IntuiText),
                             MEMF_PUBLIC | MEMF_CLEAR)))
            cleanup();

         thistext1->FrontPen = 3;      /* der Alternativtext ist rot */
         thistext1->DrawMode = JAM1;
         thistext1->LeftEdge =
            (GADWIDTH - 8 * strlen(gadnames[line][row][1])) / 2;
         thistext1->TopEdge = 10;
         thistext1->ITextFont = &textattr;
         thistext1->IText = (UBYTE *) gadnames[line][row][1];
         thistext1->NextText = thistext0;

         if (!(thisgad = (struct Gadget *)
               AllocRemember(remkey, (long) sizeof(struct Gadget),
                             MEMF_PUBLIC | MEMF_CLEAR)))
            cleanup();

         gad[line][row] = thisgad;     /* ... brauchen wir später */

         thisgad->NextGadget = lastgad;
         thisgad->LeftEdge = SPCHOR - 1 + row * (GADWIDTH + SPCHOR);
         thisgad->TopEdge = GADTOP - 1 + line * (GADHEIGHT + SPCVER);
         thisgad->Width = GADWIDTH;
         thisgad->Height = GADHEIGHT;
         thisgad->Flags = GADGHCOMP;
         thisgad->Activation = RELVERIFY;
         thisgad->GadgetType = BOOLGADGET;
         thisgad->GadgetRender = (APTR) &gadrend;
         thisgad->GadgetText = thistext1;
         thisgad->GadgetID = 10 * line + row;
                                        /* das ist unserer "Keycode" */
         lastgad = thisgad;
      }
   }

   /*
    *  Die f-Taste bekommt eine Sonderbehandlung
    */

   gad[0][0]->Activation |= TOGGLESELECT;
   gad[0][0]->GadgetRender = (APTR) &fkeygadrend; /* für orangen Rand */
   gad[0][0]->GadgetText->NextText->FrontPen = 3; /* und Buchstaben */

   return(0);
}


/*
 *  updatefkey() wird benutzt, um den Zustand der f-Taste wieder richtig an-
 *  zuzeigen, wenn die Aktivierung einer anderen Taste das "f" gelöscht hat
 *
 *  Die Lösung mit dem partiellen Löschen des Bildschirms ist beschissen,
 *  aber es geht nur so, da durch RefreshGadget nichts gelöscht wird und ohne
 *  nur ein oranger Fleck bleibt. Das Löschen selbst geht hier mit einem
 *  kleinen Kniff komfortabel über Intuition.
 */

struct Image fkeydelimage =
{
   0, 0,                                /* LeftEdge, TopEdge */
   GADWIDTH, GADHEIGHT, 2,              /* Width, Height, Depth */
   NULL,                                /* Adress */
   0x00, 0x00,                          /* PlanePick, PlaneOnOff */
   NULL                                 /* NextImage */
};

updatefkey()
{
   if (fkeypress)
      gad[0][0]->Flags |= SELECTED;       /* f ist gedrückt */
   else
      gad[0][0]->Flags &= ~SELECTED;      /* f ist nicht gedrückt */

   DrawImage(wind->RPort, &fkeydelimage,
     (long) gad[0][0]->LeftEdge, (long) gad[0][0]->TopEdge);
   RefreshGadgets(gad[0][0], wind, NULL);

   return(0);
}


/*
 *  changekeys() verändert die Tastenbelegungen, wenn ein anderes Zahlen-
 *  system eingestellt wird; außerdem werden einige Menüs desaktiviert.
 */

struct Image alldelimage =              /* wieder nur zum Löschen (s. o.) */
{
   0, 0,                                /* LeftEdge, TopEdge */
   ROWS*(GADWIDTH+SPCHOR)-SPCHOR,
   LINS*(GADHEIGHT+SPCVER)-SPCVER, 2,   /* Width, Height, Depth */
   NULL,                                /* Adress */
   0x00, 0x00,                          /* PlanePick, PlaneOnOff */
   NULL                                 /* NextImage */
};

char letter[][2] = {"A", "B", "C", "D", "E", "F" };

changekeys()
{
   register int line, row;

   /*
    *  bei den ausgefallenen Zahlensystemen lassen wir kein Komma und keine
    *  trigonometrischen Funktionen zu und stellen also die Menüs dafür ab
    */

   if (zahlsys == SYSDEZ)
   {
      OnMenu(wind, (long) SHIFTMENU(0) | SHIFTITEM(NOITEM));
      OnMenu(wind, (long) SHIFTMENU(1) | SHIFTITEM(NOITEM));
      OnMenu(wind, (long) SHIFTMENU(3) | SHIFTITEM(NOITEM));
   }
   else
   {
      OffMenu(wind, (long) SHIFTMENU(0) | SHIFTITEM(NOITEM));
      OffMenu(wind, (long) SHIFTMENU(1) | SHIFTITEM(NOITEM));
      OffMenu(wind, (long) SHIFTMENU(3) | SHIFTITEM(NOITEM));
   }

   /*
    *  Wir machen es uns einfach und Onen ert 'mal alle Gadgets
    */

   for (line = 0; line < LINS; line++)
   {
      for (row = 0; row < ROWS; row++)
      {
         if (gad[line][row]->Flags & GADGDISABLED)
            gad[line][row]->Flags &= ~GADGDISABLED;
                                        /* wir Refreshen sie ja doch */
      }
   }

   /*
    *  Die Gadgets von Funktionen, die auf jeden Fall desaktiviert werden
    *  bei den exotischen Systemen
    */

   if (zahlsys != SYSDEZ)
   {
      gad[0][1]->Flags |= GADGDISABLED; /* erste Zeile */
      gad[0][2]->Flags |= GADGDISABLED;
      gad[0][3]->Flags |= GADGDISABLED;
      gad[0][4]->Flags |= GADGDISABLED;
      gad[3][0]->Flags |= GADGDISABLED; /* E */
      gad[6][2]->Flags |= GADGDISABLED; /* . */
   }

   /*
    *  Außer für das Hexadezimalsystem und Dezimalsystem brauchen wir nicht:
    */

   if (zahlsys == SYSOKT || zahlsys == SYSBIN)
   {
      gad[1][0]->Flags |= GADGDISABLED; /* 2. Zeile und 3. Zeile, 1. Taste */
      gad[1][1]->Flags |= GADGDISABLED;
      gad[1][2]->Flags |= GADGDISABLED;
      gad[1][3]->Flags |= GADGDISABLED;
      gad[1][4]->Flags |= GADGDISABLED;
      gad[2][0]->Flags |= GADGDISABLED;
   }

   /*
    *  Alles für die speziellen Systeme
    */

   if (zahlsys == SYSBIN)
   {
      gad[3][1]->Flags |= GADGDISABLED; /* Ziffern 9 bis 2 */
      gad[3][2]->Flags |= GADGDISABLED;
      gad[3][3]->Flags |= GADGDISABLED;
      gad[4][1]->Flags |= GADGDISABLED;
      gad[4][2]->Flags |= GADGDISABLED;
      gad[4][3]->Flags |= GADGDISABLED;
      gad[5][2]->Flags |= GADGDISABLED;
      gad[5][3]->Flags |= GADGDISABLED;
   }
   else if (zahlsys == SYSOKT)
   {
      gad[3][2]->Flags |= GADGDISABLED; /* Ziffern 9 und 8 */
      gad[3][3]->Flags |= GADGDISABLED;
   }
   else if (zahlsys == SYSHEX)
   {
      for (row = 0; row <= 5; row++)
      {
         gad[1][row]->GadgetText->NextText->IText = (UBYTE *) letter[row];
         gad[1][row]->GadgetText->NextText->LeftEdge = (GADWIDTH - 8) / 2;
         gad[1][row]->GadgetText->FrontPen = 0; /* f-Belegung unsichtbar */
      }
      gad[2][0]->GadgetText->NextText->IText = (UBYTE *) letter[5];
      gad[2][0]->GadgetText->NextText->LeftEdge = (GADWIDTH - 8) / 2;
      gad[2][0]->GadgetText->FrontPen = 0;
   }
   else                                 /* Dezimalsystem */
   {
      for (row = 0; row <= 5; row++)
      {
         gad[1][row]->GadgetText->NextText->IText =
            (UBYTE *) gadnames[1][row][0];
         gad[1][row]->GadgetText->NextText->LeftEdge =
            (GADWIDTH - 8 * strlen(gadnames[1][row][0])) / 2;
         gad[1][row]->GadgetText->FrontPen = 3;
      }
      gad[2][0]->GadgetText->NextText->IText =
         (UBYTE *) gadnames[2][0][0];
      gad[2][0]->GadgetText->NextText->LeftEdge =
         (GADWIDTH - 8 * strlen(gadnames[2][0][0])) / 2;
      gad[2][0]->GadgetText->FrontPen = 3;
   }

   /*
    *  Löschen und neu zeichnen
    */

   DrawImage(wind->RPort, &alldelimage,
     (long) gad[0][0]->LeftEdge, (long) gad[0][0]->TopEdge);
   RefreshGadgets(lastgad, wind, NULL);

   return(0);
}
