/*
 * Copyright (C) Andrew Wuensche
 *
 *  This file is part of DDLab (Discrete Dynamics Lab) <www.ddlab.org>
 *
 *  DDLab is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with DDLab.  If not, see <http://www.gnu.org/licenses/>.
 */
/************************** MAIN.C *********************************/
#define EXT
#   include "edecfunc.h"
#undef EXT

#if __UNIX__
#   include <sys/types.h>
/* #ifdef __SOLARIS__ */
#if __SOLARIS__ || __IRIX__ || __DARWIN__   /* Oskar */
#include <limits.h>
#include <sys/stat.h>
#else
#   include <sys/limits.h>

#endif
#   include <fcntl.h>
#   include <dirent.h>
#endif
/********* list of functions in this file apart from main  ************/
/*void main(int argc, char *argv[])*/
void delay_and_continue(float delay_required);
/*signed int check_value_bits(signed int vr)*/
/*void set_color_order_nhd(char shuffle)*/
/*void rearange_value_colors(void)*/
void setup_postScripr_colors(char first_time);
/*void setup_value_colors(char first_time);*/
void check_clock_speed(void);
/*void show_pre_fansize_freq_hist(void)*/
/*void finish_options(char alloptions)*/
/*char mutate_rule(char nhoodz);*/
void biased_new_rule(void);
/*void draw_lambda_z_graph(char dontbias)*/
/*void gofE_z_graph(void)*/
void draw_sei(void);
void allocate_mem_istr_graph(void);//mem for the interactive state transition graph
void free_mem_istr_graph(void);


  
signed int totcode_eq_or_cl;/*total code equivalents or clusters*/
float mem_GiB=4.0; /*available memory (RAM+SWAP)*/
char istr_was_alloced=0;

/****************** main 13 May 1993 **************************/
void main(int argc, char *argv[]){
  signed int z,temp,xbox,vpercent_used,
      tempx,tempy,tempy1,main30y,main40y,selectry,show_w_ry,seed_y,branch_y,
      old_gd_x,old_gd_y;
 /*signed int demorad, rad of circle in screensave demo -- now global float 21 Jan 2017*/
 unsigned int zu,randseed,last_lineL=0,
     temp_lineL, temp_L; /*outer-totalistic rules*/
 unsigned char tempcolor;
 char sei,firstgraphics,basinfield_setting=0,range_setting=0,
   *rangeseed; /*constant seed for G-density - size graph, 
                    single basins, subtrees*/

 

#if __WATCOM__
   signed int mode;
   time_t t;

   freopen("/dev/null","w",stderr); 
   /*to suppress output for the terminal, because in Watcom appears in the DDLab window*/
#endif

        /*char cmd[1024];*/
        /*to prevent *** glibc detected *** double free or corruption etc ???*/
        /*its still intermittent e.g. in TFO-mode v2k3*/
        /*sprintf(cmd,"export MALLOC_CHECK_=0");
	  system(cmd);*/
        exh_pairs_in_jump_nodes=0;//to redraw basins within jump-graph nodes if exhaustive_testing
        inside_wiring_graphic=0; /*need this to show rules in xterm with 'x' */
        basin_not_complete=0;/*to prevent changes to network when basins interrupted*/
        TFO_SEED_FIELD=0; /*info in bottom title, 0, TFO=1 SEED=2 FIELD=3*/
        sei=0; /*disable unregistered*/
        loc_twod_fonly=0;  /*dont wire up regular 2-d CA, dont allocate wiring mem - redundant*/
        tot_only=0; /*=1 for totalistic rules only, 
                      program constrained to run forward only - no basins, 
                      this allows greater k, especially for v>2*/ 
	bground='b';
        CursorFlash_auto_reset=0;
        check_clock_speed();
        direction=0;
        value_range=2;
        nhood=0;
        new_weight=2; //bold font, can be changed to medium
	stp=0; //space-time patterns
        
	/*command line arguments, ie -wbt etc in any order*/
        
        if (argc>1 && argv[1][0]=='-'){
	  /*fprintf(stderr,"\n%s size=%d\n",argv[0],(int)strlen(argv[1]));*/
	   for (z=1; z<=strlen(argv[1]); z++){
              //fprintf(stderr,"%c",argv[1][z]); //print the arguments
	      if (argv[1][z]=='w') bground='w'; /*black background*/
              if (argv[1][z]=='w') bground='w'; /*white background*/
	      if (argv[1][z]=='t') tot_only=1;  /*totalistic/forwards only*/
              if (argv[1][z]=='L') sei=1;
#             if __WATCOM__
                 if (argv[1][z]=='m') hires=1;
                 if (argv[1][z]=='h') hires=2;	      
#             endif
	   }
        }
        system_bits=8*sizeof(unsigned long);
        Maxlu=(unsigned long)(-1);        
        Maxu=(unsigned int)(-1);
        fprintf(stderr,"\n%d bit system ",system_bits);
        /*fprintf(stderr,"\n%d bit system: Maxlu=%lu, Maxu=%u",
	  system_bits,Maxlu,Maxu);*/
	
/*#       if __UNIX__
            fprintf(stderr," compiled %s",__DATE__);//compilation date
	    fprintf(stderr,"%.*s%.*s",3,__DATE__,4,__DATE__+7);//just the xxx month and year
#       endif*/
	    
        Maxint=(signed int)(Maxu/2);
        Max_ushort=(unsigned short)(-1);
        /*32 bit system: Maxlu=4294967295, Maxu=4294967295*/
        /*64 bit system: Maxlu=18446744073709551615, Maxu=4294967295*/
	/*Maxu=USHRT_MAX;  //max unsigned short int=65535
	  Maxint=SHRT_MAX; //max signed short int=32767*/
	Maxnhood=13;     /*initial maximum allowable k nhood size*/
       

	nhood=fieldno=in_startbasin=in_startfield=pre_fansize_freq_hist=0;
	layout_notset=1;
	setting_seed=0;
        show_maj=-1; /*to show/count states with majority of 1s or 0s*/ 

#       if __WATCOM__
	   srand((unsigned) time(&t));
	   randseed=rand();
#       elif __UNIX__
	   randseed=(unsigned int)getpid()*time(0);
#       endif

	allocate_mem_buffers();
        allocate_mem_Z_parameter();
        /*allocate mem for complex rule sample set with 'g' */
        if ((no_glider_rules=(signed int **)calloc(9,
	      sizeof(signed int*)))==NULL) outof_memory("no_glider_rules");
        for (z=2;z<=8;z++){ /*the value range 2 to 8*/
	      if ((no_glider_rules[z]=(signed int *)calloc(Maxnhood+1,
	       sizeof(signed int)))==NULL) outof_memory("no_glider_rules");
        }
        /*realloc'ed in load_glider_buf() l_save.c*/
        if ((glider_buf=(unsigned char *)calloc(1,
	        sizeof(unsigned char)))==NULL) outof_memory("glider_buf");
        /*realloc'ed in force_rand_links_layer() wiring.c*/
        if ((force_layer=(signed int*)calloc(1,
                sizeof(signed int)))==NULL) outof_memory("force_layer");
        
	firstgraphics=secondpart=0;
   start:
	open_graphics(firstgraphics,sei);
	msize=vgax(200);
	Leftx=50;
	xtext=(float)vgax(Leftx)/CWidth;
        
   main10:
	cleardevice();
	setcolor(white);
        setviewport(0,0,getmaxx(),getmaxy(),0); /*to allow title*/
	draw_bottom_title(0);
        if (sei==0) draw_sei();

	firstgraphics=1;
        setviewport(0,0,Maxx,Maxy,0);
        note_viewport;
   
#       if __WATCOM__
	   srand(randseed);
#       elif __UNIX__

       
   main11:	
	srandom(randseed);
#       endif
	/*show video config/mouse*/
	/*get mode name strings*/
#       if __WATCOM__
	   _getvideoconfig(&vc);
	   sprintf(textb[0],
	       "res=%dx%d randseed=%u",
			    vc.numxpixels,vc.numypixels,randseed);
#       elif __UNIX__
	   sprintf(textb[0],
	      "res=%dx%d pt=%d randseed=%u",
			     Maxx+1,WinMaxy+1,pointsize,randseed);
#       endif
        
	xbox=draw_prompt_box(2);
        setcolor(green);
        sprintf(textb[1],"ddlabz19 %dbit Aug2026 ",system_bits);
	//sprintf(textb[1],"%s %dbit Aug2026 ",argv[0],system_bits); //show path+filename
        outtext(textb[1]);
        setcolor(white);
	outtext(textb[0]);
#if __WATCOM__
	if (mouse_found){ 
           sprintf(textb[0],
	       "mouse found: buttons: left=ret right='q'=backtrack");
           mouse_call(1,0,0,0); /*display mouse*/
        }
	if (!mouse_found) sprintf(textb[0],"mouse not found");
#elif __UNIX__
	sprintf(textb[0],
	      "mouse buttons: left=ret right='q'=backtrack");
#endif
	moveto(xbox,gety+CHeight);
	outtext(textb[0]);
        
        Max_oy=Maxy*2; /*limit of oy, any oy greater is stuck (off screen) 
                         attractor are drawn, but not transients in draw_fan()*/
        exLimit=0;
	memory_box(1,NULL);
	moveto(vgax(50),vgay(50));
               
	next_line(xtext,0);
	if (tot_only==0){
           TFO_SEED_FIELD=0; /*notset mode*/
           draw_bottom_title(0); 
           sprintf(textb[0],
	     "EXIT-q graphics-g randseed-r, TFO:totalistic/forward only-t");
        }
        else{
           sprintf(textb[0],
              "EXIT-q graphics-g randseed-r, disable TFO allow basins-b");
           TFO_SEED_FIELD=1;
        }
	outtext(textb[0]);
	next_line(xtext,1);
        if (tot_only==0) outtext(
                "SEED:forward/single basin/subtree-s (FIELD-def)");
        else{
	  setcolor(green);
          outtext("TFO:totalistic rules and forward only-(def)");          
        }
        setcolor(lightred);
        outtext(" exLimits+L");
        setcolor(white);
        outtext(":");
        sprintf(is,"%s","");
        exLimit=0;
        is[0]=0;
        input_string(2,0);

        if (tot_only==0){
           if (is[0]=='s'){
	      TFO_SEED_FIELD=2;
              basinfield=0;
           }
           else{
              TFO_SEED_FIELD=3;
              basinfield=1;
	   }
        }
        else{
           TFO_SEED_FIELD=1;
           basinfield=0;
        }

        if (is[0]=='L' || is[1]=='L') exLimit=1;
        if (exLimit==0){ 
            maxL_lu=Maxu/512;
            //fprintf(stderr,"\n exLimit==%d: maxL_lu=%u",exLimit,maxL_lu);
        }
        else{
            maxL_lu=Maxu;
            //fprintf(stderr,"\n exLimit==%d: maxL_lu=%u",exLimit,maxL_lu);
        }

        if (exLimit==1){
	   if (system_bits==64) mem_GiB=4.0; 
             /*default available memory (RAM+SWAP gibibyte GiB)*/
	   else mem_GiB=0.5; /*for system_bits==32*/
           tempx=getx;
           tempy=gety;
           if (system_bits==64 && tot_only==0) xbox=draw_prompt_box(2);
           else{
               erase_prompt_box(2);
               xbox=draw_prompt_box(1);
           }
           setcolor(lightred); 
           outtext("caution! exLimits selected");
           setcolor(white);
           if (system_bits==64) outtext(" high k or n might exceed memory");
           else outtext(" high k might exceed memory");
           if (system_bits==64 && tot_only==0){
              moveto(xbox, gety+CHeight); 
              setcolor(white);
              sprintf(textb[0],"enter total RAM+SWAP (def %.2f GiB):",mem_GiB);  
              outtext(textb[0]);
              input_string(10,0);
              if (is[0]=='q'){ 
                 clearviewport();
#                if __WATCOM__q
                    goto main10;
#                elif __UNIX__
                    goto main11;
#                endif    
              }
              else if (atof(is)>.001 && is[0]!=13) mem_GiB=atof(is);
              else mem_GiB=4.0;
           }
           moveto(tempx,tempy);
        }
  
	setfillstyle(SOLID_FILL,black);
	bar(getx,gety,getx+CWidth,gety+CHeight);
	
        CursorFlash_auto_reset=1; /*done in flashing_cursor()*/

        if ((tot_only==0 && is[0]=='t') || (tot_only==1 && is[0]=='b')){
           if (tot_only==0 && is[0]=='t'){
              tot_only=1;
              TFO_SEED_FIELD=1; /*TFO-mode*/
	   }
           else if (tot_only==1 && is[0]=='b'){
              tot_only=0;
              TFO_SEED_FIELD=0; /*notset mode*/
           }           
           goto main10;
        }
        else if (is[0]=='a'){
           clearviewport();
	   new_ant();
           clearviewport();
	   draw_bottom_title(1);
#          if __WATCOM__
              goto main10;
#          elif __UNIX__
              goto main11;
#          endif
	}   
	else if (is[0]=='r'){
	   erase_prompt_box(2);
	   draw_prompt_box(1);
           sprintf(textb[1],"%u",Maxu);
#          if __WATCOM__
	      sprintf(textb[0],
		"enter random number seed 0-%u (rnd-def):",Maxu);
#          elif __UNIX__
              sprintf(textb[0],
		      "enter random number seed 0-%u (rnd-def):",Maxu);
#          endif

	   outtext(textb[0]);
           input_string(strlen(textb[1]),0);
	   if (is[0]=='q');
	   else if (is[0]==13) randseed=(unsigned int)rand();
	   else if (atoi(is)<=Maxu) randseed=atoi(is);
#          if __WATCOM__
              goto main10;
#          elif __UNIX__
              goto main11;
#          endif
	}
	else if (is[0]=='g'){
#          if __WATCOM__
	      goto start;
#          elif __UNIX__
              show_old_colors();
              revise_graphics();
              goto main10;
#          endif
	   
	}
	else if (is[0]=='q'){
          char restart_license=0;

	   memory_box(1,NULL);
	   setcolor(lightred);
	   sprintf(textb[0],"Exit DDlab-q, Restart-ret:");
           moveto(0,-30); /*above the screen out of sight*/
           outtext(textb[0]);
           temp=getx;
	   temp=temp/2 + CWidth;	   
	   draw_box(-1,Maxx/2-temp-vgax(15),Maxy/2-vgay(15),
			Maxx/2+temp+vgax(15),Maxy/2+vgay(15),1,blue);
	   draw_box(-1,Maxx/2-temp-vgax(8),Maxy/2-vgay(8),
			     Maxx/2+temp+vgax(8),Maxy/2+vgay(8),1,black);
	   moverel(CWidth,vgay(2));	       
	   outtext(textb[0]);
	   input_string(1,0);
	   if (is[0]=='q'){
	      //if (tot_only==0) free_mem_Z_parameter();
              free_mem_Z_parameter();
              for(z=2;z<=8;z++) free(no_glider_rules[z]);
	      free(no_glider_rules);
              free(glider_buf);
              free(force_layer);
#             if __WATCOM__
                 free_mem_buffers();
		 _setvideomode(_VRES16COLOR); /*restore 640 x 480*/
		 _setvideomode(_TEXTBW80);
#             elif __UNIX__
                close_graphics();
                free_mem_buffers();
#             endif
		fprintf(stderr,"\nDDLab clean exit\n");
	      exit(0);
	   }
#          if __UNIX__
             else if (is[0]=='L' && sei==0){
                sei=1;
                restart_license=1;
             }
#          endif

	   erase_box(Maxx/2-temp-vgax(15),Maxy/2-vgay(15),
		              Maxx/2+temp+vgax(15),Maxy/2+vgay(15));
	   setcolor(white);
	   setpback_x_lines(0);

           if (restart_license==1){
              goto start; 
           }
           else goto main10;                 
        }
        
	/*if (tot_only==0){
           if (is[0]!='s' && is[0]!='S'){
              basinfield=1;
              TFO_SEED_FIELD=3; //FIELD-mode*
           }
           else TFO_SEED_FIELD=2; //SEED-mode*
	}*/

        //fprintf(stderr,"\n basinfield=%d",basinfield);

        draw_bottom_title(0);

	if (basinfield_setting!=basinfield){
	   layout_notset=1;
	   basinfield_setting=basinfield;
	}

        /*****************************************/
        /*list max types and state-space for basin field*/

        /*fprintf(stderr,"\n max unsigned long long=%llu",
		(unsigned long long)-1);
        fprintf (stderr,"\n max unsigned long (Maxlu)=%lu (c=%lu w=%lu p=%lu) (%lu bits)",
		 Maxlu, Maxlu/8, (Maxlu/8)/8, ((Maxlu/8)/8)/500, 8*sizeof(unsigned long));
        fprintf (stderr,"\n max unsigned int (Maxu)=%u (c=%u w=%u p=%u) (%lu bits)",
		 Maxu,Maxu/8, (Maxu/8)/8,((Maxu/8)/8)/500, 8*sizeof(unsigned int));

        fprintf (stderr,"\n max signed int (Maxint)=%d",Maxint);
        fprintf (stderr,"\n max unsigned short (Max_ushort)=%u",
		 Max_ushort);     

        fprintf (stderr,"\n max1d=%u",Maxu);
        fprintf (stderr,"\n max2d square=%u",
	         (unsigned int)sqrt( (double)Maxu ) );
	fprintf (stderr,"\n max3d cube=%u",
		 (unsigned int)cbrt( (double)Maxu ) );

        fprintf (stderr,"\n max1d=%u",maxL_lu);
        fprintf (stderr,"\n max2d square=%u",
	         (unsigned int)sqrt( (double)maxL_lu) );
	fprintf (stderr,"\n max3d cube=%u",
	         (unsigned int)cbrt( (double)maxL_lu) );*/

         

        /*system_bits=32 bit:  max unsigned long = int = 4294967295*/
        /*system_bits=64 bit:
          Maxlu: max unsigned long = 18446744073709551615
          Maxu: max unsigned int = 4294967295
          Maxint: max signed int = 2147483647
          max1d = 4294967295
          max2d square = 65535
          max3d cube = 1625
	*/      

 /**** select value range, sept 2001 *******/
 set_value_range: 
   value_range=2; /*always the default*/
   next_line(xtext,1);
   sprintf(textb[0],
      "Value-range v (def %d, max 8):",value_range);   
   outtext(textb[0]);
   input_string(1,0);
   if (is[0]=='q'){ 
     /*setpback_x_lines(2);*/
     clearviewport();
#     if __WATCOM__
              goto main10;
#     elif __UNIX__
              goto main11;
#     endif    
   }
   else if ((atoi(is)<2 || atoi(is)>8 || is[0]==13)); /*do nout*/
   else value_range=atoi(is);
   if (value_range==2) value_bits=1;
   else if (value_range<=4) value_bits=2; /* 3 or 4 */
   else if (value_range<=8) value_bits=3; /* 5 to 8 */

   vpercent_used=0;
   for (z=0;z<=7;z++) bias_percent_rule[z]= bias_percent_seed[z]=0;
   bias_percent_rule[8]= bias_percent_seed[8]='p';
 
   /*set default (skewed) value freqency for seed*/  
   for (z=0;z<=value_range-1;z++){
        if (z==value_range-1) bias_percent_seed[z]=100-vpercent_used;
	else if (z==(value_range-2)/2 +1) bias_percent_seed[z]=65;
        else bias_percent_seed[z]=(unsigned char)ceil(35.0/(value_range-1));
        vpercent_used+= bias_percent_seed[z];                 
   }
  
   /* vpercent_used=0;
   fprintf(stderr,"\nseed: v=%d\n",value_range);
   for (z=0;z<=value_range-1;z++){
      fprintf(stderr,"%d ",bias_percent_seed[z]);
      vpercent_used+=bias_percent_seed[z];
   }
   fprintf(stderr,"=%d",vpercent_used);*/

   vpercent_used=0;
   if (value_range==2){
      bias_percent_rule[0]=65;
      bias_percent_rule[1]=35;
   }
   else if (value_range==3){
      bias_percent_rule[0]=60;
      bias_percent_rule[1]=30;
      bias_percent_rule[2]=10;
   }
   else if (value_range==4){
      bias_percent_rule[0]=55;
      bias_percent_rule[1]=25;
      bias_percent_rule[2]=12;
      bias_percent_rule[3]= 8;
   }
   else if (value_range==5){
      bias_percent_rule[0]=50;
      bias_percent_rule[1]=25;
      bias_percent_rule[2]=12;
      bias_percent_rule[3]= 8;
      bias_percent_rule[4]= 5;
   }
   else if (value_range==6){
      bias_percent_rule[0]=45;
      bias_percent_rule[1]=23;
      bias_percent_rule[2]=13;
      bias_percent_rule[3]=10;
      bias_percent_rule[4]= 6;
      bias_percent_rule[5]= 3;
   }
   else if (value_range==7){
      bias_percent_rule[0]=40;
      bias_percent_rule[1]=21;
      bias_percent_rule[2]=14;
      bias_percent_rule[3]=10;
      bias_percent_rule[4]= 7;
      bias_percent_rule[5]= 5;
      bias_percent_rule[6]= 3;
   }
   else if (value_range==8){
      bias_percent_rule[0]=35;
      bias_percent_rule[1]=20;
      bias_percent_rule[2]=14;
      bias_percent_rule[3]=10;
      bias_percent_rule[4]= 8;
      bias_percent_rule[5]= 6;
      bias_percent_rule[6]= 4;
      bias_percent_rule[7]= 3;
   }

   /*vpercent_used=0;
   fprintf(stderr,"\nrule: v=%d\n",value_range);
   for (z=0;z<=value_range-1;z++){
          fprintf(stderr,"%d ",bias_percent_rule[z]);
          vpercent_used+=bias_percent_rule[z];
   }
   fprintf(stderr,"=%d",vpercent_used);*/

   
   /*max string length for unsigned long, 
     to show rule/string in decimal, also for length/2 for state-space matrix
     NOTE: state-space, ss = value_range^maxL_lu = vdec + 1*/

   /* set max n for FIELD, for 64 or 32 bits, restricted or exLimit */
   if (basinfield){    
     unsigned long this_limit;
      if (system_bits==64){
        if (exLimit==1) this_limit=Maxlu/2;
        else this_limit=Maxu;
      }
      else this_limit=Maxu;
   
      /*fprintf(stderr,"\nmax n: 63 limit=%lu",this_limit);*/    
      for (z=2; z<=8; z++){   
         for (zu=system_bits-1; zu>=10; zu--){
            if (pow((double)z,(double)zu) > this_limit
		|| ((pow((double)z,(double)zu)/8)/1073741824) > mem_GiB);
	          /*tickoff array < 8 Gib ram+swap, to checkin linux/Mac "cat /proc/meminfo"*/
            else{
	      /*fprintf(stderr,"\n %d^%u = %lu",z,zu,
		(unsigned long)pow((double)z,(double)zu),z,zu);*/
	      if (z==value_range){ 
                  maxL_lu=zu;
                  /*maxLu32 is for range of field/basin/subtree only*/
                  if (maxL_lu > Maxu) maxLu32=Maxu;
	          else maxLu32=zu;
	       }
               break;
            }
         }
         /*fprintf(stderr,"\n %d^%u = %lu =%f GiB",z,zu,
	     (unsigned long)pow((double)z,(double)zu),
	     (pow((double)z,(double)zu)/8)/1073741824);*/                  
      }
   }
   //fprintf(stderr,"\n 2^63 GiB =%f",(9223372036854775808.0/8)/10737418240);
   /*for basin-of-attraction field: new (greater) limits of v^n for ss tickoff,
     but above n=35  usually insufficient memory RAM+SWAP 
     -- top right "insufficient memory" notice/prompt, and Exit*/
   /* for 64-bit, nolimit (can be set in first prompt) 
   this would need 107374182.400000 GiB so impractical   
   2^63 = 9223372036854775808
   3^39 = 4052555153018976256
   4^31 = 4611686018427387904
   5^27 = 7450580596923828224
   6^24 = 4738381338321616896
   7^22 = 3909821048582988288
   8^21 = 9223372036854775808

   or 64-bit nolimit and this would needs 4.0 GiB - the default for 64-bit system 
   2^35 = 34359738368 =4.000000 GiB
   3^22 = 31381059609 =3.653236 GiB
   4^17 = 17179869184 =2.000000 GiB
   5^15 = 30517578125 =3.552714 GiB
   6^13 = 13060694016 =1.520465 GiB
   7^12 = 13841287201 =1.611338 GiB
   8^11 = 8589934592 =1.000000 GiB

   or 32-bit, or 64-bit basic, 
      or for range of field/basin/subtree only
   2^31 = 2147483648 =0.250000 GiB
   3^20 = 3486784401 =0.405915 GiB
   4^15 = 1073741824 =0.125000 GiB
   5^13 = 1220703125 =0.142109 GiB
   6^12 = 2176782336 =0.253411 GiB
   7^11 = 1977326743 =0.230191 GiB
   8^10 = 1073741824 =0.125000 GiB
   */
 
   /*max string for exhaustive testing algorithm -- random map*/
   /*limit kept because of time constraints */
   if (value_range==2)      max_exh_lu=28; /*268435455*/  
   else if (value_range==3) max_exh_lu=18; /*387420488*/
   else if (value_range==4) max_exh_lu=14; /*268435455*/
   else if (value_range==5) max_exh_lu=12; /*244140624*/
   else if (value_range==6) max_exh_lu=11; /*362797055*/
   else if (value_range==7) max_exh_lu=10; /*282475248*/
   else if (value_range==8) max_exh_lu=9;  /*134217727*/
   

   /*max neighborhood k */
   if (tot_only==0){
    unsigned long this_limit;
      if (system_bits==64){
        if (exLimit==1) this_limit=Maxu/2;
        else this_limit=Maxu/512; /*Maxu same for 64 and 32 bits*/
      }
      else this_limit=Maxu/512;
      /*fprintf(stderr,"\n exLimit=%d bits=%d, this_limit=%lu",
	exLimit,system_bits,this_limit);*/

      for (z=2;z<=8;z++){
         for (zu=27; zu>=4; zu--){
	    if ( pow(z,(double)zu)-1 > this_limit);
            else{
	        if (z==value_range) Maxk=(signed int)zu;	 	        
              break;
            }
         }
         /*fprintf(stderr,"\n %d^%d = %u Maxk=%d",z,zu,
	   (unsigned int)(pow(z,(double)zu)-1), (signed int)zu);*/
      }
      /*safe default FIELD or SEED -modes, tot_only=0*/
      if      (value_range==2) defMaxk=13; //  8162
      else if (value_range==3) defMaxk=9;  // 19683
      else if (value_range==4) defMaxk=7;  // 16484
      else if (value_range==5) defMaxk=6;  // 15629
      else if (value_range==6) defMaxk=5;  //  7776
      else if (value_range==7) defMaxk=5;  // 16807
      else if (value_range==8) defMaxk=4;  //  4096
   }

   else if (tot_only==1){ 
     unsigned long this_limit;
      if (system_bits==64){
	if (exLimit==1) this_limit=Maxu/2;
        else this_limit=Maxu;
      }
 
      //fprintf(stderr,"\n Maxk tot_only=1");
      for (z=2;z<=8;z++){
         for (zu=27; zu>=11; zu--){
	    if ( pow(z,(double)zu)-1 > this_limit);
#if         __UNIX__  /* long long doesnt work for DOS */        
             /*v-codetable size*/
	    if ((unsigned int) 
              (longlong_fact(z+zu-1,zu+1)/ 
	           (longlong_fact(z-1,1))) > this_limit);
            else{
	      if (z==value_range) Maxk=(signed int)zu;	 
              
              /*fprintf(stderr,"\n %d^%d = %d",z,zu,
	        (unsigned int)(longlong_fact(z+zu-1,zu+1)/ 
		(longlong_fact(z-1,1))) );*/
              break;
            }
# elif      __WATCOM__
	    if ((unsigned int) 
              (long_fact(z+zu-1,zu+1)/ 
	            (long_fact(z-1,1))) > this_limit);
            else{
	      if (z==value_range) Maxk=(signed int)zu;	 
              /*fprintf(stderr,"\n %d^%d = %d",z,zu,
	        (unsigned int)(long_fact(z+zu-1,zu+1)/ 
		(long_fact(z-1,1))) );*/
              break;
            }
# endif            
         }
      }
      /*safe default values TFO-mode, tot_only=1*/
      if      (value_range==2) defMaxk=27;  /*    28 */
      else if (value_range==3) defMaxk=27;  /*   406 */
      else if (value_range==4) defMaxk=26;  /*  3654 */
      else if (value_range==5) defMaxk=25;  /* 23751 */
      else if (value_range==6) defMaxk=17;  /* 26334 */
      else if (value_range==7) defMaxk=13;  /* 27132 */
      else if (value_range==8) defMaxk=11;  /* 31824 */ 

      if (exLimit==1){/*if max long pauses   rule-table,S */
         if      (value_range==2) Maxk=27;  /*    28 */
         else if (value_range==3) Maxk=27;  /*   406 */
         else if (value_range==4) Maxk=27;  /*  4060 */
         else if (value_range==5) Maxk=27;  /* 31465 */
         else if (value_range==6) Maxk=27;  /*201376 */
         else if (value_range==7) Maxk=25;  /*593775 */
         else if (value_range==8) Maxk=20;  /*888030 */
      }
   }
     
   tempx=getx;
   tempy=gety;

   Maxnhood=defMaxk; /*can be changed below*/
  change_kLimit:
   if (exLimit==1){      
      xbox=draw_prompt_box(2);  
      sprintf(textb[0],
          "change -/+  max kLimit):");
      outtext(textb[0]);      
      sprintf(textb[0]," increase with caution!");
      setcolor(lightred); 
      outtext(textb[0]);
      setcolor(white);
      moveto(xbox,gety+CHeight);  
      sprintf(textb[0],"enter new kLimit (def %d, max %d):",defMaxk,Maxk);  
      outtext(textb[0]);
      input_string(2,0);
   
      if (is[0]=='q'){ 
         /*setpback_x_lines(2);*/
         clearviewport();
#        if __WATCOM__
              goto main10;
#        elif __UNIX__
              goto main11;
#        endif    
      }
      else if (atoi(is)>1 && atoi(is)<=Maxk && is[0]!=13) Maxnhood=atoi(is);
      else Maxnhood=defMaxk;
      erase_prompt_box(2);
   }

   if (tot_only==0){
     char abort_matrix=0;
      if (exLimit==1){
         draw_prompt_box(1);
         setcolor(green);
         outtext(" setting up k matrix: abort-q:");
         while(event_ready()==0) break;/*wont outtext without this - ??*/
         abort_matrix=allocate_mem_nhood_matrix(Maxnhood);      
         setcolor(white);
         erase_prompt_box(1);
         if (abort_matrix==1) goto change_kLimit;
      }
      else{ /*exLimit==0*/
         abort_matrix=allocate_mem_nhood_matrix(Maxnhood);             
         if (abort_matrix==1){
            clearviewport();
#           if __WATCOM__
               goto main10;
#           elif __UNIX__
               goto main11;
#           endif 
         }   
      }
   }
   

   moveto(tempx,tempy);
   sprintf(textb[0]," kLimit=%d",Maxnhood);
   setcolor(lightred); 
   outtext(textb[0]);
   setcolor(white); 
   
   /*alloc buffers for color-canalizing frequency*/
   setup_value_colors(1); /*include v=2*/
   setup_postScripr_colors(1);
   set_color_order_nhd(0);/*to allow shuffle nhd colors except white and black*/

   show_multistate_color_key(3);
   scale=vgax(4);/*def size in pixels of network cell*/

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

  main15:        
	erase_prompt_box(2);
        if (tot_only==0){	   
	   next_line(xtext,1);           
	   sprintf(textb[0],"range of network size-r:");
	   outtext(textb[0]);
	   input_string(1,0);
	   if (is[0]=='q'){
              show_multistate_color_key(-1);
              free(color_v);
              for (z=0;z<=52;z++) free(dcolor[z]);
              free(dcolor);
              free(grayscale);
              free_mem_nhood_matrix(Maxnhood);
	      setpback_x_lines(1);
              goto set_value_range;
	   }
	   rangeL=0;
	   if (is[0]=='r') rangeL=1;
	   if (range_setting!=rangeL){
	      layout_notset=1;
	      range_setting=rangeL;
	   }          
        }
  main20:
	showbits_1d_as_2d=i2d=j2d=0;
        if (rangeL==1){
           select_linelength_range();
           
           if (is[0]=='q'){
	      setpback_x_lines(0);
              goto main15;
	      if (tot_only==0) goto main15;
	      else goto set_value_range;
           }
	}
        else{
	   if (basinfield && rangeL==0){ 
              select_linelength_31();
              if (lineL!=last_lineL) layout_notset=1;
              last_lineL=lineL;
           }	
	   else select_linelength_singlebasin();
            /*fprintf(stderr,"\nstatespace=%lu",
	      (unsigned long)pow(value_range,(double)lineL));*/
        
	   if (is[0]=='q'){
	      if (tot_only==0){
                 setpback_x_lines(1); 
                 goto main15;
              }
              else{ /*TFO-mode -- tot_only=1*/
                 show_multistate_color_key(-1);
                 free(color_v);
                 for (z=0;z<=52;z++) free(dcolor[z]);
                 free(dcolor);
                 free(grayscale);
                 setpback_x_lines(1);                
                 goto set_value_range;
              }
	   }
	}
	allocate_mem_CA_states();/*includes others*/
        if (tot_only==0){
	   /*nominal array for in-degree histogram*/
	   maxinhist=0;
	   if ((pre_fan_freq=
	      (unsigned long *)calloc(1,sizeof(unsigned long)))
					==NULL) outof_memory("pre_fan_freq");
	   memory_box(1,NULL);
        }
	main30y=gety;     
  main30:
	select_nhood_size(0);
	if (is[0]=='q'){
	   free(nhoodm);
	   free_mem_CA_states();
           if (tot_only==0){
	      //free(rad);
	      free(pre_fan_freq);
	      pre_fansize_freq_hist=0;
	      memory_box(1,NULL);
	      /*if (rangeL) setpback_x_lines(1);
	        else setpback_x_lines(0);*/
           }
           /*else*/ 
           setpback_x_lines(1);
           if (rangeL==1){
	     rangeL =0;
              goto main15;
           }         
	   else goto main20;
	}
        allocate_mem_tcode0(nhood);
        if (tot_only==0){
	   allocate_mem_rule0(nhood);
           allocate_mem_rule0_extra(nhood);	
	   allocate_mem_all_0s_all_1s_rules(nhood);
	   allocate_mem_iso(nhood);
        }
        memory_box(1,NULL);
	tempy=gety;
        /* up to here */
  wire_up:
	if (istr_was_alloced==0 && tot_only==0 && rangeL==0){
	      allocate_mem_istr_graph(); //calloce mem for istr and ibaf graps in mainxx
	      istr_was_alloced=1;
	}
	rules_set=0;
        NULLboundaries=0; /*NULL boundaries disabled*/
	select_wiring_options();
        if (is[0]=='q'){
	   if (istr_was_alloced==1 && tot_only==0 && rangeL==0){
	         free_mem_istr_graph(); //free mem for istr and ibaf graps in mainxx
		 istr_was_alloced=0;
	   }	 
           NULLboundaries=0; /*NULL boundaries disabled*/
	   free(nhoodm);
           free_mem_tcode0();
           if (tot_only==0){
	      free_mem_rule0();
              free_mem_rule0_extra();
              free_mem_all_0s_all_1s_rules();
	      free_mem_iso(nhood);
           }
	   moveto(vgax(50),main30y);
           memory_box(1,NULL);
	   goto main30;
	}
        /*nhood finaly known at this point 
        (possibly reset in select_wiring_options()*/
        set_up_v_code(); /*new method using recursive tree*/

        erase_memory_box(0);
	if (twod) showbits_1d_as_2d=0;
	
	if (!loc_twod_fonly){           
           /* fprintf(stderr,"\n >allocate_mem_wiring");*/
	   allocate_mem_wiring();
           memory_box(1,NULL);
	   wire_up_network(1);
	}	
	if (is[0]=='q'){
	   if (!loc_twod_fonly){
	      free_mem_wiring();
              memory_box(1,NULL);
	   }
           free_v_code_arrays();
	   goto wire_up;
	}
        moveto(vgax(50),tempy);
	main40y=gety;
 main40:        
	pdata=0;
	sep=2;
	moveto(vgax(50),main40y);
	setfillstyle(SOLID_FILL,black);
	/*bar(0,CHeight+main40y+2,Maxx,Maxy-vgay(37));*/
        bar(0,CHeight+main40y+2,Maxx,Maxy);
	select_totalistic();
	if (is[0]=='q'){
	   if (loc_twod_fonly==0){
              if (is[0]=='q'){                 
		 free_v_code_arrays();                         
	         free_mem_wiring();
                 memory_box(1,NULL);
	         goto wire_up;
              }
              else goto main40;
	   }
	   else{
	      free_v_code_arrays();
              memory_box(1,NULL);
              goto wire_up;
           }  
	}

 selectrule:
        /*set default density for rules (rnd or sym) and seed*/
        if (value_range==2) bias_density_rule=bias_density_seed=50;
        else bias_density_rule=bias_density_seed=
                           100*(((float)value_range-1)/value_range);

        isotropic_set=0;/*while setting isotropic rules*/
	set_iso_bitflip=0;/* /*isotropic rules, toggle while running forward - not iso*/
	set_iso_input_histogram=0;/*input-histogran according to iso-rule in forx.c*/
        exhaustive_testing=0;
        Ham_bias=0;
	selectry=gety; 
	rulemix=0;
	rules_set=1;
        NULLboundaries=0;
        
        /*number of rules in glider file are found and 
          reallocated in load_glider_buf() in l_savexx.c
          according to file size, so numbers are for info only
          there is no rule at index 0, so effectively one less*/

        /*
        if (tot_only==0){
	   //any rcode-mix can be a glider file if named g_vxky.r_s

	   //no_glider_rules[2][5]=63;| 
	   //no_glider_rules[2][6]=32;> these are old style files 
	   //no_glider_rules[2][7]=32;|           
           //no_glider_rules[2][9]=6; g_Gv2k9.r_s Life-like 2d rules inc g-of-L
                                      rename g_v2k9.r_s to activate
           //no_glider_rules[2][9]=34; g-Dv2k9.r_s chosen for divisions
                                      rename g_v2k9.r_s to activate

           //no_glider_rules[3][3]=32; 
           //no_glider_rules[4][2]=32; 
           //no_glider_rules[4][3]=32;
           //no_glider_rules[5][2]=32;
          
           
        }
        else if (tot_only==1 && totalistic==2){
             //any kcode-mix can be a glider file if named g_vxky.r_v
             //these wor in 2d and 3d
             //no_glider_rules[3][4]=26; chosen to pulse if rnd wiring, from v3k4bs.sta  
	     //no_glider_rules[3][6]=56; 
	     //no_glider_rules[3][7]=35; //g_v3k6.r_v minmax entropy
             //no_glider_rules[4][7]=21; //g_v4k7.w_s chosen to pulse if rnd wiring, from v4k72d52.sta
        }
        */ 

        /*fprintf(stderr,"\n >rule_selection()");*/
        if (tot_only==1) allocate_mem_tcode0_extra(nhood);
        tempy1=rule_selection(); /*tempy1=y co-ord of text*/
	if (is[0]=='q'){
	   if (tot_only==1) free_mem_tcode0_extra();
	   if (rulemix){
	      if (tot_only==0) free_mem_rulemix();              
	      free_mem_tcodemix();
	      memory_box(1,NULL);
	   }
           if (outer_tot==1) outer_tot=0; /*outer-totalistic rules*/
	   rules_set=0;
	   goto main40;
	}        
        /*load file with glider rules, buffer realloced in load_glider_buf*/
        /*check file exists*/
        if (tot_only==1 && totalistic==1); /*no glider bufs for tcode in TFO-mode*/
        else load_glider_buf(
                no_glider_rules[value_range][(signed int)nhoodm[0]]);
        
	moveto(vgax(50),tempy1);
	show_w_ry=gety;

 show_w_r:
        if (tot_only==0){	  
	   /*allocate basin levels radii*/
	   /*decreace as log2 radius circles up to lastlevel, then constant*/
	   lastlevel=90;
           trans_shrink_fact=1; /*to shrink of lengthen log2 radius circles thus trans*/
	   if ((rad=(float*)calloc(lastlevel+1,sizeof(float)))
				  ==NULL) outof_memory("rad");
        }
        basin_postScript=0; /*for basin postScript file */

        /*cant have range of size for 2d or 3d array*/
        mutant_layout=0; /*disable mutants on one screen*/
	if (!loc_twod_fonly) show_w_r_scheme();
	memory_box(1,NULL);
	secondpart=1;
	if (is[0]=='q'){	  
           if (tot_only==0) free(rad);
	   if (rulemix){
	      if (tot_only==0) free_mem_rulemix();
	      free_mem_tcodemix();
	      memory_box(1,NULL);
              
	   }
           if (outer_tot==1){
              temp_lineL=lineL;
              temp_L=L;
              lineL=value_range;
              L=value_range-1;
              free_mem_tcodemix();
              lineL= temp_lineL;
              L=temp_L;
              outer_tot=0;
           }
	   rules_set=0;
	   moveto(vgax(50),selectry);
	   secondpart=0;
	   goto selectrule;
	}
	toggle_single_field=0;
	branch_y=gety;
        dontcompress=0;
	if (regular2d) dontcompress=1;//regular2d change default to uncompressed
 
/*** stay with single basin, or branch to basin of attraction field ***/	
 branch:
        start_edge_color=lightred; /*edge start color in basins*/
        if (scale>=6){ 
            node_tight=0; /*allows divs in bit/value pattern*/
            node_dots=1; /*put a dot on zero cell -- only useful for 2d nodes*/
        }          
        else{
            node_tight=1; /*no divs*/
            node_dots=0;  /*no dots*/
        }
        if (threed){
            b_i2d=i3d;
	    b_j2d=j3d*h3d;
        }
        else if (twod){
	    b_i2d=i2d;
            b_j2d=j2d; 
        }   
        else if (oned){
	    set_i2dxj2d();
            if (i2d==0){
               i2d=lineL;
               j2d=1;
            }
            b_i2d=i2d;
            b_j2d=j2d;
        }   

	if (twod || threed) rangeL=0; 
	moveto(vgax(50),branch_y);
	if (toggle_single_field==1){
	   moveto(xtext*CWidth,vgay(275));
	   basinfield=abs(basinfield-1); /*toggle single/field*/
	   toggle_single_field=0;
	   acceptall=0;
	}
	was_changed=0;
	jump_graph=0;
        screensavedemo=0;
	
	show_maj=-1; /*to show/count states with majority of 1s or 0s*/ 
	if (basinfield){
	   TFO_SEED_FIELD=3;
           draw_bottom_title(0);
	   direction='f';
	   goto main200;
	}
        else if (TFO_SEED_FIELD!=0){
	   if (tot_only==0) TFO_SEED_FIELD=2;
           draw_bottom_title(0);
        }
	seed_y=gety;
 main50:
        /*for rules (rnd or sym) */
        /*if (value_range==2) bias_density_seed=50;
	  else bias_density_seed=100*(((float)value_range-1)/value_range);*/
                                 /*all values equal prob*/
        mutant_layout=0; /*disable mutants on one screen*/
        diff_plot=0; /*otherwise shows line dividing seed*/
        NULLboundaries=0; /*NULL boundaries disabled*/
        while(event_ready()==0) break; /*to stop Mac selecting seed twice??*/

	select_seed(0,bitseed,"SEED",1);
	if (is[0]=='q'){
           NULLboundaries=0; /*NULL boundaries disabled*/
	   moveto(vgax(50),show_w_ry);
           secondpart=0;
	   goto show_w_r;
	}

	memmove(state1,bitseed,bytesL);
	rangebytesL=bytesL;
        
 main60:
	select_pattern_scrolling();
	if (is[0]=='q'){
           moveto(vgax(50),seed_y);
           direction=0;
           basin_postScript=0;
           seq_update=0;
	   goto main50;
	}        
	if (tot_only==0 || (!loc_twod_fonly && !forward_only)){
	   /*prompts for scale and position*/
	   /*draw log2 radius circles - store radii in rad[]*/
	   setup_plot();
	   if (is[0]=='q') goto main60;
	
	   format_draw();  /*sets various basin draw options*/
	   if (is[0]=='q'){
	      pdata=0;
	      goto main60;
	   }
	   data_att();  /*sets various basin draw options including pauses*/
	   if (is[0]=='q'){
	      pdata=0;
	      goto main60;
	   }

           postScript_basin(); /*set postScript printing for basin*/
           if (is[0]=='q') goto main60;

	   /*set istr-graph for single basin or bubtree*/
           if (tot_only==0 && rangeL==0) jumpgraph_basinfield(); 
           if (is[0]=='q') goto main60;

         
	   set_mutation(); /*sets various mutation options*/
	   if (is[0]=='q') goto main60;
	}
 main90:
	totalgofE=totalprecount=0;
        /*fprintf(stderr,"\n >forward_only_para();");*/
	if (tot_only==1 || loc_twod_fonly || forward_only)
               forward_only_para(); /*space-time patterns options*/

	else select_foreward_back();
        if (tot_only==1 && is[0]=='q'){
           moveto(vgax(50),seed_y);
           goto main50;
        }
	if (direction=='b') select_stepforward();
	if (is[0]=='q') goto main60;
	setviewport(0,0,Maxx,Maxy,0);
	if (!neutral_order) clearviewport();

        firstox=ox;
	firstoy=oy;	

	mut=startmut+1;
	if (mut==0) mut=1;
	if (gd_z_graph){
	   /*rectangle to contain basins*/
	   if (stp) rectangle(lineL*scale+vgax(11),vgay(45),Maxx-2,vgay(158));
	   else  rectangle(2,vgay(45),Maxx-2,vgay(158));
	   scale=1;
	   gofE_z_graph();
	   if (mutate==5) allocate_code_mem();
	}
	if (screensavedemo==1){
	   //setfillstyle(SOLID_FILL,darkgray);
	   setfillstyle(SOLID_FILL,black);
	   bar(0,0,Maxx,Maxy);	   
	   /*  demorad= is now in drparaXX.c*/	   
	   moveto(ox,oy);
           setcolor(white);
	   setfillstyle(SOLID_FILL,black);
	   pieslice(1,ox,oy,0,360,demorad); /*draw an empty circle*/	
	}
        /*remember seed at start size */
        if (gd_z_graph==3){
           if ((rangeseed=(char*)calloc(rangebytesL,sizeof(char)))
				      ==NULL) outof_memory("rangeseed");
           memmove(rangeseed,bitseed,rangebytesL);
        }
        basintypeno=1; /*will be shown in file of states*/

/*------------------------------------------------------------------------*/
startbasin: /*drawing single basins/subtrees*/
        
        if (mutantdontpause==1 && is[0]=='q'){
           /*close the postScript file -- for DOS to work*/
           if (basin_postScript) close(fid_PS);
	   finish_options(1);
        }

        if (filedata || filestates){ /*old single basins/subtree data deleted*/
          signed int fid;
           fid=myopen(filename_data,1,0);
           vret=write(fid, "",0);
           if (vret==0) fprintf(stderr,"\n write=%d",vret);
           close(fid);
        }
       
        if (basin_postScript) prepare_basinPS(1,1); /*for interactive state transition graph
                                                      istg-graph*/	        

	if (limitcheck>0 || direction=='b') /*show onthefly prompts*/
	                         back_onthefly_prompts();
	
	in_startbasin=1;
	isexception=0;
	if (see_ppstack){
	   ppL=pp_ymax=pp_wild_tot=0;
           pp_histcount=0;
	   for (zu=lineL-1;zu!=Maxu;zu--) pp_hist_total[zu]=0;
	}
	if (see_ppstack==1 && nonlocal){
	   sprintf(textb[0],"partial pre-image histogram: start pause-p");
	   draw_prompt_box(1);
	   outtext(textb[0]);
	}

	/* range of single basins or trees for increasing CA size*/
        
        if (printstates) fprintf(stderr,"\n"); /*to start on new line when showing states*/

	if (rangeL) draw_range_single();
        else if (mutant_layout==1)  mutant_one_screen_single();
	else{   /*just stp, or single basins or trees - one size only*/
	   memmove(state1,bitseed,bytesL);
           memmove(this_firstseed,state1,bytesL);
	   /*draw single basin of attraction*/
	   if (direction=='f'){
	      bitflipcount=0;
	      totatt_states=0;
              secondpart=2;
	      if (tot_only==0) run_forward(carule);
              else{
		 if (totalistic==1) run_forward(cacode);
                 else if (totalistic==2) run_forward(v_code);
	      }
              secondpart=1;
	   }
	   /*if backward, upstream only, draw trees*/
	   else upstream_only();

           if (basin_postScript) close(fid_PS);/*close the postScript file -- for DOS to work*/

	   memory_box(1,NULL);
	   if (gd_z_graph){
	      graphspot=ceil((double)lx/275);
              
              if (gd_z_graph==3){ /*G-density -  range of net size*/
                 if (direction=='b') 
                     moveto(gox+lx*(lineL-startL)/(totalgraphrules-1),
				  goy-(signed int)(ly*totsubgofEdensity));
	         if (direction=='f') 
                     moveto(gox+lx*(lineL-startL)/(totalgraphrules-1),
			   goy-(signed int)(ly*basingofEdensity));
	         circle(getx,gety,graphspot);
                 if (lineL-startL>0){
                    tempcolor=getcolor();
                    setcolor(lightred);
                    line(old_gd_x,old_gd_y,getx,gety);
                    setcolor(tempcolor);
                 }
                 old_gd_x=getx;
                 old_gd_y=gety;
              }
	      else{ /*plot Z parameter*/
	         if (direction=='b') moveto(gox+lx*zparam[0],
				  goy-(signed int)(ly*totsubgofEdensity));
	         if (direction=='f') moveto(gox+lx*zparam[0],
			   goy-(signed int)(ly*basingofEdensity));
	         circle(getx,gety,graphspot);
	         if (gd_z_graph==2){
		    /*plot lambda ratio*/
		    if (direction=='b') moveto(gox-300+lx*lratio,
				  goy-(signed int)(ly*totsubgofEdensity));
		    if (direction=='f') moveto(gox-300+lx*lratio,
			          goy-(signed int)(ly*basingofEdensity));
		    circle(getx,gety,graphspot);
                 }
	      }
	   }
	   if (pre_fansize_freq_hist){
	      show_pre_fansize_freq_hist();
	      /*reset in-degree histogram to zero*/
	      free(pre_fan_freq);
	      sprintf(textb[0],"pre_fan_freq");
	      if ((pre_fan_freq=(unsigned long *)
	      calloc(maxinhist+1,sizeof(unsigned long)))
				  ==NULL) outof_memory(textb[0]);
	   }
	   if ((mutantdontpause==0 && screensavedemo==0) || is[0]=='q'){
                /*close the postScript file -- for DOS to work*/
                if (basin_postScript) close(fid_PS);
		finish_options(1);
           }
	}

        if (toggle_single_field==1) goto endbasin;
	if (gd_z_graph){
           if (endcount==totalgraphrules-1){
                signed int tempx2,tempy2,thisposs;
                 tempx2=getx;
                 tempy2=gety;           
                 sprintf(textb[0]," quit-q rule-r mut-(def) keep+k:");
                 moveto(Maxx-25*CWidth, vgax(1));
		 draw_box(-1,getx,gety,Maxx-vgax(1),gety+CHeight+vgay(1),1,0);
		 moverel(-vgax(2),-vgay(1));
                 outtext(textb[0]);
                 input_string(2,0);

                 /*keep/delete old graph*/
                 if (is[0]!='k' && is[1]!='k'){ 
                    setfillstyle(SOLID_FILL,black);/*clear patch for graph*/
                    bar(Maxx/2,Maxy/3,Maxx-2,Maxy-vgay(30));
                    gofE_z_graph();
                 }
                 if (is[0]=='r'){ /*revise rule*/
                    thisposs=0; 
		    revise_rule_or_code(thisposs);
		    show_rule_bottom(nhoodm[thisposs],
				       0,carule[thisposs],thisposs);
		    was_changed=1;
		 }
                 else if (is[0]=='q'){ 
                    mutantdontpause=0;
                    bar(2,vgay(45),Maxx-2,vgay(158));
                 }                 
                 moveto(tempx2,tempy2);
           }

           if (gd_z_graph<=2){
	      /*delete-restore rectangle to contain basins*/
	      setfillstyle(SOLID_FILL,black);
	      if (stp){
	         bar(2,vgay(45),Maxx-2,vgay(158));
	         bar3d(lineL*scale+vgax(11),vgay(45),Maxx-2,vgay(158),0,0);
	      }
	      else  bar3d(2,vgay(45),Maxx-2,vgay(158),0,0);
           }
	}
	else if (screensavedemo==1 && is[0]!='q'){
	   firstox=rand()%Maxx;
	   firstoy=rand()%Maxy;
	   setfillstyle(SOLID_FILL,black);
           setcolor(white);
	   setfillstyle(SOLID_FILL,black);
	   pieslice(1,firstox,firstoy,0,360,demorad);	

	   /*set new random seed*/
	   for (zu=L;zu!=Maxu;zu--) set_bit(bitseed,zu,((myrand()%100)/50));
	}
	else{
           /*pause to see*/
           if (mutantdontpause==1 && gd_z_graph==0){
#             if __WATCOM__
                 delay(defCursorFlash*5*pause_fact);
#             elif __UNIX__
                 delay_and_continue(pause_fact);
#             endif
	      if (mutantdontpause==0){
                 if (basin_postScript) close(fid_PS);
		 finish_options(1);
              }
	   }
           clearviewport();
        }
	/*mutate or change rule table*/
	if ((is[0]==13 || mutantdontpause==1) && is[0]!='q'){
	   /*space-time patterns only - dont mutate*/
	   if (direction=='f' && limitcheck==0) goto startbasin;
	   fieldno=0;
	   if (was_changed==0){
	      if (mutate<=1) mut-=1;
	      if (mut==endmut-1) mut=startmut;
	   }
	   if (gd_z_graph){
	      endcount+=1;
              if (gd_z_graph==3){ /*increace size by +1*/
		 if (endcount<=totalgraphrules){
                    free_mem_CA_states();
                    lineL+=1;
                    L+=1;
                    bytesL=(signed int)ceil(value_bits *(double)lineL/8);
                    wire_rule_extra_cell((char)1);
                    allocate_mem_CA_states();
                    memmove(bitseed,rangeseed,rangebytesL);
                    xspacing*=xspacefact;
	            yspacing*=yspacefact;
	            /*move position of next basin to the right*/
	            ox+=xspacing;
	            /*if too close to right edge of screen, start new row*/
	            if ((Maxx-ox)<(signed int)((float)xspacing*rightborder)){
	               ox=firstox;
	               oy+=yspacing;
	            }
                 }
              }
	      else biased_new_rule();
	   }
           if (gd_z_graph==3){
              if (endcount<totalgraphrules) goto startbasin;
              else{
                 change_net_size(startL);
                 memmove(bitseed,rangeseed,rangebytesL);
                 ox=firstox;
                 oy=firstoy;
                 xspacing=startxspacing;
                 yspacing=startyspacing;
                 endcount=0;
                 /*delete-restore rectangle to contain basins*/
	         setfillstyle(SOLID_FILL,black);
	         if (stp){
	            bar(2,vgay(45),Maxx-2,vgay(158));
	            bar3d(lineL*scale+vgax(11),vgay(45),Maxx-2,vgay(158),0,0);
	         }
	         else  bar3d(2,vgay(45),Maxx-2,vgay(158),0,0);
              }
           }
	   if (mutate_rule(nhood)){
               goto startbasin;
           }
	   else acceptall=0;
	}
 endbasin:
	draw_bottom_title(0);
	if (stp){
	   moveto(0,0);
	   if (nowscrolling==1){
#             if __WATCOM__
	         freeimage(stpimage);
#             endif	       
	      nowscrolling=0;
	   }
	}
	if (gd_z_graph){
	   if (!rulemix && (mutate==4 || mutate==5)){
                /*close the postScript file -- for DOS to work*/
                if (basin_postScript) close(fid_PS); 
                finish_options(1);
           }
           
	   /*delete basin rectangle*/
	   bar(2,vgay(45),Maxx-2,vgay(158));
	   endcount=0;
	   if (mutate==5){
	      free(codetickoff);
	      free(tempcode);
	   }
	}
	
	in_startbasin=0;
	if (toggle_single_field==1) goto branch;
	else if (acceptall==0 || loc_twod_fonly) goto main60;
	else goto main90;

/* * * * * * * * * * * * basin field * * * * * * * * * * */
 main200:
        use_preset_basin_pos=0;
	
	select_pattern_scrolling();
	if (is[0]=='q'){
	   moveto(vgax(50),show_w_ry);
           secondpart=0;
           direction=0;
           basin_postScript=0;
           seq_update=0;
	   goto show_w_r;
	}
	/*set layout*/
        /*draw log2 radius circles - store radii in rad[]*/
	setup_plot();	
	memory_box(1,NULL);
	if (is[0]=='q') goto main200;

	format_draw();  /*sets various basin draw options*/
	if (is[0]=='q') goto main200;
	
        data_att();  /*sets various basin draw options*/
	if (is[0]=='q'){
	      pdata=0;
	      goto main200;
	}
       
        postScript_basin(); /*set postScript printing for basin*/
        if (is[0]=='q') goto main200;

        if (basinfield){
	   /*set jump-graph, ibaf-graph, ibaf-graph or ibaf-graph for basinfield*/
           if (tot_only==0 && rangeL==0) jumpgraph_basinfield(); 
           if (is[0]=='q') goto main200;
        }
        
	set_mutation(); /*sets various mutation options*/
	if (is[0]=='q') goto main200;

	see_ppstack=0;
        exhaustive_testing=0;
        Ham_bias=0;
	//-----------------------------------------------------------
	/*sprintf(textb[3],"%s","");
        
        if (oned){
           if (nonlocal==0) sprintf(textb[4],"nonlocal-x ");
           else sprintf(textb[4],"local-x ");
        }
        else sprintf(textb[4],"");

        neutral_order=0;
        //nto-o = neutral order components
        if (basinfield && lineL<=12 && value_range==2){
	  if (NULLboundaries || rangeL) sprintf(textb[3],
                                 "%sexh-e rmap-r",textb[4]); 
	   else sprintf(textb[3],"%sexh-e rmap-r seq-s nto-o",textb[4]);
        }
	else if (lineL<=max_exh_lu){
           if (NULLboundaries || rangeL) sprintf(textb[3],
                                 "%sexh-e rmap-r",textb[4]);
	   else sprintf(textb[3],"%sexh-e rmap-r seq-s",textb[4]);
        }
        else sprintf(textb[3],"%s",textb[4]);

	if (nonlocal){
           sprintf(textb[2],"(nonlocal)");
           if (reorderRBN==1)
	    sprintf(textb[1],
               "view ppstack-1 +pause-2, reorder(on) tog +R:");
           else if (reorderRBN==0)
	    sprintf(textb[1],
               "view ppstack-1, +pause-2, reorder(off) tog +R:");
	}
	else{
	   sprintf(textb[2],"(local)");
	   sprintf(textb[1],"view ppstack-1:");
	}
	if (rangeL) sprintf(textb[0],"basin field %s n=%d-%d, %s",
			       textb[2],startL,endL,textb[3]);
	else sprintf(textb[0],"basin field %s n=%d, %s",
			       textb[2],lineL,textb[3]);

	xbox=draw_prompt_box(2);
	outtext(textb[0]);
	moveto(xbox,gety+CHeight);
	outtext(textb[1]);*/
        //----------------------------prompts rearanged----------------
	neutral_order=0;
        xbox=draw_prompt_box(2);
	if (nonlocal) sprintf(textb[2],"(nonlocal)");
	else sprintf(textb[2],"(local)");
        if (rangeL) sprintf(textb[0],"basin field %s n=%d-%d, ",textb[2],startL,endL);
	else sprintf(textb[0],"basin field %s n=%d, ",textb[2],lineL);
	outtext(textb[0]);
	if (oned){
           if (nonlocal==0) sprintf(textb[4],"nonlocal-x ");
           else sprintf(textb[4],"local-x ");
        }
        else sprintf(textb[4],"");
	outtext(textb[4]);
        if (ibaf_graph==1){
	   setcolor(yellow);		
	   outtext("ibaf: exh-e ");
	   setcolor(white);
	}
        else outtext("exh-e ");
        if (ibaf_graph==1){
	    setcolor(yellow);	
	   /* nto-o = neutral order components*/
           if (basinfield && lineL<=12 && value_range==2){
	      if (NULLboundaries || rangeL) outtext("rmap-r"); 
	      else outtext("rmap-r seq-s");
	      //setcolor(white);
	      //outtext(" nto-o");
	      //neutral order components don't work for the (ibaf_graph	       
           }
	   else if (lineL<=max_exh_lu){
	      if (NULLboundaries || rangeL) outtext("rmap-r");
	      else outtext("rmap-r seq-s");
           }
	   setcolor(white);
	}    	
	else{
           /* nto-o = neutral order components*/
           if (basinfield && lineL<=12 && value_range==2
	                      && istr_graph==0 && ibaf_graph==0){
	      if (NULLboundaries || rangeL) outtext("rmap-r"); 
	      else outtext("rmap-r seq-s nto-o");	    
           }
	   else if (lineL<=max_exh_lu){
	      if (NULLboundaries || rangeL) outtext("rmap-r");
	      else outtext("rmap-r seq-s");
           }
        }

	
	moveto(xbox,gety+CHeight);	
	if (nonlocal){
	   if (reorderRBN==1) outtext("view ppstack-1 +pause-2, reorder(on) tog +R:");
           else if (reorderRBN==0) outtext("view ppstack-1, +pause-2, reorder(off) tog +R:");
	}
        else outtext("view ppstack-1:");
	//--------------------------------------------
	input_string(2,0);
	if (is[0]=='q'){
	   erase_prompt_box(2);
	   pdata=0;
	   goto main200;
	}
        seq_update=0;
	if (is[0]=='1') see_ppstack=1;
	if (is[0]=='2') see_ppstack=2;
        if (((is[0]=='1' || is[0]=='2') && is[1]=='R') || is[0]=='R'){
           if (reorderRBN==1) reorderRBN=0;
           else if (reorderRBN==0) reorderRBN=1;
        }
        if (is[0]=='x' /*&& rulemix==0*/ && oned){
	    if (nonlocal==0) nonlocal=1;
            else if (nonlocal==1){
              unsigned int poss;            
               for (poss=0;poss<=lineL-1;poss++)
                     oneD_local_wire_cell(poss,lineL-1);
               nonlocal=0;
           }
        }                 
	else if (lineL<=max_exh_lu){ /*max_exh_lu depends on value_range*/
	   if (is[0]=='e' || is[0]=='s') exhaustive_testing=1;
	   else if (is[0]=='o' && NULLboundaries==0 && basinfield 
                        && lineL<=12 && value_range==2
		        && istr_graph==0 && ibaf_graph==0){
              neutral_order=1;
              jump_graph=0;
           }
	   else if (is[0]=='r') exhaustive_testing=2;          
           if (is[0]=='s' && NULLboundaries==0 && rangeL==0){
              erase_prompt_box(2);
              set_seq_update();
              if (is[0]=='q') goto main200;
           } 	              
	}
	clearviewport();

	firstox=ox;
	firstoy=oy;	
	firstxspacing=xspacing;
	firstyspacing=yspacing;

        fieldno=0;
	mut=startmut+1;
	if (mut==0) mut=1;
	if (gd_z_graph){
	   /*rectangle to contain basins*/
	   scale=1;
	   if (stp) rectangle(lineL*scale+vgax(11),vgay(45),Maxx-2,vgay(158));
	   else  rectangle(2,vgay(45),Maxx-2,vgay(158));
	   gofE_z_graph();
	   if (mutate==5) allocate_code_mem();
	   endcount=0;
	}

/*-------------------------------------------------------------------------*/
startfield: /*basin of attraction fields*/
        if (filedata || filestates){ /*old field data deleted*/ 
          signed int fid;
           fid=myopen(filename_data,1,0);
           vret=write(fid, "",0);
           if (vret==0) fprintf(stderr,"\n write=%d",vret);
           close(fid);
        }

        if (basin_postScript) prepare_basinPS(1,1); /*to create a postScript file*/

        back_onthefly_prompts();/*show onthefly prompts*/
        
	in_startfield=1;
	isexception=0;
	
	if (see_ppstack){
	   ppL=pp_ymax=pp_wild_tot=0;
           pp_histcount=0;
	   for (zu=lineL-1;zu!=Maxu;zu--) pp_hist_total[zu]=0;
	}
	if (see_ppstack==1 && nonlocal){
	   sprintf(textb[0],"partial pre-image histogram: start pause-p");
	   draw_prompt_box(1);
	   outtext(textb[0]);
	}
        if (printstates) fprintf(stderr,"\n"); /*to start on new line when showing states*/

	if (rangeL) draw_range_field();
	else{
           totatt_states=0;
	   draw_field(); /*draw basin of attraction field*/
	   if (gd_z_graph){
	      graphspot=ceil((double)lx/250);
              if (gd_z_graph==3 && earlyexitfield==0){
                 /*plot range of size*/
                 moveto(gox+lx*(lineL-startL)/(totalgraphrules-1),
				goy-(signed int)(ly*fieldgofEdensity));
	         circle(getx,gety,graphspot);
                 if (lineL-startL>0){
                    tempcolor=getcolor();
                    setcolor(lightred);
                    line(old_gd_x,old_gd_y,getx,gety);
                    setcolor(tempcolor);
                 }
                 old_gd_x=getx;
                 old_gd_y=gety;
              }
              else if (gd_z_graph<3){
	         /*plot Z parameter*/
	         moveto(gox+lx*zparam[0],
				goy-(signed int)(ly*fieldgofEdensity));
	         circle(getx,gety,graphspot);
	         if (gd_z_graph==2){
		    /*plot lambda ratio*/
		    moveto(gox-vgax(300)+lx*lratio,
				goy-(signed int)(ly*fieldgofEdensity));
		    circle(getx,gety,graphspot);
                 }
	      }
	   }
           /*mixed rules, for Rodney Douglas - Telluride*/
           if (rulemix && filedata && lineL<=6){
              signed int z;
              save_data(" R=");
              for (z=lineL-1;z>=0;z--){
		 print_current_bitstring_hexbytes(1,1,carule[z],nhoodm[z],Maxx,white,3);
                 save_data(" ");
              }
              save_data("\n");
	   }
         
	   if (( !(exhaustive_testing && earlyexitfield)) || gd_z_graph==3)
                                 print_field_data();

	   if (pre_fansize_freq_hist){
	      show_pre_fansize_freq_hist();
	      /*reset in-degree histogram to zero*/
	      free(pre_fan_freq);
	      sprintf(textb[0],"pre_fan_freq");
	      if ((pre_fan_freq=(unsigned long *)
	         calloc(maxinhist+1,sizeof(unsigned long)))
				  ==NULL) outof_memory(textb[0]);
	   }
	   if (mutantdontpause==0 || is[0]=='q'){ 
               /*close the postScript file (otherwize done in jump_graph) -- for DOS to work*/
               if (basin_postScript && jump_graph==0) close(fid_PS);
               finish_options(1);
	   }                        
	}
	if (toggle_single_field==1) goto endfield;

	if (gd_z_graph){
	  if (endcount==totalgraphrules-1){
                signed int tempx2,tempy2,thisposs;
                 tempx2=getx;
                 tempy2=gety;
                 sprintf(textb[0]," quit-q rule-r mut-(def) keep+k:");
                 moveto(Maxx-25*CWidth, vgax(1));
		 draw_box(-1,getx,gety,Maxx-vgax(1),gety+CHeight+vgay(1),1,0);
		 moverel(-vgax(2),-vgay(1));
                 outtext(textb[0]);
                 input_string(2,0);

                 /*keep/delete old graph*/
                 if (is[0]!='k' && is[1]!='k'){ 
                    setfillstyle(SOLID_FILL,black);/*clear patch for graph*/
                    bar(Maxx/2,Maxy/3,Maxx-2,Maxy-vgay(30));
                    gofE_z_graph();
                 }
                 if (is[0]=='r'){ /*revise rule*/
                    thisposs=0; 
		    revise_rule_or_code(thisposs);
		    show_rule_bottom(nhoodm[thisposs],
				       0,carule[thisposs],thisposs);
		    was_changed=1;
		 }
                 else if (is[0]=='q'){ 
                    mutantdontpause=0;
                    bar(2,vgay(45),Maxx-2,vgay(158));
                 }
                 
                 moveto(tempx2,tempy2);
           }
	   /*delete-restore rectangle to contain basins*/
	   setfillstyle(SOLID_FILL,black);
	   if (stp){
	      bar(2,vgay(45),Maxx-2,vgay(158));
	      bar3d(lineL*scale+vgax(11),vgay(45),Maxx-2,vgay(158),0,0);
	   }
	   else  bar3d(2,vgay(45),Maxx-2,vgay(158),0,0);
	}
	else{ 
           /*pause to see*/
           if (mutantdontpause==1 && gd_z_graph==0){
#             if __WATCOM__
		 delay(defCursorFlash*5*pause_fact);
#             elif __UNIX__
                 delay_and_continue(pause_fact);
#             endif
              if (mutantdontpause==0){
                 if (basin_postScript) close(fid_PS);
		 finish_options(1);
              }              
	   }
           clearviewport();
        }

	/*mutate or change rule table*/
	if (is[0]==13 || mutantdontpause==1){
	   fieldno=0;
	   if (was_changed==0){
	      if (mutate<=1) mut-=1;
	      if (mut==endmut-1) mut=startmut;
	   }
	   if (gd_z_graph){
	      endcount+=1;
              if (gd_z_graph==3){ /*increace size by +1*/
                 if (endcount<=totalgraphrules){
                    free_mem_CA_states();
                    lineL+=1;
                    L+=1;
                    bytesL=(signed int)ceil(value_bits *(double)lineL/8);
                    allocate_mem_CA_states();
                    wire_rule_extra_cell((char)1);
                    ox=firstox;
                    oy=firstoy;
                 }
              }
	      else biased_new_rule();
	   }
           if (gd_z_graph==3){
              if (endcount<totalgraphrules) goto startfield;
              else{
                 change_net_size(startL);
                 ox=firstox;
                 oy=firstoy;
                 endcount=0;
              }              
              if (mutate_rule(nhood)) goto startfield;           
           }
	   if (mutate_rule(nhood)) goto startfield;           
	   else acceptall=0;
	}
 endfield:
	draw_bottom_title(0);
	if (gd_z_graph){
	   if (!rulemix && (mutate==4 || mutate==5)){
               /*close the postScript file (otherwise done in jump_graph) -- for DOS to work*/
               if (basin_postScript && jump_graph==0) close(fid_PS);
               finish_options(1);
           }
	   /*delete basin rectangle*/
	   bar(2,vgay(45),Maxx-2,vgay(158));
	   endcount=0;
	   if (mutate==5){
	      free(codetickoff);
	      free(tempcode);
	   }
	}
        /*restore original position for field, basin or subtree*/
        if (gd_z_graph==3){ 
            ox=firstox;
            oy=firstoy;
        }         
	in_startfield=0;
	if (toggle_single_field==1) goto branch;
	moveto(vgax(50),vgay(100));
	goto main200;
}

/*************** delay required in float seconds March 2012 ****************/ 
void delay_and_continue(float delay_required){    
     
# if __WATCOM__
     delay((unsigned long)(delay_required*1000000));
# elif __UNIX__ 
  
  unsigned long starttime,starttime_m,
                endtime,endtime_m;
  long  elapsedtime_m;
  unsigned long  elapsedtime;
  struct timeval  tp;
  struct timezone tzp;


  float timesec=0;
  signed int timemin=0; 
        
   gettimeofday(&tp,&tzp);
   starttime=(unsigned long)tp.tv_sec; //seconds
   starttime_m=(unsigned long)tp.tv_usec;//micro-sec 1/million
   /*fprintf(stderr,"\n%lu:starttime=%lu",
	           last_flash,starttime*1000000 + starttime_m);*/

   
   while (1){
             if (event_ready()){
	       if (is[0]=='q'){ 
                   mutantdontpause=0;
                   is[0]=0;
                   break;
               }
             }  
              
             gettimeofday(&tp,&tzp);
             endtime=(unsigned long)tp.tv_sec; //seconds
             endtime_m=(unsigned long)tp.tv_usec;//micro-sec 1/million
 
             usleep(1);     /*this makes cpu=0*/		
             
             gettimeofday(&tp,&tzp);
             endtime=(unsigned long)tp.tv_sec; //seconds
             endtime_m=(unsigned long)tp.tv_usec; //micro-sec 1/million
               /*fprintf(stderr,"\n    endtime=%lu",
		         endtime*1000000 + endtime_m);*/
               
             elapsedtime=endtime-starttime;
             elapsedtime_m=endtime_m-starttime_m; 
    
             if (elapsedtime_m<0){ 
                  elapsedtime-=1;
                  elapsedtime_m=(1000000-starttime_m)+endtime_m;
             }
               timesec=(float)
                 ((elapsedtime%60)+((float)elapsedtime_m/1000000));
     
               if (timesec >= delay_required) break;

               /*else fprintf(stderr,"\n%fsec",timesec);*/
               /*automatically adjust flash to about .5sec*/
               //kCursorFlash*=.5/(timemin*60 + timesec);
    }
#   endif
}

/*********** how many bits required for value_range, Sept 2002 **************/
signed int check_value_bits(signed int vr){
  signed int vb;
     if (vr==2) vb=1;
     else if (vr<=4) vb=2; /* 3 or 4 */
     else if (vr<=8) vb=3; /* 5 to 8 */
     else if (vr<=16) vb=4; /* 9 to 16 */
     else if (vr<=32) vb=5; /* 17 to 32 */
     else vb=0;
     return(vb);
}

/********** set up color order for nhd colors June2020 ********/
void set_color_order_nhd(char shuffle){
  unsigned char *tick_used;
  signed int z,temprnd;

  if ((tick_used=(unsigned char*)calloc(2,sizeof(unsigned char)))
			    ==NULL) outof_memory("tick_used");

  if ((nhd_color_order=(unsigned char*)calloc(16,sizeof(unsigned char)))
			    ==NULL) outof_memory("nhd_color_order");
  if (shuffle==0){
     for (z=0;z<=15;z++) nhd_color_order[z]=z;
  }
  else{/*shuffle nhd colors except white and black*/
     set_bit(tick_used,0,1);
     set_bit(tick_used,15,1);
     //fprintf(stderr,"\nshuffle order=",temprnd);
     for (z=1;z<=14;z++){ /*fill nhd_color_order[z] with random non repeating values 1- 14*/
        rerand:
         temprnd=myrand()%(16);
         if (get_bit(tick_used,temprnd)==0){ 
               nhd_color_order[z]=temprnd;
               set_bit(tick_used,temprnd,1);
               //fprintf(stderr,"%d ",temprnd);
         } 
         else goto rerand;
     }
  }
  free(tick_used);
}

/********** set up value range colors ********/
void rearange_value_colors(void){
     unsigned char *temp_color_v;
     signed int *shuffle_no,z;

      if ((temp_color_v=(unsigned char*)calloc(value_range,sizeof(unsigned char)))
			    ==NULL) outof_memory("temp_color_v");     
      if ((shuffle_no=(signed int*)calloc(value_range,sizeof(signed int)))
			    ==NULL) outof_memory("shuffle_no");

      for (z=0;z<=value_range-1;z++) shuffle_no[z]=z;      
      shuffle_order(shuffle_no,value_range);
      
      /*keep color at color-index 0 as 0*/
      /*if (shuffle_no[0]!=0){
	unsigned char temp0,color_other;
         for(z=0;z<=value_range-1;z++){
	    if (shuffle_no[z]==0) temp0=z;
            color_other=shuffle_no[0];
         }
         shuffle_no[0]=0;
         shuffle_no[temp0]=color_other;
      }*/

      for (z=0;z<=value_range-1;z++)
		temp_color_v[shuffle_no[z]]=color_v[z];
      memmove(color_v,temp_color_v,value_range);
      b_value=color_v[b_value]; /* for absorbent border */
      free(temp_color_v);
      free(shuffle_no);
}

/********** set up colors for postScript files.Dec 2007 ********/
void setup_postScripr_colors(char first_time){

    /*postScript color and greyscale buffers*/
 
    if (first_time==1){
      signed int z;
       if ((dcolor=(char**)calloc(53,sizeof(char*)))
				  ==NULL) outof_memory("dcolor");
       for (z=0;z<=52;z++){ /*to contain the RGB string*/
          sprintf(textb[0],"dcolor[%d]",z);
          if ((dcolor[z]=(char *)calloc(15,sizeof(char)))
				   ==NULL) outof_memory(textb[0]);
       }

       /*grayscale colors  Y = 0.3*R + 0.59*G + 0.11*B*/
       if ((grayscale=(float*)calloc(53,sizeof(float)))
				  ==NULL) outof_memory("grayscale");
    
    }

#if __UNIX__                                                                   
    if (bground=='w'){  
       sprintf(dcolor[oldcolor[0]],"1 1 1");          /*black*/
       sprintf(dcolor[oldcolor[1]],"1 .843 0");       /*blue*/   
       sprintf(dcolor[oldcolor[2]],".235 .702 .443"); /*green*/
       sprintf(dcolor[oldcolor[3]],".647 .165 .165"); /*lightcyan*/ 
       sprintf(dcolor[oldcolor[4]],"1 0 0");          /*lightred*/
       sprintf(dcolor[oldcolor[5]],".816 .125 .565"); /*magenta*/
       sprintf(dcolor[oldcolor[6]],"0 .392 0");       /*brown*/
       sprintf(dcolor[oldcolor[7]],"0 .808 .820");    /*lightgray*/
       sprintf(dcolor[oldcolor[8]],".596 .984 .596"); /*darkgray*/ 
       sprintf(dcolor[oldcolor[9]],".392 .584 .929"); /*lightblue*/
       sprintf(dcolor[oldcolor[10]],".196 .804 .196");/*lightgreen*/
       sprintf(dcolor[oldcolor[11]],".42 .557 .137"); /*cyan*/    
       sprintf(dcolor[oldcolor[12]],".804 .361 .361");/*red*/      
       /*sprintf(dcolor[oldcolor[13]],".816 .125 .565");*/ /*lightmagenta*/
       sprintf(dcolor[oldcolor[13]],"1.0 .647 0"); /*lightmagenta changed to orange*/
       sprintf(dcolor[oldcolor[14]],"0 0 1");         /*yellow*/
       sprintf(dcolor[oldcolor[15]],"0 0 0");         /*white*/ 

       /*black*/    grayscale[oldcolor[0]]=1;
       /*blue*/     grayscale[oldcolor[1]]=0.3*1 + 0.59*.843 + 0.11*0;     
       /*green*/    grayscale[oldcolor[2]]=0.3*.235 + 0.59*.702 + 0.11*.443;
       /*lightcyan*/grayscale[oldcolor[3]]=0.3*.647 + 0.59*.165 + 0.11*.165; 
       /*lightred*/ grayscale[oldcolor[4]]=0.3*1 + 0.59*0 + 0.11*0;
       /*magenta*/  grayscale[oldcolor[5]]=0.3*.816 + 0.59*.125 + 0.11*.565;
       /*brown*/    grayscale[oldcolor[6]]=0.3*0 + 0.59*.392 + 0.11*0;
       /*lightgray*/grayscale[oldcolor[7]]=0.3*0 + 0.59*.808 + 0.11*.820; 
       /*darkgray*/ grayscale[oldcolor[8]]=0.3*596 + 0.59*.984 + 0.11*.596; 
       /*lightblue*/grayscale[oldcolor[9]]=0.3*.392 + 0.59*.584 + 0.11*.929; 
       /*lightgreen*/grayscale[oldcolor[10]]=0.3*.196 + 0.59*.804 + 0.11*.196; 
       /*cyan*/     grayscale[oldcolor[11]]=0.3*.42 + 0.59*.557 + 0.11*.137;
       /*red*/      grayscale[oldcolor[12]]=0.3*.804 + 0.59*.361 + 0.11*.361;
       /*lightmagenta*/ /*grayscale[oldcolor[13]]=0.3*.816 + 0.59*.125 + 0.11*.565;*/
       /*lightmagenta*/ grayscale[oldcolor[13]]=0.3*1 + 0.59*.647 + 0.11*0; /*changed to orange*/
       /*yellow*/   grayscale[oldcolor[14]]=0.3*0 + 0.59*0 + 0.11*1;
       /*white*/    grayscale[oldcolor[15]]=0;
   }
   else if (bground=='b'){
       sprintf(dcolor[oldcolor[0]],"1 1 1");          /*black*/
       sprintf(dcolor[oldcolor[1]],"1 1 0");          /*blue*/
       sprintf(dcolor[oldcolor[2]],".678 1 .184");    /*green*/
       sprintf(dcolor[oldcolor[3]],"0 1 1");          /*lightcyan*/
       sprintf(dcolor[oldcolor[4]],"1 .271 0");       /*lightred*/
       sprintf(dcolor[oldcolor[5]],".816 .125 .565"); /*magenta*/
       sprintf(dcolor[oldcolor[6]],".627 .322 .176"); /*brown*/
       sprintf(dcolor[oldcolor[7]],".690 .769 .871"); /*lightgray*/
       sprintf(dcolor[oldcolor[8]],"0 .392 0");       /*darkgray*/
       sprintf(dcolor[oldcolor[9]],".392 .584 .929"); /*lightblue*/ 
       sprintf(dcolor[oldcolor[10]],"0 1 0");         /*lightgreen*/
       sprintf(dcolor[oldcolor[11]],"0 .808 .820");   /*cyan*/
       sprintf(dcolor[oldcolor[12]],".980 .502 .447");/*red*/
       sprintf(dcolor[oldcolor[13]],".1 .753 .796");  /*lightmagenta*/
       sprintf(dcolor[oldcolor[14]],"0 0 1");         /*yellow*/
       sprintf(dcolor[oldcolor[15]],"0 0 0");         /*white*/

       /*black*/    grayscale[oldcolor[0]]=1;
       /*blue*/     grayscale[oldcolor[1]]=0.3*1 + 0.59*1 + 0.11*0;
       /*green*/    grayscale[oldcolor[2]]=0.3*.678 + 0.59*1 + 0.11*.184;
       /*lightcyan*/grayscale[oldcolor[3]]=0.3*0 + 0.59*1 + 0.11*1;
       /*lightred*/ grayscale[oldcolor[4]]=0.3*1 + 0.59*.271 + 0.11*0;
       /*magenta*/  grayscale[oldcolor[5]]=0.3*.816 + 0.59*.125 + 0.11*.565;
       /*brown*/    grayscale[oldcolor[6]]=0.3*.627 + 0.59*.322 + 0.11*.176;
       /*lightgray*/grayscale[oldcolor[7]]=0.3*.690 + 0.59*.769 + 0.11*.871;
       /*darkgray*/ grayscale[oldcolor[8]]=0.3*0 + 0.59*.392 + 0.11*0;
       /*lightblue*/grayscale[oldcolor[9]]=0.3*.392 + 0.59*.584 + 0.11*.929; 
       /*lightgreen*/grayscale[oldcolor[10]]=0.3*0 + 0.59*1 + 0.11*0; 
       /*cyan*/     grayscale[oldcolor[11]]=0.3*0 + 0.59*.808 + 0.11*.820;
       /*red*/      grayscale[oldcolor[12]]=0.3*.980 + 0.59*.502 + 0.11*.447;
       /*lightmagenta*/grayscale[oldcolor[13]]=0.3*1 + 0.59*.753 + 0.11*.796;
       /*yellow*/   grayscale[oldcolor[14]]=0.3*0 + 0.59*0 + 0.11*1;
       /*white*/    grayscale[oldcolor[15]]=0;
       
    }
#elif __WATCOM__
    if (bground=='w'){  
       sprintf(dcolor[black],"1 1 1");                /*black*/
       sprintf(dcolor[blue],"1 .843 0");              /*blue*/ 
       sprintf(dcolor[green],".235 .702 .443");       /*green*/ 
       sprintf(dcolor[lightcyan],".647 .165 .165");   /*lightcyan*/ 
       sprintf(dcolor[lightred],"1 0 0");             /*lightred*/ 
       sprintf(dcolor[magenta],".816 .125 .565");     /*magenta*/ 
       sprintf(dcolor[brown],"0 .392 0");             /*brown*/ 
       sprintf(dcolor[lightgray],"0 .808 .820");      /*lightgray*/ 
       sprintf(dcolor[darkgray],".596 .984 .596");    /*darkgray*/
       sprintf(dcolor[lightblue],".392 .584 .929");   /*lightblue*/ 
       sprintf(dcolor[lightgreen],".196 .804 .196");  /*lightgreen*/  
       sprintf(dcolor[cyan],".42 .557 .137");         /*cyan*/  
       sprintf(dcolor[red],".804 .361 .361");         /*red*/  
       /*sprintf(dcolor[lightmagenta],".816 .125 .565");*/ /*lightmagenta*/
       sprintf(dcolor[lightmagenta],"1.0 .647 0"); /*lightmagenta changed to orange*/
       sprintf(dcolor[yellow],"0 0 1");               /*yellow*/ 
       sprintf(dcolor[white],"0 0 0");                /*white*/

       /*black*/    grayscale[black]=1;
       /*blue*/     grayscale[blue]=0.3*1 + 0.59*.843 + 0.11*0;     
       /*green*/    grayscale[green]=0.3*.235 + 0.59*.702 + 0.11*.443;
       /*lightcyan*/grayscale[lightcyan]=0.3*.647 + 0.59*.165 + 0.11*.165; 
       /*lightred*/ grayscale[lightred]=0.3*1 + 0.59*0 + 0.11*0;
       /*magenta*/  grayscale[magenta]=0.3*.816 + 0.59*.125 + 0.11*.565;
       /*brown*/    grayscale[brown]=0.3*0 + 0.59*.392 + 0.11*0;
       /*lightgray*/grayscale[lightgray]=0.3*0 + 0.59*.808 + 0.11*.820; 
       /*darkgray*/ grayscale[darkgray]=0.3*596 + 0.59*.984 + 0.11*.596; 
       /*lightblue*/grayscale[lightblue]=0.3*.392 + 0.59*.584 + 0.11*.929; 
       /*lightgreen*/grayscale[lightgreen]=0.3*.196 + 0.59*.804 + 0.11*.196; 
       /*cyan*/     grayscale[cyan]=0.3*.42 + 0.59*.557 + 0.11*.137;
       /*red*/      grayscale[red]=0.3*.804 + 0.59*.361 + 0.11*.361;
       /*lightmagenta*/ /*grayscale[lightmagenta]=0.3*.816 + 0.59*.125 + 0.11*.565;*/
       /*lightmagenta*/ grayscale[lightmagenta]=0.3*1 + 0.59*.647 + 0.11*0;/*changed to orange*/
       /*yellow*/   grayscale[yellow]=0.3*0 + 0.59*0 + 0.11*1;
       /*white*/    grayscale[white]=0;
   }
   else if (bground=='b'){
       sprintf(dcolor[black],"1 1 1");               /*black*/      
       sprintf(dcolor[blue],"1 1 0");                /*blue*/ 
       sprintf(dcolor[green],".678 1 .184");         /*green*/ 
       sprintf(dcolor[lightcyan],"0 1 1");           /*lightcyan*/
       sprintf(dcolor[lightred],"1 .271 0");         /*lightred*/ 
       sprintf(dcolor[magenta],".816 .125 .565");    /*magenta*/ 
       sprintf(dcolor[brown],".627 .322 .176");      /*brown*/ 
       sprintf(dcolor[lightgray],".690 .769 .871");  /*lightgray*/
       sprintf(dcolor[darkgray],"0 .392 0");         /*darkgray*/
       sprintf(dcolor[lightblue],".392 .584 .929");  /*lightblue*/ 
       sprintf(dcolor[lightgreen],"0 1 0");          /*lightgreen*/ 
       sprintf(dcolor[cyan],"0 .808 .820");          /*cyan*/
       sprintf(dcolor[red],".980 .502 .447");        /*red*/  
       sprintf(dcolor[lightmagenta],".1 .753 .796"); /*lightmagenta*/ 
       sprintf(dcolor[yellow],"0 0 1");              /*yellow*/ 
       sprintf(dcolor[white],"0 0 0");               /*white*/

       /*black*/    grayscale[black]=1;
       /*blue*/     grayscale[blue]=0.3*1 + 0.59*1 + 0.11*0;
       /*green*/    grayscale[green]=0.3*.678 + 0.59*1 + 0.11*.184;
       /*lightcyan*/grayscale[lightcyan]=0.3*0 + 0.59*1 + 0.11*1;
       /*lightred*/ grayscale[lightred]=0.3*1 + 0.59*.271 + 0.11*0;
       /*magenta*/  grayscale[magenta]=0.3*.816 + 0.59*.125 + 0.11*.565;
       /*brown*/    grayscale[brown]=0.3*.627 + 0.59*.322 + 0.11*.176;
       /*lightgray*/grayscale[lightgray]=0.3*.690 + 0.59*.769 + 0.11*.871;
       /*darkgray*/ grayscale[darkgray]=0.3*0 + 0.59*.392 + 0.11*0;
       /*lightblue*/grayscale[lightblue]=0.3*.392 + 0.59*.584 + 0.11*.929; 
       /*lightgreen*/grayscale[lightgreen]=0.3*0 + 0.59*1 + 0.11*0; 
       /*cyan*/     grayscale[cyan]=0.3*0 + 0.59*.808 + 0.11*.820;
       /*red*/      grayscale[red]=0.3*.980 + 0.59*.502 + 0.11*.447;
       /*lightmagenta*/grayscale[lightmagenta]=0.3*1 + 0.59*.753 + 0.11*.796;
       /*yellow*/   grayscale[yellow]=0.3*0 + 0.59*0 + 0.11*1;
       /*white*/    grayscale[white]=0;       
    }
#endif

}


/********** set up value range colors ********/
void setup_value_colors(char first_time){
     unsigned char thisblue,thisyellow;
     /*unsigned char z;*/

      if (first_time==1){
         if ((color_v=(unsigned char*)calloc(
                  value_range,sizeof(unsigned char)))
			    ==NULL) outof_memory("color_v");     
      }

      thisblue=yellow;
      thisyellow=blue;
      if (bground==white){
	 thisblue=blue;
         thisyellow=yellow;
      }
      /*color_v[0]=darkgray;*/
      color_v[0]=black;
      if (value_range==2) color_v[1]=thisblue;
      if (value_range==3){
	  color_v[1]=red;  /*was lightred*/
         color_v[2]=white;
      }
      else if (value_range==4){
         color_v[1]=thisyellow;/*blue*/
# if _CYGWIN__
         color_v[2]=red;/*lightred comes out grey in CYGWIN*/
# else 
         color_v[2]=lightred;/*lightred=grey when printing greyscale*/
# endif
         color_v[3]=white;
      }
      else if (value_range==5){
         color_v[1]=thisyellow;/*blue*/
         color_v[2]=lightred;
         color_v[3]=thisblue;/*yellow*/
         color_v[4]=white;
      }
      else if (value_range==6){
         color_v[1]=thisyellow;/*blue*/
         if (bground=='b'){ 
             color_v[2]=lightred;
             color_v[3]=lightgreen;/*lightblue;*/
         }
         else{
             color_v[2]=lightgreen;/*lightblue;*/
             color_v[3]=lightred;
         }
         color_v[4]=thisblue;/*yellow*/
         color_v[5]=white;
      }
      else if (value_range==7){      
         if (bground=='b'){ 
            color_v[1]=magenta;
            color_v[2]=thisyellow;/*blue*/
            color_v[3]=lightred;
            color_v[4]=lightgreen;
         }
         else{
            color_v[1]=thisyellow;/*blue*/
            color_v[2]=lightgreen;
            color_v[3]=lightred;
            color_v[4]=magenta;
         }
         color_v[5]=thisblue;/*yellow*/
         color_v[6]=white;
      }
      else if (value_range==8){       
         if (bground=='b'){
             color_v[1]=magenta;              
             color_v[2]=thisyellow;/*blue*/             
             color_v[3]=lightred;
             color_v[4]=lightblue;
             color_v[5]=lightgreen;
         }
         else{
            color_v[1]=thisyellow;/*blue*/
            color_v[2]=lightgreen;
            color_v[3]=lightblue;
            color_v[4]=lightred;
            color_v[5]=magenta;
         }
         color_v[6]=thisblue;/*blue*/
         color_v[7]=white;
      }
      /*for (z=0;z<=value_range-1;z++) fprintf(stderr,"\n color_v[%d]=%d",
	    z,color_v[z]);*/
}

/****** check the speed of the computer ***********/
void check_clock_speed(void){
  
#  if __UNIX__
      struct timeval tp;
      struct timezone tzp;
#  endif
 
   unsigned long zu,elapsedtime;
   unsigned long j;
   clock_t starttime, endtime;
   
  /*this sets an initial cursor flash freq -- which is not reliable for
   differnt platforms -- but the flash freq is reset automatically
   when the cursor is first activated to about .5 sec, independent
   of platform speed. The flash freq can also be reset manualy as before*/   

#     if __WATCOM__
         starttime = clock();  /*start time*/
         for (zu=1; zu<=100000; zu++) /*test delay*/
	         for (j=0;j<1000;j++);           
         endtime = clock(); 
         elapsedtime=(unsigned long)(endtime-starttime);
         defCursorFlash= kCursorFlash=
                (unsigned long)(250*390.0/elapsedtime);
         /*test dos on new laptop elapsedtime=390 clock ticks*/   
         /*fprintf(stderr,"\n%lu-%lu=%lu\n",
	             endtime,starttime,elapsedtime);*/        

#     elif __UNIX__
      unsigned long prime_count=0;
      char is_prime;

         prime_count=0;
         gettimeofday(&tp,&tzp);
         starttime=(unsigned long)tp.tv_usec;/*micro-sec 1/million*/

         for (zu=3; zu<=10000; zu+=2){ /*primes <= 10000*/
            is_prime=1;
	    for (j=3;j<=zu/2;j++){             
	      if (zu%j==0){
                  is_prime=0; 
                  break;
              }               	         
	    }
            if (is_prime==1){
                 prime_count++;/*test delay*/
	         /*fprintf(stderr,"\n %lu: %lu",prime_count,zu);*/
	    } 
         }
         gettimeofday(&tp,&tzp);
         endtime=(unsigned long)tp.tv_usec;

         elapsedtime=endtime-starttime;
         /*for ubuntu 11.04*/
         //kCursorFlash=(unsigned long)(200000000000.0/elapsedtime);
         /*for ubuntu 6.06*/
         kCursorFlash=(unsigned long)(  1000000000.0/elapsedtime);
	 /*fprintf(stderr,"\n%lu-%lu=%lu microsec, sec =%f, CF=%lu",
	   endtime,starttime,elapsedtime,
	     float)elapsedtime/100000, kCursorFlash);*/ /*CLOCKS_PER_SEC*/

          /*adjust for slower/faster cpu's*/

	  if (kCursorFlash<10000) kCursorFlash=10000; /*smaller=faster*/
          defCursorFlash=kCursorFlash;
          /*fprintf(stderr,"\n CF=%lu\n",defCursorFlash);*/
          /*this does not work properly*/
#     endif

}

/****** show pre-image fan frequency histogram, jan 1994 ***********/
void show_pre_fansize_freq_hist(void){

 unsigned long zz,thisfreq,maxfreq,ss=0,totalss,
     totalnodes=0,totaledges=0,maxfan=0,interval=0,
     thismaxinhist,maxshowinhist,lastinbin;
 signed int z,border,
     leftborder,botborder,xright,ybot,xaxismax,
     tempx,tempy,tempx1,tempy1,tempx2,tempX,tempY;
 char xlog=0,ylog=0,end_while,
     data_was_loaded=0,in_degrees_binned=1; 
 unsigned int   zu,zu1,
                 log_count,
                 buf1,buf2; 
 unsigned long buf_total,max_bin;

 double histheight,totalxaxis,
        maxheight,histwidth,addx=0;
 /*for saving and loading data files*/
 unsigned long filebytes;
 char file_ret;
 char load_save;
 signed int fid;

   
    maxheight=vgay(120);
    leftborder=vgax(50);
    botborder=vgax(40);
    border=vgay(35);
    xright=80;
    ybot=67;
    histwidth=vgax(5);
    tempx=getx;
    tempy=gety;

    if (basinfield){      /*basin field*/
		totalss=ss=(unsigned long)(pow(2,(double)lineL));
		maxfan=maxfieldfan;
    }
    else if (direction=='f'){  /*single basin*/
		totalss=(unsigned long)basinsize;
		maxfan=maxbasinfan;
    }
    else{                 /*subtree only*/
		totalss=(unsigned long)totsubtree;
		maxfan=maxtreefan;
    }
    
   start: 
    for (zu=0;zu<=maxinhist;zu++){ 
		totalnodes+=pre_fan_freq[zu];
		totaledges+=zu*pre_fan_freq[zu];
    }
        
    if (pre_fan_freq[maxinhist]>=1) totaledges+=maxfan-maxinhist;
    if (totalnodes<=totaledges) totalss=totalnodes;

    /*in case basin was interrupted too soon*/
    if (totalss==0 || (direction=='f'&& totatt_states==0)
		      || !totalnodes || !totaledges){	
       moveto(tempx,tempy);
       return;
    }
    /*find largest in-degree frequency*/    
    maxfreq=pre_fan_freq[0];
    for (z=maxinhist;z>=1;z--){
       if (pre_fan_freq[z]>maxfreq) maxfreq=pre_fan_freq[z];
    }
    
    ss=maxfreq;
    /*find largest in-degree<=maxhist*/
    for (z=maxinhist;z>=0;z--){
       if (pre_fan_freq[z]>0){
	  maxshowinhist=z;
	  break;
       }
    }
    thismaxinhist=maxshowinhist;

  redrawhist:
    lastinbin=pre_fan_freq[maxshowinhist];
    xaxismax=(signed int)thismaxinhist;
    if (xaxismax<30) xaxismax=30;
    histwidth= (double)vgax(500)/xaxismax;
    if (histwidth>vgax(10)) histwidth=vgax(10);
    totalxaxis=(xaxismax+1)*histwidth;


    for (zz=thismaxinhist+1;zz<=maxshowinhist;zz++) lastinbin+=pre_fan_freq[zz];

    draw_box(11,vgax(xright-3)-leftborder,Maxy-vgay(ybot)-maxheight-border,
	  vgax(xright)+totalxaxis+border,
			 Maxy-vgay(ybot)+botborder,1,0);

    histheight=maxheight;
    line(vgax(xright),Maxy-vgay(ybot),vgax(xright),Maxy-vgay(ybot)-maxheight);
    if (ss>16) interval=(unsigned long)(ss/16);
    else interval=1;
    setcolor(yellow);
    /*centre y axis title*/
     moveto(vgax(xright)-leftborder+2,Maxy-vgay(ybot)-maxheight*.4);
     tempx2=getx;
     outtext("nodes");
     moveto(tempx2,gety+CHeight);
     if (ylog) outtext("(log)");

    /*centre x axis title, bias to left*/
    sprintf(textb[0],"in-degree");
    if (textwidth(textb[0])>=xaxismax*histwidth)
			moveto(vgax(xright),Maxy-vgay(ybot)+vgay(20));
    else moveto(vgax(xright)+(xaxismax*histwidth-textwidth(textb[0]))/5,
					    Maxy-vgay(ybot)+vgay(20));
    outtext(textb[0]);
    if (xlog) outtext(" (log)");


    /*---- if xlog, in-degrees binned by powers of 2, otherwise simple log ----*/
    if (in_degrees_binned==1){
     if (!xlog){
       /*draw-label y axis*/    
       for (zz=0;zz<=ss;zz+=interval){
	  if (ylog) histheight=(double)maxheight*
		    log2((((double)zz/ss)*maxheight))
			  /log2(maxheight);
	  else histheight=(double)maxheight*((double)zz/ss);
          	  
	  moveto(vgax(xright),Maxy-vgay(ybot)-histheight);
      	  if (zz%(interval*4)==0 || ss<8){
	     line(getx-4,gety,getx,gety);
	     sprintf(textb[0],"%lu",zz);
	     moveto(getx-4-textwidth(textb[0]),
		    gety-CHeight*.5);
	     outtext(textb[0]);
	  }
	  else line(getx-2,gety,getx,gety);
       }
       if (ss%(interval*4)!=0 && ss>7){
	  moveto(vgax(xright),Maxy-vgay(ybot)-maxheight);
	  line(getx-4,gety,getx,gety);
	  sprintf(textb[0],"%lu",(unsigned long)ss);
	  moveto(getx-4-textwidth(textb[0]),
		     gety-CHeight*1.3);
	  outtext(textb[0]);
       }
       /*draw-label x axis*/
       line(vgax(xright),Maxy-vgay(ybot),
	    vgax(xright)+(histwidth*(xaxismax+1)),
				       Maxy-vgay(ybot));	
       for (zu=0;zu<=xaxismax+1;zu++){
	  moveto(vgax(xright)+(zu*histwidth),Maxy-vgay(ybot));
	  if (zu%(10*(signed int)ceil((double)thismaxinhist/100))==0){
	     lineto(getx,gety+4);
	     moveto(getx-CWidth/2,gety);
	     if (zu==maxinhist) sprintf(textb[0],"%d+",zu);
	     else sprintf(textb[0],"%d",zu);
	     outtext(textb[0]);
	  }
	  else if (thismaxinhist<=200) line(getx,gety,getx,gety+2);
	  else if (zu%(5*(signed int)ceil((double)thismaxinhist/100))==0)
				      line(getx,gety,getx,gety+2);
       }
       if (lastinbin>0 && thismaxinhist<maxshowinhist){
	  moveto(getx+CWidth,Maxy-vgay(ybot)-CHeight/2);
	  outtext("+");
       }
    }
    setcolor(white);

    /*find highest col*/
    if (xlog){        
       histwidth=vgax(25);
       log_count=0;
       setfillstyle(SOLID_FILL,yellow);
       max_bin=end_while=0;
       while(1){
	  buf1=(unsigned int)ceil(pow(2,(double)log_count));
	  buf2=(unsigned int)ceil(pow(2,(double)log_count+1));
          buf_total=0;
          for (zu1=buf1-1;zu1<=buf2-2;zu1++){
             if (zu1>thismaxinhist && zu1>16){
		end_while=1;
		break;
	     }
	     buf_total+=pre_fan_freq[zu1];
          }
	   
	  if (end_while==1) break;
	  if (buf_total>max_bin) max_bin=buf_total;
	  log_count+=1;
       }
	  
       moveto(vgax(xright)-1,Maxy-vgay(ybot));
       for (zu1=0;zu1<=4;zu1++){ /*label y axis*/
          if (!ylog || zu1==0) moveto(vgax(xright)-1,
                           Maxy-vgay(ybot)-(maxheight/4)*zu1);
          else moveto(vgax(xright)-1,
                  Maxy-vgay(ybot)-
			  maxheight*log2((maxheight/4)*zu1)/
                                 log2(maxheight) );
	  linerel(-vgax(3),0);
             sprintf(textb[0],"%lu",
                  (unsigned long) (((double)max_bin/4)*zu1));
	     
	  moverel(-(strlen(textb[0])*CWidth),-vgay(4));
	  outtext(textb[0]);		       
       }
       log_count=end_while=0;  
       while(1){ 
          if (log_count==0) setfillstyle(INTERLEAVE_FILL,red);
	  else setfillstyle(SOLID_FILL,blue);
	  
          buf1=(unsigned int)ceil(pow(2,(double)log_count));
	  buf2=(unsigned int)ceil(pow(2,(double)log_count+1));
          buf_total=0;
	  
	  for (zu1=buf1-1;zu1<=buf2-2;zu1++){
             if (zu1>thismaxinhist && zu1>16){
		end_while=1;
		break;
             }
	     if (zu1<=thismaxinhist){
		buf_total+=pre_fan_freq[zu1];               
             }	     
	  }          
          line(vgax(xright)+log_count*histwidth,
                Maxy-vgay(ybot),vgax(xright)+log_count*histwidth,
                     Maxy-vgay(ybot)+vgay(4));
	  line(vgax(xright)+log_count*histwidth,
                Maxy-vgay(ybot)+1,vgax(xright)+(log_count+1)*histwidth,
                      Maxy-vgay(ybot)+1); 
	  moveto(vgax(xright)+log_count*histwidth,
                                       Maxy-vgay(ybot)+vgay(4));
	  sprintf(textb[0],"%d",buf1-1);
	  outtext(textb[0]);
          moveto(vgax(xright)+histwidth*log_count,Maxy-vgay(ybot));
          /*draw logx histogram*/
          if (buf_total>0){
	     if (!ylog) bar3d(getx,gety-
                       (((double)buf_total/
                              max_bin)*maxheight),
				      getx+histwidth-3,gety,0,0);
             else{
               double log_height;
                log_height=maxheight*
                      log2((((double)buf_total/max_bin)*maxheight))
			  /log2(maxheight);
                if (log_height<0) log_height=1;
                  
                bar3d(getx,gety-log_height,getx+histwidth-3,gety,0,0);

                /*show buf_total for each log column*/
                if (log_count>0){
                   set_small_font();     
                   moveto(getx+1,gety-log_height-CHeight*1.1);
                   sprintf(textb[0],"%lu",buf_total);
                   outtext(textb[0]);
                   restore_def_font();
                }
	     }
          }
          log_count+=1;                          	      
          if (end_while==1) break;
       }           	  
    }
    else{
       /*draw histogram*/    
       for (z=0;z<=thismaxinhist;z++){
	  if (z==0) setfillstyle(INTERLEAVE_FILL,red);
	  else setfillstyle(SOLID_FILL,blue);
	  thisfreq=pre_fan_freq[z];

	  if (z==thismaxinhist){
	     /*last frquency shown + all the rest in black*/
	     thisfreq=lastinbin;
	     if (lastinbin>0) setfillstyle(SOLID_FILL,white);
	  }

	  if (thisfreq>0){      
             if (ylog){
		 histheight=(double)maxheight*
		    log2((((double)thisfreq/(double)ss)*(double)maxheight))
			  /log2((double)maxheight);
                 if (histheight<1) histheight=1;
	     }
	     else histheight=
		    (double)maxheight*((double)thisfreq/(double)ss);
	     if (histheight>maxheight+border) histheight=maxheight+border;
	     bar3d(vgax(xright)+z*histwidth,Maxy-vgay(ybot)-histheight,
			 vgax(xright)+(z+1)*histwidth,Maxy-vgay(ybot),0,0);
	  }
       }
    }
  }

  /*---- if xlog, simple log, not in-degrees binned by powers of 2----*/
  else{
    if (1){
       /*draw-label y axis*/    
       for (zz=0;zz<=ss;zz+=interval){
	  if (ylog) histheight=(double)maxheight*
		    log2((((double)zz/ss)*maxheight))
			  /log2(maxheight);
	  else histheight=(double)maxheight*((double)zz/ss);
          	  
	  moveto(vgax(xright),Maxy-vgay(ybot)-histheight);
      	  if (zz%(interval*4)==0 || ss<8){
	     line(getx-4,gety,getx,gety);
	     sprintf(textb[0],"%lu",zz);
	     moveto(getx-4-textwidth(textb[0]),
		    gety-CHeight*.5);
	     outtext(textb[0]);
	  }
	  else line(getx-2,gety,getx,gety);
       }
       if (ss%(interval*4)!=0 && ss>7){
	  moveto(vgax(xright),Maxy-vgay(ybot)-maxheight);
	  line(getx-4,gety,getx,gety);
	  sprintf(textb[0],"%lu",(unsigned long)ss);
	  moveto(getx-4-textwidth(textb[0]),
		     gety-CHeight*1.3);
	  outtext(textb[0]);
       }

       /*draw-label x axis*/
       line(vgax(xright),Maxy-vgay(ybot),
	    vgax(xright)+(histwidth*(xaxismax+1)),
				       Maxy-vgay(ybot));

       /*if (xlog==1 && histwidth<1.0) addx=1.0-histwidth;
              log(min=1) to prevent neg or -inf       
       fprintf(stderr,"\n addx=%.2f",addx);*/
	
       for (zu=0;zu<=xaxismax+1;zu++){
	 if (xlog==0){
	     moveto(vgax(xright)+(zu*histwidth),Maxy-vgay(ybot));
	     if (zu%(10*(signed int)ceil((double)thismaxinhist/100))==0){
	        lineto(getx,gety+4);
	        moveto(getx-CWidth/2,gety);
	        if (zu==maxinhist) sprintf(textb[0],"%d+",zu);
	        else sprintf(textb[0],"%d",zu);
	        outtext(textb[0]);
	     }
	     else if (thismaxinhist<=200) line(getx,gety,getx,gety+2);
	     else if (zu%(5*(signed int)ceil((double)thismaxinhist/100))==0)
				      line(getx,gety,getx,gety+2);
         }
         else if (xlog==1){
	   if (zu*histwidth<1.0) addx=1.0-zu*histwidth;
	   moveto(vgax(xright)+
               (signed int)( ((double)(xaxismax+1)*histwidth) *
			       ( log2((double)zu*histwidth +addx)/  /*+1 to prevent neg or -inf*/
		  log2((double)(xaxismax+1)*histwidth) ) ),Maxy-vgay(ybot));

	   fprintf(stderr,"\n %d:%f %d", zu, addx, (signed int)( ((double)(xaxismax+1)*histwidth) *
			       ( log2((double)zu*histwidth +addx)/  
		  log2((double)(xaxismax+1)*histwidth) )));

            tempX=getx;
            tempY=gety;
            if ((xaxismax+1)<=200) linerel(0,vgay(2));
            if  ( zu<10 || zu%(unsigned int)((float)(xaxismax+1)/4)==0) {
                         line(tempX,tempY,tempX,tempY+vgay(4)); 
		         sprintf(textb[0],"%d",zu);
		         outtext(textb[0]);
            }
	    
         } 
       }
       
       if (xlog==0){
          if (lastinbin>0 && thismaxinhist<maxshowinhist){
	     moveto(getx+CWidth,Maxy-vgay(ybot)-CHeight/2);
	     outtext("+");
          }
       }

       
    }
    setcolor(white);
   
    if (1){
       /*draw histogram*/    
       for (z=0;z<=thismaxinhist;z++){
          thisfreq=pre_fan_freq[z];
          if (thisfreq==0) continue;
	  if (z==0) setfillstyle(INTERLEAVE_FILL,red);
	  //else setfillstyle(SOLID_FILL,blue);
          else setfillstyle(SOLID_FILL,green);
	  
	  if (z==thismaxinhist){
	     /*last frquency shown + all the rest in black*/
	     thisfreq=lastinbin;
	     if (lastinbin>0) setfillstyle(SOLID_FILL,white);
	  }

	  if (xlog==0){
             if (ylog==0) histheight=
		    (double)maxheight*((double)thisfreq/(double)ss);     
             else if (ylog==1){
		 histheight=(double)maxheight*
		    log2((((double)thisfreq/(double)ss)*(double)maxheight))
			  /log2((double)maxheight);
                 if (histheight<1) histheight=1;
	     }
	     

	     if (histheight>maxheight+border) histheight=maxheight+border;
	     bar3d(vgax(xright)+z*histwidth,Maxy-vgay(ybot)-histheight,
			 vgax(xright)+(z+1)*histwidth,Maxy-vgay(ybot),0,0);
	  }
          else if (xlog==1){
             tempX=vgax(xright)+
               (signed int)( ((double)(xaxismax+1)*histwidth) *
                  ( log2((double)z*histwidth +addx)/ /*log(min=1) to prevent neg or -inf*/
                      log2((double)(xaxismax+1)*histwidth) ) );

             if (ylog==0) histheight=
		    (double)maxheight*((double)thisfreq/(double)ss);     
             else if (ylog==1){
		histheight=(double)maxheight*
		    log2((((double)thisfreq/(double)ss)*(double)maxheight))
			  /log2((double)maxheight);
                if (histheight<1) histheight=1;
	     }
             tempY=Maxy-vgay(ybot)-histheight;
             /*fprintf(stderr,"\n %d: freq=%lu hh=%.2f x=%d y=%d",
	                          z,thisfreq, histheight,tempX,tempY);*/
             bar(tempX-1,tempY-1,tempX+1,tempY+1);
             putpixel(tempX,tempY,white);
          }
       }
    }
  }
   /*-------------- end  simple log -----------------------------------------*/  
  /*--------- applies to both binned and simple -----------------------------*/
  if (xlog==0){  
          z--;
          if ((unsigned int)z<maxinhist && pre_fan_freq[z]>0){
             //last frequency only in "blue"
             setfillstyle(SOLID_FILL,blue);
             thisfreq=pre_fan_freq[z];
	     if (thisfreq>0){	  
	        if (ylog){
	           histheight=(double)maxheight*
		       log2((((double)thisfreq/(double)ss)*(double)maxheight))
			  /log2((double)maxheight);
                   if (histheight<1) histheight=1;
	        }
                else histheight=
		 (double)maxheight*((double)thisfreq/(double)ss);
	     }
             if (histheight>maxheight+border) histheight=maxheight+border;
             bar3d(vgax(xright)+z*histwidth,Maxy-vgay(ybot)-histheight,
			 vgax(xright)+(z+1)*histwidth,Maxy-vgay(ybot),0,0);
          }
  }
  /*--------------------------------------------------------------------------*/


    moveto(vgax(140),Maxy-vgay(ybot)-maxheight-border+vgay(3));
                          
    if (data_was_loaded==1) outtext("data loaded: ");
    if (direction=='b')
       sprintf(textb[0],"subtree: nodes/edges=%lu/%lu",
					      totalnodes,totaledges);    
    else sprintf(textb[0],"total att/nodes/edges=%lu/%lu/%lu",
				totatt_states,totalnodes,totaledges);
    outtext(textb[0]);
    outtext(" win-w ops-o");
       
    moveto(vgax(140),gety+CHeight);
    if (data_was_loaded==0){
       sprintf(textb[0],"max in-degree=%lu, ",maxfan);   
       outtext(textb[0]);
    }   
    sprintf(textb[0],"gE=%lu=%.3f, ",
               pre_fan_freq[0],(float)pre_fan_freq[0]/totalnodes);
    outtext(textb[0]);
    
    if (in_degrees_binned==1)           
       outtext(" log:-x -y both-b tog bins(on)-B");
    else outtext(" log:-x -y both-b tog bins(off)-B");
    moveto(vgax(140),gety+CHeight);
    outtext("hist:save/load-s/l, data:save/prt-S/p, rescale-r, quit-q:");
    input_string(1,0);

    xlog=ylog=0;
    if (is[0]=='q') goto skip;
    else if (is[0]=='b'){
	xlog=ylog=1;
        ss=maxfreq; /*reset - could have been changed*/
	goto skip0;
    }
    else if (is[0]=='x'){
	xlog=1;
	goto skip0;
    }
    else if (is[0]=='y'){
	ylog=1;
	goto skip0;
    }
    else if (is[0]=='B'){
        in_degrees_binned=abs(in_degrees_binned-1);
	goto skip0;
    }
    else if (is[0]=='p'){
       fprintf(stderr,"\npre-image frequency distribution\n");
       for (z=0; z<=maxinhist; z++){
             if (pre_fan_freq[z]>0) 
               fprintf(stderr,"%d: %lu\n",z,pre_fan_freq[z]);
       }
       goto skip0;
    }
    else if (is[0]=='S'){
       signed int fid;         
 	 file_ret=select_filename("SAVE","DATA","*.dat","my_data");
	 if (file_ret=='q') goto skip0;
	 memmove(filename_data,filename,13);
         fid=myopen(filename_data,1,1);
         if (fid==-1) file_error(filename_data);
	 close(fid);
         save_data("\npre-image frequency distribution\n");
         for (z=0; z<=maxinhist; z++){
            if (pre_fan_freq[z]>0){
               sprintf(textb[0],"%d: %lu\n",z,pre_fan_freq[z]);
               save_data(textb[0]);
            }
         }
         goto skip0;
    }
    else if (is[0]=='o'){ 
       finish_options(1);
       goto skip0;
    }
    else if (is[0]=='w'){ /*tog histogram window*/
       sprintf(textb[9],"%s","boximage[11]");
       putimage(vgax(xright-3)-leftborder,
		   Maxy-vgay(ybot)-maxheight-border,boximage[11],COPY_PUT,textb[9]);
       input_string(1,0);
       goto skip0;
    }
    else if (is[0]=='s' || is[0]=='l'){     
       tempx1=getx;
       tempy1=gety;
       if (is[0]=='l'){
	   load_save='l';
           sprintf(textb[4],"LOAD ");
       }
       else if (is[0]=='s'){
	   load_save='s';
           sprintf(textb[4],"SAVE ");
       }   
       /*extention changed *.prh, for  pre-image histogram,
         was *.his but this is now for damage/attractor/skeleton
         histograms (from space-time patterns) see 
         show_diff_plot(..
         *.his stores frequencies as unsigned int
         *.prh as unsigned long*/  
       file_ret=select_filename(textb[4],
                     "PRE-HIST-DATA", "*.prh","my_prh"); 
       if (file_ret=='q') goto skipfile;
       else{
          if (load_save=='l'){
	     fid=myopen(filename,0,0);
             filebytes= filelength(fid);
	     maxinhist=(unsigned int)(filebytes/sizeof(unsigned long)-1);
             /*reset array for in-degree histogram*/
	     free(pre_fan_freq);
	     if ((pre_fan_freq=(unsigned long *)
		  calloc(maxinhist+1,sizeof(unsigned long)))
				==NULL) outof_memory("pre_fan_freq");
             data_was_loaded=1;
	  }
	  if (load_save=='s') fid=myopen(filename,1,0);
          if (fid==-1){
	     file_error(filename);
             draw_prompt_box(1);
	     outtext(textb[0]);
	     input_string(1,0);
	     erase_prompt_box(1);
	     close(fid);
	     goto skip;
	  }
       }
       
       if (load_save=='s')
          vret=write(fid,pre_fan_freq,(maxinhist+1)*sizeof(unsigned long));
       else if (load_save=='l') 
          vret=read(fid,pre_fan_freq,(maxinhist+1)*sizeof(unsigned long));
       if (vret==0) fprintf(stderr,"\n read/write=%d",vret);
       close(fid);
       if (load_save=='s') goto skip0;        
   
     skipfile:
       moveto(tempx1,tempy1);
       if (load_save=='l') goto start;
    }
    
    else if (is[0]=='r') 
          moveto(vgax(140),gety+CHeight);/*continue with more prompts*/
    else goto skip0; /*redraw same histogram + prompts*/

#   if __WATCOM__
       outtext("prtbox-p, ");
#   endif
    
    if (maxshowinhist>30) outtext("re-scale x/y axis (def-d):");
    else outtext("re-scale y axis (def-d):");
    if (maxshowinhist>30){
       sprintf(textb[0],"x-max (30-%lu):",maxshowinhist);
       outtext(textb[0]);
       input_string(8,0);
       if (is[0]=='q') goto skip;
       /*print histogram box*/
#      if __WATCOM__
	  if (is[0]=='p') printimage('L',0,0,
	       vgax(xright-3)-leftborder,Maxy-vgay(ybot)-maxheight-border,
	          vgax(xright)+((xaxismax+1)*histwidth)+border,
			 Maxy-vgay(ybot)+botborder);
#      endif
       else if (is[0]=='d') thismaxinhist=maxshowinhist;
       else if (is[0]!=13 && atol(is)>=25 && atoi(is)<=maxshowinhist)
						thismaxinhist=atol(is);
    }
    outtext(" y-max:");
    input_string(8,0);
    
    
    //if (is[0]=='q') goto skip;
    /*print histogram box*/
#   if __WATCOM__
      if (is[0]=='p') printimage('L',0,0,
	  vgax(xright-3)-leftborder,Maxy-vgay(ybot)-maxheight-border,
	     vgax(xright)+((xaxismax+1)*histwidth)+border,
			 Maxy-vgay(ybot)+botborder);
#   endif
    if (is[0]=='d') ss=maxfreq;
    else if (is[0]!=13 && atol(is)>0) ss=atol(is);

   skip0:
    sprintf(textb[9],"%s","boximage[11]");
    putimage(vgax(xright-3)-leftborder,
	 Maxy-vgay(ybot)-maxheight-border,boximage[11],COPY_PUT,textb[9]);
    freeimage(boximage[11]);
    goto redrawhist;

   skip:
    sprintf(textb[9],"%s","boximage[11]");
    putimage(vgax(xright-3)-leftborder,
	 Maxy-vgay(ybot)-maxheight-border,boximage[11],COPY_PUT,textb[9]);
    freeimage(boximage[11]);
    is[0]=0;
    moveto(tempx,tempy);
}

/******************** finish options, Sept 1993 *********************/
void finish_options(char alloptions){
 signed int tempx,tempy;
 unsigned int z;

   tempx=getx;
   tempy=gety;
   moveto(0,0);
  start:
   finish_options_box(alloptions);
   switch (is[0]){
      case 'g':
         if (basin_not_complete==1){
             sprintf(textb[9],"%s","boximage[1]");
	     putimage(2,2,boximage[1],COPY_PUT,textb[9]);
	     freeimage(boximage[1]);
             goto start;
         }
	 freeimage(boximage[1]);
#        if __WATCOM__
            if (alloptions) open_graphics(1,0);
#        elif __UNIX__
            if (alloptions) revise_graphics();
#        endif
         setup_value_colors(0); /*in case background color was changed*/
         setup_postScripr_colors(0);
         start_edge_color=lightred;
         goto start;

      case 'o':
	 if (limitcheck==0 && direction=='f') break; /*forwards only*/

         sprintf(textb[9],"%s","boximage[1]");
	 putimage(2,2,boximage[1],COPY_PUT,textb[9]);
	 freeimage(boximage[1]);
         if (basin_not_complete==1) goto start;
	 if (alloptions){
	    if (nhood){
	       if (tot_only==0) interrupt_stp_box(2,carule[0],0,0,0,NULL,NULL,NULL,NULL);
               else if (tot_only==1){
                  if (totalistic==1) interrupt_stp_box(2,cacode[0],0,0,0,NULL,NULL,NULL,NULL);
                  else if (totalistic==2) interrupt_stp_box(2,v_code[0],0,0,0,NULL,NULL,NULL,NULL);
               }
	       if (rulemix==0 && tot_only==0)
                      show_rule_bottom(nhood,0,carule[0],0);
	    }
	    /*if not forward only*/
	    if (is[0]=='q' && !(limitcheck==0 && direction=='f')) goto start;
	 }
	 break;
      case 'V': case 's': /*added V for consistancy with other speed prompts*/
         sprintf(textb[9],"%s","boximage[1]");
	 putimage(2,2,boximage[1],COPY_PUT,textb[9]);
	 freeimage(boximage[1]);
	 if (alloptions){
	    if (slowfactor==0){ 
	       if (stp==1) slowfactor=300;
               else slowfactor=33000; /*for basin need to be slower*/
            }
            sprintf(textb[0],
	       "speed: max-(def), or slowmotion (try %d):",slowfactor);
	    draw_prompt_box(1);
	    outtext(textb[0]);
            input_string(6,0);
            if (is[0]==13) pre_speed=0;
            else if (atol(is)>1){ 
               slowfactor=atol(is);
               pre_speed=slowfactor*500;
            }
	 }
	 goto start;
      case 'n':
         sprintf(textb[9],"%s","boximage[1]");
	 putimage(2,2,boximage[1],COPY_PUT,textb[9]);
	 freeimage(boximage[1]);
	 if (alloptions){
	    if (!loc_twod_fonly && alloptions) show_w_r_scheme();
	 }
	 goto start;
      case 't':
         sprintf(textb[9],"%s","boximage[1]");
	 putimage(2,2,boximage[1],COPY_PUT,textb[9]);
	 freeimage(boximage[1]);
         if (basin_not_complete==1 || hilight_learn) goto start;
	 if (alloptions) toggle_single_field=1;
	 break;
      case 'P':/*turn space-time pattern on/off*/
         sprintf(textb[9],"%s","boximage[1]");
	 putimage(2,2,boximage[1],COPY_PUT,textb[9]);
	 freeimage(boximage[1]);
	 if (alloptions){
	     /*if (!(limitcheck==0 && direction=='f')) stp=abs(stp-1);*/
             stp=abs(stp-1);
	 }
	 break;
      case 'e':/*reset seed*/
         sprintf(textb[9],"%s","boximage[1]");
	 putimage(2,2,boximage[1],COPY_PUT,textb[9]);
	 freeimage(boximage[1]);
         if (basin_not_complete==1) goto start;
	 if (alloptions){
	    if (!basinfield){
	       moveto(vgax(200),vgay(315));
	       select_seed(0,bitseed,"SEED",1);
	       memmove(state1,bitseed,bytesL);
	    }
	 }
	 break;
	 //default: /*including 'q'*/
         case 'q':	
         sprintf(textb[9],"%s","boximage[1]");
	 putimage(2,2,boximage[1],COPY_PUT,textb[9]);
	 freeimage(boximage[1]);
         istr_graph=0;
	 break;

         case 13:/*continue --- to next mutant*/
	   break;
	   
         default:
	   goto start;
      }
      moveto(tempx,tempy);
}

/****** mutate the rule, Sept 1993, for fields,basins,subtrees only *****/
char mutate_rule(char nhoodz){
  signed int tablebytes,
	      equivcode,codeclustersize,
	      codedec,tcd1,tcd2,tcd3,/*decimal code + 3 EQUIVALENTS*/
	      z,zz,sod,counter,temp;
 unsigned int cellno,cellmax=0,
		poss,wire,bit;
 char tempbit,this_nhood;
 unsigned long ruledec;
 float ztemp,tempinc;
 signed int tablemax,tablecodemax=0;
 unsigned long rule_dec_max,code_dec_max=0;
 unsigned int zu;

 //fprintf(stderr,"\n mutate=%d",mutate); //fprintf??
 /*if (isalpha(mutate))
       fprintf(stderr,
         "\n totalistic=%d mutate=%c bits_to_flip=%lu",
                              totalistic,mutate,bits_to_flip);
   else fprintf(stderr,
         "\n totalistic=%d mutate=%d bits_to_flip=%lu",
	               totalistic,mutate,bits_to_flip);*/

   if (was_changed==1 || mutate=='n'){
      was_changed=0;
      fieldno=0;

      ox=firstox;
      oy=firstoy;
      
      xspacing=startxspacing;
      yspacing=startyspacing;
      return(1);
   }

   /*check if decimal is allowed*/
   tablemax= (signed int)pow(value_range,(double)nhood)-1;
   rule_dec_max=max_dec_rule(tablemax,value_range);
   if (totalistic==1) /*tcode*/
       tablecodemax=nhood*(value_range-1); /*max index of tcode table*/
   else if (totalistic==2){ /*kcode*/
       tablecodemax=v_tablecodemax[nhood]; /*max index of kcode table*/
   }
   if (totalistic) code_dec_max=max_dec_rule(tablecodemax,value_range);


   /*
   (mutate_wiring==1) mutate wiring - randomly move a wire at random in the network
                             until "wires_to_move" are moved.
                                -rewire rnd all wires (wires_to_move==-1)
                                (applies to mixed k)
   (mutate_wiring==2) as above, but restore original wiring before wiring mutation 
   (mutate_wiring_and_rule==1) allow rule mutations as well as wiring
                              
   (mutate=='b' && bits_to_flip>0) flip one or more bits at random
                       mixed-rules: choose 1 rnd cell, flip selected no bits/values
                       (applies to mixed k)
                 Note: this is also the 1st mautation prompt default, with bits_to_flip=1
                       
   (mutate=='t') random tcode -mixed-rules: all cells (applies to mixed k)
   (mutate=='k') random kcode -mixed-rules: all cells (applies to mixed k)
   (mutate=='P') (restricted to v=2)
                 random Post rule --mixed-rules: all cells (applies to mixed k)
                 if (this_nhood<=5) find a Post function among rcode
                 else find a Post function among kcode -- more likely
   (mutate=='c') random chain rule --mixed-rules: all cells (applies to mixed k)

   (mutate==1 || mutate==0) 1 bit-flip (or value change) from left to right
                 (1)cumulative or (0)single mutation -- in rcode, kcode or tcode table
                --mixed-rules: all cells (NOT mixed k)
                  
   (mutate==5)   decriment code number (tcode or vcode) -- if can be expressed as decimal.
                --mixed-rules: all cells (applies to mixed k)
   (mutate==4) rnd bit-flip (or value change) 
               in preset number of number of position in the rule-table,
               (but 1 only from special mutation) 
               rcode, kcode or tcode table (whichever was selected)
                --mixed-rules: as above for one rnd cell (applies to mixed k)
   (mutate==3) decriment rcode number-- if can be expressed as decimal.
                --mixed-rules: all cells (applies to mixed k)
   (mutate==2) or (mutate=='b' && bits_to_flip==-1)
               reset rcode at random
               --mixed-rules: all cells (applies to mixed k)
               Note: for a single rule zparam>0.06 to avoid exteme order
                 and if v=2 and set_z_high (?? zparam>.55 ??) to force disorder.
                 This is for G-density, lambda and Z graphs.
    */ 

   /*fprintf(stderr,
      "\n mutate=%c mutate_wiring=%d mutate_wiring_and_rule=%d wires_to_move=%d",
      mutate, mutate_wiring, mutate_wiring_and_rule,wires_to_move);*/

   if (mutate_wiring || mutate_wiring_and_rule==1){
     
      nonlocal=1;
      if (wires_to_move==-1){ 
	 for (poss=lineL-1;poss!=Maxu;poss--)
			   randomly_wire_cell(poss,lineL-1);
      }
      else{ /*choose 1 cell at random, randomly move selected number of wires*/
        unsigned int poss1,poss2;
	 if (mutate_wiring==2){  /*restore original before rewiring*/
            /*backup current wiring*/
            for (zu=lineL-1;zu!=Maxu;zu--){
	       for (z=nhood-1;z>=0;z--){
		  wiring[zu][z]=wiring_backup[zu][z];
	       }
            }
         }
	 for (wire=1;wire<=wires_to_move;wire++){
	    poss=myrand()%lineL;
            poss1=myrand()%lineL;
            poss2=myrand()%lineL;
            /*fprintf(stderr,"\n%d %d %d",poss,poss1,poss2);*/ 
	    wiring[poss][myrand()%nhoodm[poss1]]=poss2;
	 }
      }
      if (mutate_wiring_and_rule==0) goto end_mutate;
   }


   /*flip one or more bits at random, 
     mixed-rules: choose 1 rnd cell, flip selected no bits/values*/   
   if (mutate=='b' && bits_to_flip>0){
     startbit:
      for (bit=1;bit<=bits_to_flip;bit++){
	 if (rulemix) cellno=rand()%lineL;
	 else cellno=0;
         if (value_range==2){
	    poss=myrand()%(signed int)pow(2,(double)nhoodm[cellno]);
	    set_bit(carule[cellno],poss,abs(get_bit(carule[cellno],poss)-1));
         }
         else{
	   char flip_value; 
            poss=rand()%(signed int)pow(value_range,(double)nhoodm[cellno]);
	   flip_again:
	    flip_value=myrand()%value_range;            
            if (flip_value==get_value(carule[cellno],poss)) goto flip_again;
	    set_value(carule[cellno],poss,flip_value);
         }
      }
      if (!rulemix){
	 if (value_range==2) z_parameter_all(nhood,0,carule[0]);
         else z_parameter_all_mvalue(nhood,0,carule[0]);
	 if (zparam[0]<.1) goto startbit;
      }
   }

   /*other mutations rule/s or totalistic code/s*/
   else{
      /*5-code+1,4-code rand,3-rule+1,2-rule rand,1-onebit cum,0-bit single*/
      tablemax=(signed int)pow(value_range,(double)nhoodz)-1;
      tablebytes=(signed int)ceil(value_bits * (double)(tablemax+1)/8);
      if (rulemix) cellmax=L;

      for (cellno=0;cellno<=cellmax;cellno++){
	 if (nhood_mixed){
	     tablemax=(signed int)pow(value_range,(double)nhoodm[cellno])-1;
             tablebytes=(signed int)ceil(value_bits * (double)(tablemax+1)/8);
	     this_nhood=nhoodm[cellno];
         }
         else this_nhood=nhoodz;

         if (mutate=='t'){ /*random tcode, -mixed-rules: all cells*/
            totalistic=1;
            for (z=nhoodz*(value_range-1);z>=0;z--)	          
                       set_value(cacode[cellno],z,myrand()%value_range);
            /*convert code to rule*/
	    code2rule(carule[cellno],cacode[cellno],this_nhood);
         }
         else if (mutate=='k'){ /*random kcode, -mixed-rules: all cells*/
	    totalistic=2;
            for (z=v_tablecodemax[nhoodz];z>=0;z--)
		        set_value(v_code[cellno],z,myrand()%value_range);
            v_code2rule(carule[cellno],v_code[cellno],this_nhood,1);
         } 
         else if (mutate=='P'){ /*random Post rule, --mixed-rules: all cells*/ 
           char post=0;
   
	   if (this_nhood<=5){ /* find a Post function among rcode*/
	       while(1){
                  for (zz=0;zz<=tablemax;zz++) 
                     set_value(carule[cellno],zz,myrand()%(value_range));
	           post=post_func(this_nhood, carule[cellno],0,0,0,0); /*check post*/
                   if (post==1) break;
               }
            }
	    else{ /* find a Post function among kcode -- more likely*/
              char this_bit,bit_changed=0;
               totalistic=2;
               while(1){
		  for (z=v_tablecodemax[nhoodz];z>=0;z--){
		     this_bit=myrand()%value_range;
		     set_value(v_code[cellno],z,this_bit);
                     if (z<v_tablecodemax[nhoodz] && bit_changed==0){
		        if (get_value(v_code[cellno],z+1)!=this_bit) bit_changed=1;
		     }                     
                  }
                  v_code2rule(carule[cellno],v_code[cellno],this_nhood,1);
                  post=post_func(this_nhood, carule[cellno],0,0,0,0); /*check post*/
                  if (post==1 && bit_changed==1) break;
               }
            }
         }
         /*random chain-rule, for encryption, --mixed-rules: all cells*/       
         else if (mutate=='c'){ 
           chain_rule(carule[cellno],nhoodm[cellno],tablemax,cellno);            
         }
         	 
         /*1 bit-flip (or value change) from left to right
           (1)cumulative or (0)single mutation -- in rcode, kcode or tcode table
	   --mixed-rules: all cells*/
	 else if (mutate==1 || mutate==0){
	    signed int this_tablemax,this_tablebytes;
            char temp_value;
	     
             if (totalistic==0) this_tablemax=(signed int)pow(value_range,(double)this_nhood)-1;
             else if (totalistic==1) this_tablemax=this_nhood*(value_range-1);  
             else if (totalistic==2) this_tablemax=v_tablecodemax[this_nhood];

             if (mut==startmut){
	       //fprintf(stderr,"\n");
                this_tablebytes=(signed int)ceil(value_bits * (double)(tablemax+1)/8); 
                if (totalistic==0) memmove(carule_mut[cellno],carule[cellno],this_tablebytes);        
	        else if (totalistic==1) memmove(carule_mut[cellno],cacode[cellno],this_tablebytes); 
                else if (totalistic==2) memmove(carule_mut[cellno],v_code[cellno],this_tablebytes);
             }
 
             /*flip next bit*/
	     //fprintf(stderr,"\n%d:%d",mut,get_value(carule_mut,mut));

	     while(1){
	           temp_value=myrand()%(value_range);
                   //if (temp_value!=get_value(carule_mut,mut)) break;
                   if (totalistic==0){
                       if (temp_value!=get_value(carule[cellno],mut)) break;
                   }
                   else if (totalistic==1){
                       if (temp_value!=get_value(cacode[cellno],mut)) break;
	           }
                   else if (totalistic==2){
                       if (temp_value!=get_value(v_code[cellno],mut)) break;
		   }
             }

	     if (totalistic==0) set_value(carule[cellno],mut,temp_value);
             else if (totalistic==1){ 
                    set_value(cacode[cellno],mut,temp_value);
                    code2rule(carule[cellno],cacode[cellno],this_nhood);
             } 
             else if (totalistic==2){
                     set_value(v_code[cellno],mut,temp_value);
                     v_code2rule(carule[cellno],v_code[cellno],this_nhood,1);
             }

             if (mutate==0){
	          /*flip last value back*/
		  if (mut<this_tablemax){
                     if (totalistic==0) 
                        set_value(carule[cellno],mut+1,get_value(carule_mut[cellno],mut+1));
                     else if (totalistic==1){
                        set_value(cacode[cellno],mut+1,get_value(carule_mut[cellno],mut+1));
                        code2rule(carule[cellno],cacode[cellno],this_nhood);
                     }
                     else if (totalistic==2){
                        set_value(v_code[cellno],mut+1,get_value(carule_mut[cellno],mut+1));
                        v_code2rule(carule[cellno],v_code[cellno],this_nhood,1);
		     }
                  }
	     }
	 }

         /*decriment code number (tcode or vcode) -- if can be expressed as decimal.
	   --mixed-rules: all cells*/
         else if (mutate==5 && code_dec_max>0){
	    /*decriment code number*/
	    if (value_range>2){           
	       if (totalistic==1) ruledec=dec_equiv(cacode[cellno],tablecodemax);
               else if (totalistic==2) ruledec=dec_equiv(v_code[cellno],tablecodemax);
	      startdec_code:
	       ruledec-=1;
	       if (ruledec<1){
	          if (rulemix==0) return(0);
	          else ruledec=(unsigned long) 
                         (pow(value_range,(double)(tablecodemax+1))-1);
	       }
               if (totalistic==1){ 
                    dec_to_value_line(cacode[cellno],ruledec,tablecodemax+1);
                    code2rule(carule[cellno],cacode[cellno],this_nhood);
               }
	       else if (totalistic==2){
                    dec_to_value_line(v_code[cellno],ruledec,tablecodemax+1);
                    v_code2rule(carule[cellno],v_code[cellno],this_nhood,1);
               } 
	       if (!rulemix){
	          if (value_range==2) z_parameter_all(nhoodz,0,carule[0]);
                  else z_parameter_all_mvalue(nhoodz,0,carule[0]);
	             if (gd_z_graph){
		     /*fprintf(stderr,"rule=%lu z=%f l=%f h=%f\n",
                                   ruledec,zparam[0],lowlimZ,highlimZ);*/
		     if (zparam[0]<lowlimZ || zparam[0]>highlimZ)
						  goto startdec_code;
	          }
	       }
	    }

	    else if (value_range==2){
              /*for v=2 cacode[0],v_code[0] are the same -- this uses cacode*/
              if (totalistic==2) memmove(cacode[0],v_code[cellno],
			      (signed int)ceil((double)(nhoodz+1)/8));
	      startmutate5:
	       if ((gd_z_graph || (codetypeonly!='a')) && rulemix==0){
		   /*totalistc rules are symetric
		   typical cluster

		   start---tcd2   equiv
		    |       |
		    |       |
		    |       |
		   tcd1----tcd3   equiv   compliment
			   negative
		  */

		  /*negatine transformation*/
		  memmove(tempcode,cacode[0],
			      (signed int)ceil((double)(nhoodz+1)/8));
		  /*flip bits*/	  
		  for (z=nhoodz;z>=0;z--)
			  set_bit(tempcode,z,abs(get_bit(tempcode,z)-1));
		  /*compliment transformation of start*/
		  tcd1=(signed int)dec_equiv(tempcode,nhoodz);

		  /*swap bits*/
		  /*negative transformation of start, done on compliment*/
		  if (nhoodz%2==1){ /*if odd nhood, even size code table*/
		     for (z=nhoodz;z>=(nhoodz+1)/2;z--){
			tempbit=get_bit(tempcode,z);
			set_bit(tempcode,z,get_bit(tempcode,nhoodz-z));
			set_bit(tempcode,nhoodz-z,tempbit);
		     }
		  }
		  else { /*if even nhood, odd size code table*/
		     for (z=nhoodz;z>=(nhoodz/2)+1;z--){
			tempbit=get_bit(tempcode,z);
			set_bit(tempcode,z,get_bit(tempcode,nhoodz-z));
			set_bit(tempcode,nhoodz-z,tempbit);
		     }
		  }
		  tcd2=(signed int)dec_equiv(tempcode,nhoodz);
		  /*flip bits*/
		  /*compliment of negative of start*/
		  for (z=nhoodz;z>=0;z--)
			   set_bit(tempcode,z,abs(get_bit(tempcode,z)-1));
		  tcd3=(signed int)dec_equiv(tempcode,nhoodz);
	       }
	       codedec=(signed int)dec_equiv(cacode[cellno],nhoodz);

	       /*if (rulemix==0 && !lambda_z_graph){*/
	       if (rulemix==0 && codetypeonly!='a'){
		  equivcode=codeclustersize=1;
		  if (!lambda_z_graph || pause_show_code){
		     draw_prompt_box(1);
		     sprintf(textb[0],"v%dk%d-tcode cluster:%d",
                             value_range,nhoodz,codedec);
		     outtext(textb[0]);
		  }
		  set_bit1(codetickoff,codedec);

		  /*tickoff equivalent, max one*/
		  if (tcd2!=codedec){
		     if (!lambda_z_graph || pause_show_code){
			sprintf(textb[0],"=%d",tcd2);
			outtext(textb[0]);
		     }
		     set_bit1(codetickoff,tcd2);
		     equivcode+=1;
		     codeclustersize+=1;
		     endcount+=1;
		  }

		  if (gd_z_graph || codetypeonly=='c'){
		     /*tick off rest of cluster*/
		     if (tcd1!=codedec && tcd1!=tcd2){
			if (!lambda_z_graph || pause_show_code){
			   sprintf(textb[0]," %d",tcd1);
			   outtext(textb[0]);
			}
			set_bit1(codetickoff,tcd1);
			codeclustersize+=1;
			endcount+=1;
		     }
		     if (tcd3!=codedec && tcd3!=tcd2 && tcd3!=tcd1){
			if (!lambda_z_graph || pause_show_code){
			   sprintf(textb[0],"=%d",tcd3);
			   outtext(textb[0]);

			}
			set_bit1(codetickoff,tcd3);
			codeclustersize+=1;
			endcount+=1;
		     }
		  }
		  totcode_eq_or_cl+=1;
		  if (!lambda_z_graph || pause_show_code){
		     sprintf(textb[0]," equiv=%d clust=%d",
					 equivcode,codeclustersize);
		     outtext(textb[0]);
		  }
		  if (pause_show_code){
		     sprintf(textb[0]," tot=%d cont-ret:",
						   totcode_eq_or_cl);
		     outtext(textb[0]);
		     input_string(1,0);
		     if (is[0]=='q'){
			pause_show_code=0;
			is[0]=0;
		     }
		  }
	       }
	      nextblank:
	       codedec-=1;
	       if (rulemix==0){
		  if (codedec<1) return(0);
		  if (gd_z_graph || codetypeonly!='a'){
		     if (get_bit(codetickoff,codedec)==1) goto nextblank;
		  }
	       }
	       if (codedec<1) codedec=(signed int)pow(2,(double)nhoodz+1)-1;
	       /*max code dec*/
	       dec_to_bit_line(cacode[cellno],codedec,nhoodz+1);
	       /*skip codes with Z parameter <.1*/
	       if (gd_z_graph && !rulemix){
		  for (zz=tablemax;zz>=0;zz--){
		     sod=0;
		     for (z=nhoodm[cellno]-1;z>=0;z--)
					sod+=get_bit(nm[z],zz);
		     set_bit(carule[cellno],zz,get_bit(cacode[cellno],sod));
		  }
		  if (value_range==2) z_parameter_all(nhoodz,0,carule[0]);
                  else z_parameter_all_mvalue(nhoodz,0,carule[0]);
		  if (zparam[0]<lowlimZ || zparam[0]>highlimZ){
		     codedec-=1;
		     endcount+=1;
		     goto startmutate5;
		  }
	       }
               code2rule(carule[cellno],cacode[cellno],nhoodz);

               /*convert cacode[0] back to v_code[0]*/ 
               if (totalistic==2){
                    memmove(v_code[cellno],cacode[cellno],
			      (signed int)ceil((double)(nhoodz+1)/8));
                    v_code2rule(carule[cellno],v_code[cellno],nhoodz,1);
               }                
	    }           
	 }
         /*rnd bit-flip (or value change) 
           in preset number of position in the rule-table, 
	   rcode, kcode or tcode table  (whichever was selected)*
	   --mixed-rules: as above for one rnd cell*/
	 else if (mutate==4){
               for (bit=1;bit<=bits_to_flip;bit++){
                   if (totalistic==1){
                     if (value_range==2){
	                poss=myrand()%(nhoodz+1);
	                set_bit(cacode[cellno],poss,abs(get_bit(cacode[cellno],poss)-1));
                     }
                     else{
	               char flip_value; 
                        poss=rand()%(nhoodz*(value_range-1)+1);
	                flip_again1:
	                flip_value=myrand()%value_range;            
                        if (flip_value==get_value(cacode[cellno],poss)) goto flip_again1;
	                set_value(cacode[cellno],poss,flip_value);
                     }	           
                     /*convert code to rule*/
	             code2rule(carule[cellno],cacode[cellno],this_nhood);
	          }
	          else if (totalistic==2){
                     if (value_range==2){
	                poss=myrand()%(v_tablecodemax[nhoodz]+1);
	                set_bit(v_code[cellno],poss,abs(get_bit(v_code[cellno],poss)-1));
                     }
                     else{
	               char flip_value; 
                        poss=rand()%(v_tablecodemax[this_nhood]+1);
	                flip_again2:
	                flip_value=myrand()%value_range;            
                        if (flip_value==get_value(v_code[cellno],poss)) goto flip_again2;
                        set_value(v_code[cellno],poss,flip_value);	                
                     }
                     /*convert code to rule*/
                     v_code2rule(carule[cellno],v_code[cellno],this_nhood,1);
                  }
               }
	 }
	    
	 /*decriment rule number*/
	 else if (mutate==3 && rule_dec_max>0){           
	    ruledec=dec_equiv(carule[cellno],tablemax);
	   startdecr:
	    ruledec-=1;
	    if (ruledec<1){
	       if (rulemix==0) return(0);
	       else ruledec=(unsigned long) 
                         (pow(value_range,(double)(tablemax+1))-1);
	    }
	    if (value_range==2) dec_to_bit_line(carule[cellno],ruledec,tablemax+1);
            else dec_to_value_line(carule[cellno],ruledec,tablemax+1);

	    if (!rulemix){
	       if (value_range==2) z_parameter_all(nhoodz,0,carule[0]);
               else z_parameter_all_mvalue(nhoodz,0,carule[0]);
	       if (gd_z_graph){
		 /*fprintf(stderr,"rule=%lu z=%f l=%f h=%f\n",
                                   ruledec,zparam[0],lowlimZ,highlimZ);*/
		  if (zparam[0]<lowlimZ || zparam[0]>highlimZ)
						  goto startdecr;
	       }
	    }
	 }

	 /*reset rule at random*/
	 else if (mutate==2 || (mutate=='b' && bits_to_flip==-1)){
	   startrandom:
	    if (!rulemix){
	       if (lambda_bias==0) lambda_bias=50;
	       for (z=tablemax;z>=0;z--){
		  if (value_range==2){
		     set_bit(carule[cellno],z,((myrand()%100)/lambda_bias));
                  }
                  else	/*no bias*/	     
                     set_value(carule[cellno],z,myrand()%value_range);
               }
	       if (value_range==2) z_parameter_all(nhood,0,carule[0]);
               else z_parameter_all_mvalue(nhood,0,carule[0]);
	       if (zparam[0]<.06) goto startrandom;
              
	       if  (value_range==2 && set_z_high){ /*to be revised for multi-value*/
		  z_parameter_all(nhoodz,0,carule[0]);
		  if (zparam[0]<.55) goto startrandom;  /*.65*/

		  tempinc= myrand() % 35;                 /* 27*/

		  counter=0;
		  if (zparam[0]<.6 +tempinc/100){    /*.7*/
		     ztemp=zparam[0];
		    changebit:
		     counter+=1;
		     temp= myrand() % tablemax;
		     /*random bit flip*/
		     set_bit(carule[0],temp,abs(get_bit(carule[0],temp)-1));
		     if (value_range==2) z_parameter_all(nhoodz,0,carule[0]);
                     else z_parameter_all_mvalue(nhoodz,0,carule[0]);
		     if (zparam[0]<ztemp){
			/*flip back*/
			set_bit(carule[0],temp,abs(get_bit(carule[0],temp)-1));
			/*flip another*/
			if (counter<500) goto changebit;
		     }
		     ztemp=zparam[0];
		     if (zparam[0]<.6+tempinc/100){   /*7*/
			if (counter<500) goto changebit;
		     }
		  }
	       }
	    }
	    else{
	       for (z=tablemax;z>=0;z--)
		  if (value_range==2){
                      set_bit(carule[cellno],z,((myrand()%100)/50));
                  }
                  else set_value(carule[cellno],z,myrand()%value_range);
	    }
	 }
      }
      if (!rulemix){
         if (value_range==2)  z_parameter_all(nhoodz,0,carule[0]);
         else z_parameter_all_mvalue(nhoodz,0,carule[0]);
      }
   }

 end_mutate:
   fieldno=0;
   if (mutant_layout==0){
      ox=firstox;
      oy=firstoy;
   
      xspacing=startxspacing;
      yspacing=startyspacing;
   }
   return(1);
}

/************ set biased new rule for Gd - Z graph, Jan 94 ***************/
void biased_new_rule(void){
  unsigned int tempx,tempy;

    tempx=getx;
    tempy=gety;

    if (mutate==2){
       if (endcount<.2 * totalgraphrules) {
	  lambda_bias=50;
	  set_z_high=1;
	  goto skipcount;
       }
       if (endcount<.28 * totalgraphrules) {
	  lambda_bias=50;
	  set_z_high=0;
	  goto skipcount;
       }
       if (endcount<.36 * totalgraphrules) {
	  lambda_bias=45;
	  set_z_high=0;
	  goto skipcount;
       }
       if (endcount<.44 * totalgraphrules) {
	  lambda_bias=40;
	  set_z_high=0;
	  goto skipcount;
       }
       if (endcount<.52 * totalgraphrules) {
	  lambda_bias=35;
	  set_z_high=0;
	  goto skipcount;
       }
       if (endcount<.6 * totalgraphrules) {
	  lambda_bias=30;
	  set_z_high=0;
	  goto skipcount;
       }
       if (endcount<.68 * totalgraphrules) {
	  lambda_bias=25;
	  set_z_high=0;
	  goto skipcount;
       }
       if (endcount<.76  * totalgraphrules) {
	  lambda_bias=20;
	  goto skipcount;
       }
       if (endcount<.84  * totalgraphrules){
	  lambda_bias=15;
	  goto skipcount;
       }
       if (endcount<.92  * totalgraphrules){
	  lambda_bias=10;
	  goto skipcount;
       }

       if (endcount<=totalgraphrules){
	  lambda_bias=5;
	  goto skipcount;
       }
    }
    skipcount:

    /*if (!(mutate==3 || mutate==5)){
       sprintf(textb[0],"t=%lu c=%lu lb=%d zh=%d",
	      totalgraphrules,endcount,lambda_bias,set_z_high);
       if (endcount>=totalgraphrules) mutantdontpause=0;

       draw_box(-1,Maxx-vgax(150),2,Maxx-2,vgay(17),1,0);
       outtext(textb[0]);
    }*/
    /*show number of rules plotted*/
    draw_box(-1,Maxx-vgax(150),vgay(138),vgax(610),vgay(153),1,0);
    sprintf(textb[0],"total plotted=%lu",endcount);
    outtext(textb[0]);
    moveto(tempx,tempy);
}

/********************* lamdda ratio - Z parameter graph *******************/
void draw_lambda_z_graph(char dontbias){
    
  signed int z,zz,sod,tablemax,xbox,xbox1,xbox_CP;
 unsigned long tgr,*canal_freq,*lr_freq,**canal_lr_freq,zu;
 char show_CP;

   tablemax=(signed int)pow(2,(double)nhood)-1;


   sprintf(textb[0],"canal_freq");
   if ((canal_freq=
      (unsigned long *)calloc(nhood+1,sizeof(unsigned long)))
				   ==NULL) outof_memory(textb[0]);

   sprintf(textb[0],"lr_freq");
   if ((lr_freq=
      (unsigned long *)calloc((tablemax+1)/2+1,sizeof(unsigned long)))
				   ==NULL) outof_memory(textb[0]);

   sprintf(textb[0],"canal_lr-freq");
   if ((canal_lr_freq=
      (unsigned long **)calloc(nhood+1,sizeof(unsigned long*)))
				   ==NULL) outof_memory(textb[0]);
   for (z=0;z<=nhood;z++){
      sprintf(textb[0],"canal_lr_freq");
      if ((canal_lr_freq[z]=
	(unsigned long *)calloc((tablemax+1)/2+1,sizeof(unsigned long)))
				   ==NULL) outof_memory(textb[0]);

   }
   
   /*if (nhood==4) mutate=3;*/    /*To check exhaustivly*/

   /*count down code-space from set code*/
   if (mutate==5){
      totalgraphrules=(unsigned long) dec_equiv(cacode[0],nhood);
      /*convert code to rule*/
      for (zz=tablemax;zz>=0;zz--){
	 sod=0;
	 for (z=nhood-1;z>=0;z--) sod+=get_bit(nm[z],zz);
	 set_bit(carule[0],zz,get_bit(cacode[0],sod));
      }
   }
   /*show all of rulespace*/
   else if (mutate==3)
      totalgraphrules=(unsigned long) dec_equiv(carule[0],tablemax);
   graphspot=ceil((double)lx/275);
   totcode_eq_or_cl=0;
   endcount=0;


   /* count ruleno or codeno */
   if (mutate==3 || mutate==5){
      if (value_range==2) z_parameter_all(nhood,0,carule[0]);
      else z_parameter_all_mvalue(nhood,0,carule[0]);
      
      if (lambda_z_graph==1)  /*x=Zpara graph - y=Lambda ratio*/
           moveto(gox+lx*zparam[0],goy-(signed int)(ly*lratio));
      /*plot Zleft - Zright, x=z->=zparam[1],  y=z->=zparam[2]*/
      else if (lambda_z_graph==2)        
           moveto(gox+lx*zparam[1],goy-ly*zparam[2]);
      circle(getx,gety,graphspot);

      for (endcount=0;endcount<=totalgraphrules;endcount++){
	 /*fprintf(stderr,"%lu ",endcount);*/
         if (value_range==2) z_parameter_all(nhood,0,carule[0]);
         else z_parameter_all_mvalue(nhood,0,carule[0]);
	 canal_freq[canaltotal]+=1;
	 lr_freq[(signed int)(lratio*(tablemax+1)/2)]+=1;
	 canal_lr_freq[canaltotal][(signed int)(lratio*(tablemax+1)/2)]+=1;

	 if (keycheck(0)=='q') break; /*to interrupt*/
	 /*draw_box(-1,Maxx-vgax(150),2,Maxx-2,vgay(17),1,0);*/

	 if (endcount%100==0){
	    draw_prompt_box(1);
	    sprintf(textb[0],"c-frequency:");
	    outtext(textb[0]);
	    for (z=0;z<=nhood;z++){
	       sprintf(textb[0],"%lu ",canal_freq[z]);
	       outtext(textb[0]);
	    }
	    sprintf(textb[0]," total rules=%lu last=%lu",
				    totalgraphrules+1,endcount);
	    outtext(textb[0]);
	 }

         /*mutate rule here, count down*/
	 /*if (mutate_rule(nhood)==0) break;*/ /*exiting before rule 0*/
         mutate_rule(nhood);

	 if (pause_show_code){
            show_rule_bottom(nhood,0,carule[0],0);
            input_string(1,0);
         }
         if (lambda_z_graph==1)  /*x=Zpara graph - y=Lambda ratio*/
               moveto(gox+lx*zparam[0],goy-(signed int)(ly*lratio));
         /*plot Zleft - Zright, x=z->=zparam[1],  y=z->=zparam[2]*/
         else if (lambda_z_graph==2)      
              moveto(gox+lx*zparam[1],goy-ly*zparam[2]); 
         circle(getx,gety,graphspot);
         /*print data*/
         /*if (get_bit(carule[0],0)==0){
            fprintf(stderr,"%3lu\t",dec_equiv(carule[0],tablemax));
            for (z=tablemax;z>=0;z--)
                          fprintf(stderr,"%d",get_bit(carule[0],z));
            fprintf(stderr,
             " \t%g \t%g \t%g \t%g\n",
                    lratio,zparam[1],zparam[2],zparam[0]);
         }*/
      }
      draw_prompt_box(1);
      sprintf(textb[0],"c-frequency:");
      outtext(textb[0]);
      for (z=0;z<=nhood;z++){
	 sprintf(textb[0],"%lu ",canal_freq[z]);
	 outtext(textb[0]);
      }
      sprintf(textb[0]," total rules=%lu last=%lu",
				    totalgraphrules+1,endcount);
      outtext(textb[0]);

      /*show number of rules plotted*/
      /*draw_box(-1,vgax(160),vgay(405),vgax(320),vgay(420),1,0);*/
      xbox_CP=draw_box(-1,vgax(160),vgay(405)-CHeight,vgax(320),vgay(420),1,0);
      if (codetypeonly=='a' || mutate==3)
	 sprintf(textb[0],"tot plotted=%lu",endcount);
      else if (codetypeonly=='e')
	 sprintf(textb[0],"tot plotted=%lu, equivs=%d",
					   endcount,totcode_eq_or_cl);
      else sprintf(textb[0],"tot plotted=%lu, clusters=%d",
					   endcount,totcode_eq_or_cl);
      outtext(textb[0]);


   }
   else{
      for (zu=1;zu<=totalgraphrules;zu++){
         if (value_range==2) z_parameter_all(nhood,0,carule[0]);
         else z_parameter_all_mvalue(nhood,0,carule[0]);
	 canal_freq[canaltotal]+=1;
	 lr_freq[(signed int)(lratio*(tablemax+1)/2)]+=1;
	 canal_lr_freq[canaltotal][(signed int)(lratio*(tablemax+1)/2)]+=1;

	 if (dontbias==1) goto skipcountf;

	 if (zu<.09*totalgraphrules) {
	    lambda_bias=5;
	    goto  skipcountf;
	 }
	 if (zu<.18*totalgraphrules) {
	    lambda_bias=10;
	    goto skipcountf;
	 }
	 if (zu<.27*totalgraphrules) {
	    lambda_bias=15;
	    goto skipcountf;
	 }
	 if (zu<.36*totalgraphrules) {
	    lambda_bias=20;
	    goto skipcountf;
	 }
	 if (zu<.45*totalgraphrules) {
	    lambda_bias=25;
	    goto skipcountf;
	 }
	 if (zu<.54*totalgraphrules) {
	    lambda_bias=30;
	    set_z_high=0;
	    goto skipcountf;
	 }
	 if (zu<.63*totalgraphrules) {
	    lambda_bias=35;
	    set_z_high=0;
	    goto skipcountf;
	 }
	 if (zu<.72*totalgraphrules) {
	    lambda_bias=40;
	    set_z_high=0;
	    goto skipcountf;
	 }
	 if (zu<.81*totalgraphrules) {
	    lambda_bias=45;
	    set_z_high=0;
	    goto skipcountf;
	 }
	 if (zu<.90*totalgraphrules) {
	    lambda_bias=50;
	    set_z_high=0;
	    goto skipcountf;
	 }

	 if (zu<=totalgraphrules) {
	    lambda_bias=50;
	    set_z_high=1;
	    /*set_z_high=0;*/
	    goto skipcountf;
	 }
	skipcountf:

	 if (keycheck(0)=='q') break; /*to interrupt*/

	 /*if (zu%100==0){ //info not shown
	    draw_box(-1,Maxx-vgax(150),2,Maxx-2,vgay(17),1,0);
	    sprintf(textb[0],"t=%lu c=%lu lb=%d zh=%d",
			    totalgraphrules,zu,lambda_bias,set_z_high);
	    outtext(textb[0]);
	 }*/

	 mutate_rule(nhood);

         if (lambda_z_graph==1)  /*x=Zpara graph - y=Lambda ratio*/
              moveto(gox+lx*zparam[0],goy-(signed int)(ly*lratio));
         /*plot Zleft - Zright, x=z->=zparam[1],  y=z->=zparam[2]*/
         else if (lambda_z_graph==2)       
              moveto(gox+lx*zparam[1],goy-ly*zparam[2]);
         circle(getx,gety,graphspot);
      }
      /*show number of rules plotted*/
      /*draw_box(-1,vgax(160),vgay(405),vgax(320),vgay(420),1,0);*/
      xbox_CP=draw_box(-1,vgax(160),vgay(405)-CHeight,vgax(320),vgay(420),1,0);
      sprintf(textb[0],"tot plotted=%lu",zu-1);
      outtext(textb[0]);
   }

   show_CP=0;
   moveto(xbox_CP,gety+CHeight);
#    if __UNIX__
        outtext("C-P data-d, +print-p:");
#    elif __WATCOM__
        outtext("C-P data-d:");
#    endif
   input_string(1,0);
   if (is[0]=='d') show_CP=1;
   if (is[0]=='p') show_CP=2;
     /*if (is[0]!='s') goto skip_CP;*/ 
   if (show_CP){ 
     unsigned int totalCin, totalCg;
     float column_space;

      column_space=10;

      if (mutate==5 || mutate==3) tgr=totalgraphrules+1;
      else tgr=totalgraphrules;

      if (nhood>=5) set_small_font();
     
      setcolor(lightred);
      draw_box(11,2,vgay(35),Maxx-2, Maxy/3,1,0);
      setcolor(white);
      xbox=getx;

      sprintf(textb[0],
        "Canalyzing-lambda ratio and P frequency count, total rules=%lu",
						  tgr);
#    if __UNIX__
        if (show_CP==2) fprintf(stderr,"\n%s\n",textb[0]);
#    endif
      outtext(textb[0]);

      moveto(xbox,gety+CHeight);
#    if __UNIX__
        if (show_CP==2) outtext("Canalyzing freq: ");
#    endif
      xbox1=getx;
      totalCin=totalCg=0;
      for (z=0;z<=nhood;z++){
	 if (canal_freq[z]<=9999) sprintf(textb[0],"C%d=%lu=%.3f%% ",
	   z,canal_freq[z],100*(float)canal_freq[z]/tgr);         
         else sprintf(textb[0],"C%d=%.3f%% ",
	       z,100*(float)canal_freq[z]/tgr);
#        if __UNIX__
             if (show_CP==2) fprintf(stderr,"%s",textb[0]);
#        endif 
         outtext(textb[0]);
         if (z>0) totalCg+=canal_freq[z];
         totalCin+=canal_freq[z]*z;/*total number of C inputs*/
      }
      
      sprintf(textb[0],"Cr=%d=%.3f%%, Cin=%d=%.3f%%",
              totalCg,100*( (float)totalCg/tgr ), 
	      totalCin,100*( (float)totalCin/(tgr*nhood) ) );
      outtext(textb[0]);
#        if __UNIX__
             if (show_CP==2) fprintf(stderr," %s",textb[0]);
#        endif         

      /*columns  range of lambda ratio*/
      moveto(xbox,gety+CHeight);
      xbox1=getx+CWidth*10;
      outtext("ldr  ");
#        if __UNIX__
             if (show_CP==2) fprintf(stderr,"\nldr  ");
#        endif 
      for (z=0;z<=(tablemax+1)/2;z++){
         moveto(xbox1+CWidth*column_space*z,gety);
         sprintf(textb[0],"%d/%d",z,(tablemax+1)/2);
         outtext(textb[0]);
#        if __UNIX__         
             if (show_CP==2) fprintf(stderr,"%-11s",textb[0]);
#        endif   

      }
      moveto(xbox,gety+CHeight);
      outtext("ldr  ");
#        if __UNIX__
             if (show_CP==2) fprintf(stderr,"\nldr  ");
#        endif 
      for (zz=0;zz<=(tablemax+1)/2;zz++){
	 moveto(xbox1+CWidth*column_space*zz,gety);
	 sprintf(textb[0],"%g",(float)zz/((tablemax+1)/2));
	 outtext(textb[0]);
#        if __UNIX__         
             if (show_CP==2) fprintf(stderr,"%-11s",textb[0]);
#        endif  
      }
      /*columns  range of P*/
      moveto(xbox,gety+CHeight);
      xbox1=getx+CWidth*10;
      outtext("P");
#        if __UNIX__
             if (show_CP==2) fprintf(stderr,"\nP    ");
#        endif 
      for (zz=0;zz<=(tablemax+1)/2;zz++){	 
	 moveto(xbox1+CWidth*column_space*zz,gety);
	 sprintf(textb[0],"%g",1-((float)zz/((tablemax+1)/2))/2);
	 outtext(textb[0]);
#        if __UNIX__         
             if (show_CP==2) fprintf(stderr,"%-11s",textb[0]);
#        endif  
      }

      moveto(xbox,gety+CHeight); 
      xbox1=getx+CWidth*10;  
      outtext("freq"); 
#        if __UNIX__
             if (show_CP==2) fprintf(stderr,"\nfreq ");
#        endif     
      for (z=0;z<=(tablemax+1)/2;z++){
         moveto(xbox1+CWidth*column_space*z,gety);
         if (lr_freq[z]>0){
	    if (lr_freq[z]<=999) sprintf(textb[0],"%lu=%.3f%%",
		   lr_freq[z],100*(float)lr_freq[z]/tgr);
            else sprintf(textb[0],"%.3f%%",
	        100*(float)lr_freq[z]/tgr);
            /*if (lr_freq[z]<=9999) sprintf(textb[0],"%lu",
		   lr_freq[z]);
            else sprintf(textb[0],"%.3f%%",
	             100*(float)lr_freq[z]/tgr);*/
            outtext(textb[0]);
         }
         else outtext("0");
#        if __UNIX__         
             if (show_CP==2) fprintf(stderr,"%-11s",textb[0]);
#        endif          
      }

      for (z=0;z<=nhood;z++){
         for (zz=0;zz<=(tablemax+1)/2;zz++){
	    if (zz==0){
	       moveto(xbox,gety+CHeight);
               xbox1=getx+CWidth*10;
	       sprintf(textb[0],"C=%d ",z);
	       outtext(textb[0]);
#              if __UNIX__
                  if (show_CP==2) fprintf(stderr,"\n%s ",textb[0]);
#              endif 
	    }
	    moveto(xbox1+CWidth*column_space*zz,gety);
	    if (canal_lr_freq[z][zz]>0){
	      if (canal_lr_freq[z][zz]<=999) sprintf(textb[0],"%lu=%.3f%%",
	         canal_lr_freq[z][zz],
		    100*(float)canal_lr_freq[z][zz]/(totalgraphrules+1));
               else sprintf(textb[0],"%.3f%%",
	       100*(float)canal_lr_freq[z][zz]/(totalgraphrules+1));
	      /*if (canal_lr_freq[z][zz]<=9999) sprintf(textb[0],"%lu",
	         canal_lr_freq[z][zz]);
               else sprintf(textb[0],"%.3f%%",
	           100*(float)canal_lr_freq[z][zz]/(totalgraphrules+1));*/

	       outtext(textb[0]);
	    }
	    else{
               sprintf(textb[0],"0");
               outtext(textb[0]);
            }
#           if __UNIX__         
                if (show_CP==2) fprintf(stderr,"%-11s",textb[0]);
#           endif  
         }   
      } 
      if (nhood>=5) restore_def_font();
   } /* end if (show_CP==1) */
    
   finish_options(0);
   erase_prompt_box(3);
   
   free(canal_freq);   
   free(lr_freq);   
   for (z=0;z<=nhood;z++) free(canal_lr_freq[z]);   
   free (canal_lr_freq);
   
   if (show_CP){
      sprintf(textb[9],"%s","boximage[11]");
      putimage(2,vgay(35),boximage[11],COPY_PUT,textb[9]);
      freeimage(boximage[11]);
   }
}

/***************** garden-of-Eden density <-> Z parameter ***************/
void gofE_z_graph(void){
 signed int z,zz,tempx2,xfinish;
 double ix,iy;
 char graphno;

    gox=vgax(360);
    /*goy=vgay(420);*/
    goy=vgay(415);

    lx=vgax(250);
    ly=vgay(250);

    setcolor(white);

    if (lambda_z_graph){ 
        graphno=1;/*graph of lambda ratio - Z*/
        setfillstyle(SOLID_FILL,black);/*clear patch for graph*/
        bar(Maxx/2,Maxy/3,Maxx-2,Maxy-vgay(30));      	        
    }
    else{
       if (gd_z_graph==1 || gd_z_graph==3) 
                      graphno=1;    /*1=graph for Z parameter*/
                                    /*3=graph size range*/
       else if (gd_z_graph==2) graphno=2;/*2=graph for lambda ratio*/
    }                                  

    iy=ly/10; 
    if (gd_z_graph==3){ 
       xfinish=totalgraphrules-1;
       ix=lx/(totalgraphrules-1);           
    }
    else{ 
       xfinish=10;
       ix=lx/10; 
    }
    for (zz=1;zz<=graphno;zz++){
	if (zz==2) gox-=vgax(300);

	moveto(gox,goy);
	linerel(lx,0);
      
	/*draw x-axis*/
	for (z=0;z<=xfinish;z++){
	   moveto(gox+ix*z,goy);
	   if (z!=xfinish) linerel(0,-vgay(5));
	   if (z%5==0 || (gd_z_graph==3 && z==xfinish)){
	      if (z!=xfinish) linerel(0,-vgay(5));
              moveto(gox+ix*z,goy+vgay(3));
              if (gd_z_graph==3){ 
                 sprintf(textb[0],"%d",z+startL);
                 if (z+startL>9) moverel(-CWidth/2,0);
              }
	      else sprintf(textb[0],"%.1f",(float)(z)/10);
	      outtext(textb[0]);
	   }
	}
	moveto(gox+lx,goy);
	linerel(0,-ly);

	/*title x-axis*/
	/*moveto(gox+ix*2,goy+CHeight*.75);*/
        moveto(gox+ix*2,goy+CHeight*.35);
        if (lambda_z_graph==2) sprintf(textb[0],"Z right");
        else {
	   if (zz==1){
                if (gd_z_graph==1 || gd_z_graph==2
                      || lambda_z_graph==1) 
                           sprintf(textb[0],"Z parameter");
                else if (gd_z_graph==3){
                   moveto(gox+ix*1.5,goy+CHeight*.35);
                   sprintf(textb[0],"network size");
		}
           }
	   if (zz==2) sprintf(textb[0],"Lambda ratio");
        }
	outtext(textb[0]);

	/*draw y-axis*/
	moveto(gox,goy);
	linerel(0,-ly);
	for (z=0;z<=10;z++){
	   moveto(gox,goy-iy*z);
	   if (z!=10) linerel(vgay(5),0);
	   if (z%5==0){
	      if (z!=10) linerel(vgay(5),0);
	      sprintf(textb[0],"%.1f",(float)(z)/10);
              moveto(gox-textwidth(textb[0]),goy-iy*z-CHeight/2);
	      outtext(textb[0]);
	   }
	}
	/*title y-axis*/
        if (lambda_z_graph==1) sprintf(textb[0],"Lda ratio");
        else if (lambda_z_graph==2) sprintf(textb[0],"Z left");
	else sprintf(textb[0],"G-density");
        moveto(gox-CWidth*3,goy-(signed int)(iy*4));       
	tempx2=getx;
	for (z=0;z<=strlen(textb[0])-1;z++){
	      sprintf(textb[1],"%c",textb[0][z]);
	      outtext(textb[1]);
	      moveto(tempx2,gety+CHeight*.7);
	}

	moveto(gox,goy-(signed int)ly);
	linerel((signed int)lx,0);
    }
    gox=vgax(360);
}

/***************** sei box Sept 2007 ***************/
void draw_sei(void){
    signed int temp;

           sprintf(textb[0],
             "UNREGISTERED, see www.ddlab.org, continue-ret:");
           moveto(0,-100); /*above the screen out of sight*/
           outtext(textb[0]);
	   
           temp=getx;
           temp=temp/2 + CWidth;
           draw_box(-1,Maxx/2-temp-vgax(15),Maxy/2-vgay(15),
			Maxx/2+temp+vgax(15),Maxy/2+vgay(15),1,green);
           draw_box(-1,Maxx/2-temp-vgax(8),Maxy/2-vgay(8),
			Maxx/2+temp+vgax(8),Maxy/2+vgay(8),1,black);
           moverel(CWidth,vgay(2));
           outtext(textb[0]);
           input_string(1,0);
           draw_box(-1,Maxx/2-temp-vgax(15),Maxy/2-vgay(15),
			Maxx/2+temp+vgax(15),Maxy/2+vgay(15),0,black);
}
/******************** allocate mem for istr-graph **********June2025*/
void allocate_mem_istr_graph(void){
            unsigned int z;
	       //max_istr_node_no is global
	       //all below is freed in main free_mem_istr_graph below
	       (stderr,"\n********** in allocate_mem_istr_graph *********");
	       if (basinfield)  /*size of state-space*/
		  max_istr_node_no=(unsigned int)(pow(value_range,(double)lineL)+1);
	       else max_istr_node_no=40951+1; //2^12+1
	       
	       //bytesL = no of bytes required to contain lineL bits
	       //fprintf(stderr,"\nbytesL=%d max_istr_node_no=%d",bytesL,max_istr_node_no);
	       //fprintf(stderr,"\ncalloc index_successor");	   
               if ((index_successor=(unsigned int*)calloc(max_istr_node_no,sizeof(unsigned int)))
		      ==NULL) outof_memory("index_successor");//used in graphxx
	      	       
               //used in graphxx and drawxx to print only
	       //fprintf(stderr,"\ncalloc pat_states");
	       if ((pat_state0=(char**)calloc(max_istr_node_no,sizeof(char*)))
				     ==NULL) outof_memory("pat_state0");
	       if ((pat_state1=(char**)calloc(max_istr_node_no,sizeof(char*)))
				     ==NULL) outof_memory("pat_state1");
	       //fprintf(stderr,"\ncalloc pat_states[]");
	       for (z=0;z<=max_istr_node_no-1;z++){
                   if ((pat_state0[z]=(char *)calloc(bytesL,sizeof(char)))==NULL) outof_memory("(pat_state0[0]");
	           if ((pat_state1[z]=(char *)calloc(bytesL,sizeof(char)))==NULL) outof_memory("(pat_state0[1]");
	       }

	       //note: (basin_pos was calloc and freed in runXX (changed, now below)
	       //fprintf(stderr,"\ncalloc basin_pos");
               if ((basin_pos=(signed int**)calloc(max_istr_node_no, 
		       sizeof(signed int*)))==NULL) outof_memory("basin_pos");
	       //fprintf(stderr,"\ncalloc basin_pos[]");
	       for (z=0;z<=max_istr_node_no-1;z++){
	          if ((basin_pos[z]=(signed int *)calloc(
			2,sizeof(signed int)))==NULL) outof_memory("basin_pos[]");
               }
	       //fprintf(stderr,"\ncalloc complete in mainxx, bytesL=%d max_istr_node_no=%d",bytesL,max_istr_node_no);
}
/******************** free mem for istr-graph **********June2025*/
void free_mem_istr_graph(void){
      unsigned int z;
            //fprintf(stderr,"\n>>>>>>>>>>>>in free_mem_istr_graph>>>>>>>>>>>>");
            //was calloced in allocate_mem_istr_graph above
      
            //fprintf(stderr,"\nfree basin_pos[z]");
	    for (z=0;z<=max_istr_node_no-1;z++) free(basin_pos[z]);
	    //fprintf(stderr,"\nffree(basin_pos);");
	    free(basin_pos);

            //fprintf(stderr,"\nfree pat_state1[z]");
	    for (z=0;z<=max_istr_node_no-1;z++) free(pat_state1[z]);
	    //fprintf(stderr,"\nffree(pat_state1);");
	    free(pat_state1);

	    //fprintf(stderr,"\nfree pat_state0[z]");
	    for (z=0;z<=max_istr_node_no-1;z++) free(pat_state0[z]);
	    //fprintf(stderr,"\nfree(pat_state0);");	    
	    free(pat_state0);

            //fprintf(stderr,"\nfree(index_successor)");          
	    free(index_successor);	    
}
/*-----------------------------------------------------------------------------*/
