/*
   Library routines to support Menu and Gadget primitives
   in an easy (and hopefully Computer independent) way.
   In stead of using the conventional STATIC structure initialization,
   these routines support DYNAMIC structure initialization, which
   is more flexible and easier to use.
   All primitives (Push buttons, toggle buttons, scalers, selection boxes,
   String boxes and Menustrips) are added to the new_window pointer
   using the Function add_item.
   Look at the file skeletton.c for examples on how to use this library
*/

#include <stdio.h>

#include <exec/types.h>             /* Laedt die Include-Files */
#include <exec/ports.h>
#include <exec/tasks.h>
#include <exec/libraries.h>
#include <exec/devices.h>
#include <exec/memory.h>
#include <exec/execbase.h>
#include <exec/exec.h>
#include <graphics/gfxbase.h>
#include <graphics/gfx.h>
#include <graphics/view.h>
#include <graphics/rastport.h>
#include <graphics/layers.h>
#include <graphics/display.h>
#include <graphics/gfxmacros.h>
#include <intuition/intuition.h>
#include <libraries/dos.h>
#include <libraries/dosextens.h>
#include <workbench/workbench.h>
#include <workbench/startup.h>
#include <workbench/icon.h>

#define  PUSH        1
#define  TOGGLE      2
#define  SCALEX      3
#define  SCALEY      4
#define  DIALOG      5
#define  MENU        6
#define  NEW_MENU    7
#define  FILE_SELECT 8
#define  BOARD       9
#define  BULLETIN   10
#define  SELECTION  11
#define  MESSAGE    12
#define  RADIO      13
#define  ROWCOL     14
#define  SCALEX11   15
#define  SCALEY11   16
#define  STRING     17
#define  INTEGER    18
#define  FLOAT      19
#define  SCALEX00   20
#define  SCALEY00   21
#define  SELBOXGAD  201
#define  FSELBOXGAD 202
#define  FSELSTRING 203
#define  SPECIALPRO 204
#define  SPECIALPAR 205
#define  SPECIALOK  206
#define  SPECIALCAN 207

struct IntuitionBase *IntuitionBase;
struct GfxBase *GfxBase;
struct Screen *WBScreen = NULL;
struct Window *my_window;
struct Window *prop_window;
struct Gadget *prop_gadget;
struct NewWindow *my_new_window;
struct Menu *menu_bar=NULL;

struct RastPort *rp;                  /* RastPort - Zeiger */
struct IntuiMessage *message;         /* IntuiMessage - Zeiger */
struct TmpRas tmp;

struct Preferences *oldprefs, *newprefs;
int   lenprefs;

int   propdwn = 0;
int   last_gadgetid = 0;
int    menu_line = 0;
int    menu_column = 0;
int    fn_number = 0;
int    top_slider = -1;
void   (*fn_command[160])();
int    *var_value[160];
int    var_funct[160];
int    scale_var0[160];
int    scale_var1[160];
int    selector[160];
int    acc_x=0;               /* accumulated x   */
int    acc_y=0;               /* accumulated y   */
int    bas_y=5;               /* base scale for y-increment */
int    fin_flg=FALSE;         /* tells the MainLoop to termitate */
char   menu_name[80];         /* store menu bar name */
char   return_string[80];     /* string returned from dialog box */

extern struct WBStartup *WBenchMsg;
extern struct IconBase *IconBase;

struct memtree {
   struct memtree *Next;
   char *memory;
} *mem_status = NULL;


/* --------------------------------------------------------------
   allocate memory for possible deallocation of a whole tree
   -------------------------------------------------------------- */
char *tree_alloc(amount)
int amount;
{
struct memtree *memory,*old;

   if(mem_status == NULL) 
      mem_status = (struct memtree *) malloc(sizeof(struct memtree));
   memory = (struct memtree *) malloc(amount + sizeof(struct memtree));
   memory->Next = NULL;
   mem_status->Next = memory;
   return(&memory->memory);
}

/* --------------------------------------------------------------
   free a whole tree of memory allocated by tree_alloc
   -------------------------------------------------------------- */
tree_free(start)
struct memtree *start;
{
struct memtree *entry;

   mem_status = start;
   entry = start;

   while(entry->Next != NULL) {
      start = entry->Next;
      free(entry);
      entry = start;
   }
}

/* --------------------------------------------------------------
   read directory information into buffer. directories are
   preceeded by a /
   -------------------------------------------------------------- */
read_dir(subdir,buffer)
char subdir[];
char *buffer[];
{
struct FileLock *actdir;
struct FileInfoBlock *dirinfo;
char s[80],z[80];
int n,m,i,l,p;

   dirinfo = (struct FileInfoBlock *)AllocMem(sizeof(struct FileInfoBlock),0L);
   actdir = (struct FileLock *) Lock(subdir,-2);

   if(actdir == 0) {
      for(n=0;n<300;n++) {
         if(buffer[n] != NULL) free(buffer[n]);
         buffer[n] = NULL;
      }
      FreeMem(dirinfo,sizeof(struct FileInfoBlock));
      return(0);
   }

   n = Examine(actdir,dirinfo);
   p = 0;
   while(n != 0) {
      n = ExNext(actdir,dirinfo);
      if(n == 0) break;
      m = 1; i = 0;
      while(m != 0) {
         m = dirinfo->fib_FileName[i];
         s[i++] = m;
      }
      if(dirinfo->fib_DirEntryType > 0) {
         strcpy(z,"/");
      } else {
         strcpy(z," ");
      }
      strcat(z,s);
      if(buffer[p] == NULL) buffer[p] = (char *) malloc(32);
      strcpy(buffer[p],z);
      p = p + 1;
   }
   for(n=p;n<300;n++) {
      if(buffer[n] != NULL) free(buffer[n]);
      buffer[n] = NULL;
   }
/* ---------- Sorting buffer :--------- */
   for(n = 1; n < (p - 1); n++) {
      i = TRUE;
      for(m = 0; m < (p - n); m++) {
         if(strcmp(buffer[m],buffer[m+1]) > 0) {
            strcpy(z,buffer[m]);
            strcpy(buffer[m],buffer[m+1]);
            strcpy(buffer[m+1],z); i = FALSE;
         }
      }
      if(i) break;
   }
/* ---------- end sorting ------------- */
   UnLock(actdir);
   FreeMem(dirinfo,sizeof(struct FileInfoBlock));
}

/* --------------------------------------------------------------
   only refresh ONE gadget
   -------------------------------------------------------------- */
Refresh1Gadget(gadget,window)
struct Gadget *gadget;
struct Window *window;
{
struct Gadget *nextgad;

   nextgad = gadget->NextGadget;
   gadget->NextGadget = NULL;
   RefreshGadgets(gadget,window,NULL);
   if(gadget->GadgetType == PROPGADGET) DrawPropBorder(gadget,window);
   gadget->NextGadget = nextgad;
}

/* --------------------------------------------------------------
   initialize NewWindow structure
   -------------------------------------------------------------- */
struct NewWindow *init_window(x,y,title,pen1,pen2)
int x,y,pen1,pen2;
char *title;
{
struct NewWindow *window;
char *strptr;
int left, top, wbwidth, wbheight;

   if(GfxBase == NULL) GfxBase = 
         (struct GfxBase *)OpenLibrary("graphics.library",0);
   if(IntuitionBase == NULL) IntuitionBase = 
          (struct IntuitionBase *) OpenLibrary("intuition.library",0);
   if(WBScreen == NULL) WBScreen = (struct Screen *)OpenWorkBench();
   wbwidth = WBScreen->Width;
   wbheight = WBScreen->Height;
   left = (wbwidth - x) / 2;
   top = (wbheight - y) / 2;
   if(left <= 0) {left = 1; x = wbwidth - 2;}
   if(top <= 0) {top = 1; y = wbheight -2;}

   window = (struct NewWindow *) malloc(sizeof(struct NewWindow));
   strptr = (char *) tree_alloc(strlen(title)+1); strcpy(strptr,title);
   window->LeftEdge = left;
   window->TopEdge = top;
   window->Width = x;
   window->Height = y;
   window->DetailPen = pen1;
   window->BlockPen = pen2;
   window->IDCMPFlags =
CLOSEWINDOW | GADGETDOWN | GADGETUP  | MENUPICK | NEWSIZE;
   window->Flags = 
SMART_REFRESH | WINDOWCLOSE | WINDOWDRAG | WINDOWDEPTH | WINDOWSIZING;
   window->FirstGadget = NULL;
   window->CheckMark = NULL;
   window->Title = (UBYTE *) strptr;
   window->Screen = WBScreen;
   window->BitMap = NULL;
   window->MinWidth = 150;
   window->MinHeight = 100;
   window->MaxWidth = 720;
   window->MaxHeight = 560;
   window->Type = WBENCHSCREEN;
   if(WBScreen->Flags && CUSTOMSCREEN) window->Type = CUSTOMSCREEN;
   return(window);
}

/* -------------------------------------------------------------
   open a window and return structure
   ------------------------------------------------------------- */
struct Window *open_win(x,y,title,pen1,pen2)
int x,y,pen1,pen2;
char *title;
{
struct NewWindow *new_window;
struct Window *main_window;

   new_window = init_window(x,y,title,pen1,pen2);
   main_window = (struct Window *) OpenWindow(new_window);
   free(new_window);
   return(main_window);
}

/* -------------------------------------------------------------
   initialize gadget structure
   ------------------------------------------------------------- */
struct Gadget *init_gadget(x,y,flg,act,type,my_text,window)
int x,y;
USHORT flg,act,type;
struct IntuiText *my_text;
struct NewWindow *window;
{
struct Gadget *my_gadget;
   my_gadget = (struct Gadget *) tree_alloc(sizeof(struct Gadget));
   my_gadget->NextGadget = window->FirstGadget;
   my_gadget->LeftEdge = acc_x;
   my_gadget->TopEdge = acc_y;
   my_gadget->Width = x;
   my_gadget->Height = y;
   my_gadget->Flags = flg;
   my_gadget->Activation = act;
   my_gadget->GadgetType = type;
   my_gadget->GadgetRender = NULL;
   my_gadget->SelectRender = NULL;
   my_gadget->GadgetText = my_text;
   my_gadget->MutualExclude = 0;
   my_gadget->SpecialInfo = NULL;
   my_gadget->GadgetID = fn_number;
   my_gadget->UserData = NULL;

   window->FirstGadget = my_gadget;
   return(my_gadget);
}

/* --------------------------------------------------------------
   initialize intuition text structure
   -------------------------------------------------------------- */
struct IntuiText *init_textstruct(left,top)
int top,left;
{
struct IntuiText *my_text;

   my_text = (struct IntuiText *) tree_alloc(sizeof(struct IntuiText));
   my_text->FrontPen = 1;
   my_text->BackPen = 0;
   my_text->DrawMode = JAM1;
   my_text->LeftEdge = left;
   my_text->TopEdge = top;
   my_text->ITextFont = NULL;
   my_text->IText = NULL;
   my_text->NextText = NULL;
   return(my_text);
}

struct IntuiText *init_text(title,left,top)
char *title;
int top,left;
{
struct IntuiText *my_text;
char  *strptr;

   my_text = init_textstruct(left,top);
   strptr = (char *) tree_alloc(strlen(title)+1); strcpy(strptr,title);
   my_text->IText = (UBYTE *) strptr;
   return(my_text);
}
/* --------------------------------------------------------------
   add border to gadget
   -------------------------------------------------------------- */

add_border(gadget,x,y)
struct Gadget *gadget;
int x,y;
{
SHORT *my_points1, *my_points2;
struct Border *my_border1, *my_border2, *my_border3, *my_border4;
int n,m,i;

   my_points1 = (SHORT *) tree_alloc(20);
   my_points2 = (SHORT *) tree_alloc(20);
   my_border1 = (struct Border *) tree_alloc(sizeof(struct Border));
   my_border2 = (struct Border *) tree_alloc(sizeof(struct Border));
   my_border3 = (struct Border *) tree_alloc(sizeof(struct Border));
   my_border4 = (struct Border *) tree_alloc(sizeof(struct Border));

   my_points1[0] = x+1 ; my_points1[1] = 0 ;
   my_points1[2] = 0   ; my_points1[3] = 0 ;
   my_points1[4] = 0   ; my_points1[5] = y+1 ;

   my_points2[0] = x+1 ; my_points2[1] = 0 ;
   my_points2[2] = x+1 ; my_points2[3] = y+1 ;
   my_points2[4] = 0   ; my_points2[5] = y+1 ;

   my_border1->LeftEdge = -1;
   my_border1->TopEdge = -1;
   my_border1->FrontPen = 2;
   my_border1->BackPen = 0;
   my_border1->DrawMode = JAM1;
   my_border1->Count = 3;
   my_border1->XY = my_points1;
   my_border1->NextBorder = my_border2;

   my_border2->LeftEdge = -1;
   my_border2->TopEdge = -1;
   my_border2->FrontPen = 1;
   my_border2->BackPen = 0;
   my_border2->DrawMode = JAM1;
   my_border2->Count = 3;
   my_border2->XY = my_points2;
   my_border2->NextBorder = NULL;

   my_border3->LeftEdge = -1;
   my_border3->TopEdge = -1;
   my_border3->FrontPen = 1;
   my_border3->BackPen = 0;
   my_border3->DrawMode = JAM1;
   my_border3->Count = 3;
   my_border3->XY = my_points1;
   my_border3->NextBorder = my_border4;

   my_border4->LeftEdge = -1;
   my_border4->TopEdge = -1;
   my_border4->FrontPen = 2;
   my_border4->BackPen = 0;
   my_border4->DrawMode = JAM1;
   my_border4->Count = 3;
   my_border4->XY = my_points2;
   my_border4->NextBorder = NULL;

   gadget->GadgetRender = (APTR) my_border1;
   gadget->SelectRender = (APTR) my_border3;
}

add_border2(gadget,x,y)
struct Gadget *gadget;
int x,y;
{
SHORT *my_points1, *my_points2, *my_points3, *my_points4;
struct Border *my_border1, *my_border2, *my_border3, *my_border4;
int n,m,i;

   my_points1 = (SHORT *) tree_alloc(20);
   my_points2 = (SHORT *) tree_alloc(20);
   my_points3 = (SHORT *) tree_alloc(20);
   my_points4 = (SHORT *) tree_alloc(20);
   my_border1 = (struct Border *) tree_alloc(sizeof(struct Border));
   my_border2 = (struct Border *) tree_alloc(sizeof(struct Border));
   my_border3 = (struct Border *) tree_alloc(sizeof(struct Border));
   my_border4 = (struct Border *) tree_alloc(sizeof(struct Border));

   my_points1[0] = x+1 ; my_points1[1] = 0 ;
   my_points1[2] = 0   ; my_points1[3] = 0 ;
   my_points1[4] = 0   ; my_points1[5] = y+1 ;

   my_points2[0] = x+1 ; my_points2[1] = 0 ;
   my_points2[2] = x+1 ; my_points2[3] = y+1 ;
   my_points2[4] = 0   ; my_points2[5] = y+1 ;

   my_points3[0] = x+3 ; my_points3[1] = 0 ;
   my_points3[2] = 0   ; my_points3[3] = 0 ;
   my_points3[4] = 0   ; my_points3[5] = y+3 ;

   my_points4[0] = x+3 ; my_points4[1] = 0 ;
   my_points4[2] = x+3 ; my_points4[3] = y+3 ;
   my_points4[4] = 0   ; my_points4[5] = y+3 ;

   my_border1->LeftEdge = -1;
   my_border1->TopEdge = -1;
   my_border1->FrontPen = 1;
   my_border1->BackPen = 0;
   my_border1->DrawMode = JAM1;
   my_border1->Count = 3;
   my_border1->XY = my_points1;
   my_border1->NextBorder = my_border2;

   my_border2->LeftEdge = -1;
   my_border2->TopEdge = -1;
   my_border2->FrontPen = 2;
   my_border2->BackPen = 0;
   my_border2->DrawMode = JAM1;
   my_border2->Count = 3;
   my_border2->XY = my_points2;
   my_border2->NextBorder = my_border3;

   my_border3->LeftEdge = -2;
   my_border3->TopEdge = -2;
   my_border3->FrontPen = 2;
   my_border3->BackPen = 0;
   my_border3->DrawMode = JAM1;
   my_border3->Count = 3;
   my_border3->XY = my_points3;
   my_border3->NextBorder = my_border4;

   my_border4->LeftEdge = -2;
   my_border4->TopEdge = -2;
   my_border4->FrontPen = 1;
   my_border4->BackPen = 0;
   my_border4->DrawMode = JAM1;
   my_border4->Count = 3;
   my_border4->XY = my_points4;
   my_border4->NextBorder = NULL;

   gadget->GadgetRender = (APTR) my_border1;
}

/* --------------------------------------------------------------
   add a proportional gadget to the window structure
   -------------------------------------------------------------- */
add_yprop(title,min,max,window,flag)
int min,max;
char *title;
struct NewWindow *window;
int flag;
{
int n,m,l;
char *strptr;
struct IntuiText *my_text, *my_value;
struct Image *my_image;
struct PropInfo *my_prop_info;
struct Gadget *my_gadget;

   add_xprop(title,min,max,window,flag);
                               /* OK, not the finest style, but very efficient */
   my_gadget = window->FirstGadget;
   my_prop_info = (struct PropInfo *) my_gadget->SpecialInfo;

   my_prop_info->Flags = FREEVERT | AUTOKNOB;
   my_prop_info->VertBody = MAXBODY / 100 ;
   my_prop_info->HorizBody = 0;

   my_gadget->Width = 13;
   my_gadget->Height = 100;
}

add_xprop(title,min,max,window,flag)
int min,max;
char *title;
struct NewWindow *window;
int flag;
{
int n,m,l;
char s[40];
struct IntuiText *my_text, *my_value;
struct Image *my_image;
struct PropInfo *my_prop_info;
struct Gadget *my_gadget;

   scale_var0[fn_number]=min;
   scale_var1[fn_number]=max;

   my_image = (struct Image *) tree_alloc(sizeof(struct Image));

   if(flag == 1) {
      sprintf(s,"%d",min);
      my_value = init_text(s,10,-10);
      my_text = init_text(title,0,12);
      my_text->NextText = my_value;
   } else {
      my_text = NULL;
   }

   my_prop_info = (struct PropInfo *) tree_alloc(sizeof(struct PropInfo));
   my_prop_info->Flags = FREEHORIZ | AUTOKNOB;
   my_prop_info->HorizPot = 0;
   my_prop_info->VertPot = 0;
   my_prop_info->HorizBody = MAXBODY / 100;
   my_prop_info->VertBody = 0;

   my_gadget = 
init_gadget(100,10,GADGHCOMP,GADGIMMEDIATE|RELVERIFY,PROPGADGET,my_text,window);
   my_gadget->GadgetRender = (APTR) my_image;
   my_gadget->SpecialInfo = (APTR) my_prop_info;

   *var_value[fn_number] = min;
}

CallBack_prop(gadget,window) /* no display of value */
struct Gadget *gadget;
struct Window *window;
{
ULONG class;
ULONG code;
struct PropInfo *my_prop_info;
char *strptr;
int gadgetid;
int i,n,m;
int type,max,min;

   gadgetid = gadget->GadgetID; type = var_funct[gadgetid];
   my_prop_info = (struct PropInfo *) gadget->SpecialInfo;
   if(type == SCALEY00) {
      n = my_prop_info->VertPot;
   } else {
      n = my_prop_info->HorizPot;
   }
   max=scale_var1[gadgetid]; min=scale_var0[gadgetid];
   n = min + (((max - min) * n) / MAXPOT);
   *var_value[gadgetid] = n;
   DrawPropBorder(gadget,window);
}


CallBack_disp_prop(gadget,window) /* display value */
struct Gadget *gadget;
struct Window *window;
{
ULONG class;
ULONG code;
struct IntuiMessage *my_message;
struct PropInfo *my_prop_info;
struct IntuiText *my_text;
struct RastPort *rp;
char *strptr;
int gadgetid;
int i,n,m,x,y;
int type,max,min;

   rp = window->RPort;
   x = gadget->LeftEdge;
   y = gadget->TopEdge;

   gadgetid = gadget->GadgetID; type = var_funct[gadgetid]; m=129845;
   my_prop_info = (struct PropInfo *) gadget->SpecialInfo;
   while(1==1) {
      my_message=(struct IntuiMessage *)GetMsg(window->UserPort);
      if(my_message) {
         class = my_message->Class;      /* Save the IDCMP flag. */
         code = my_message->Code;
         ReplyMsg( my_message );
         if( class = GADGETUP ) return(0);
       }

      if((type == SCALEY) || (type == SCALEY11)) {
         n = my_prop_info->VertPot;
      } else {
         n = my_prop_info->HorizPot;
      }
      max=scale_var1[gadgetid]; min=scale_var0[gadgetid];
      n = min + (((max - min) * n) / MAXPOT);
      if(m!=n) {
         my_text = gadget->GadgetText; my_text = my_text->NextText;
         my_text->FrontPen = 0; PrintIText(rp,my_text,x,y);
         strptr = (char *) my_text->IText; sprintf(strptr,"%d",n);
         my_text->FrontPen = 1; PrintIText(rp,my_text,x,y);
                                DrawPropBorder(gadget,window);
         *var_value[gadgetid] = n;
      }
   }
}

DrawAllPropBorders(window)
struct Window *window;
{
int n,m,i;
int type;
struct Gadget *gadget;

   gadget = window->FirstGadget;
   while(gadget != NULL) {
      gadget = gadget->NextGadget;
      if(gadget->GadgetType == PROPGADGET) DrawPropBorder(gadget,window);
   }
}



/* --------------------------------------------------------------
   Draw a border for prop gadgets
   -------------------------------------------------------------- */
DrawPropBorder(gadget,window)
struct Gadget *gadget;
struct Window *window;
{
int n,sx,sy,ex,ey;
struct RastPort *rp;

   rp = window->RPort;
   sx = gadget->LeftEdge;
   sy = gadget->TopEdge;
   ex = sx + gadget->Width - 1;
   ey = sy + gadget->Height - 1;
   SetAPen(rp,0);
   Move(rp,sx,sy);   Draw(rp,sx,ey);
   SetAPen(rp,1);
   Move(rp,sx+1,ey); Draw(rp,sx+1,sy);
                     Draw(rp,ex,sy);
   SetAPen(rp,0);
   Move(rp,ex,sy);   Draw(rp,ex,ey);
   SetAPen(rp,2);
   Move(rp,ex-1,sy); Draw(rp,ex-1,ey);
                     Draw(rp,sx+1,ey);
}
   

/* --------------------------------------------------------------
   add toggle button to window
   -------------------------------------------------------------- */
add_toggle(title,window)
char *title;
struct NewWindow *window;
{
int n,m,l;
struct IntuiText *my_text;
struct Gadget *my_gadget;

   my_text = init_text(title,10,0);

   my_gadget = 
init_gadget(7,7,GADGHCOMP,TOGGLESELECT|GADGIMMEDIATE,BOOLGADGET,my_text,window);
   add_border(my_gadget,7,7);
   *var_value[fn_number] = 0;
}

CallBack_toggle(gadget,window)
struct Gadget *gadget;
struct Window *window;
{
int gadgetid;
int i,n,m;

   gadgetid = gadget->GadgetID;
   n = *var_value[gadgetid];
   n = n ^ 1;
   *var_value[gadgetid] = n;
}

add_integer(title,window)              /* NEW! */
char *title;
struct NewWindow *window;
{
struct Gadget *my_gadget;

   add_string(title,window);
   my_gadget = window->FirstGadget;
   my_gadget->Activation = my_gadget->Activation | LONGINT;
}

add_float(title,window)              /* NEW! */
char *title;
struct NewWindow *window;
{
struct Gadget *my_gadget;

   add_string(title,window);
   my_gadget = window->FirstGadget;
   my_gadget->Activation = my_gadget->Activation | STRINGRIGHT;
}

add_string(title,window)
char *title;
struct NewWindow *window;
{
int n,m,l;
struct IntuiText *my_text;
struct StringInfo *my_string_info;
struct Gadget *my_gadget;
UBYTE *buf, *undobuf;

   my_text = init_text(title,0,12);

   buf = (UBYTE *) tree_alloc(100); for(n=0;n<100;n++) buf[n]=0;
   undobuf = (UBYTE *) tree_alloc(100); for(n=0;n<100;n++) undobuf[n]=0;
   my_string_info = (struct StringInfo *) tree_alloc(sizeof(struct StringInfo));
   my_string_info->Buffer = buf;
   my_string_info->UndoBuffer = undobuf;
   my_string_info->BufferPos = 0;
   my_string_info->MaxChars = 99;
   my_string_info->DispPos = 0;

   my_gadget =
init_gadget(100,10,GADGHCOMP,RELVERIFY,STRGADGET,my_text,window);
   my_gadget->SpecialInfo = (APTR) my_string_info;
   add_border2(my_gadget,100,10);
}

CallBack_string(gadget,window)                           /* NEW! (modified) */
struct Gadget *gadget;
struct Window *window;
{
struct StringInfo *my_string_info;
struct IntuiText *my_text;
char *strptr;
int gadgetid;
int i,n,m;

   gadgetid = gadget->GadgetID;

   my_string_info = (struct StringInfo *) gadget->SpecialInfo;

   strptr = (char *) my_string_info->Buffer;
   if(gadget->Activation == RELVERIFY) {  /* simple string gadget */
      strcpy(var_value[gadgetid],strptr);
   }
   if(gadget->Activation & LONGINT) {     /* integer gadget */
      *var_value[gadgetid] = atoi(strptr);
   }
   if(gadget->Activation & STRINGRIGHT) { /* floating point gadget */
      sscanf(strptr,"%f",var_value[gadgetid]);
   }
   last_gadgetid = gadgetid;
   if(gadgetid < 150) (*fn_command[gadgetid])();
}


add_push(title,window)
char *title;
struct NewWindow *window;
{
int n,m,l;
struct IntuiText *my_text;
struct Gadget *my_gadget;

   my_text = init_text(title,0,0);
   l = strlen(title); n = 2 + ( l * 8 );

   my_gadget =
init_gadget(n,9,GADGHIMAGE,GADGIMMEDIATE|RELVERIFY,BOOLGADGET,my_text,window);
   add_border(my_gadget,n,9);
}

CallBack_push(gadget,window)
struct Gadget *gadget;
struct Window *window;
{
struct IntuiText *my_text;
int gadgetid;
int i,n,m;

   gadgetid = gadget->GadgetID;
   if(gadgetid < 150) (*fn_command[gadgetid])();
}


add_new_menu(title)
char *title;
{
int n,m,l;
char *my_text;
struct Menu *my_menu;

   l = strlen(title); n = ( 8 * l ) + 15;
   my_text = (char *)malloc(l+1); strcpy(my_text,title);


   my_menu = (struct Menu*)malloc(sizeof(struct Menu));
   my_menu->NextMenu = menu_bar;
   my_menu->LeftEdge = menu_column; menu_column = menu_column + n;
   my_menu->TopEdge = 0;
   my_menu->Width = n;
   my_menu->Height = 10;
   my_menu->Flags = MENUENABLED;
   my_menu->MenuName = my_text;
   my_menu->FirstItem = NULL;

   menu_bar = my_menu;
   menu_line = 0;
}


add_menu(title)
char *title;
{
int n,m,l;
struct IntuiText *my_text, *my_value;
struct MenuItem *my_item;
char s[80];

   my_value = init_textstruct(fn_number,0);
   my_text = init_text(title,0,1);
   my_text->FrontPen = 2;
   my_text->NextText = my_value;

   my_item = (struct MenuItem *)malloc(sizeof(struct MenuItem));
   my_item->NextItem = menu_bar->FirstItem;
   my_item->LeftEdge = 0;
   my_item->TopEdge = menu_line; menu_line = menu_line + 10;
   my_item->Width = 150;
   my_item->Height = 10;
   my_item->Flags = ITEMTEXT | ITEMENABLED | HIGHCOMP;
   my_item->MutualExclude = 0;
   my_item->ItemFill = (APTR) my_text;
   my_item->SelectFill = NULL;
   my_item->Command = 0;
   my_item->SubItem = NULL;
   my_item->NextSelect = MENUNULL;
   menu_bar->FirstItem = my_item;
}

CallBack_menu(menu_number)
int menu_number;
{
struct MenuItem *item;
struct IntuiText *my_text, *my_value;
int i,n,l;
char *str;

   item = (struct MenuItem *) ItemAddress(menu_bar,menu_number);
   if(item == NULL) return();
   my_text = (struct IntuiText *)item->ItemFill;
   str = (char *) my_text->IText;
   my_value = my_text->NextText;
   n = my_value->LeftEdge;
   last_gadgetid = n;
   if((n>0) && (n < 150)) (*fn_command[n])();
}


/* -------------------------------------------------------------
   create a simple requester with a message
   ------------------------------------------------------------- */
Help(message)
char *message;
{
struct Window *helpwin;
struct RastPort *rp;
char c,s[80];
int l,ml,n,m,i;
int   x,y;
BOOL close_me;
ULONG class;
ULONG code;
struct IntuiMessage *my_message;
struct Gadget *my_gadget;

  close_me = FALSE;

   ml=0 ; l=0; n=1; c=32; i=0;
   while(c!=0) {
      c = message[i++];
      if(c == 0) break;
      if(c == 10) {
         n++; if(l > ml) ml = l;
         l = 0;
      }
      l++;
   }
   n = 30 + n * 10; /* number of lines needed */
   ml = 30 + ml * 8; /* number of columns needed */

   helpwin = open_win(ml,n,"message:",0,3); rp = helpwin->RPort;
   SetDrMd(rp,JAM1); SetAPen(rp,2); RectFill(rp,2,10,ml-2,n-2); SetAPen(rp,1);
   x = 10 ; y = 30;


   c=32; i=0; n=0;
   while(c!=0) {
      c = message[i++];
      if(c <= 10) {
         s[n] = 0;
         Move(rp,x,y);
         Text(rp,s,n);
         n = 0; y = y + 10;
         continue;
      }
      s[n++] = c;
   }
   while(!((*((UBYTE*)0xbfe001))&64)); /* wait for release of mouse button */
   while(1 == 1) {
      Delay(5L);
      while(my_message=(struct IntuiMessage *)GetMsg(helpwin->UserPort)) {
         class = my_message->Class;      /* Save the IDCMP flag. */
         code = my_message->Code;
         ReplyMsg( my_message );
         switch( class ) {
            case CLOSEWINDOW:  /* The user selected the Close window gadget! */
               close_me=TRUE;
               break;       
         }
      }
      if(close_me == TRUE) break;
      if(!((*((UBYTE*)0xbfe001))&64)) break; /*left mouse button ? */
   }
   close_gfx(helpwin);
}

/* *************************************************************
   selector box and fileselector box
   ************************************************************* */
struct Gadget *create_selector(x,y,b,title,window,items,fn)
char *title;
char **items;
int x,y,b,fn;
struct NewWindow *window;
{
struct Gadget *choiceg;
struct Gadget *slide;
struct Gadget *result;
struct Gadget *accept;
struct Gadget *cancel;
struct IntuiText *my_text;
struct Image *my_image;
struct PropInfo *my_prop_info;
struct StringInfo *my_string_info;
int n,m,i,l;
UBYTE *buf, *undobuf;

   m = 2 + ( b * 8 );

/* stringbox */
   my_text = init_text(title,0,-84);
   buf = (UBYTE *) tree_alloc(100); for(n=0;n<100;n++) buf[n]=0;
   undobuf = (UBYTE *) tree_alloc(100); for(n=0;n<100;n++) undobuf[n]=0;
   my_string_info = (struct StringInfo *) tree_alloc(sizeof(struct StringInfo));
   my_string_info->Buffer = buf;
   my_string_info->UndoBuffer = undobuf;
   my_string_info->BufferPos = 0;
   my_string_info->MaxChars = 99;
   my_string_info->DispPos = 0;

   result =
init_gadget(m,10,GADGHCOMP,RELVERIFY,STRGADGET,my_text,window);
   result->SpecialInfo = (APTR) my_string_info;
   result->LeftEdge = x ;
   result->TopEdge = y + 96 ;
   result->GadgetID = fn ;
   add_border2(result,m,10);

/* 7 push buttons for text window */
   for(n=7;n>0;n--) {
      my_text = init_textstruct(0,0); my_text->IText = (UBYTE *) items[n-1];
      choiceg = init_gadget(m,10,GADGHNONE,GADGIMMEDIATE,BOOLGADGET,my_text,window);
      choiceg->LeftEdge = x ;
      choiceg->TopEdge = y + (10*n) + 12 ;
      choiceg->GadgetID = SELBOXGAD ;
   }
   add_border(choiceg,m,70);

/* slider */
   my_image = (struct Image *) tree_alloc(sizeof(struct Image));
   my_prop_info = (struct PropInfo *) tree_alloc(sizeof(struct PropInfo));
   my_prop_info->Flags = FREEVERT | AUTOKNOB;
   my_prop_info->HorizPot = 0;
   my_prop_info->VertPot = 0;
   my_prop_info->HorizBody = 0;
   my_prop_info->VertBody = MAXBODY / 100;
   slide = 
init_gadget(13,70,GADGHCOMP,GADGIMMEDIATE|RELVERIFY,PROPGADGET,NULL,window);
   slide->GadgetRender = (APTR) my_image;
   slide->SpecialInfo = (APTR) my_prop_info;
   slide->GadgetID = SPECIALPRO ;
   slide->LeftEdge = x+m+2;
   slide->TopEdge = y+22;
   slide->UserData = (APTR) items;

/* ok button */
   my_text = init_text("OK",0,0);
   accept = 
   init_gadget(m,10,GADGHIMAGE,GADGIMMEDIATE|RELVERIFY,BOOLGADGET,my_text,window);
   accept->LeftEdge = x ;
   accept->TopEdge = y + 110 ;
   accept->GadgetID = SPECIALOK ;
   add_border(accept,18,10);

/* cancel button */
   my_text = init_text("CANCEL",0,0);
   cancel = 
   init_gadget(m,10,GADGHIMAGE,GADGIMMEDIATE|RELVERIFY,BOOLGADGET,my_text,window);
   cancel->LeftEdge = x + 40;
   cancel->TopEdge = y + 110 ;
   cancel->GadgetID = SPECIALCAN ;
   add_border(cancel,50,10);

   result->UserData = (APTR) slide;     /* IMPORTANT !!! */

   return(result);
}

/* ------------------------------------------------
   create a file selector box
   ------------------------------------------------ */
struct Gadget *create_fselect(x,y,b,title,window,items,fn)
char *title;
char **items;
int x,y,b,fn;
struct NewWindow *window;
{
struct Gadget *gg;
struct Gadget *strbox;
struct Gadget *slide;
struct Gadget *choice;
struct Gadget *parent;
struct IntuiText *my_text;
struct StringInfo *my_string_info;
int n,m,i,l;
UBYTE *buf, *undobuf;

      m = 2 + ( b * 8 );

   gg = create_selector(x,y+1,b,title,window,items,fn);
   slide = (struct Gadget *) gg->UserData;
   choice = slide->NextGadget;

/* add another stringbox */
   buf = (UBYTE *) tree_alloc(100); for(n=0;n<100;n++) buf[n]=0;
   undobuf = (UBYTE *) tree_alloc(100); for(n=0;n<100;n++) undobuf[n]=0;
   my_string_info = (struct StringInfo *) tree_alloc(sizeof(struct StringInfo));
   my_string_info->Buffer = buf;
   my_string_info->UndoBuffer = undobuf;
   my_string_info->BufferPos = 0;
   my_string_info->MaxChars = 99;
   my_string_info->DispPos = 0;

   strbox =
init_gadget(m,10,GADGHCOMP,RELVERIFY,STRGADGET,NULL,window);
   strbox->SpecialInfo = (APTR) my_string_info;
   strbox->LeftEdge = x ;
   strbox->TopEdge = y ;
   strbox->GadgetID = FSELSTRING ;
   strbox->UserData = (APTR) slide;        /* IMPORTANT !!! */
   add_border2(strbox,m,10);

   for(n=0;n<7;n++) {
      choice->UserData = (APTR) strbox;    /* IMPORTANT !!! */
      choice->GadgetID = FSELBOXGAD;
      choice = choice->NextGadget;
   }

/* add Parent Button */

   my_text = init_text("Parent",0,0);
   parent = 
   init_gadget(m,10,GADGHIMAGE,GADGIMMEDIATE|RELVERIFY,BOOLGADGET,my_text,window);
   parent->LeftEdge = x + m - 50 ;
   parent->TopEdge = y + 111 ; /* should be 110, WB 2.0 ? */
   parent->GadgetID = SPECIALPAR ;
   add_border(parent,50,10);

   return(gg);
}

/* ------------------------------------------
   call back functions for selection boxes
   ------------------------------------------ */
CallBack_OK(gadget,window)
struct Gadget *gadget;
struct Window *window;
{
struct StringInfo *my_string_info;
struct IntuiText *my_text;
struct Gadget *result;
char *strptr;
int gadgetid;
int i,n,m;

   result = gadget->NextGadget;
   while(1==1) {
      if( result->GadgetType == STRGADGET ) break;
      result = result->NextGadget;
   }

   gadgetid = result->GadgetID;
   last_gadgetid = gadgetid;

   my_string_info = (struct StringInfo *) result->SpecialInfo;

   strptr = (char *) my_string_info->Buffer;
   strcpy(var_value[gadgetid],strptr);
   if(gadgetid < 150) (*fn_command[gadgetid])();
}

CallBack_CAN(gadget,window)
struct Gadget *gadget;
struct Window *window;
{
struct StringInfo *my_string_info;
struct IntuiText *my_text;
struct Gadget *result;
char *strptr;
int gadgetid;
int i,n,m;

   result = gadget->NextGadget;
   while(1==1) {
      if( result->GadgetType == STRGADGET ) break;
      result = result->NextGadget;
   }

   gadgetid = result->GadgetID;

   strcpy(var_value[gadgetid],"");
   if(gadgetid < 150) (*fn_command[gadgetid])();
}

CallBack_SELBOX(gadget,window)
struct Gadget *gadget;
struct Window *window;
{
struct StringInfo *my_string_info;
struct IntuiText *my_text;
struct Gadget *result;
char *strptr, *textptr;
int gadgetid;
int i,n,m;

   my_text = gadget->GadgetText;
   textptr = (char *) my_text->IText;

   result = gadget->NextGadget;
   while(1==1) {
      if( result->GadgetType == STRGADGET ) break;
      result = result->NextGadget;
   }

   gadgetid = result->GadgetID;

   my_string_info = (struct StringInfo *) result->SpecialInfo;

   strptr = (char *) my_string_info->Buffer;
   if(strcmp(strptr,textptr)==0){         /* simple check for double click */
      CallBack_OK(gadget,window);
      return(0);
   }
   strcpy(strptr,textptr);
   Refresh1Gadget(result,window);
}

/* read string, update dir-box, read directory, update strings */
CallBack_FSELBOX(gadget,window)
struct Gadget *gadget;
struct Window *window;
{
struct StringInfo *result_info;
struct StringInfo *path_info;
struct IntuiText *my_text;
struct Gadget *result;
struct Gadget *path;
char *strptr, *textptr, *pathptr;
int gadgetid;
int i,n,m,l;
char s[100],z[100];

   my_text = gadget->GadgetText;
   textptr = (char *) my_text->IText;

   result = gadget->NextGadget;
   while(1==1) {
      if( result->GadgetType == STRGADGET ) break;
      result = result->NextGadget;
   }
   path = (struct Gadget *) gadget->UserData;
   result_info = (struct StringInfo *) result->SpecialInfo;
   path_info = (struct StringInfo *) path->SpecialInfo;
   strptr = (char *) result_info->Buffer;
   pathptr = (char *) path_info->Buffer;

   if(textptr[0] == '/') {
      strcpy(s,pathptr);
      l=strlen(s); n=0;
      if(l==0) {
         n = 1;
      } else {
         if(s[l-1] == ':') n=1;
      }
      while(textptr[n] > 32) s[l++] = textptr[n++]; s[l]=0;
      strcpy(pathptr,s);
      Refresh1Gadget(path,window);
      CallBack_FSELSTRING(path,window); /* dirty trick, I know ! */
   } else {
      strcpy(s,pathptr);
      l = strlen(s); if((l > 0) && (s[l-1] != ':')) strcat(s,"/");
      i=0; n=1; while(textptr[n] > 32) z[i++] = textptr[n++]; z[i]=0;
      strcat(s,z);
      if(strcmp(strptr,s)==0){         /* simple check for double click */
         CallBack_OK(gadget,window);
         return(0);
      }
      strcpy(strptr,s);
      Refresh1Gadget(result,window);
   }
}

/* read dir-string, read directory, update string list */
CallBack_FSELSTRING(gadget,window)
struct Gadget *gadget;
struct Window *window;
{
struct StringInfo *my_string_info;
struct IntuiText *my_text;
struct Gadget *slide;
struct Gadget *push;
char *strptr;
char **items;
char s[80];
int gadgetid;
int i,n,m;

   slide = (struct Gadget *) gadget->UserData;
   push = slide->NextGadget;
   for(i=0;i<7;i++) {
      my_text = push->GadgetText; my_text->FrontPen = 0;
      Refresh1Gadget(push,window);
      push = push->NextGadget;
   }

   items = (char **) slide->UserData;

   my_string_info = (struct StringInfo *) gadget->SpecialInfo;

   strptr = (char *) my_string_info->Buffer;
   strcpy(s,strptr);
   read_dir(s,items);

   push = slide->NextGadget;
   for(i=0;i<7;i++) {
      my_text = push->GadgetText; my_text->IText = (UBYTE *) items[i];
      if(items[i][0] == '/') {
         my_text->FrontPen = 2;
      } else {
         my_text->FrontPen = 1;
      }
      Refresh1Gadget(push,window);
      push = push->NextGadget;
   }
}

CallBack_PAR(gadget,window)
struct Gadget *gadget;
struct Window *window;
{
struct StringInfo *my_string_info;
struct IntuiText *my_text;
struct Gadget *slide;
struct Gadget *push;
struct Gadget *dirgad;
struct FileLock *actdir, *pardir;
struct FileInfoBlock *dirinfo;
char *strptr;
char **items;
char s[80];
int gadgetid;
int i,n,m,flag;

   dirgad = gadget->NextGadget;
   slide = dirgad->NextGadget;
   while(1==1) {
      if(slide->GadgetType == PROPGADGET ) break;
      slide = slide->NextGadget;
   }
   push = slide->NextGadget;
   for(i=0;i<7;i++) {
      my_text = push->GadgetText; my_text->FrontPen = 0;
      Refresh1Gadget(push,window);
      push = push->NextGadget;
   }
   items = (char **) slide->UserData;
   my_string_info = (struct StringInfo *) dirgad->SpecialInfo;
   strptr = (char *) my_string_info->Buffer;
   strcpy(s,strptr);

   i = strlen(s); flag = 0;
   while(i > 0) {
      if(s[i] == ':') {flag = 1 ; break;}
      if(s[i] == '/') {flag = 1 ; s[i] = 0; break;}
      s[i--] = 0;
   }

   if((i == 0) || (flag == 0)) {
      dirinfo = (struct FileInfoBlock *)AllocMem(sizeof(struct FileInfoBlock),0L);
      actdir = (struct FileLock *) Lock(s,-2);
      pardir = (struct FileLock *) ParentDir(actdir);
      n = Examine(pardir,dirinfo);

      m = 1; i = 0; s[0] = ':';
      while(m != 0) {
         m = dirinfo->fib_FileName[i++];
         s[i] = m;
      }
      UnLock(actdir);
      UnLock(pardir);
      FreeMem(dirinfo,sizeof(struct FileInfoBlock));
   }

   strcpy(strptr,s);
   Refresh1Gadget(dirgad,window);
   read_dir(s,items);
   push = slide->NextGadget;
   for(i=0;i<7;i++) {
      my_text = push->GadgetText; my_text->IText = (UBYTE *) items[i];
      if(items[i][0] == '/') {
         my_text->FrontPen = 2;
      } else {
         my_text->FrontPen = 1;
      }
      Refresh1Gadget(push,window);
      push = push->NextGadget;
   }
}

CallBack_PRO(slide,window)
struct Gadget *slide;
struct Window *window;
{
ULONG class;
ULONG code;
struct IntuiMessage *my_message;
struct PropInfo *my_prop_info;
struct Gadget *push;
struct IntuiText *my_text;
char *strptr;
char **items;
int i,n,m;
int max;

   m=129845; items = (char **) slide->UserData;
   max = 0; while(items[max] != NULL) max++;
   max = max - 7;

   my_prop_info = (struct PropInfo *) slide->SpecialInfo;
   while(1==1) {
      my_message=(struct IntuiMessage *)GetMsg(window->UserPort);
      if(my_message) {
         class = my_message->Class;      /* Save the IDCMP flag. */
         code = my_message->Code;
         ReplyMsg( my_message );
         if( class = GADGETUP ) return(0);
       }

      n = my_prop_info->VertPot; n = ((max * n) / MAXPOT);
      if((m != n) & (n < max)) {
         push = slide->NextGadget;
         for(i=0;i<7;i++) {
            my_text = push->GadgetText; my_text->FrontPen = 0;
            Refresh1Gadget(push,window);
            my_text->IText = (UBYTE *) items[n+i];
            if(items[n+i][0] == '/') {
               my_text->FrontPen = 2;
            } else {
               my_text->FrontPen = 1;
            }
            Refresh1Gadget(push,window);
            push = push->NextGadget;
         }
         m = n;
      }
   }
}


/* ------------------------------------------------------------
   now we can go and add these boxes
   ------------------------------------------------------------ */

add_selector(title,window)
char *title;
struct NewWindow *window;
{
struct Gadget *gg;
char s[80],z[80];
char **items;
int n,m,i,l;

   items = (char **)tree_alloc(1200);
   for(i=0;i<300;i++) items[i] = NULL;

/* do string parsing for SELECTION box */
   extract_str(s,title,0,',');
   i=1; m=1;
   while(m>0) {
      m = extract_str(z,title,i,',');
      l = strlen(z);
      if(l == 0) break;
      items[i-1] = (char *) tree_alloc(l+1) ; strcpy(items[i-1],z); i++;
   }

   gg=create_selector(acc_x,acc_y,20,s,window,items,fn_number);
}

add_fselect(title,window)
char *title;
struct NewWindow *window;
{
struct Gadget *gg;
char s[80],z[80];
char **items;
int n,m,i,l;

   items = (char **)tree_alloc(1200);
   for(i=0;i<300;i++) items[i] = NULL;

   read_dir("",items);

   gg=create_fselect(acc_x,acc_y,20,title,window,items,fn_number);
}


/* -------------------------------------------------------------
   create a file requester window
   ------------------------------------------------------------- */
FileSelect(message,rtstr)
char *message,*rtstr;
{
struct Gadget *gg;
struct Window *win;
struct NewWindow *new_win;
struct memtree *recall;
char c,s[80];
char **items;
int l,ml,n,m,i;
int   x,y;

   items = (char **)malloc(1200);
   for(i=0;i<300;i++) items[i] = NULL;

   read_dir("",items);

   recall = mem_status;

   ml = 215 ; n = 140;
   new_win = init_window(ml,n,"FileSelect by RAKO",0,3);
   gg = create_fselect(15,15,20,message,new_win,items,150);
   win = (struct Window *) OpenWindow(new_win);

   var_funct[150] = FILE_SELECT; fin_flg = TRUE;
   var_value[150] = rtstr;
   MainLoop(win);
   fin_flg = FALSE;

   free(new_win);
   n = 0;
   while(items[n] != NULL) free(items[n++]);
   free(items);
   tree_free(recall);
}

/* -------------------------------------------------------------
   create a string requester window
   ------------------------------------------------------------- */
StringBox(message,rtstr)
char *message,*rtstr;
{
struct Gadget *gg;
struct Window *win;
struct NewWindow *new_win;
struct memtree *recall;
char c,s[80];
int l,ml,n,m,i;
int   x,y;

   recall = mem_status;
   ml = 200 ; n = 70; fn_number = 150;
   new_win = init_window(ml,n,"StringBox by RAKO",0,3);
   acc_x = 20 ; acc_y = 30 ; add_string(message,new_win);
   gg = new_win->FirstGadget;
   while((gg->GadgetType && STRGADGET) == 0) {
      gg = gg->NextGadget;
      if(gg == 0) break;
   }
   gg->Flags = GADGHCOMP|SELECTED;
   win = (struct Window *) OpenWindow(new_win);

   ActivateWindow(win);
   ActivateGadget(gg,win,0); /* why the hell does this not work ? */

   var_funct[150] = STRING; fin_flg = TRUE;
   var_value[150] = rtstr;
   MainLoop(win);
   fin_flg = FALSE;

   free(new_win);
   tree_free(recall);
}

/* -------------------------------------------------------------
    add an item to the menu list
   ------------------------------------------------------------- */
add_item(x,y,type,text,p1,p2)
int x,y,type,p1,p2;
char text[];
{
int i,m;

/* check, if position has to be adjusted */
   if(x != -1) acc_x = x;
   if(y != -1) acc_y = y;

   var_funct[fn_number] = type;

   switch(type) {

   case PUSH:
        add_push(text,my_new_window);
        acc_y = acc_y + (3 * bas_y);
        break;

   case TOGGLE:
        add_toggle(text,my_new_window);
        acc_y = acc_y + (3 * bas_y);
        break;

   case SCALEX:
        add_xprop(text,p1,p2,my_new_window,1);
        acc_y = acc_y + (8 * bas_y);
        break;

   case SCALEX00:
        add_xprop(text,p1,p2,my_new_window,0);
        acc_y = acc_y + (8 * bas_y);
        break;

   case SCALEY:
        add_yprop(text,p1,p2,my_new_window,1);
        acc_y = acc_y + (8 * bas_y);
        break;

   case SCALEY00:
        add_yprop(text,p1,p2,my_new_window,0);
        acc_y = acc_y + (22 * bas_y);
        break;

   case SCALEY11:
        add_yprop(text,p1,p2,my_new_window,1);
        acc_y = acc_y + (22 * bas_y);
        break;

   case SCALEX11:
        add_xprop(text,p1,p2,my_new_window,1);
        acc_y = acc_y + (8 * bas_y);
        break;

   case SELECTION:
        add_selector(text,my_new_window);
        acc_y = acc_y + (75 * bas_y);
        break;

   case STRING:
        add_string(text,my_new_window);
        acc_y = acc_y + (5 * bas_y);
        break;

   case INTEGER:                                /* NEW! */
        add_integer(text,my_new_window);
        acc_y = acc_y + (5 * bas_y);
        break;

   case FLOAT:                                  /* NEW! */
        add_float(text,my_new_window);
        acc_y = acc_y + (5 * bas_y);
        break;

   case RADIO:
        return(0);
        break;

   case FILE_SELECT:
        add_fselect(text,my_new_window);
        acc_y = acc_y + (90 * bas_y);
        break;

   case MENU:
        add_menu(text);
        break;

   case NEW_MENU:
        add_new_menu(text);
        break;

   default:
        break;
   }
}

MainLoop(window)
struct Window *window;
{
BOOL close_me;
ULONG class;
ULONG code;
struct IntuiMessage *my_message;
struct Gadget *my_gadget;

  close_me = FALSE;
  DrawAllPropBorders(window);

  while( close_me == FALSE )
  {
    Wait( 1 << window->UserPort->mp_SigBit );

    while(my_message=(struct IntuiMessage *)GetMsg(window->UserPort))
    {
      class = my_message->Class;      /* Save the IDCMP flag. */
      code = my_message->Code;
      ReplyMsg( my_message );
      switch( class )
      {
        case CLOSEWINDOW:  /* The user selected the Close window gadget! */
               close_me=TRUE;
               break;
             
        case GADGETDOWN:   /* The user has selected a gadget: */
               close_me=read_gadgets(my_message,window);
               break;

        case GADGETUP:     /* The user has released a gadget: */
              my_gadget = (struct Gadget *) my_message->IAddress;
              if(my_gadget->GadgetType == STRGADGET) {
                  close_me=read_gadgets(my_message,window);
               }
               break;
        case MENUPICK:
               CallBack_menu(code);
               break;
      }
    }
  }
  close_gfx(window);
}

read_gadgets(message,window)
struct IntuiMessage *message;
struct Window *window;
{
struct Gadget *my_gadget;
int gadgetid;
int i,n,m;
int class,type;

   class = message->Class;      /* Save the IDCMP flag. */
   my_gadget = (struct Gadget *) message->IAddress;
   gadgetid = my_gadget->GadgetID;
   last_gadgetid = gadgetid;

   if(gadgetid > 200) {
      switch(gadgetid) {
      case SELBOXGAD:
         CallBack_SELBOX(my_gadget,window);
         break;
      case FSELBOXGAD:
         CallBack_FSELBOX(my_gadget,window);
         break;
      case FSELSTRING:
         CallBack_FSELSTRING(my_gadget,window);
         break;
      case SPECIALPRO:
         CallBack_PRO(my_gadget,window);
         break;
      case SPECIALOK:
         if(class == GADGETDOWN) {
            CallBack_OK(my_gadget,window);
            return(fin_flg);
         }
         break;
      case SPECIALPAR:
         if(class == GADGETDOWN) CallBack_PAR(my_gadget,window);
         break;
      case SPECIALCAN:
         if(class == GADGETDOWN) {
            CallBack_CAN(my_gadget,window);
            return(fin_flg);
         }
         break;
      }
      return(FALSE);
   }

   type = var_funct[gadgetid];

   switch(type) {
   case SCALEX:
   case SCALEY:
   case SCALEX11:
   case SCALEY11:
       prop_gadget = my_gadget;
       prop_window = window;
       CallBack_disp_prop(my_gadget,window);
       if(class == GADGETDOWN) propdwn = -1;
       if(class == GADGETUP) propdwn = 0;
       break;
   case SCALEX00:
   case SCALEY00:
       prop_gadget = my_gadget;
       prop_window = window;
       CallBack_prop(my_gadget,window);
       if(class == GADGETDOWN) propdwn = -1;
       if(class == GADGETUP) propdwn = 0;
       break;
   case TOGGLE:
       CallBack_toggle(my_gadget,window);
       break;
   case STRING:
   case INTEGER:
   case FLOAT:
       CallBack_string(my_gadget,window);
       return(fin_flg);
       break;
   case PUSH:
       if(class == GADGETDOWN) CallBack_push(my_gadget,window);
       break;
   case SELECTION:
       CallBack_string(my_gadget,window);
       break;
   case FILE_SELECT:
       CallBack_string(my_gadget,window);
       return(fin_flg);
       break;
   default:
       printf("unknown function: %d gadgetID= %d \n",type,gadgetid);
       break;
   }
   return(FALSE);
}

/* -------------------------------------------------------------------

   look for altered variables and assotiated gadgets, Update Gadgets
   (Writes back altered wariables to Gadgets)

   ------------------------------------------------------------------- */

UpdateGadgets(window)            /* NEW! */
struct Window *window;
{
int n,m,i;
int type,max,min;
int gadgetid;
char *strptr;
struct Gadget *gadget;
struct StringInfo *my_string_info;
struct IntuiText *my_text;
struct PropInfo *my_prop_info;


   gadget = window->FirstGadget;
   while(gadget != NULL) {
      gadget = gadget->NextGadget;
      gadgetid = gadget->GadgetID;
      if(gadget->Flags & SELECTED) continue;
      if((gadgetid < 150) && (gadgetid > 0)) {
         if(gadget->GadgetType & STRGADGET) {
            my_string_info = (struct StringInfo *) gadget->SpecialInfo;
            strptr = (char *) my_string_info->Buffer;
            if(gadget->Activation == RELVERIFY) {  /* simple string */
               strcpy(strptr,var_value[gadgetid]);
            }
            if(gadget->Activation & LONGINT) {     /* integer gadget */
               sprintf(strptr,"%d",*var_value[gadgetid]);
               my_string_info->LongInt = *var_value[gadgetid];
            }
            if(gadget->Activation & STRINGRIGHT) { /* floating point gadget */
               sprintf(strptr,"%f",*var_value[gadgetid]);
            }
            Refresh1Gadget(gadget,window);
         }
/*
         if(gadget->GadgetType == PROPGADGET) {
            max=scale_var1[gadgetid]; min=scale_var0[gadgetid];
            n = *var_value[gadgetid];
            m = (max - min);
            if(m == 0) continue;
            n = (n - min) * MAXPOT / m;
            if((type == SCALEY) || (type == SCALEY11) || (type == SCALEY00)) {
               my_prop_info->VertPot = n;
            } else {
               my_prop_info->HorizPot = n;
            }
            Refresh1Gadget(gadget,window);
         }
*/
      }
   }
}

/* ********************************************************************

   S T R I N G H A N D L I N G

   ******************************************************************** */

/* --------------------------------------------------
   reurns in s1 s2 from nth occurence of c up to c
   -------------------------------------------------- */

extract_str(s1,s2,n,c)
char s1[],s2[],c;
int n;
{
int m,i,l;
char c1;

   m=0; l=strlen(s2);
   i = 0;
   if(n > 0) {
      for(i=0;i<l;i++) {
          c1=s2[i];
          if(c1 == c) m++;
          if(m == n) break;
      }
      s1[0] = 0;
      if(c1 != c) return(-1);
      i++;
   }
   m=0;
   while(i<l) {
      c1 = s2[i++];
      if(c1 == c) break;
      s1[m++] = c1;
   }
   s1[m] = 0;
   if(strlen(s1)==0) return(-1);
   return(1);
}

void dummy()
{
}

set_new_pointer()
{
   int n,i;
   char s[8];

   oldprefs = (struct Preferences *)malloc(sizeof(struct Preferences));
   newprefs = (struct Preferences *)malloc(sizeof(struct Preferences));
   lenprefs = GetPrefs(oldprefs,sizeof(struct Preferences));
   lenprefs = GetPrefs(newprefs,sizeof(struct Preferences));

   newprefs->PointerMatrix[2]  = 0x8001 ;
   newprefs->PointerMatrix[4]  = 0x4002 ;
   newprefs->PointerMatrix[6]  = 0x2004 ;
   newprefs->PointerMatrix[8]  = 0x1008 ;
   newprefs->PointerMatrix[10] = 0x0810 ;
   newprefs->PointerMatrix[12] = 0x0420 ;
   newprefs->PointerMatrix[14] = 0x0240 ;
   newprefs->PointerMatrix[16] = 0x0180 ;
   newprefs->PointerMatrix[18] = 0x0240 ;
   newprefs->PointerMatrix[20] = 0x0420 ;
   newprefs->PointerMatrix[22] = 0x0810 ;
   newprefs->PointerMatrix[24] = 0x1008 ;
   newprefs->PointerMatrix[26] = 0x2004 ;
   newprefs->PointerMatrix[28] = 0x4002 ;
   newprefs->PointerMatrix[30] = 0x8001 ;
   for(n = 3 ; n<32 ; n = n + 2) newprefs->PointerMatrix[n] = 0;
   newprefs->XOffset = -8 ;
   newprefs->YOffset = -8 ;

   SetPrefs(newprefs,lenprefs);
}

set_old_pointer()
{
   SetPrefs(oldprefs,lenprefs);
   free(oldprefs);
   free(newprefs);
}

RequestYesNo(text)
char *text;
{
int i,n,m;
struct IntuiText body=
{ 0, 0, JAM1, 15, 5, NULL,
   ">>>>>>>>>>>>>>>!!!!!! Undefined Yes / No Requester !!!!!!!<<<<<<<<<<<<<<<<<<",
   NULL};
struct IntuiText yes=
{ 0, 0, JAM1, 6, 3, NULL, "YES", NULL};
struct IntuiText no=
{ 0, 0, JAM1, 6, 3, NULL, "NO", NULL};

   strcpy(body.IText,text);
   n = 8 * strlen(text) + 50;
  return(AutoRequest( NULL, &body, &yes, &no, NULL, NULL, n, 72));

}


/* Unterroutine zum Abschluss des Programm */
close_gfx(struct Window *my_window)
{
  if(my_window != NULL) CloseWindow(my_window);
  CloseLibrary(GfxBase);
  CloseLibrary(IntuitionBase);
}

