/***************************************************************************/
/*                                                                         */
/*              D O P R O   V1.5                                           */
/*                                                                         */
/***************************************************************************/
/*                                                                         */
/* This file defines the OpenScreenRequester. It is heavily using the new  */
/* gadtools.library. Thanks to Matt Dillon for tpledit, an excellent tool  */
/* and tutorial for using this library                                     */
/*                                                                         */
/***************************************************************************/

/* the window dimensions */
#define WIN_LEFT   150
#define WIN_TOP    100
#define WIN_WIDTH  470
#define WIN_HEIGHT 199

static ULONG NewDisplay, NormDisplay;
static SHORT NormNr;
static char  HexID[] = "0x00000000";
static BOOL  Pal = TRUE;

/* the normal DisplayIDs from graphics/displayinfo.h */
static ULONG NormalIDs[] =
{
 LORES_KEY, HIRES_KEY, SUPER_KEY, HAM_KEY, LORESLACE_KEY, HIRESLACE_KEY, SUPERLACE_KEY,
 HAMLACE_KEY, LORESDPF_KEY, HIRESDPF_KEY, SUPERDPF_KEY, LORESLACEDPF_KEY, HIRESLACEDPF_KEY,
 SUPERLACEDPF_KEY, LORESDPF2_KEY, HIRESDPF2_KEY, SUPERDPF2_KEY, LORESLACEDPF2_KEY,
 HIRESLACEDPF2_KEY, SUPERLACEDPF2_KEY, EXTRAHALFBRITE_KEY, EXTRAHALFBRITELACE_KEY
};

/* the vga DisplayIDs */
static ULONG VGAIDs[] =
{
 VGAEXTRALORES_KEY, VGALORES_KEY, VGAPRODUCT_KEY, VGAHAM_KEY, VGAEXTRALORESLACE_KEY,
 VGALORESLACE_KEY, VGAPRODUCTLACE_KEY, VGAHAMLACE_KEY, VGAEXTRALORESDPF_KEY, VGALORESDPF_KEY,
 VGAPRODUCTDPF_KEY, VGAEXTRALORESLACEDPF_KEY, VGALORESLACEDPF_KEY, VGAPRODUCTLACEDPF_KEY,
 VGAEXTRALORESDPF2_KEY, VGALORESDPF2_KEY, VGAPRODUCTDPF2_KEY, VGAEXTRALORESLACEDPF2_KEY,
 VGALORESLACEDPF2_KEY, VGAPRODUCTLACEDPF2_KEY, VGAEXTRAHALFBRITE_KEY, VGAEXTRAHALFBRITELACE_KEY
};

/* count the ID's */
#define NormalNum (sizeof(NormalIDs)/sizeof(ULONG))
#define VGANum    (sizeof(VGAIDs)/sizeof(ULONG))

/* used by the monitor gadget */
static char *Monitors[] = {"PAL", "NTSC", NULL};

/* all my gadgets */
enum Gads
{
 LeftEdge, TopEdge, Width, Height, Depth, Detail, Block, Res, Lace, Ham, EHB, Topaz,
 Title, NormalID, Monitor, VGAID, DisplayID, LastGads
};

static struct NewGadget NGAry[] = {
    { 77,16,67,16,"LeftEdge",NULL,LeftEdge, PLACETEXT_LEFT,NULL },
    { 77,34,67,16,"TopEdge",NULL,TopEdge, PLACETEXT_LEFT,NULL },
    { 77,52,67,16,"Width",NULL,Width, PLACETEXT_LEFT,NULL },
    { 78,70,67,16,"Height",NULL,Height, PLACETEXT_LEFT,NULL },
    { 244,16,32,16,"Depth",NULL,Depth,PLACETEXT_LEFT,NULL },
    { 244,34,43,16,"DetailPen",NULL,Detail,PLACETEXT_LEFT,NULL },
    { 244,52,43,16,"BlockPen",NULL,Block,PLACETEXT_LEFT,NULL },
    { 425,16,84,16,"HIRES",NULL,Res,PLACETEXT_LEFT,NULL },
    { 425,30,84,16,"INTERLACE",NULL,Lace,PLACETEXT_LEFT,NULL },
    { 425,44,84,16,"HAM",NULL,Ham,PLACETEXT_LEFT,NULL },
    { 425,58,84,16,"EHB",NULL,EHB,PLACETEXT_LEFT,NULL },
    { 425,76,84,16,"Topaz8",NULL,Topaz,PLACETEXT_LEFT,NULL},
    { 244,70,120,16,"Title",NULL,Title,PLACETEXT_LEFT,NULL },
    {  31,105,170,69,"Display_ID",NULL,NormalID,PLACETEXT_ABOVE,NULL },
    { 134,180,67,16,"Monitor",NULL,Monitor,PLACETEXT_LEFT,NULL },
    { 235,105,170,69,"VGA_ID",NULL,VGAID,PLACETEXT_ABOVE,NULL },
    { 308,180,97,16,"NewDisplay",NULL,DisplayID,PLACETEXT_LEFT, NULL},
};

static struct Gadget *Gadgets[LastGads];


extern struct List List_NormalID, List_VGAID;
static struct Node NodeAry_NormalID[] =
{
    { NodeAry_NormalID + 1, (struct Node *)&List_NormalID.lh_Head, 0, 0,"LORES"},
    { NodeAry_NormalID + 2, NodeAry_NormalID + 0, 0, 0, "HIRES"},
    { NodeAry_NormalID + 3, NodeAry_NormalID + 1, 0, 0, "SUPER"},
    { NodeAry_NormalID + 4, NodeAry_NormalID + 2, 0, 0, "HAM"},
    { NodeAry_NormalID + 5, NodeAry_NormalID + 3, 0, 0, "LORESLACE"},
    { NodeAry_NormalID + 6, NodeAry_NormalID + 4, 0, 0, "HIRESLACE"},
    { NodeAry_NormalID + 7, NodeAry_NormalID + 5, 0, 0, "SUPERLACE"},
    { NodeAry_NormalID + 8, NodeAry_NormalID + 6, 0, 0, "HAMLACE"},
    { NodeAry_NormalID + 9, NodeAry_NormalID + 7, 0, 0, "LORESDPF"},
    { NodeAry_NormalID +10, NodeAry_NormalID + 8, 0, 0, "HIRESDPF"},
    { NodeAry_NormalID +11, NodeAry_NormalID + 9, 0, 0, "SUPERDPF"},
    { NodeAry_NormalID +12, NodeAry_NormalID +10, 0, 0, "LORESLACEDPF"},
    { NodeAry_NormalID +13, NodeAry_NormalID +11, 0, 0, "HIRESLACEDPF"},
    { NodeAry_NormalID +14, NodeAry_NormalID +13, 0, 0, "SUPERLACEDPF"},
    { NodeAry_NormalID +15, NodeAry_NormalID +14, 0, 0, "LORESDPF2"},
    { NodeAry_NormalID +16, NodeAry_NormalID +15, 0, 0, "HIRESDPF2"},
    { NodeAry_NormalID +17, NodeAry_NormalID +16, 0, 0, "SUPERDPF2"},
    { NodeAry_NormalID +18, NodeAry_NormalID +17, 0, 0, "LORESLACEDPF2"},
    { NodeAry_NormalID +19, NodeAry_NormalID +18, 0, 0, "HIRESLACEDPF2"},
    { NodeAry_NormalID +20, NodeAry_NormalID +19, 0, 0, "SUPERLACEDPF2"},
    { NodeAry_NormalID +21, NodeAry_NormalID +20, 0, 0, "EXTRAHALFBRITE"},
    { (struct Node *)&List_NormalID.lh_Tail, NodeAry_NormalID + 21, 0, 0,"EXTRAHALFBRITELACE"}
};

static struct Node NodeAry_VGAID[] =
{
    { NodeAry_VGAID + 1, (struct Node *)&List_VGAID.lh_Head, 0, 0,"EXTRALORES"},
    { NodeAry_VGAID + 2, NodeAry_VGAID + 0, 0, 0, "LORES"},
    { NodeAry_VGAID + 3, NodeAry_VGAID + 1, 0, 0, "PRODUCT"},
    { NodeAry_VGAID + 4, NodeAry_VGAID + 2, 0, 0, "HAM"},
    { NodeAry_VGAID + 5, NodeAry_VGAID + 3, 0, 0, "EXTRALORESLACE"},
    { NodeAry_VGAID + 6, NodeAry_VGAID + 4, 0, 0, "LORESLACE"},
    { NodeAry_VGAID + 7, NodeAry_VGAID + 5, 0, 0, "PRODUCTLACE"},
    { NodeAry_VGAID + 8, NodeAry_VGAID + 6, 0, 0, "HAMLACE"},
    { NodeAry_VGAID + 9, NodeAry_VGAID + 7, 0, 0, "EXTRALORESDPF"},
    { NodeAry_VGAID +10, NodeAry_VGAID + 8, 0, 0, "LORESDPF"},
    { NodeAry_VGAID +11, NodeAry_VGAID + 9, 0, 0, "PRODUCTDPF"},
    { NodeAry_VGAID +12, NodeAry_VGAID +10, 0, 0, "EXTRALORESLACEDPF"},
    { NodeAry_VGAID +13, NodeAry_VGAID +11, 0, 0, "LORESLACEDPF"},
    { NodeAry_VGAID +14, NodeAry_VGAID +13, 0, 0, "PRODUCTLACEDPF"},
    { NodeAry_VGAID +15, NodeAry_VGAID +14, 0, 0, "EXTRALORESDPF2"},
    { NodeAry_VGAID +16, NodeAry_VGAID +15, 0, 0, "LORESDPF2"},
    { NodeAry_VGAID +17, NodeAry_VGAID +16, 0, 0, "PRODUCTDPF2"},
    { NodeAry_VGAID +18, NodeAry_VGAID +17, 0, 0, "EXTRALORESLACEDPF2"},
    { NodeAry_VGAID +19, NodeAry_VGAID +18, 0, 0, "LORESLACEDPF2"},
    { NodeAry_VGAID +20, NodeAry_VGAID +19, 0, 0, "PRODUCTLACEDPF2"},
    { NodeAry_VGAID +21, NodeAry_VGAID +20, 0, 0, "EXTRAHALFBRITE"},
    { (struct Node *)&List_VGAID.lh_Tail, NodeAry_VGAID + 21, 0, 0,"EXTRAHALFBRITELACE"}
};

static struct List List_NormalID =
{
 &NodeAry_NormalID[0], NULL, &NodeAry_NormalID[NormalNum-1], NULL, NULL
};

static struct List List_VGAID =
{
 &NodeAry_VGAID[0], NULL, &NodeAry_VGAID[VGANum-1], NULL, NULL
};

static struct Gadget *GList;
static struct VisualInfo *VisInfo;

/* converts an unsigned long to a hex string, string must begin with 0x, no checking ! */
static void Int2Hex(char *s, ULONG n)
{
 short i;

 for(i=9; i>1; i--)
 {
  s[i] = "0123456789ABCDEF"[n & 0x0F];
  n >>= 4;
 }
}

/* default font */
extern struct TextAttr MyAttr =
{
 "topaz.font", 8, NULL, NULL
};

/* initializes and displays all my gadgets */
/* original created by tpledit */
static struct Gadget *InitGads(struct Screen *scr, struct NewScreen *ns)
{
 struct Gadget *gad;
 UWORD          SigViewMode;
 short          i;

 GList = NULL;
 if ((VisInfo = GetVisualInfo(scr, TAG_END)) == NULL) return(NULL);
 {
  struct NewGadget *ng;
  for (i = 0, ng = NGAry; i < sizeof(NGAry)/sizeof(NGAry[0]); ++i, ++ng)
  {
   ng->ng_VisualInfo = VisInfo;
   ng->ng_TextAttr = &MyAttr;
  }
 }
 if (!(gad = CreateContext(&GList))) return(NULL);
 Gadgets[LeftEdge] = CreateGadget(INTEGER_KIND, gad, NGAry + 0,
                                  GTIN_MaxChars, 4,
                                  GTIN_Number, ns->LeftEdge,
                                  TAG_END
                                 );
 if (!Gadgets[LeftEdge]) return(NULL);
 Gadgets[TopEdge] = CreateGadget(INTEGER_KIND, Gadgets[LeftEdge], NGAry + 1,
                                 GTIN_MaxChars, 4,
                                 GTIN_Number, ns->TopEdge,
                                 TAG_END
                                );
 if (!Gadgets[TopEdge]) return(NULL);
 Gadgets[Width] = CreateGadget(INTEGER_KIND, Gadgets[TopEdge], NGAry + 2,
                               GTIN_MaxChars, 4,
                               GTIN_Number, ns->Width,
                               TAG_END
                              );
 if (!Gadgets[Width]) return(NULL);
 Gadgets[Height] = CreateGadget(INTEGER_KIND, Gadgets[Width], NGAry + 3,
                               GTIN_MaxChars, 4,
                               GTIN_Number, ns->Height,
                               TAG_END
                              );
 if (!Gadgets[Height]) return(NULL);
 Gadgets[Depth] = CreateGadget(INTEGER_KIND, Gadgets[Height], NGAry + 4,
                               GTIN_MaxChars, 2,
                               GTIN_Number, ns->Depth,
                               GA_Disabled, TRUE,
                               TAG_END
                              );
 if (!Gadgets[Depth]) return(NULL);
 Gadgets[Detail] = CreateGadget(INTEGER_KIND, Gadgets[Depth], NGAry + 5,
                                GTIN_MaxChars, 3,
                                GTIN_Number, ns->DetailPen,
                                GA_Disabled, TRUE,
                                TAG_END
                               );
 if (!Gadgets[Detail]) return(NULL);
 Gadgets[Block] = CreateGadget(INTEGER_KIND, Gadgets[Detail], NGAry + 6,
                               GTIN_MaxChars, 2,
                               GTIN_Number, ns->BlockPen,
                               GA_Disabled, TRUE,
                               TAG_END
                              );
 if (!Gadgets[Block]) return(NULL);
 Gadgets[Res] = CreateGadget(CHECKBOX_KIND, Gadgets[Block], NGAry + 7,
                             GTCB_Checked, ns->ViewModes & HIRES,
                             GA_Disabled, TRUE,
                             TAG_END
                            );
 if (!Gadgets[Res]) return(NULL);
 Gadgets[Lace] = CreateGadget(CHECKBOX_KIND, Gadgets[Res], NGAry + 8,
                              GTCB_Checked, ns->ViewModes & LACE,
                              GA_Disabled, TRUE,
                              TAG_END
                             );
 if (!Gadgets[Lace]) return(NULL);
 Gadgets[Ham] = CreateGadget(CHECKBOX_KIND, Gadgets[Lace], NGAry + 9,
                             GTCB_Checked, ns->ViewModes & HAM,
                             GA_Disabled, TRUE,
                             TAG_END
                            );
 if (!Gadgets[Ham]) return(NULL);
 Gadgets[EHB] = CreateGadget(CHECKBOX_KIND, Gadgets[Ham], NGAry + 10,
                             GTCB_Checked, ns->ViewModes & EXTRA_HALFBRITE,
                             GA_Disabled, TRUE,
                             TAG_END
                            );
 if (!Gadgets[EHB]) return(NULL);
 Gadgets[Topaz] = CreateGadget(CHECKBOX_KIND, Gadgets[EHB], NGAry + 11,
                               GTCB_Checked, FALSE,
                               GA_Disabled, ns->Font != NULL,
                               TAG_END
                              );
 if (!Gadgets[Topaz]) return(NULL);
 Gadgets[Title] = CreateGadget(STRING_KIND, Gadgets[Topaz], NGAry + 12,
                               GTST_String, ns->DefaultTitle,
                               GTST_MaxChars, 25,
                               GA_Disabled, TRUE,
                               TAG_END
                              );
 if (!Gadgets[Title]) return(NULL);

 /* find the actual (old ?) DisplayID */
 SigViewMode = ns->ViewModes & (LACE|PFBA|EXTRA_HALFBRITE|DUALPF|HAM|HIRES);
 for(NormNr=0; NormNr<NormalNum; NormNr++)
  if (SigViewMode == NormalIDs[NormNr]) break;
 if (NormNr == NormalNum) NormNr = 0;
 NewDisplay = NormDisplay = NormalIDs[NormNr];
 Gadgets[NormalID] = CreateGadget(LISTVIEW_KIND, Gadgets[Title], NGAry + 13,
                                  GTLV_Labels, &List_NormalID,
                                  GTLV_Selected, NormNr,
                                  GTLV_ShowSelected, NULL,
                                  TAG_END
                                 );
 if (!Gadgets[NormalID]) return(NULL);

 Gadgets[Monitor] = CreateGadget(CYCLE_KIND, Gadgets[NormalID], NGAry + 14,
                                 GTCY_Labels, Monitors,
                                 TAG_END
                                );
 if(!Gadgets[Monitor]) return(NULL);

 Gadgets[VGAID] = CreateGadget(LISTVIEW_KIND, Gadgets[Monitor], NGAry + 15,
                               GTLV_Labels, &List_VGAID,
                               GTLV_ShowSelected, NULL,
                               GA_Disabled, !MayUseProductivity,
                               TAG_END
                              );
 if (!Gadgets[VGAID]) return(NULL);

 Int2Hex(HexID, NewDisplay);
 Gadgets[DisplayID] = CreateGadget(STRING_KIND, Gadgets[VGAID], NGAry + 16,
                                   GTST_String, HexID,
                                   GTST_MaxChars, 10,
                                   GA_Disabled, FALSE,
                                   TAG_END
                                  );
 if (!Gadgets[DisplayID]) return(NULL);

 return(GList);
}



static void FreeGads(void)
{
    FreeGadgets(GList);
    if (VisInfo) FreeVisualInfo(VisInfo);
    VisInfo = NULL;
    GList = NULL;
}

/* the OpenScreenRequester */
/* stolen from test.c by Matt Dillon  ;-) */
ULONG ScreenRequest(struct NewScreen *ns, BOOL *UseTopaz) /* stupid hack for topaz */
{
 struct Screen *scr;
 struct Window *win;
 struct Gadget *glist, *Gad;
 ULONG  Num;

 if (scr = LockPubScreen(NULL))
 {
  if (glist = InitGads(scr, ns))
  {
   win = OpenWindowTags(NULL,
                        WA_Flags,   WFLG_DRAGBAR|WFLG_DEPTHGADGET|WFLG_CLOSEGADGET|
                                    WFLG_SIZEGADGET|WFLG_SMART_REFRESH|WFLG_ACTIVATE, 
                        WA_IDCMP,   IDCMP_NEWSIZE|IDCMP_MOUSEBUTTONS|IDCMP_GADGETDOWN|
                                    IDCMP_GADGETUP|IDCMP_MENUPICK|IDCMP_VANILLAKEY|
                                    IDCMP_RAWKEY|IDCMP_CHANGEWINDOW|IDCMP_CLOSEWINDOW|
                                    IDCMP_REFRESHWINDOW,
                        WA_Left,    WIN_LEFT,
                        WA_Top,     WIN_TOP,
                        WA_Width,   WIN_WIDTH,
                        WA_Height,  WIN_HEIGHT,
                        WA_Title,   ProgTitle,
                        WA_MinWidth,  32,
                        WA_MinHeight, 32,
                        WA_MaxWidth,  -1,
                        WA_MaxHeight, -1,
                        WA_AutoAdjust, 1,
                        WA_PubScreen, NULL,
                        WA_PubScreenFallBack, 1,
                        WA_Gadgets, glist,
                        TAG_END
                       );
   if (win)
   {
    struct IntuiMessage *im;
    short notDone = 1;

    GT_RefreshWindow(win, NULL);
    ScreenToFront(scr);

    while (notDone) 
    {
     WaitPort(win->UserPort);
     while (im = GT_GetIMsg(win->UserPort))
     {
      switch(im->Class)
      {
       case IDCMP_CLOSEWINDOW:
         notDone = 0;
         break;
       case IDCMP_REFRESHWINDOW:
         GT_BeginRefresh(win);
         GT_EndRefresh(win, TRUE);
         break;
       case IDCMP_GADGETUP:
         Gad = (struct Gadget *)im->IAddress;
         Num = ((struct StringInfo *)Gad->SpecialInfo)->LongInt;
         switch(Gad->GadgetID)
         {
          case LeftEdge:
            ns->LeftEdge = Num;
            break;
          case TopEdge:
            ns->TopEdge = Num;
            break;
          case Width:
            ns->Width = Num;
            break;
          case Height:
            ns->Height = Num;
            break;
          case Topaz:
            *UseTopaz = !*UseTopaz;
             break;
          case NormalID:
            NormNr = im->Code;
            NormDisplay = NormalIDs[NormNr];
            NewDisplay = NormDisplay | (Pal ? PAL_MONITOR_ID : NTSC_MONITOR_ID);
            Int2Hex(HexID, NewDisplay);
            GT_SetGadgetAttrs(Gadgets[DisplayID], win, NULL,
                              GTST_String, HexID,
                              TAG_END
                             );
            GT_SetGadgetAttrs(Gadgets[VGAID], win, NULL,
                              GTLV_Selected, ~0,
                              TAG_END
                             );
            break;
          case Monitor:
            Pal = !im->Code;
            NewDisplay = NormDisplay | (Pal ? PAL_MONITOR_ID : NTSC_MONITOR_ID);
            Int2Hex(HexID, NewDisplay);
            GT_SetGadgetAttrs(Gadgets[DisplayID], win, NULL,
                              GTST_String, HexID,
                              TAG_END
                             );
            GT_SetGadgetAttrs(Gadgets[VGAID], win, NULL,
                              GTLV_Selected, ~0,
                              TAG_END
                             );
            GT_SetGadgetAttrs(Gadgets[NormalID], win, NULL,
                              GTLV_Selected, NormNr,
                              TAG_END
                             );
            break;
          case VGAID:
            NewDisplay = VGAIDs[im->Code];
            Int2Hex(HexID, NewDisplay);
            GT_SetGadgetAttrs(Gadgets[DisplayID], win, NULL,
                              GTST_String, HexID,
                              TAG_END
                             );
            GT_SetGadgetAttrs(Gadgets[NormalID], win, NULL,
                              GTLV_Selected, ~0,
                              TAG_END
                             );
            break;
         }
         break;
       default:
         break;
      }
      GT_ReplyIMsg(im);
     }
    }
    CloseWindow(win);
   }
   FreeGads();
  }
  UnlockPubScreen(NULL, scr);
 }
 return NewDisplay;
}
