/*  kurvemake  */
/* this is the name of the makefile */
/*******************************************************************/
/*                                                                 */
/*                        fileandscreen                            */
/*                                                                 */
/*                       Modul zu  Kurve                           */
/*                                                                 */
/*                       Kurvendiskusion                           */
/*                                                                 */
/*                   © 91-92 by Henning  Rink                      */
/*                                                                 */
/*     splited from Kurve.c and Funkrequest.c on 28.12.1991        */
/*                                                                 */
/*                     more info in Kurve.c                        */
/*                                                                 */
/* copyright notes -> see ReadMe                                   */
/*******************************************************************/

#define NAMELEN 256L


extern struct   Screen      *FirstScreen;
extern struct   NewWindow   FirstNewWindow,SecondNewWindow;
extern struct   NewWindow   ThirdNewWindow,FourthNewWindow;
extern struct   NewScreen   FirstNewScreen; /* this is an ExtNewScreen !! */
extern struct   Gadget      FuncPropGadget;
extern struct   Border      PropBorderB;
extern struct   ReqLib      *ReqBase;
extern const    char        *coltoolname;
extern struct   Window      *ThirdWindow,*FuncReqWindow;
extern struct   IntuiMessage  *message;
extern struct   TextAttr    NormalAttr;
extern unsigned char        minx[],maxx[],miny[],maxy[];
extern unsigned char        funktion[],funktion1[],funktion2[],UndoBuffer[];
extern char                 mycolors[];
extern struct   GfxBase     *GfxBase;
extern char                 configpath[];
extern double               xmin,xmax,ymin,ymax,xstep,xe,ye;
extern long                 scrheight,scrwidth,winheightmax,scrmode;
extern struct   FuncNode    *FirstFunc;
extern struct   FuncNode    *activeFunc;
extern char                  configfile[],configdir[];
extern short    fehler;
extern UWORD   *mousemem;
extern char    LoadText[],SaveText[];
extern struct Window *FirstWindow;


/*  definitions for changescreenmode */
extern struct Window *screenmodewin;
extern struct NewWindow ScrModeNewWindow;
extern struct Gadget *nullgadget;
extern struct NewGadget modeuse,modecancel,defwidth,defheight;
extern struct NewGadget scrwidthgadget,scrheightgadget,modelistview;
extern char   monitordescript[4][32];
extern struct NameInfo namebuffer;
extern struct DimensionInfo dimensionbuffer;
extern USHORT defscr;
extern struct List monitorlist;
extern struct Node l1mode,l2mode,l3mode,l4mode;
extern struct IntuiText modeproptxt,vissizetxt2;
extern char monitormaxsize[],monitorminsize[],monitorvissize[],colorstring[];
/* end of changescrmode data defines */

extern void  printpara(unsigned char *,double);
extern short ShowErr(short,BOOL);
extern BOOL  addfuncnode(void);
extern BOOL  changefuncnode(struct FuncNode *);
extern void  NeueP(void);
extern void  Open_WINS(void);
extern void  Close_WINS(void);
extern void  Clear(void);
extern void  Maus(void);
extern void  ReDrawFuncs(void);
extern short checkfuncs(void);
extern void  updatedisplay(long);
extern void  printactivefunc(void);
extern void  activatefunc(struct FuncNode *);
extern void  delallfuncs(void);
extern void  stripstr( char *);

/*******************************************************************/
/*                                                                 */
/*                 list of functions in this modul                 */
/*                                                                 */
/*******************************************************************/

/* BOOL    resfilemem(void); cleared 06.08.1992 */
/* void    doreqreq(void);   */

void    extLoadConfig(void);
void    extSaveConfig(void);
void    clearfilemem(void);
void    setscreenprefs(void);
void    getscreenprefs(void);
void    LoadConfig(char *);
void    SaveConfig(char *);
void    changecolor(void);
void    setcolors(void);
void    getcolors(void);
BOOL    writefunclist(BPTR,BOOL);
void    handlesave(void);
void    handleload(long *,long *);
long    filelength(UBYTE *);
void    helpdruck(UBYTE **, long *);
BOOL    readfunclist(FILE *);
long    hextol(char *);

void    changescreenmode(void);
void    FillSizeInfo(ULONG modeid);
void    MouseCenterWin(struct NewWindow *,short,short);


char     *funcdir="";               /* default path and name of the */
char     *funcfile="functions.kur"; /* function list file           */

struct  FileRequester *myaslFileReq;  /* pointer to asl FileRequester  */
char    *pathnamearray;



extern APTR ScreenVI;



/*******************************************************************/
/*                                                                 */
/*           Screenmode Requester like Prefs-Screenmode            */
/*   03.08.1992                                                    */
/*******************************************************************/

void changescreenmode(void)
{
  short  ntscavail,palavail,offs=0;
  struct Gadget *gad,*heightgad,*widthgad;
  long class;
  USHORT code,GadgetID,endless=TRUE,defscr2,height,width;
  struct IntuiMessage *modemessage;
  struct RastPort *moderp;
  ULONG vidmode,selected;

  defscr2=defscr;



  if(!ModeNotAvailable(NTSC_MONITOR_ID))
    {
     ntscavail=TRUE;
     offs=2;
     if(!(GetDisplayInfoData(NULL,(UBYTE *)&namebuffer,
       sizeof(struct NameInfo),DTAG_NAME,NTSC_MONITOR_ID|HIRES_KEY)))
        strcpy(&monitordescript[0][0],"NTSC: HIRES");
     else
       strcpy(&monitordescript[0][0],(char *)namebuffer.Name);

     if(!(GetDisplayInfoData(NULL,(UBYTE *)&namebuffer,
       sizeof(struct NameInfo),DTAG_NAME,NTSC_MONITOR_ID|HIRESLACE_KEY)))
        strcpy(&monitordescript[1][0],"NTSC: HIRES-LACE");
     else
       strcpy(&monitordescript[1][0],(char *)namebuffer.Name);

    }

  if(!ModeNotAvailable(PAL_MONITOR_ID))
    {
     palavail=TRUE;

     if(!(GetDisplayInfoData(NULL,(UBYTE *)&namebuffer,
       sizeof(struct NameInfo),DTAG_NAME,PAL_MONITOR_ID|HIRES_KEY)))
        strcpy(&monitordescript[offs][0],"PAL: HIRES");
     else
       strcpy(&monitordescript[offs][0],(char *)namebuffer.Name);

     if(!(GetDisplayInfoData(NULL,(UBYTE *)&namebuffer,
       sizeof(struct NameInfo),DTAG_NAME,PAL_MONITOR_ID|HIRESLACE_KEY)))
        strcpy(&monitordescript[1+offs][0],"PAL: HIRES-LACE");
     else
      strcpy(&monitordescript[1+offs][0],(char *)namebuffer.Name);

    }


  NewList(&monitorlist);
  AddHead(&monitorlist,&l1mode);
  AddTail(&monitorlist,&l2mode);

 if(palavail&ntscavail) /* all 4 modes */
  {
   AddTail(&monitorlist,&l3mode);
   AddTail(&monitorlist,&l4mode);
  }

modeuse.ng_VisualInfo=modecancel.ng_VisualInfo=defwidth.ng_VisualInfo=
defheight.ng_VisualInfo=scrwidthgadget.ng_VisualInfo=
scrheightgadget.ng_VisualInfo=modelistview.ng_VisualInfo=ScreenVI;

vidmode=GetVPModeID(&FirstScreen->ViewPort);

if(!(vidmode&(PAL_MONITOR_ID|NTSC_MONITOR_ID)))/* I don't know how to get the  */
  if(GfxBase->DisplayFlags&NTSC)             /* full monitor_id -> all I get */
    vidmode|=NTSC_MONITOR_ID;                /* is the default monitorid     */
  else                                       /* == no id,  so I have to ask  */
    vidmode|=PAL_MONITOR_ID;                 /* GfxBase for default monitor  */


 vidmode&=PAL_MONITOR_ID|NTSC_MONITOR_ID|HIRES_KEY|HIRESLACE_KEY;

  if(vidmode==(NTSC_MONITOR_ID|HIRES_KEY))
    selected=0;
  if(vidmode==(NTSC_MONITOR_ID|HIRESLACE_KEY))
    selected=1;
  if(vidmode==(PAL_MONITOR_ID|HIRES_KEY))
    selected=offs;
  if(vidmode==(PAL_MONITOR_ID|HIRESLACE_KEY))
    selected=offs+1;

gad=CreateContext((struct Gadget **)&nullgadget);

gad=CreateGadget((ULONG)CHECKBOX_KIND,gad,&defwidth,
                 GTCB_Checked,(ULONG)(defscr2&1),TAG_DONE);
gad=CreateGadget((ULONG)CHECKBOX_KIND,gad,&defheight,
                 GTCB_Checked,(ULONG)(defscr2&2),TAG_DONE);
gad=CreateGadget((ULONG)BUTTON_KIND,gad,&modeuse,TAG_DONE);
gad=CreateGadget((ULONG)BUTTON_KIND,gad,&modecancel,TAG_DONE);

widthgad=gad=CreateGadget((ULONG)INTEGER_KIND,gad,&scrwidthgadget,
  GA_Disabled,(ULONG)(defscr2&1),GTIN_Number,scrwidth,GTIN_MaxChars,5L,TAG_DONE);

heightgad=gad=CreateGadget((ULONG)INTEGER_KIND,gad,&scrheightgadget,
  GA_Disabled,(ULONG)(defscr2&2),GTIN_Number,scrheight,GTIN_MaxChars,5L,TAG_DONE);

gad=CreateGadget((ULONG)LISTVIEW_KIND,gad,&modelistview,GTLV_ScrollWidth,(ULONG)18,
          GTLV_Labels,(void *)&monitorlist,LAYOUTA_Spacing,1L,
          GTLV_Selected,selected,GTLV_ShowSelected,NULL,TAG_DONE);


ScrModeNewWindow.Screen=FirstScreen;
ScrModeNewWindow.FirstGadget=nullgadget;
MouseCenterWin(&ScrModeNewWindow,0,0);

if(!(screenmodewin=OpenWindowTagList(&ScrModeNewWindow,NULL)))
 {
   if(nullgadget)     FreeGadgets(nullgadget);
   ShowErr(9,FALSE);
   return();
 }

moderp=screenmodewin->RPort;

DrawBevelBox(moderp,310L,30L,298L,100L,GT_VisualInfo,(ULONG)ScreenVI,
    GTBB_Recessed,(ULONG)TRUE,TAG_DONE);


 FillSizeInfo(vidmode);
 PrintIText(moderp,&modeproptxt,310L,30L); 


GT_RefreshWindow(screenmodewin,NULL);

while(endless)
 {
   if(!(modemessage=GT_GetIMsg(screenmodewin->UserPort)))
    {
     Wait(1L<<screenmodewin->UserPort->mp_SigBit);
      continue;
    }

 class=modemessage->Class;
 code=modemessage->Code;

 if(class&(GADGETUP|GADGETDOWN)) /* user clicked a Gadget */
  {
     gad=(struct Gadget *)modemessage->IAddress;
     GadgetID=gad->GadgetID;
  }


switch(class)
{
  case IDCMP_REFRESHWINDOW:
   GT_BeginRefresh(screenmodewin);
   DrawBevelBox(moderp,310L,30L,298L,100L,GT_VisualInfo,(ULONG)ScreenVI,
       GTBB_Recessed,(ULONG)TRUE,TAG_DONE);
   PrintIText(moderp,&modeproptxt,310L,30L); 
   GT_EndRefresh(screenmodewin,(LONG)TRUE);
   break;

  case GADGETUP:
   switch(GadgetID)
    {
     case 1:
      endless=FALSE;
      break;
     case 2:
      endless=FALSE;
      break;

     case 3:
      if(gad->Flags&SELECTED)
       {
        defscr2|=1;
        GT_SetGadgetAttrs(widthgad,screenmodewin,NULL,GA_Disabled,(ULONG)TRUE,
             GTIN_Number,(dimensionbuffer.TxtOScan.MaxX+1L),TAG_DONE);
       }
      else
       {
        defscr2&=~1;
        GT_SetGadgetAttrs(widthgad,screenmodewin,NULL,GA_Disabled,(ULONG)FALSE,
           TAG_DONE);
       }
     break;

     case 4:
      if(gad->Flags&SELECTED)
       {
        defscr2|=2;
        GT_SetGadgetAttrs(heightgad,screenmodewin,NULL,GA_Disabled,(ULONG)TRUE,
            GTIN_Number,(dimensionbuffer.TxtOScan.MaxY+1L),TAG_DONE);
       }
      else
       {
        defscr2&=~2;
        GT_SetGadgetAttrs(heightgad,screenmodewin,NULL,GA_Disabled,(ULONG)FALSE,
           TAG_DONE);
       }
      break;

     case 5:  /* width */
      if(((struct StringInfo *)widthgad->SpecialInfo)->LongInt<dimensionbuffer.MinRasterWidth||
         ((struct StringInfo *)widthgad->SpecialInfo)->LongInt>dimensionbuffer.MaxRasterWidth)
       {
        GT_SetGadgetAttrs(widthgad,screenmodewin,NULL,
            GTIN_Number,(dimensionbuffer.TxtOScan.MaxX+1L),TAG_DONE);
        ActivateGadget(widthgad,screenmodewin,NULL);
       }
      else
       if(!(heightgad->Flags&GFLG_DISABLED)) /* 12.09.1992 */
        ActivateGadget(heightgad,screenmodewin,NULL);
      break;

     case 6:  /* height */
      if(((struct StringInfo *)heightgad->SpecialInfo)->LongInt<dimensionbuffer.MinRasterHeight||
         ((struct StringInfo *)heightgad->SpecialInfo)->LongInt>dimensionbuffer.MaxRasterHeight)
       {
        GT_SetGadgetAttrs(heightgad,screenmodewin,NULL,
            GTIN_Number,(dimensionbuffer.TxtOScan.MaxY+1L),TAG_DONE);
        ActivateGadget(heightgad,screenmodewin,NULL);
       }
      else
       if(!(widthgad->Flags&GFLG_DISABLED))/* 12.09.1992 */
        ActivateGadget(widthgad,screenmodewin,NULL);
      break;

     case 7:
      selected=code;
      switch(selected+2-offs) /* if only  pal -> offs=0 */
       {
         case 0:
          vidmode=NTSC_MONITOR_ID|HIRES_KEY;
          break;
         case 1:
          vidmode=NTSC_MONITOR_ID|HIRESLACE_KEY;
          break;
         case 2:
          vidmode=PAL_MONITOR_ID|HIRES_KEY;
          break;
         case 3:
          vidmode=PAL_MONITOR_ID|HIRESLACE_KEY;
          break;
       }
      FillSizeInfo(vidmode);
      PrintIText(moderp,&vissizetxt2,310L,30L);

      if((defscr2&2)||dimensionbuffer.MinRasterHeight>((struct StringInfo *)
              heightgad->SpecialInfo)->LongInt)
       {
        GT_SetGadgetAttrs(heightgad,screenmodewin,NULL,GTIN_Number,
                      (dimensionbuffer.TxtOScan.MaxY+1L));
       }
      if((defscr2&1)||dimensionbuffer.MinRasterWidth>((struct StringInfo *)
              widthgad->SpecialInfo)->LongInt)
       {
        GT_SetGadgetAttrs(widthgad,screenmodewin,NULL,GTIN_Number,
                      (dimensionbuffer.TxtOScan.MaxX+1L));
       }
     break;
    }

 }

 GT_ReplyIMsg(modemessage);
}

 width=((struct StringInfo *)widthgad->SpecialInfo)->LongInt;
 height=((struct StringInfo *)heightgad->SpecialInfo)->LongInt;


if(screenmodewin)  CloseWindow(screenmodewin);
if(nullgadget)     FreeGadgets(nullgadget);


if(GadgetID==1)
 {
  if(width<dimensionbuffer.MinRasterWidth||width>dimensionbuffer.MaxRasterWidth)
    width=dimensionbuffer.TxtOScan.MaxX+1;
  if(height<dimensionbuffer.MinRasterHeight||height>dimensionbuffer.MaxRasterHeight)
    height=dimensionbuffer.TxtOScan.MaxY+1;

  if(vidmode!=scrmode||width!=scrwidth||height!=scrheight)
   {
    scrmode=vidmode;
    scrheight=height;
    scrwidth=width;
    defscr=defscr2;
    setscreenprefs(); /* set the NewScreen and NewWindow structures  */
    NeueP();          /* new calculation of zero points              */

    Close_WINS();
    Open_WINS();
    ReDrawFuncs();
   }
  }
}


/*******************************************************************/
/*                                                                 */
/*             FillSizeInfo looks for dimensioninfo of             */
/*                      the desired videomode                      */
/*                         done 03.08.1992                         */
/*                                                                 */
/*******************************************************************/

void FillSizeInfo(ULONG modeid)
{
 GetDisplayInfoData(NULL,(UBYTE *)&dimensionbuffer,
        sizeof(struct DimensionInfo),DTAG_DIMS,modeid);


 if(dimensionbuffer.MinRasterWidth<640)
  dimensionbuffer.MinRasterWidth=640;

 if(dimensionbuffer.MinRasterHeight<200)
  dimensionbuffer.MinRasterHeight=200;


 sprintf(monitormaxsize,"%5d  x  %5d",dimensionbuffer.MaxRasterWidth,
                                    dimensionbuffer.MaxRasterHeight);

 sprintf(monitorminsize,"%5d  x  %5d",dimensionbuffer.MinRasterWidth,
                                    dimensionbuffer.MinRasterHeight);

 sprintf(monitorvissize,"%5d  x  %5d",dimensionbuffer.TxtOScan.MaxX+1,
                                    dimensionbuffer.TxtOScan.MaxY+1);

 strcpy(colorstring,"8");
}



/*******************************************************************/
/*                                                                 */
/*             Center a window under the mousepointer              */
/*                needs a lot of security checks!!!                */
/*                 done 03.08.1992 and 04.08.1992                  */
/*                                                                 */
/*******************************************************************/

void MouseCenterWin(struct NewWindow *win,short xoffs, short yoffs)
{
 short middley,middlex;

 middley=FirstScreen->MouseY-win->Height/2+yoffs;
 middlex=FirstScreen->MouseX-win->Width/2+yoffs;

 if(middley<(-FirstScreen->TopEdge))
   middley=-FirstScreen->TopEdge;

 if(middley+win->Height>=dimensionbuffer.TxtOScan.MaxY+(-FirstScreen->TopEdge))
    middley=-FirstScreen->TopEdge+dimensionbuffer.TxtOScan.MaxY-win->Height;

if(middley+win->Height>=scrheight)  /* still needed if screen is smaller */
    middley=scrheight-win->Height;  /* than TxtOScan !!                  */


 if(middlex<(-FirstScreen->LeftEdge))
   middlex=-FirstScreen->LeftEdge;

 if(middlex+win->Width>=dimensionbuffer.TxtOScan.MaxX+(-FirstScreen->LeftEdge))
    middlex=-FirstScreen->LeftEdge+dimensionbuffer.TxtOScan.MaxX-win->Width;

 if(middlex+win->Width>=scrwidth)
    middlex=scrwidth-win->Width;

 if(middlex<0) middlex=0;
 if(middley<0) middley=0;

 win->TopEdge=middley;
 win->LeftEdge=middlex;

}




/*******************************************************************/
/*                                                                 */
/*     changecolor() calls the color requester from req.libary     */
/*            or the official color tool from workbench            */
/*          default name for color tool is in globdata.c           */
/* added 17.11.1991                                                */
/*******************************************************************/

void changecolor(void)
{
  if(ReqBase)
    ColorRequester(0L);
  else
    Execute((UBYTE *)coltoolname,NULL,NULL);

  getcolors();  /* read the new ColorMap from Viewport */
}               /* and store it to mycolors[]          */


/*******************************************************************/
/*                                                                 */
/*      setcolors() reads colortable mycolors[] and sets them      */
/*                     to the screens ColorMap                     */
/*                                                                 */
/*******************************************************************/

void setcolors(void)
{
 short i;

 for(i=0;i<8;i++)
  SetRGB4(&FirstScreen->ViewPort,(long)i,(long)mycolors[i*3],
    (long)mycolors[i*3+1],(long)mycolors[i*3+2]);
}


/*******************************************************************/
/*                                                                 */
/*     getcolors() reads colors from ColorMap and cpoies them      */
/*                          to mycolors[]                          */
/*                                                                 */
/*******************************************************************/

void getcolors(void)
{
  long color;
  short i;

    for(i=0;i<8;i++)
     {
       color=GetRGB4(FirstScreen->ViewPort.ColorMap,(long)i);
       mycolors[i*3]=(color>>8)&0xf;
       mycolors[i*3+1]=(color>>4)&0xf;
       mycolors[i*3+2]=color&0xf;
     }
}

/*******************************************************************/
/*                                                                 */
/*          setscreenprefs changes my screen and windows           */
/*             to fit the size given in scrheight and              */
/*         scrwidth (->getscreenprefs, ->changescreenmode)         */
/*                                                                 */
/*******************************************************************/


void setscreenprefs(void)
{
 extern struct TagItem ExtDef[];

 ExtDef[0].ti_Data=scrmode;

 FillSizeInfo(scrmode); /* 03.08.1992 */

 FirstNewScreen.Height=scrheight;
 FirstNewScreen.Width=scrwidth;

 FirstNewWindow.Height=scrheight-10;
 winheightmax=scrheight-11;
 FirstNewWindow.Width=scrwidth;

 SecondNewWindow.LeftEdge=scrwidth-SecondNewWindow.Width;

 FourthNewWindow.Height=scrheight-10;

}

/*******************************************************************/
/*                                                                 */
/*      getscreenprefs() reads Screensize values from GfxBase      */
/*                                                                 */
/*******************************************************************/

void getscreenprefs(void)
{
 defscr=3; /* default height and width */

 if(GfxBase->DisplayFlags&NTSC)
   scrmode=NTSC_MONITOR_ID|HIRES_KEY;
 else
   scrmode=PAL_MONITOR_ID|HIRES_KEY;

 FillSizeInfo(scrmode); /* 03.08.1992 */

 scrheight=dimensionbuffer.TxtOScan.MaxY+1;
 scrwidth=dimensionbuffer.TxtOScan.MaxX+1;

}


/*******************************************************************/
/*                                                                 */
/* extLoadConfig() loads the configuration from a user choosen file*/
/* if there is no req.library it loads the config from the default */
/*                pathname as defined in globdata.c                */
/*                                                                 */
/*       all load and save functions from 19. and 20.11.1991       */
/*       changed 06.08.1992 for asl filerequester                  */
/*******************************************************************/

void extLoadConfig(void)
{
  long oldscrmode,oldscrwidth,oldscrheight;
  short flag=FALSE;

  oldscrmode=scrmode;
  oldscrwidth=scrwidth;
  oldscrheight=scrheight;

 MouseCenterWin(&ThirdNewWindow,0,0); /* 27.09.1992 */

 myaslFileReq=AllocAslRequestTags((ULONG)ASL_FileRequest,ASL_Dir,&configdir[0],
 ASL_Hail,LoadText,ASL_File,&configfile[0],ASL_Pattern,"#?.config",
 ASL_Window,FirstWindow,ASL_LeftEdge,(long)ThirdNewWindow.LeftEdge,
 ASL_TopEdge,(long)ThirdNewWindow.TopEdge,
 ASL_FuncFlags,FILF_NEWIDCMP|FILF_PATGAD,TAG_DONE);

 pathnamearray=AllocMem(NAMELEN,MEMF_PUBLIC);


 if(!pathnamearray||!myaslFileReq)/* did I get all the memory  ?  */
   {                              /* no -> so clear it            */
     clearfilemem();              /* show "Out of memory !"       */
     ShowErr(14,FALSE); 
     return();
   }

   if(RequestFile(myaslFileReq))/* zero lenght if cancel request */
    {
    if (myaslFileReq->rf_Dir)
     strncpy(pathnamearray,(void *)myaslFileReq->rf_Dir,NAMELEN);
    else
     pathnamearray[0]='\0';

    AddPart((UBYTE *)pathnamearray,(UBYTE *)myaslFileReq->rf_File,NAMELEN);

     LoadConfig(pathnamearray);
     flag=TRUE;
    }

clearfilemem();

if(flag) /* I load something */
 {
  if(scrmode!=oldscrmode||scrwidth!=oldscrwidth||scrheight!=oldscrheight)
   {
     Close_WINS();  /* screen settings have been changed      */
     Open_WINS();   /* so close screen and open the new one   */
     ReDrawFuncs(); /* needed changes in New.. structures are */
   }                /* done from LoadConfig                   */
  else /* I don't wanna check all fields  -> so always set them  */
   {
    setcolors(); /* if changed screen, Open_WINS() does this calls for me */
    Clear();
    Maus();
    ReDrawFuncs();
   }
 }
}



/*******************************************************************/
/*                                                                 */
/*     clearfilemem() frees all used memory for filerequester      */
/*                                                                 */
/*******************************************************************/

void  clearfilemem(void)
{
  if(myaslFileReq)   FreeAslRequest(myaslFileReq);
  if(pathnamearray)  FreeMem(pathnamearray, (long)(REQ_DSIZE+REQ_FCHARS)+2L);
}

/* BOOL resfilemem() {}  cleared 06.08.1992 */



/*******************************************************************/
/*                                                                 */
/*   doreqreq() sets some needed flags in the FileReq structure    */
/*         and then pops up the req.library FileRequester          */
/*                                                                 */
/*******************************************************************/

/* void doreqreq(void) {}  cleared 06.08.1992 */



/*******************************************************************/
/*                                                                 */
/*   extSaveConfig() saves the configuration to a specific file    */
/*           therefore it uses req.library FileRequester           */
/*      if there is no req.library it saves to s:Kurve.config      */
/*                     the default configfile                      */
/* changed 06.08.1992                                              */
/*******************************************************************/

void extSaveConfig(void)
{

 MouseCenterWin(&ThirdNewWindow,0,0); /* 27.09.1992 */

 myaslFileReq=AllocAslRequestTags((ULONG)ASL_FileRequest,ASL_Dir,&configdir[0],
 ASL_Hail,SaveText,ASL_File,&configfile[0],ASL_Pattern,"#?.config",ASL_Window,
 FirstWindow,ASL_LeftEdge,(long)ThirdNewWindow.LeftEdge,
 ASL_TopEdge,(long)ThirdNewWindow.TopEdge,
 ASL_FuncFlags,FILF_SAVE|FILF_NEWIDCMP|FILF_PATGAD,TAG_DONE);

 pathnamearray=AllocMem(NAMELEN,MEMF_PUBLIC);

     if(!myaslFileReq||!pathnamearray) /* did I get all the memory  ?  */
      {                                /* no -> so clear it            */
       clearfilemem();                 /* show "Out of memory !"       */
       ShowErr(14,FALSE);
       return();
      }

     if(RequestFile(myaslFileReq)) /*  zero if cancel request */
      {
        if (myaslFileReq->rf_Dir)
          strncpy(pathnamearray,(void *)myaslFileReq->rf_Dir,NAMELEN);
        else
          pathnamearray[0]='\0';

        AddPart((UBYTE *)pathnamearray,(UBYTE *)myaslFileReq->rf_File,NAMELEN);

        SaveConfig(pathnamearray);
      }
    clearfilemem();           /* free the used memory */
}


/******************************************/
/*                                        */
/*     Configuration abspeichern          */
/*                                        */
/******************************************/

void SaveConfig(char * filename)
{
  short fd;

 if(!filename)
   filename=&configpath[0];

 fd=open(filename,O_WRONLY+O_CREAT);

 if(fd != -1)
  {
     write(fd,activeFunc->Func,(size_t)255); /* changed from funktion to     */
     write(fd,minx,(size_t)20);              /* activeFunc->Func  17.04.1992 */
     write(fd,maxx,(size_t)20);
     write(fd,miny,(size_t)20);
     write(fd,maxy,(size_t)20);
     write(fd,&scrmode,(size_t)4);
     write(fd,&scrheight,(size_t)4);
     write(fd,&scrwidth,(size_t)4);
     write(fd,&mycolors[0],(size_t)24);
     write(fd,&defscr,(size_t)2); /* 03.08.1992 */
   
     close(fd);
  }

}


/******************************************/
/*                                        */
/*          Configuration laden           */
/*                                        */
/******************************************/

void LoadConfig(char * filename)
{
 short fd;

 if(!filename)
   filename=&configpath[0];

 fd=open(filename,O_RDONLY);

 if(fd != -1)
  {
     funktion1[0]=0;
     funktion2[0]=0;
     read(fd,funktion,(size_t)255);
     read(fd,minx,(size_t)20);
     read(fd,maxx,(size_t)20);
     read(fd,miny,(size_t)20);
     read(fd,maxy,(size_t)20);
     if(read(fd,&scrmode,(size_t)4)) /* so it handels old Kurve.config too */
      {                              /* 19.11.1991 */
        read(fd,&scrheight,(size_t)4);
        read(fd,&scrwidth,(size_t)4);
        read(fd,&mycolors[0],(size_t)24);
        if(!read(fd,&defscr,(size_t)2))
           defscr=0;
      }
     else
      getscreenprefs();
     close(fd);
  }
 else
  {
    strcpy((char *)funktion,"sin(x)");
    strcpy((char *)funktion1,"cos(x)");
    strcpy((char *)funktion2,"-sin(x)");

    xmin=-5.0;
    ymin=-10.0;
    xmax=5.0;
    ymax=10.0;

    printpara(minx,xmin);
    printpara(miny,ymin);
    printpara(maxx,xmax);
    printpara(maxy,ymax);
    getscreenprefs();
  }


if(!activeFunc)
    addfuncnode();
 else
   changefuncnode(activeFunc);


 NeueP();
 setscreenprefs();

}


/*******************************************************************/
/*                                                                 */
/*     handlesave() opens a file requester and then saves the      */
/*      complete list of functions via writefunclist() to the      */
/*      choosen file                          done 20.01.1992      */
/*                                                                 */
/*******************************************************************/

void handlesave(void)
{
  BPTR fp;

  MouseCenterWin(&ThirdNewWindow,-20,-90); /* 27.09.1992 */

 myaslFileReq=AllocAslRequestTags((ULONG)ASL_FileRequest,ASL_Dir,funcdir,
 ASL_Hail,"Save functionlist",ASL_File,funcfile,ASL_Pattern,"#?.kur",
 ASL_Window,FuncReqWindow,ASL_LeftEdge,(long)ThirdNewWindow.LeftEdge,
 ASL_TopEdge,(long)ThirdNewWindow.TopEdge,ASL_FuncFlags,
 FILF_SAVE|FILF_NEWIDCMP|FILF_PATGAD,TAG_DONE);

  pathnamearray=AllocMem(NAMELEN,MEMF_PUBLIC);

     if(!myaslFileReq||!pathnamearray) /* get memory for requester     */
      {                                /* did I get all the memory  ?  */
       clearfilemem();                 /* no -> so clear it            */
       ShowErr(14,FALSE);              /* show "Out of memory !"       */
       return();
     }

     if(RequestFile(myaslFileReq))
      {
        if (myaslFileReq->rf_Dir)
         strncpy(pathnamearray,(void *)myaslFileReq->rf_Dir,NAMELEN);
        else
         pathnamearray[0]='\0';

        AddPart((UBYTE *)pathnamearray,(UBYTE *)myaslFileReq->rf_File,NAMELEN);

        if(fp=Open((UBYTE *)pathnamearray,(long)MODE_NEWFILE))
          {
           SetPointer(FuncReqWindow,mousemem,16L,16L,0L,0L);
           writefunclist(fp,TRUE);
           Close(fp);
           ClearPointer(FuncReqWindow);
          }
      }
     clearfilemem();
}


/*******************************************************************/
/*                                                                 */
/*           handleload() open a file requester and then           */
/*           tries to load a file via readfunclist with            */
/*           a list of functions        done 01.02.1992            */
/*                                                                 */
/*******************************************************************/

void handleload(long *n,long *top)
{
  FILE *fp;
  struct FuncNode *ptr1,*ptr2;
  long vertb,count=1;

  ptr1=FirstFunc;
  ptr2=activeFunc;

  MouseCenterWin(&ThirdNewWindow,-20,-80); /* 27.09.1992 */

  myaslFileReq=AllocAslRequestTags((ULONG)ASL_FileRequest,ASL_Hail,
  "Load functionlist",ASL_File,funcfile,ASL_Dir,funcdir,ASL_Pattern,"#?.kur",
  ASL_Window,FuncReqWindow,ASL_LeftEdge,(long)ThirdNewWindow.LeftEdge,
  ASL_TopEdge,(long)ThirdNewWindow.TopEdge,
  ASL_FuncFlags,FILF_NEWIDCMP|FILF_PATGAD,TAG_DONE);

  pathnamearray=AllocMem(NAMELEN,MEMF_PUBLIC);

     if(!myaslFileReq||!pathnamearray)/* get memory for requester     */
      {                               /* did I get all the memory  ?  */
       clearfilemem();                /* no -> so clear it            */
       ShowErr(14,FALSE);             /* show "Out of memory !"       */
       return();
     }


     if(RequestFile(myaslFileReq))
      {
        if (myaslFileReq->rf_Dir)
         strncpy(pathnamearray,(void *)myaslFileReq->rf_Dir,NAMELEN);
        else
         pathnamearray[0]='\0';

        AddPart((UBYTE *)pathnamearray,(UBYTE *)myaslFileReq->rf_File,NAMELEN);

        if(fp=fopen((const char *)pathnamearray,"r"))
          {
           SetPointer(FuncReqWindow,mousemem,16L,16L,0L,0L);
           FirstFunc=0;
           if(!readfunclist(fp))
            {
             if(FirstFunc)
               delallfuncs();
             FirstFunc=ptr1;
             activatefunc(ptr2);
            }
           else
            {
             ptr2=FirstFunc;
             FirstFunc=ptr1;
             delallfuncs();
             FirstFunc=ptr2;
             activatefunc(FirstFunc);
             printactivefunc();
             updatedisplay(0L);
             Clear();  /* delete displayed old functions in FirstWindow */

            while(ptr2=ptr2->Next)
              count++;

            if(count>8)
             vertb=(MAXBODY*8L)/(count);
            else
             vertb=MAXBODY;

             *n=count;
             *top=0;

             NewModifyProp(&FuncPropGadget,FuncReqWindow,NULL,(long)AUTOKNOB|
              FREEVERT|PROPBORDERLESS,NULL,NULL,NULL,vertb,1L);
            }
           fclose(fp);
           ClearPointer(FuncReqWindow);
          }
      }
     clearfilemem();
}


/*******************************************************************/
/*                                                                 */
/*         readfunclist() reads the file pointed by fp and         */
/*         tries to alloc FuncNodes       done 01.02.1992          */
/*                                                                 */
/*******************************************************************/

BOOL readfunclist(FILE *fp)
{
  char *i;
  UWORD pattern;
  UndoBuffer[0]=0;


 do  /* read the overhead before first function */
  {
   if(!fgets((char *)UndoBuffer,280,fp)) /* 17.04.1992  old version */
    return(FALSE);                       /* reads only 256 bytes    */
  }
 while(strncmp((const char *)UndoBuffer,"Function",8L));

while(!feof(fp))
 {
   funktion[0] = funktion1[0]= funktion2[0] =0;

 do
  {
    UndoBuffer[0]=0;

   if(!fgets((char *)UndoBuffer,280,fp))  /* 17.04.1992 */
    break;            /* lets add the last function */

   i=strrchr((const char *)UndoBuffer,'=');
   if(i)
    {
     i++;
     i[strlen(i)-1L]=0;
    }

   if(!strncmp((const char *)UndoBuffer,"f ",2L))
     {
       if(!i)  /* there must be a '=' */
        continue;

       strcpy((char *)funktion,(const char *)i);
       continue;
     }

   if(!strncmp((const char *)UndoBuffer,"fa1",3L))
     {
       if(!i)  /* there must be a '=' */
        continue;

       strcpy((char *)funktion1,(const char *)i);
       continue;
     }

   if(!strncmp((const char *)UndoBuffer,"fa2",3L))
     {
       if(!i)  /* there must be a '=' */
        continue;

       strcpy((char *)funktion2,(const char *)i);
       continue;
     }

   if(!strncmp((const char *)UndoBuffer,"Pattern",7L))
     {
       if(!i)  /* there must be a '=' */
        continue;

/*       sscanf((const char *)i,"%hx",&pattern); */

       stripstr(i);  /* cut spaces and strlwr() */

       if(!strncmp((const char *)i,"0x",2L))
        {
         pattern=hextol(i);
         continue;
        }
       else
        continue;
     }  
  }while(strncmp((const char *)UndoBuffer,"Function",8L));

  if(checkfuncs())
   {
    fehler=0;
    return(FALSE);
   }
  
  if(!addfuncnode())
    return(FALSE);

  if(!pattern)
    pattern=0xffff;

   activeFunc->FuncPattern=pattern;
 }

 return(TRUE);
}


/*******************************************************************/
/*                                                                 */
/*          writefunclist() writes all or only displayed           */
/*             functions into the file pointed by fp               */
/*                        done 20.01.1992                          */
/*                                                                 */
/*******************************************************************/

BOOL writefunclist(BPTR fp,BOOL t)
{
  struct FuncNode *nodeptr;
  long i=1;
  char *memp;

  if(!(memp=AllocMem(300L,NULL)))
    {
       ShowErr(14,FALSE);
       return();
    }

  nodeptr=FirstFunc;

  if(t)
   strcpy(memp,"List of all functions stored in Kurve!\n\n");
  else
   strcpy(memp,"List of displayed functions!\n\n");
    if(Write(fp,memp,strlen(memp))==-1)
        return(FALSE);


  do
   {
    if((nodeptr->isdrawn&0x07)|t)  /* prints only if t=TRUE and one part of */
     {                             /* the function is drawn                 */
       sprintf(memp,"Function %ld:\n",i);
       if(Write(fp,memp,strlen(memp))==-1)
         return(FALSE);
     }

    if((nodeptr->isdrawn&0x01)|t) /* only if t and function is drawn  */
     {
       sprintf(memp,"f   = %s\n",nodeptr->Func);
       if(Write(fp,memp,strlen(memp))==-1)
         return(FALSE);
     }

    if((nodeptr->isdrawn&0x02)|t)/* only if t and 1st diff. is drawn  */
     {
       sprintf(memp,"fa1 = %s\n",nodeptr->Func1);
       if(Write(fp,memp,strlen(memp))==-1)
         return(FALSE);
     }

    if((nodeptr->isdrawn&0x03)|t)/* only if t and 2nd diff. is drawn  */
     {
       sprintf(memp,"fa2 = %s\n",nodeptr->Func2);
       if(Write(fp,memp,strlen(memp))==-1)
         return(FALSE);
     }

    if((nodeptr->isdrawn&0x07)|t)/* see above ^^^^ */
     {
      sprintf(memp,"Pattern = 0x%x\n\n",nodeptr->FuncPattern);
      if(Write(fp,memp,strlen(memp))==-1)
         return(FALSE);
     }

    i++;
   }while(nodeptr=nodeptr->Next);

 return(TRUE);
}


/*******************************************************************/
/*                                                                 */
/*         helpdruck() writes the displayed functions to a         */
/*          temporary file and then reload it into memory          */
/*         controlled by drucken()        done 28.01.1992          */
/*                                                                 */
/*******************************************************************/

void helpdruck(UBYTE **memblck, long *len)
{
  BPTR         fp;
  UBYTE        tempname[]="ram:Kurve.TMP";

  *len=0;

  if(fp=Open(tempname,(long)MODE_NEWFILE))
   {
     writefunclist(fp,FALSE);  /* write dispalyed functions  */
     Close(fp);
   }
  else
    return();


  if(!(*len=filelength(tempname))) /* get filelength */
   {
    DeleteFile(tempname);
    return();
   }

  if(*memblck=AllocMem(*len,NULL)) /* allocate mem and load temporary file */
   {
    if(fp=Open(tempname,(long)MODE_OLDFILE))
     {
      Read(fp,*memblck,*len);
      Close(fp);
    }
   }
  else
    *len=0;

   DeleteFile(tempname);

}


/*******************************************************************/
/*                                                                 */
/*           filelenght() returns the lenght of the file           */
/*           given with name            done 28.01.1992            */
/*                                                                 */
/*******************************************************************/

long filelength(UBYTE * name)
{
  struct FileInfoBlock  *fib;
  long   len;
  BPTR   fp;


     /* struct FileInfoBlock must be longword aligned !! */
  if(!(fib=AllocMem(sizeof(struct FileInfoBlock),(long)MEMF_CLEAR)))
    return(0L);

  if(fp=Lock(name,(long)ACCESS_READ))
   {
     Examine(fp,fib);  /* fill FileInfoBlock with information  */
     len=fib->fib_Size;
     UnLock(fp);
   }
  else
    len=0L;

  FreeMem(fib,sizeof(struct FileInfoBlock));

 return(len);

}


/*******************************************************************/
/*                                                                 */
/*              hextol() converts a hex string to a                */
/*                        signed long value                        */
/*            created 14.10.1990   inserted 02.02.1992             */
/*                                                                 */
/*******************************************************************/

long hextol(char *string)
{
  long i,n;
  long wert=0;

  string+=2L;  /* jump over leading '0x'   */
  n=strlen(string)-1L;

  for(i=0;i<=n;i++)
   {
     if(isxdigit(string[i]))
      {
        if(isdigit(string[i]))
           wert+=(1L<<((n-i)*4))*(string[i]-'0');
        else
           wert+=(1L<<((n-i)*4))*(toupper(string[i])-'7');
      }
     else
       return(0L);
   }
 return(wert);
}

