/*  kurvemake  */
/* this is the name of the makefile */
/*******************************************************************/
/*                                                                 */
/*                         funkrequest                             */
/*                                                                 */
/*                       Modul zu  Kurve                           */
/*                                                                 */
/*                       Kurvendiskusion                           */
/*                                                                 */
/*                  © 90-92 by Henning  Rink                       */
/*                                                                 */
/*                     more info in Kurve.c                        */
/*                                                                 */
/* copyright notes -> see ReadMe                                   */
/*******************************************************************/


/*******************************************************************/
/*                                                                 */
/* see detailed list of changes in kurve.c                         */
/*                                                                 */
/*******************************************************************/


extern  long     ys,xs,xn,yn,xmouse,ymouse;/* Startendkoordinaten für Zoombox */
extern  short    flag;
extern  struct   RastPort  *rp;
extern  struct   Window    *FirstWindow;
extern  struct   NewWindow ThirdNewWindow;
extern  struct   Window    *ThirdWindow;
extern  struct   IntuiMessage  *message;
extern  long     xnull,ynull;
extern  double   xmin,xmax,ymin,ymax,xe,ye;
extern  UBYTE    UndoBuffer[],minx[],maxx[];
extern  UBYTE    miny[],maxy[];
extern  unsigned char funktion[],funktion1[],funktion2[];
extern  short    fehler;
extern  short    array[];
extern  struct   TextAttr NormalAttr;

extern  struct   NewWindow ReqNewWindow,FuncReqNewWindow;
extern  struct   IntuiText PatternBoxText;

extern  struct   FuncNode  *FirstFunc,*activeFunc;
extern  struct   Image UpImage,DownImage;
extern  UWORD    UpData[],DownData[];
extern  struct   Gadget    FuncUpGadget,FuncDownGadget,FuncPropGadget;
extern  struct   Border    ListBorderW;
extern  struct   PropInfo  FuncProp;
extern  UWORD    *mousemem;



extern APTR     ScreenVI;
extern struct   NewGadget  NewOKGadget;
extern struct   NewGadget  NewCancelGadget;
extern struct   Gadget     *nullgadget;
extern struct   NewGadget  NewPatternGadget;
extern struct   NewGadget  NewFGadget,NewF1Gadget,NewF2Gadget;

extern struct   NewGadget  NewResetGadget,NewmaxyGadget,NewmaxxGadget;
extern struct   NewGadget  NewminyGadget,NewminxGadget;
extern struct   IntuiText  Intervall2Text;

extern  short    ShowErr(short,BOOL);
extern  void     NeueP(void);
extern  void     scan(unsigned char *,short *);
extern  void     Clear(void);
extern  void     DrawFunc(double (*)(double),long);
extern  double   f(double),fa(double),fa2(double);
extern  double   (*numb)(void),(*numb1)(void),(*numb2)(void);
extern  BOOL     writefunclist(BPTR,BOOL);
extern  void     handlesave(void);
extern  void     handleload(long *,long *);
extern  void     MouseCenterWin(struct NewWindow *,short,short);


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

void    drawbox(void);
void    ZoomBox(USHORT p);
void    UnZoom(void);
void    printpara(unsigned char *,double);
void    checkstring(unsigned char *);

void    changeintervall(void);

BOOL    addfuncnode(void);
BOOL    changefuncnode(struct FuncNode *);
void    deletefuncnode(struct FuncNode *);
BOOL    myallocfunc(APTR *,ULONG *,char *);
void    delallfuncs(void);
void    clearfuncnode(struct FuncNode *);

void    FuncReq(void);
void    handlefuncreq(void);
void    printactivefunc(void);
void    printonefunc(long,struct FuncNode *);
void    updatedisplay(long);
BOOL    handlenew(long *,long *);
BOOL    hitdisplay(long num,long total);
void    handleprop(long *,long);
void    handleupdown(long,long);
void    handledelete(long *,long *);
void    handleedit(long);
void    activatefunc(struct FuncNode *);
void    ReDrawFuncs(void);
void    stripstr( char * s);
void    handlepattern(void);
void    handleprint(void);
void    enablemessages(void);
void    disablemessages(void);
short   checkfuncs(void);

struct  RastPort        *rpreq,*funcreqrp;
struct  Window          *ReqWindow,*FuncReqWindow;
UWORD   DrawPattern=0xff;


/* 12.01.1992 */
void FuncReq(void)
{
 UWORD  *dataptr,*dataptr2;
 struct TextFont  *oldtextfont,*newtextfont;
 extern struct TextAttr BigAttr;

 dataptr=AllocMem(12L,(long)MEMF_CHIP);
 dataptr2=AllocMem(12L,(long)MEMF_CHIP);

 if(!((ULONG)dataptr|(ULONG)dataptr2)) /* got I any CHIPMEM  ? */
  {
   ShowErr(14,FALSE);
   if(dataptr)
     FreeMem(dataptr,12L);

   if(dataptr2)
     FreeMem(dataptr2,12L);

   return();
  }

 CopyMem((char *)&UpData[0],(char *)dataptr,12L); /* copy Image Data */
 UpImage.ImageData=dataptr;                       /* to CHIPMEM      */
 CopyMem((char *)&DownData[0],(char *)dataptr2,12L);
 DownImage.ImageData=dataptr2;

 MouseCenterWin(&FuncReqNewWindow,0,0);
 if(FuncReqWindow = OpenWindow(&FuncReqNewWindow))
  {
   funcreqrp=FuncReqWindow->RPort;

   DrawBorder(funcreqrp,&ListBorderW,0L,0L);
   DrawImage(funcreqrp,&UpImage,FuncUpGadget.LeftEdge+4L,FuncUpGadget.TopEdge+1L);
   DrawImage(funcreqrp,&DownImage,FuncDownGadget.LeftEdge+4L,FuncDownGadget.TopEdge+1L);

   SetAPen(funcreqrp,1L);
   SetBPen(funcreqrp,0L);
   oldtextfont=funcreqrp->Font;
   newtextfont=OpenFont(&BigAttr);
   SetFont(funcreqrp,newtextfont);

   printactivefunc();
   updatedisplay(0L);
   handlefuncreq();

   SetFont(funcreqrp,oldtextfont);
   CloseFont(newtextfont);
   CloseWindow(FuncReqWindow);
  }
 else
  ShowErr(13,FALSE);

 FreeMem(dataptr,12L);
 FreeMem(dataptr2,12L);
}


/* 13.01.1992 */
void printactivefunc(void)
{
 char buf[37];

 sprintf(buf,"%-35.35s",activeFunc->Func);
 Move(funcreqrp,22L,110L);
 Text(funcreqrp,(STRPTR)buf,35L);
}


/* 13.01.1992 */
void printonefunc(long num,struct FuncNode *nodeptr)
{
 long base;
 char buf[35];

 base=20+num*10;

if(!nodeptr) /* so it can be used to clear if there's no function */
 {
  SetAPen(funcreqrp,0L);
  RectFill(funcreqrp,22L,base,349L,base+9L);
  SetAPen(funcreqrp,1L);
 }
else
 {
   sprintf(buf,"%-32.32s",nodeptr->Func);
   Move(funcreqrp,23L,base+7L);
   Text(funcreqrp,(STRPTR)buf,32L);
  }
}


/* 14.01.1992 */
void updatedisplay(long firstone)
{
  long num=0;
  struct FuncNode *nodeptr;

  nodeptr=FirstFunc;

  while(num!=firstone)
   {
     nodeptr=nodeptr->Next;
     num++;
   }


for(num=0;num<8;num++)
 {
  printonefunc(num,nodeptr);
  if(nodeptr)/* so print..() may get a NULL pointer and so clear this position */
   nodeptr=nodeptr->Next;
 }
}

/* 13.01.1992 */
void handlefuncreq(void)
{
 ULONG  MessageClass;
 USHORT code;
 struct Gadget *GadgetPTR;
 SHORT  GadgetID=0,count;
 struct FuncNode  *nodeptr;
 long   numfunc,topfunc;
 long   vertbody,vertpot,startsec,startmic,endsec,endmic;

 nodeptr=FirstFunc;

 numfunc=topfunc=startsec=startmic=vertpot=0;

 do
  {
   numfunc++;
  }while(nodeptr=nodeptr->Next);


 if(numfunc>8)
  vertbody=(MAXBODY*8L)/(numfunc);
 else
  vertbody=MAXBODY;

NewModifyProp(&FuncPropGadget,FuncReqWindow,NULL,(long)AUTOKNOB|
           FREEVERT|PROPBORDERLESS,NULL,vertpot,NULL,vertbody,1L);


FOREVER
 {
   Wait(1L << FuncReqWindow->UserPort->mp_SigBit);
    while(message=(struct IntuiMessage *)GetMsg(FuncReqWindow->UserPort))
       {
           MessageClass=message->Class;
           code=message->Code;
           if(MessageClass&(GADGETUP|GADGETDOWN))
             {
               GadgetPTR=(struct Gadget *)message->IAddress;
               GadgetID=GadgetPTR->GadgetID;

             if(GadgetID>20)
              {
               endmic=message->Micros;
               endsec=message->Seconds;
              }
             }
           ReplyMsg((struct Message *)message);
           switch(MessageClass)
            {
                case GADGETDOWN:
                  switch(GadgetID)
                   {
                     case 11:
                      count=0;
                      if(topfunc>0)
                       {
                        topfunc--;
                        handleupdown(topfunc,numfunc);
                       }
                      break;
                     case 12:
                       count=0;
                       if((numfunc-topfunc)>8)
                        {
                          topfunc++;
                          handleupdown(topfunc,numfunc);
                        }
                       break;
                   }
                  break;
                case GADGETUP:
                  switch(GadgetID)
                   {
                     case 1:
                       handledelete(&numfunc,&topfunc);
                       break;
                     case 13:
                     case 2:
                       disablemessages();
                       handleedit(topfunc);
                       enablemessages();
                       break;
                     case 3:
                       handlenew(&numfunc,&topfunc);
                       break;
                     case 4:
                       disablemessages();
                       handleload(&numfunc,&topfunc);
                       enablemessages();
                       break;
                     case 5:
                       disablemessages();
                       handlesave();
                       enablemessages();
                       break;
                     case 7:
                       handleprint();
                       break;
                     case 8:
                       disablemessages();
                       handlepattern();
                       enablemessages();
                       break;
                     case 10:
                       GadgetID=0;
                       if(numfunc>8)
                         handleprop(&topfunc,numfunc);
                       break;
                     case 11:
                     case 12:
                        GadgetID=0;
                        break;

                     default:
                      if(GadgetID>20)
                       {
                        if(hitdisplay((GadgetID-20L+topfunc),numfunc))
                          if(DoubleClick(startsec,startmic,endsec,endmic))
                            GadgetID=6;
                        startsec=endsec;
                        startmic=endmic;
                       }
                      break;
                   }
                  break;

                case INTUITICKS:
                   if((FuncDownGadget.Flags&SELECTED)||(FuncUpGadget.Flags&SELECTED))
                     {
                      if(count++<2)
                        break;
                      if(GadgetID==12&&((numfunc-topfunc)>8))
                       {
                          topfunc++;
                          handleupdown(topfunc,numfunc);
                       }
                      else
                       {
                        if(GadgetID==11&&topfunc>0)
                         {
                          topfunc--;
                          handleupdown(topfunc,numfunc);
                         }
                       }
                     }
                   break;

                  case MOUSEMOVE:
                     if(GadgetID==10&&numfunc>8)
                        handleprop(&topfunc,numfunc);
                      break;
            }
       }

     if( GadgetID == 6  )
       break;
  }
}


/* If you call ModifyIDCMP  with Flags=NULL then Intuition */
/* will close the IDCMP Port completely -> free mem......  */
/* and then create a new port if turning flags on          */
/* so you have to check for success!!!                     */
/* 26.01.1992 */
void disablemessages(void)
{
   ModifyIDCMP(FuncReqWindow,(long)INTUITICKS);
}

void enablemessages(void)
{
  ModifyIDCMP(FuncReqWindow,(long)INTUITICKS|MOUSEMOVE|GADGETUP|GADGETDOWN);
}


/*******************************************************************/
/*                                                                 */
/*       handleupdown() handles clicking the UP DOWN gadgets       */
/*               with the mouse      done 14.01.1992               */
/*                                                                 */
/*******************************************************************/

void handleupdown(long top,long count)
{

  FuncProp.VertPot=(MAXBODY*top)/(count-8L);

  RefreshGList(&FuncPropGadget,FuncReqWindow,NULL,1L);

  updatedisplay(top);
}


/*******************************************************************/
/*                                                                 */
/*           handleprop() handels moving the prop gadget           */
/*            with the mouse by calling updatedisplay()            */
/* done 14.01.1992                                                 */
/*                                                                 */
/*******************************************************************/

void handleprop(long *top,long count)
{
 long temptop;

temptop=(FuncProp.VertPot*(count-8L)/MAXBODY);
if(temptop!=*top)
 {
    *top=temptop;
    updatedisplay(temptop);
 }
}


/*******************************************************************/
/*                                                                 */
/*            handlenew() inserts a new funtion to the             */
/*            end of the functionslist  done 14.01.1992            */
/*                                                                 */
/*******************************************************************/

BOOL handlenew(long *count,long *top)
{
 long vertb;

 sprintf((char *)funktion,"sin(x)+%ld",(*count)+1L);
 strcpy((char *)funktion1,"cos(x)");
 strcpy((char *)funktion2,"-sin(x)");

 if(!addfuncnode())
   return(FALSE);

 (*count)++;

 if((*count)>8)
  {
     vertb=(MAXBODY*8L)/(*count);
     *top=(*count)-8L;   /* if 9 functions display from 2 to 9  */

     NewModifyProp(&FuncPropGadget,FuncReqWindow,NULL,(long)AUTOKNOB|
      FREEVERT|PROPBORDERLESS,NULL,(long)MAXBODY,NULL,vertb,1L);
  }

  printactivefunc();
  updatedisplay(*top);

  return(TRUE);
}


/*******************************************************************/
/*                                                                 */
/*         handledelete() deletes the active function and          */
/*          activates a new onw           done 15.01.1992          */
/*                                                                 */
/*******************************************************************/

void handledelete(long *count,long *top)
{
 struct FuncNode *nodeptr;
 long vertp,vertb;

 if(*count==1)
   return();

 if(activeFunc->Next)
   nodeptr=activeFunc->Next;
 else
   nodeptr=activeFunc->Prev;

 deletefuncnode(activeFunc);
  (*count)--;

 activatefunc(nodeptr);
 printactivefunc();

 if(( (*count)-8L-(*top)<0L) && (*top)>0)
   (*top)--;

 updatedisplay(*top);

if((*count)>8)
 {
  vertb=(MAXBODY*8L)/(*count);
  vertp=(MAXBODY*(*top))/((*count)-8L);
 }
else
 {
   vertb=MAXBODY;
   vertp=0L;
 }

 NewModifyProp(&FuncPropGadget,FuncReqWindow,NULL,(long)AUTOKNOB|
   FREEVERT|PROPBORDERLESS,NULL,vertp,NULL,vertb,1L);

}


/*******************************************************************/
/*                                                                 */
/*           hitdisplay() handles clicking into the list           */
/*            of the displayed functions and activates             */
/*             the choosen function    done 14.01.1992             */
/*                                                                 */
/*******************************************************************/

BOOL hitdisplay(long num,long total)
{
 long active=1;
 struct FuncNode *nodeptr;

 if(num>total)
   return(FALSE);

 nodeptr=FirstFunc;

 while(active!=num)
  {
   nodeptr=nodeptr->Next;
   active++;
  }

 activatefunc(nodeptr);
 printactivefunc();
 return(TRUE);
}


void handleedit(long top)  /* done 16.01.1992 */
{
 ULONG   MessageClass;
 USHORT  code,qualifier;
 struct  Gadget *GadgetPTR,*firstgadget,*gad[3];
 SHORT   GadgetID=0;
 struct  IntuiMessage  *emessage;
 short   error;

 strcpy((char *)funktion,activeFunc->Func);
 strcpy((char *)funktion1,activeFunc->Func1);
 strcpy((char *)funktion2,activeFunc->Func2);


 NewOKGadget.ng_LeftEdge          =24;      /* GadTools Gadgets from */
 NewCancelGadget.ng_LeftEdge      =506;      /*      05.08.1992       */
 
 NewCancelGadget.ng_TopEdge       = NewOKGadget.ng_TopEdge = 114;

 NewFGadget.ng_VisualInfo=NewF1Gadget.ng_VisualInfo=
 NewF2Gadget.ng_VisualInfo=ScreenVI;

 GadgetPTR=CreateContext((struct Gadget **)&firstgadget);
 GadgetPTR=CreateGadget((ULONG)BUTTON_KIND,GadgetPTR,&NewOKGadget,
         GT_Underscore,(ULONG)'_',TAG_DONE);
 GadgetPTR=CreateGadget((ULONG)BUTTON_KIND,GadgetPTR,
          &NewCancelGadget,GT_Underscore,(ULONG)'_',TAG_DONE);

gad[0]=GadgetPTR=CreateGadget((ULONG)STRING_KIND,GadgetPTR,&NewFGadget,
   GTST_String,funktion,GTST_MaxChars,254L,GT_Underscore,(ULONG)'_',TAG_DONE);
 GadgetPTR->Activation |=GACT_STRINGCENTER;

gad[1]=GadgetPTR=CreateGadget((ULONG)STRING_KIND,GadgetPTR,&NewF1Gadget,
   GTST_String,funktion1,GTST_MaxChars,254L,GT_Underscore,(ULONG)'_',TAG_DONE);
 GadgetPTR->Activation |=GACT_STRINGCENTER;

gad[2]= GadgetPTR=CreateGadget((ULONG)STRING_KIND,GadgetPTR,&NewF2Gadget,
   GTST_String,funktion2,GTST_MaxChars,254L,GT_Underscore,(ULONG)'_',TAG_DONE);
 GadgetPTR->Activation |=GACT_STRINGCENTER;

 ReqNewWindow.FirstGadget=firstgadget;

 MouseCenterWin(&ReqNewWindow,0,0);

 if (!(ReqWindow = OpenWindow(&ReqNewWindow)))
  {
    FreeGadgets(firstgadget);
    ShowErr(13,FALSE);
    return();
  }

  rpreq=ReqWindow->RPort;
  GT_RefreshWindow(ReqWindow,NULL);
  ActivateGadget(gad[0],ReqWindow,NULL);

errlabel:

FOREVER
 {
   Wait(1L << ReqWindow->UserPort->mp_SigBit);
    while(emessage=(struct IntuiMessage *)GT_GetIMsg(ReqWindow->UserPort))
       {
           MessageClass=emessage->Class;
           code=emessage->Code;
           qualifier=emessage->Qualifier;
           if(MessageClass&(GADGETUP|GADGETDOWN))
             {
               GadgetPTR=(struct Gadget *)emessage->IAddress;
               GadgetID=GadgetPTR->GadgetID;

             }
           GT_ReplyIMsg(emessage);
           switch(MessageClass)
            {
                case IDCMP_REFRESHWINDOW:   /*  refreshing 05.08.1992 */
                  GT_BeginRefresh(ReqWindow);
                    GT_RefreshWindow(ReqWindow,NULL);
                  GT_EndRefresh(ReqWindow,(LONG)TRUE);
                  break;

                case VANILLAKEY:
                  switch(code)
                   {
                     case 'f':  /* 05.08.1992 */
                     case 'F':
                       ActivateGadget(gad[0],ReqWindow,NULL);
                       break;
                    case '1':
                       ActivateGadget(gad[1],ReqWindow,NULL);
                       break;
                    case '2':
                       ActivateGadget(gad[2],ReqWindow,NULL);
                       break;

                     case 'v':
                     if(!(qualifier&IEQUALIFIER_LCOMMAND))
                        break;
                     case 'O':
                     case 'o':
                      GadgetID=7;
                      break;

                     case 'b':
                     if(!(qualifier&IEQUALIFIER_LCOMMAND))
                        break;
                     case 'C':
                     case 'c':
                     case 27:
                      GadgetID=6;
                      break;

                    }
                   break;

                case GADGETUP:
                  switch (GadgetID)
                   {
                      case 1:
                         ActivateGadget(gad[1],ReqWindow,NULL);
                         break;
                      case 2:
                         ActivateGadget(gad[2],ReqWindow,NULL);
                         break;
                      default :
                         break;
                   }
               default :
                  break;
            }
       }

     if( GadgetID == 6 || GadgetID == 7 )
       break;
  }


 if(GadgetID==7)
  {
   strcpy((char *)funktion,(char *)((struct StringInfo *)gad[0]->SpecialInfo)->Buffer);
   strcpy((char *)funktion1,(char *)((struct StringInfo *)gad[1]->SpecialInfo)->Buffer);
   strcpy((char *)funktion2,(char *)((struct StringInfo *)gad[2]->SpecialInfo)->Buffer);

     error=checkfuncs();  /* changed 01.02.1992  */

     if(error)
      ShowErr(fehler,FALSE);

     switch(error)
        {
           case 1:
            ActivateGadget(gad[0],ReqWindow,NULL);
            break;
           case 2:
            ActivateGadget(gad[1],ReqWindow,NULL);
            break;
           case 3:
            ActivateGadget(gad[2],ReqWindow,NULL);
            break;
        }

     if(error)
      {
         GadgetID=0;  /* got an endless loop because GadgetID=7 */
                      /* and Intuition sends a refreshwindow    */
                      /* so the programm didn't stop at WAIT()  */
         goto errlabel;  /* my first and only goto!!  */
      }                  /* jumps to FOREVER          */

     changefuncnode(activeFunc);
     activatefunc(activeFunc);  /* necessary for numb(),num1(),numb2() */
     printactivefunc();
     updatedisplay(top);
  }

 CloseWindow(ReqWindow);
 FreeGadgets(firstgadget);
}


/*******************************************************************/
/*                                                                 */
/*           handlepattern() displays a window where the           */
/*            user can choose a pattern for drawing the            */
/*            function                  done 25.01.1992            */
/*         changed for Kick 2.0   04.08.1992 and 05.08.1992        */
/*                                                                 */
/*******************************************************************/

void handlepattern(void)
{
 ULONG    MessageClass;
 USHORT   code,qualifier;
 struct   Gadget *GadgetPTR,*firstgadget,*gad[16];
 SHORT    GadgetID=0;
 struct   IntuiMessage  *emessage;
 USHORT   i;



 NewOKGadget.ng_LeftEdge          =24;      /* GadTools Gadgets from */
 NewCancelGadget.ng_LeftEdge      =286;     /*      04.08.1992       */

 NewCancelGadget.ng_TopEdge   =  NewOKGadget.ng_TopEdge   = 94;

 NewPatternGadget.ng_VisualInfo=ScreenVI;

 GadgetPTR=CreateContext((struct Gadget **)&firstgadget);
 GadgetPTR=CreateGadget((ULONG)BUTTON_KIND,GadgetPTR,&NewOKGadget,
         GT_Underscore,(ULONG)'_',TAG_DONE);
 GadgetPTR=CreateGadget((ULONG)BUTTON_KIND,GadgetPTR,
          &NewCancelGadget,GT_Underscore,(ULONG)'_',TAG_DONE);


for(i=0;i<16;i++)  /* pattern gadgets from 05.08.1992 */
{
 NewPatternGadget.ng_LeftEdge=24+i*22;
 NewPatternGadget.ng_GadgetID=10+i;

 gad[i]=GadgetPTR=CreateGadget((ULONG)BUTTON_KIND,GadgetPTR,
                &NewPatternGadget,TAG_DONE);

 GadgetPTR->Activation |=GACT_TOGGLESELECT;

 if(activeFunc->FuncPattern&(1<<i))
   GadgetPTR->Flags|=SELECTED;
 else
   GadgetPTR->Flags&=~SELECTED;
}

 ThirdNewWindow.FirstGadget=firstgadget;

 MouseCenterWin(&ThirdNewWindow,0,0);

 if (!(ReqWindow = OpenWindow(&ThirdNewWindow)))
  {
    FreeGadgets(firstgadget);
    ShowErr(13,FALSE);
    return();
  }

  rpreq=ReqWindow->RPort;
  PrintIText(rpreq,&PatternBoxText,0L,0L);

  GT_RefreshWindow(ReqWindow,NULL);

FOREVER
 {
   Wait(1L << ReqWindow->UserPort->mp_SigBit);
    while(emessage=(struct IntuiMessage *)GT_GetIMsg(ReqWindow->UserPort))
       {
           MessageClass=emessage->Class;
           code=emessage->Code;
           qualifier=emessage->Qualifier;
           if(MessageClass&(GADGETUP|GADGETDOWN))
             {
               GadgetPTR=(struct Gadget *)emessage->IAddress;
               GadgetID=GadgetPTR->GadgetID;

             }

           GT_ReplyIMsg(emessage);

           switch(MessageClass)
            {
                case IDCMP_REFRESHWINDOW:   /*  refreshing 04.08.1992 */
                  GT_BeginRefresh(ReqWindow);
                    PrintIText(rpreq,&PatternBoxText,0L,0L);
                    GT_RefreshWindow(ReqWindow,NULL);
                  GT_EndRefresh(ReqWindow,(LONG)TRUE);
                  break;

                case VANILLAKEY:
                  switch(code)
                   {
                     case 'v':
                     if(!(qualifier&IEQUALIFIER_LCOMMAND))
                        break;
                     case 'O':
                     case 'o':
                      GadgetID=7;
                      break;

                     case 'b':
                     if(!(qualifier&IEQUALIFIER_LCOMMAND))
                        break;
                     case 'C':
                     case 'c':
                     case 27:
                      GadgetID=6;
                      break;
                    }
                   break;

               default :
                  break;
            }
       }

     if( GadgetID == 6 || GadgetID == 7 )
       break;
  }

if(GadgetID==7)
 {
   for(i=0;i<16;i++)
    {
     if(gad[i]->Flags&SELECTED)
      activeFunc->FuncPattern|=(1<<i);
     else
      activeFunc->FuncPattern&=~(1<<i);
    }
 }

 CloseWindow(ReqWindow);
 FreeGadgets(firstgadget);


}

void handleprint(void)
{
  BPTR fp;

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



/*******************************************************************/
/*                                                                 */
/*        changeintervall() displays a window where you can        */
/*         change the intervall limits xmin,xmax,ymin,ymax         */
/*                         done 19.01.1992                         */
/*                                                                 */
/*******************************************************************/

void changeintervall(void)
{
 ULONG    MessageClass;
 USHORT   code,qualifier;
 struct   Gadget *GadgetPTR,*firstgadget,*resgad,*gad[4];
 SHORT    GadgetID=0;
 struct   IntuiMessage  *emessage;

 NewOKGadget.ng_LeftEdge          =24;      /* GadTools Gadgets from */
 NewCancelGadget.ng_LeftEdge      =286;     /* 05. to 06.08.1992     */

 NewCancelGadget.ng_TopEdge   =  NewOKGadget.ng_TopEdge   = 94;


 NewResetGadget.ng_VisualInfo=NewmaxxGadget.ng_VisualInfo=
 NewminxGadget.ng_VisualInfo=
 NewmaxyGadget.ng_VisualInfo=NewminyGadget.ng_VisualInfo=ScreenVI;

 GadgetPTR=CreateContext((struct Gadget **)&firstgadget);
 GadgetPTR=CreateGadget((ULONG)BUTTON_KIND,GadgetPTR,&NewOKGadget,
         GT_Underscore,(ULONG)'_',TAG_DONE);
 GadgetPTR=CreateGadget((ULONG)BUTTON_KIND,GadgetPTR,
          &NewCancelGadget,GT_Underscore,(ULONG)'_',TAG_DONE);

 resgad=GadgetPTR=CreateGadget((ULONG)BUTTON_KIND,GadgetPTR,
          &NewResetGadget,GT_Underscore,(ULONG)'_',TAG_DONE);

 gad[0]=GadgetPTR=CreateGadget((ULONG)STRING_KIND,GadgetPTR,&NewminxGadget,
   GTST_String,minx,GTST_MaxChars,19L,GT_Underscore,(ULONG)'_',TAG_DONE);
 GadgetPTR->Activation |=GACT_STRINGCENTER;

 gad[1]=GadgetPTR=CreateGadget((ULONG)STRING_KIND,GadgetPTR,&NewmaxxGadget,
   GTST_String,maxx,GTST_MaxChars,19L,TAG_DONE);
 GadgetPTR->Activation |=GACT_STRINGCENTER;

 gad[2]=GadgetPTR=CreateGadget((ULONG)STRING_KIND,GadgetPTR,&NewminyGadget,
   GTST_String,miny,GTST_MaxChars,19L,TAG_DONE);
 GadgetPTR->Activation |=GACT_STRINGCENTER;

 gad[3]=GadgetPTR=CreateGadget((ULONG)STRING_KIND,GadgetPTR,&NewmaxyGadget,
   GTST_String,maxy,GTST_MaxChars,19L,TAG_DONE);
 GadgetPTR->Activation |=GACT_STRINGCENTER;




 ThirdNewWindow.FirstGadget=firstgadget;

 MouseCenterWin(&ThirdNewWindow,0,0);

 if (!(ReqWindow = OpenWindow(&ThirdNewWindow)))
  {
    FreeGadgets(firstgadget);
    ShowErr(13,FALSE);
    return();
  }

  rpreq=ReqWindow->RPort;
  PrintIText(rpreq,&Intervall2Text,0L,0L);
  GT_RefreshWindow(ReqWindow,NULL);
  ActivateGadget(gad[0],ReqWindow,NULL);

FOREVER
 {
   Wait(1L << ReqWindow->UserPort->mp_SigBit);
    while(emessage=(struct IntuiMessage *)GT_GetIMsg(ReqWindow->UserPort))
       {
           MessageClass=emessage->Class;
           code=emessage->Code;
           qualifier=emessage->Qualifier;
           if(MessageClass&(GADGETUP|GADGETDOWN))
             {
               GadgetPTR=(struct Gadget *)emessage->IAddress;
               GadgetID=GadgetPTR->GadgetID;

             }
           GT_ReplyIMsg(emessage);
           switch(MessageClass)
            {
               case IDCMP_REFRESHWINDOW:   /*  refreshing 06.08.1992 */
                 GT_BeginRefresh(ReqWindow);
                    PrintIText(rpreq,&Intervall2Text,0L,0L);
                    GT_RefreshWindow(ReqWindow,NULL);
                  GT_EndRefresh(ReqWindow,(LONG)TRUE);
                  break;

                case VANILLAKEY:
                  switch(code)
                   {

                     case 'X':
                     case 'x':
                        ActivateGadget(gad[0],ReqWindow,NULL);
                        break;
                     
                     case 'v':
                     if(!(qualifier&IEQUALIFIER_LCOMMAND))
                        break;
                     case 'O':
                     case 'o':
                      GadgetID=7;
                      break;

                     case 'b':
                     if(!(qualifier&IEQUALIFIER_LCOMMAND))
                        break;
                     case 'C':
                     case 'c':
                     case 27:
                      GadgetID=6;
                      break;

                     case 'R':  /*  23.01.1992  */
                     case 'r':
                      GadgetID=5;
                      break;

                    }
                   break;

                case GADGETUP:
                  switch (GadgetID)
                   {
                      case 1:
                           ActivateGadget(gad[1],ReqWindow,NULL);
                           break;
                      case 2:
                           ActivateGadget(gad[2],ReqWindow,NULL);
                           break;
                      case 3:
                           ActivateGadget(gad[3],ReqWindow,NULL);
                           break;
                    }
                   break;

               default :
                  break;
            }
       }

  if(GadgetID==5) /* 23.01.1992 , 06.08.1992 */
   {
    strcpy((char *)((struct StringInfo *)gad[0]->SpecialInfo)->Buffer,"-10");
    strcpy((char *)((struct StringInfo *)gad[1]->SpecialInfo)->Buffer,"10");
    strcpy((char *)((struct StringInfo *)gad[2]->SpecialInfo)->Buffer,"-10");
    strcpy((char *)((struct StringInfo *)gad[3]->SpecialInfo)->Buffer,"10");

    RefreshGList(gad[0],ReqWindow,NULL,4L);
    ActivateGadget(gad[0],ReqWindow,NULL);
   }


  if(GadgetID==7) /* 06.08.1992 */
   {
    strcpy((char *)minx,(char *)((struct StringInfo *)gad[0]->SpecialInfo)->Buffer);
    strcpy((char *)maxx,(char *)((struct StringInfo *)gad[1]->SpecialInfo)->Buffer);
    strcpy((char *)miny,(char *)((struct StringInfo *)gad[2]->SpecialInfo)->Buffer);
    strcpy((char *)maxy,(char *)((struct StringInfo *)gad[3]->SpecialInfo)->Buffer);
    break;
   }

  if( GadgetID == 6)
    break;
 }

 CloseWindow(ReqWindow);
 FreeGadgets(firstgadget);

 if(GadgetID==7) /* OK */
  {
    NeueP();
    Clear();
    ReDrawFuncs();
  }

}




/************************************************/
/*                                              */
/*          Rechteck im Complement Modus        */
/*            für Rubberband Effekt             */
/*                                              */
/************************************************/

void ZoomBox(USHORT p)
{
struct RastPort *rp3;
ULONG  MessageClass;
double fys,fxs,fyn,fxn;
char   puffer[60];
SHORT  GadgetID=0;
long   help;
USHORT code,qualifier;
struct Gadget *GadgetPTR;

    if(p==1)  /* MouseButton gedrückt   */
      {
       if(flag)
         {
           drawbox();       /* altes Rechteck löschen  */

/* BIT cycling added 24.09.1991 */
#asm
        MOVE.W   _DrawPattern,d0
        ROR.W    #3,d0
        MOVE.W   d0,_DrawPattern
#endasm

           SetDrPt(rp,DrawPattern);

           xn=xmouse;
           yn=ymouse;
           drawbox();      /* neues Rechteck Zeichnen   */
         }
       else
        {
          SetDrPt(rp,DrawPattern);
          flag=1;
          xn=xmouse;
          yn=ymouse;
          drawbox();       /* neues Rechteck Zeichnen */
        }
     }

  else    /* !p Button nicht mehr gedrückt   */
   {
     flag=0;
     drawbox();         /* altes Recheck löschen  */
     SetDrPt(rp,0xffff);
     if(p==2)
       return();

     if(xn<xs)   /* Werte tauschen */
      {
        help=xs;
        xs=xn;
        xn=help;
      }
    if(yn<ys)
     {
       help=ys;
       ys=yn;
       yn=help;
     }

     if((xn-xs)<5 || (yn-ys)<5) /*  inserted 10.03.1991          */
         return();              /*  no smaller box than 5 points */

    NewOKGadget.ng_LeftEdge          =24;      /* GadTools Gadgets from */
    NewCancelGadget.ng_LeftEdge      =286;     /*     03.08.1992        */

    NewCancelGadget.ng_TopEdge  = NewOKGadget.ng_TopEdge    = 94;

    GadgetPTR=CreateContext((struct Gadget **)&nullgadget);
    GadgetPTR=CreateGadget((ULONG)BUTTON_KIND,GadgetPTR,&NewOKGadget,
           GT_Underscore,(ULONG)'_',TAG_DONE);
    GadgetPTR=CreateGadget((ULONG)BUTTON_KIND,GadgetPTR,&NewCancelGadget,
           GT_Underscore,(ULONG)'_',TAG_DONE);

    ThirdNewWindow.FirstGadget=nullgadget;

     fys=(ynull-yn)/ye;  /* NOTE: float start != integer start */
     fyn=(ynull-ys)/ye;  /* so  fys = f(yn) ; fyn = f(ys)      */
     fxs=(xs-xnull)/xe;  /* but fxs = f(xs) ; fxn = f(xn);     */
     fxn=(xn-xnull)/xe;

     printpara(minx,fxs);
     printpara(miny,fys);
     printpara(maxx,fxn);
     printpara(maxy,fyn);

      /* same value should not occur 10.08.1991 */

     if(!(strcmp((char *)minx,(char *)maxx)))
       {
         fxs=xmin;
         fxn=xmax;
         printpara(minx,xmin);
         printpara(maxx,xmax);
       }

     if(!(strcmp((char *)miny,(char *)maxy)))
       {
         fys=ymin;
         fyn=ymax;
         printpara(miny,ymin);
         printpara(maxy,ymax);
       }

     MouseCenterWin(&ThirdNewWindow,-110,-40); /* 03.08.1992 */
     if (!(ThirdWindow = OpenWindow(&ThirdNewWindow)))
       {
        FreeGadgets(nullgadget);
        ShowErr(9,FALSE);
       }
    else
      {

       rp3=ThirdWindow->RPort;
       GT_RefreshWindow(ThirdWindow,NULL);
       SetDrMd(rp3,(long)JAM1);
       SetAPen(rp3,1L);

       Move(rp3,52L,17L);
       Text(rp3,(UBYTE *)"Do you want to use the new intervall",36L);
       Move(rp3,96L,33L);
       Text(rp3,(UBYTE *)"for further calculations ?",26L);

       sprintf(puffer,"Xmin:  %s",minx);
       Move(rp3,25L,55L);
       Text(rp3,(UBYTE *)puffer,(long)strlen(puffer));
       sprintf(puffer,"Ymin:  %s",miny);
       Move(rp3,25L,72L);
       Text(rp3,(UBYTE *)puffer,(long)strlen(puffer));

       sprintf(puffer,"Xmax:  %s",maxx);
       Move(rp3,225L,55L);
       Text(rp3,(UBYTE *)puffer,(long)strlen(puffer));
       sprintf(puffer,"Ymax:  %s",maxy);
       Move(rp3,225L,72L);
       Text(rp3,(UBYTE *)puffer,(long)strlen(puffer));

       FOREVER
         {
           Wait(1L << ThirdWindow->UserPort->mp_SigBit);
           while(message=(struct IntuiMessage *)GT_GetIMsg(ThirdWindow->UserPort))
           {
             MessageClass=message->Class;
             code=message->Code;
             qualifier=message->Qualifier;
             if(MessageClass&(GADGETUP|GADGETDOWN))
              {
               GadgetPTR=(struct Gadget *)message->IAddress;
               GadgetID=GadgetPTR->GadgetID;
               }
             GT_ReplyIMsg(message);

             switch(MessageClass)
               {
                case IDCMP_REFRESHWINDOW: /* sorry no refreshing 04.08.1992 */
                  GT_BeginRefresh(ThirdWindow);
                  GT_EndRefresh(ThirdWindow,(LONG)TRUE);
                  break;

                case VANILLAKEY: /* 17. and 18.11.1991 */
                  switch(code)   /* think this hole function needs some improvement!!*/
                   {
                     case 'v':
                     if(!(qualifier&IEQUALIFIER_LCOMMAND))
                        break;
                     case 'O':
                     case 'o':
                      GadgetID=7;
                      break;

                     case 'b':
                     if(!(qualifier&IEQUALIFIER_LCOMMAND))
                        break;
                     case 'C':
                     case 'c':
                     case 27:
                      GadgetID=6;
                      break;

                    }
                   break;
                case GADGETUP:
                     break;
               }
           }

         if(GadgetID==6 || GadgetID==7)
         break;

         }/* FOREVER */
       CloseWindow(ThirdWindow);
       FreeGadgets(nullgadget);
       if(GadgetID==7)
        {
          SetDrMd(rp,(long)JAM1);
          NeueP();
          Clear();
          ReDrawFuncs();
          SetDrMd(rp,(long)JAM1|COMPLEMENT);
        }
       else /* CANCEL */
        {
         printpara(minx,xmin);
         printpara(miny,ymin);
         printpara(maxx,xmax);
         printpara(maxy,ymax);
        }
      }
   }
}


/************************************************/
/*                                              */
/*               Rechteck zeichnen              */
/*                                              */
/************************************************/

void drawbox(void)
{
register  long startx,endx,starty,endy;

   if(xs>xn)  /* changed 24.09.1991 */
    {
      startx=xn;
      endx=xs;
    }
   else
    {
      startx=xs;
      endx=xn;
    }

   if(ys>yn)
    {
      starty=yn;
      endy=ys;
    }
   else
    {
      starty=ys;
      endy=yn;
    }

   if(startx==endx)
    {
      Move(rp,startx,endy);
      Draw(rp,endx,starty);
    }
   else
    {
      Move(rp,startx,starty);
      if(starty==endy)
         Draw(rp,endx,endy);
      else
       {
         Draw(rp,endx,starty);
         Draw(rp,endx,endy);
         Draw(rp,startx,endy);
         Draw(rp,startx,starty);
       }
    }
}


/*******************************************************************/
/*                                                                 */
/*                             UnZoom                              */
/* Einfaches herauszoomen aus dem momentan gewählten Ausschnitt    */
/*                                                                 */
/*******************************************************************/

void UnZoom(void)
{
register double xdelta,ydelta;

 xdelta=(xmax-xmin)*0.5;
 ydelta=(ymax-ymin)*0.5;

/*
    (xmax-xmin)*sqrt(2.0)-(xmax-xmin)
    --------------------------------- = (dx)*0.207
                  2.0

diese Formel führt zur Flächenverdoppelung, bei (xmax-xmin)/2 vervierfacht
sich die abgebildete Fläche
*/

 xmax+=xdelta;
 xmin-=xdelta;
 ymax+=ydelta;
 ymin-=ydelta;

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

 SetDrMd(rp,(long)JAM1);
 NeueP();
 Clear();
 ReDrawFuncs();
 SetDrMd(rp,(long)JAM1|COMPLEMENT);

}


/*******************************************************************/
/*                                                                 */
/*                           printpara()                           */
/*                      parameter to strings                       */
/*                           25.07.1991                            */
/*                                                                 */
/*******************************************************************/

void printpara(unsigned char *s,double a)
{
 sprintf((char *)s,"%-14.7g",a);
 checkstring(s);

}

/*******************************************************************/
/*                                                                 */
/*                   checkstring()  18.08.1991                     */
/*                                                                 */
/* added because the MANX 5.0a,d format() routine losses 0 at the  */
/* end of strings if formated with g format                        */
/* 1e10 is printed as 1e1 !!!!!!!                                  */
/*                                                                 */
/* Aztec 3.6a losses "0" in the mantisse while turning from        */
/* f in e format, so I printed with %14.7e                         */
/*                                                                 */
/* AztecC5.0b,c not tested ->didn't get them                       */
/* Version 5.2a works well     24.12.1991                          */
/*                                                                 */
/*******************************************************************/


void checkstring(unsigned char *zahl)
{

#ifdef AztecVERSION500
register  short j;
register  long i;
#endif

stripstr((char *)zahl); /* cut spaces */

#ifdef AztecVERSION500                /* 24.12.1991 */
   i=strcspn((const char *)zahl,"e");
   if(i)
    {
      j=strlen((const char *)zahl);
      switch((j-i))
         {
          case 4:
            strcat((char *)zahl,"0");
            break;
          case 3:
            strcat((char *)zahl,"00");
            break;
         }
    }
#endif
}


/*******************************************************************/
/*                                                                 */
/*     myallocfunc() compiles the given function via scan and      */
/*           allocates memory for the compiled function            */
/*                         done 29.12.1991                         */
/*                                                                 */
/*******************************************************************/

BOOL myallocfunc(APTR *memblck,ULONG *len, char *funcstr)
{
 ULONG lenofCFunc;
 extern short *point;

 scan((unsigned char *)funcstr,array);

 lenofCFunc=(ULONG)point-(ULONG)array;

 if(!(*memblck=AllocMem(lenofCFunc,MEMF_PUBLIC)))
  {
   ShowErr(14,FALSE);
   return(FALSE);
  }
 else
  *len=lenofCFunc;

  CopyMem(array,*memblck,*len); /* moving code -> so flush cache */

/* 06.02.1992 */
#asm 
     xref      _SysBase     /* do it with inline assembler, so              */
     move.l    a6,-(sp)     /* it compiles with old Kick1.3 too             */
     movea.l   _SysBase,a6  /* need to clear data cache 68030 ?, 68040 sure */
     cmpi.w    #37,$14(a6)  /* only 2.0 kickstart                           */
     bcs.s     weiter       /* !! makes no sense to test for 68030 or 68040 */
     jsr       -636(a6)     /* kickstart can do it for me                   */
weiter: movea.l   (sp)+,a6  /* CacheClearU(); routine                       */
#endasm

  return(TRUE);
}


/*******************************************************************/
/*                                                                 */
/*    addfuncnode() allocates memory for a FuncNode adds it to     */
/*     the end of all other FuncNodes and the calls change..()     */
/*     to alloc memory for the rest            done 29.12.1991     */
/*                                                                 */
/*******************************************************************/

BOOL  addfuncnode(void)
{
 struct FuncNode *lastnode,*nodeptr;

 if(FirstFunc)
  {
   lastnode=FirstFunc;
   while(lastnode->Next)
     lastnode=lastnode->Next;
  }

  if(!(nodeptr=AllocMem(sizeof(struct FuncNode),MEMF_CLEAR)))
   {                         /* memory have to be cleared for */
    ShowErr(14,FALSE);       /* sanity checks with pointers   */
    return(FALSE);
   }

 if(FirstFunc)
  {
   lastnode->Next=nodeptr;
   nodeptr->Prev=lastnode;
  }
 else
   FirstFunc=nodeptr;


changefuncnode(nodeptr);
activatefunc(nodeptr);

nodeptr->FuncPattern=0xffff;

return(TRUE);
}


/*******************************************************************/
/*                                                                 */
/*        deletefuncnode() deletes a funcnode via clear..()        */
/*            and then freeing mem from struct Funcnode            */
/*                         done 29.12.1991                         */
/*                                                                 */
/*******************************************************************/

void  deletefuncnode(struct FuncNode *oldnode)
{
  struct FuncNode *prevnode,*nextnode;

  prevnode=oldnode->Prev;
  nextnode=oldnode->Next;

 if(prevnode)
   prevnode->Next=nextnode;
 else
   FirstFunc=nextnode;

 if(nextnode)
   nextnode->Prev=prevnode;

  clearfuncnode(oldnode);
  FreeMem(oldnode,sizeof(struct FuncNode));
}


/*******************************************************************/
/*                                                                 */
/*           clearfuncnode() frees the FuncNode from all           */
/*             function strings and comiled functions              */
/*                         done 29.12.1991                         */
/*                                                                 */
/*******************************************************************/

void clearfuncnode(struct FuncNode *oldnode)
{
  ULONG  *lenptr;
  APTR   *CFuncptr;
  char   **Funcptr;
  short i;

  lenptr=&oldnode->LenCFunc;
  CFuncptr=&oldnode->CFunc;
  Funcptr=&oldnode->Func;

  oldnode->isdrawn=0;  /* note I'm not changing FuncPattern 20.01.1992 */

  for(i=0;i<3;i++)  /* free memory from compiled func  */
   {
    if(*lenptr) /* is there a compiled function? */
      FreeMem(*CFuncptr,*lenptr);
    *lenptr++=NULL;
    *CFuncptr++=NULL;
   }

  for(i=0;i<3;i++) /* free memory from functionstrings  */
   {
     if(*Funcptr) /* is there a string ? */
       FreeMem(*Funcptr,strlen((const char *)*Funcptr)+1L);
     *Funcptr++=NULL;
   }
}


/********************************************************************/
/*                                                                  */
/* changefuncnode() deletes all strings and compiled functions      */
/* via clearfuncnode() and then allocates mem for the new function- */
/* strings and compiles the function with myallocfunc()             */
/* done 29.12.1991                                                  */
/********************************************************************/

BOOL changefuncnode(struct FuncNode *oldnode)
{
  ULONG len,len1,len2;

  len=strlen((const char *)funktion);
  len1=strlen((const char *)funktion1);
  len2=strlen((const char *)funktion2);

  if(!len)          /* 06.02.1992 */
   return(FALSE);

  clearfuncnode(oldnode);

  if(!(oldnode->Func=AllocMem(len+1L,MEMF_PUBLIC)))
   {
     ShowErr(14,FALSE);
     return(FALSE);
   }
  else
   strcpy(oldnode->Func,(const char *)funktion);

  if(len1)
   {
    if(!(oldnode->Func1=AllocMem(len1+1L,MEMF_PUBLIC)))
     {
       ShowErr(14,FALSE);
       return(FALSE);
     }
    else
     strcpy(oldnode->Func1,(const char *)funktion1);
   }
  else
    oldnode->Func1=NULL;

  if(len2)
   {
    if(!(oldnode->Func2=AllocMem(len2+1L,MEMF_PUBLIC)))
     {
      ShowErr(14,FALSE);
      return(FALSE);
     }
    else
     strcpy(oldnode->Func2,(const char *)funktion2);
   }
   else
    oldnode->Func2=NULL;

/* compiling of functions and allocation via myallocfunc */

  if(!myallocfunc(&oldnode->CFunc,&oldnode->LenCFunc,oldnode->Func))
     return(FALSE);


  if(oldnode->Func1) /* is there anything ? */
    if(!myallocfunc(&oldnode->CFunc1,&oldnode->LenCFunc1,oldnode->Func1)) /* 30.12.1991 */
      return(FALSE);

  if(oldnode->Func2)/* is there anything ? */
    if(!myallocfunc(&oldnode->CFunc2,&oldnode->LenCFunc2,oldnode->Func2))/* 30.12.1991 */
       return(FALSE);

 return(TRUE);
}


/*******************************************************************/
/*                                                                 */
/*         delallfuncs() deletes the complete functionlist         */
/*         pointed by FirstFunc           done 29.12.1991          */
/*                                                                 */
/*******************************************************************/

void delallfuncs(void)
{
 while(FirstFunc)
    deletefuncnode(FirstFunc);
 activeFunc=NULL;
}


/*******************************************************************/
/*                                                                 */
/*            ReDrawFuncs() redraws all functions after            */
/*              changing screenmode, intervall, etc..              */
/*                         done 20.01.1992                         */
/*                                                                 */
/*******************************************************************/

void ReDrawFuncs(void)
{
  struct FuncNode *nodeptr,*oldactfunc;

 nodeptr=FirstFunc;
 oldactfunc=activeFunc;
 SetDrMd(rp,(long)JAM1);
 do
  {
    if(nodeptr->isdrawn)
     {
       activatefunc(nodeptr);

       if(nodeptr->isdrawn&0x01)
         DrawFunc(f,1L);

       if(nodeptr->isdrawn&0x02)
         DrawFunc(fa,4L);

       if(nodeptr->isdrawn&0x04)
         DrawFunc(fa2,5L);
     }

  }while(nodeptr=nodeptr->Next);

 activatefunc(oldactfunc);
 SetDrMd(rp,(long)JAM1|COMPLEMENT);
}


/*******************************************************************/
/*                                                                 */
/*            activatefunc() activates a given FuncNode            */
/*                         done 20.01.1992                         */
/*                                                                 */
/*******************************************************************/

void activatefunc(struct FuncNode *nodeptr)
{
  activeFunc=nodeptr;
  numb=(void *)activeFunc->CFunc;
  numb1=(void *)activeFunc->CFunc1;
  numb2=(void *)activeFunc->CFunc2;
}


/*******************************************************************/
/*                                                                 */
/*             stripstr() removes blanks from a string             */
/*              and converts the string to lower case              */
/*                        done 25.01.1992                          */
/*                                                                 */
/*******************************************************************/

void stripstr( char * s)
{
 char *st;
long i;

 st=s;
 strlwr(s);

 while(*st==' ')/* cut leading spaces */
  st++;

 i=strcspn((const char *)st," "); /* cut following spaces */
 st[i]=0;

  if(!(s==st))
   {
     do
      {
        *s++=*st++;
      }while(*st);

     *s=0;
   }

}


/*******************************************************************/
/*                                                                 */
/*        checkfuncs() checks via scan the integrity of the        */
/*        function given in funktion?      done 01.02.1992         */
/*                                                                 */
/*******************************************************************/

short checkfuncs(void)
{
     stripstr((char *)funktion);
     stripstr((char *)funktion1);
     stripstr((char *)funktion2);

     scan((unsigned char *)funktion,array);
     if(fehler)
       return(1);

     if(strlen((char *)funktion1))
      {
       scan((unsigned char *)funktion1,array);
        if(fehler)
         return(2);
      }

     if(strlen((char *)funktion2))
      {
        scan((unsigned char *)funktion2,array);
        if(fehler)
         return(3);
      }
  return(0);
}
