/*
 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/>.
 */

/******** various functions that work with run_forward() ******/
#include "edecfunc.h"
#include <fcntl.h>
#if __WATCOM__
#   include <io.h>
#   include <sys\stat.h>

#elif __UNIX__
#   include <sys/types.h>
#   include <sys/uio.h>
#endif
/***************  list of functions in this file *************/
/*
void plot_diff_pattern(diff_var *dp, ent_eeg *eg, int_stp *it)
void show_frozen_skel_hist(sk_att *sk, diff_var *dp,int_stp *it,
                       signed int stpwidth)
void show_att_type_hist(sk_att *sk,diff_var *dp, int_stp *it,
                       signed int stpwidth)
void draw_2d_frame(ent_eeg *eg, int_stp *it)
void setup_diff_plot(diff_var *dp)
void show_diff_plot(char redraw,diff_var *dp)*/

/*these two functions occur only in this file,
but if declared locally instead of globaly, there's a difference
in the damage histogram, more chaotic, dont know why??*/
/*char redraw,diff_var *dp);*/
/*void hist_save_load(unsigned int thismax_histno,
                     unsigned int *this_hist);*/  
/*void draw_diff_graphframe(diff_var *dp, 
                 char first, char xlog, char ylog);*/

/*void entropy_eeg_plot(auto_ent *ae, ent_eeg *eg,int_stp *it,
                                            unsigned char nhdcolor)*/
/*char moment(auto_ent *ae, ent_eeg *eg, int_stp *it, char *thisrule)*/

void set_new_rnd_or_biased_rule(auto_ent *ae,int_stp *it,float sdev);

/*void glider_rule(int_stp *it)
unsigned long stat_rule(char autostat, unsigned long statrule_index,
			             int_stp *it,signed int stpwidth)
void draw_axon_plane(float fscale,signed int tempy,draw_3d_grid)
signed int set_nhdcolor(char tnhood,signed int z)
void draw_stpframe(signed int stpwidth,float framewidth)
void draw_entgraph_frame(char draw_clear, signed int stpwidth,
	                          char show_edata,char ylabel)
void draw_Hamming_plot(char draw_clear, signed int stpwidth)
char select_stat_filename(auto_ent *ae)
unsigned int load_rule_stats(char repeat_sample, signed int stpwidth)*/
void ent_3d(unsigned char *Zbuf, unsigned char *lambdabuf,
	    unsigned long filebytes,char graphtype,signed int stpwidth);

void highlight_box(signed int X1,signed int Y1,
		   signed int X2,signed int Y2,
		     char show_list,
		     char listbox,
		     char graphtype,
		     signed int stpwidth,
		     signed int rulebytes,
		     unsigned long filebytes,
		     unsigned int datachunk,
		     char *rulebuf,
		     unsigned char *Zbuf,
		     unsigned char *lambdabuf,
		     float ave,
                     float sdev);

void show_list_rules(char smalldots,
                     char show_list,             
		     char listbox,
		     char graphtype,
		     signed int stpwidth,
		     signed int rulebytes,
		     unsigned long filebytes,
		     unsigned int datachunk,
		     char *rulebuf,
		     unsigned char *Zbuf,
		     unsigned char *lambdabuf,
		     float ave,
                     float sdev,
                     unsigned char m_ent_box,
		     unsigned char sdev_box);
signed int
     statx,
     staty,
     oldstatx,
     oldstaty;/*position of point on statistics graph*/

float tempent=0, old_tempent=0, tempmin=0, minmin=1, 
  tempmax=0, maxmax=0,tempminmax=0,minmax=0,max_minmax=0;

char auto_glider_sample=0;

char barcolor=1, showlog=1;
//these were local to in void ent_3d, now file-global to preserve values if changed

char sublist=0; //was local, now file-global to preserve values if changed

/***************** plot difference pattern **********************/  
void plot_diff_pattern(diff_var *dp,
		       ent_eeg *eg,
		       int_stp *it){

unsigned int n,zu,tempdiffx,tempdiffy;
signed int ii,jj,xbox;
char isdiff,same;
unsigned char diffcolor;

#  define clear_diff_plot {\
      for (zu=0;zu<=bytesL-1;zu++) tempState[zu]=0;\
}
	   dp->damage_count=dp->percent_damage=0;
	   tempdiffx=getx;
	   tempdiffy=gety;
	   setcolor(white);

	   /*draw 2d difference pattern*/
	   if (twod==2){
              if (stp){
	         eg->topleftx=(it->fscale*(i2d+it->diffgap))/4;
	         eg->toplefty=it->fscale*(j2d+it->diffgap);
	         moveto(eg->topleftx,eg->toplefty);
              }
	      for (jj=j2d-1;jj>=0;jj--){
		 for (ii=i2d-1;ii>=i2d/2;ii--){
		    isdiff=0;
		    /*cell already damaged*/
		    if (diff_plot>=2 &&  /*retain damage*/
			    get_value(tempState,jj*i2d+ii)==1){
		       dp->damage_count+=1;
                       if (stp){
		          setfillstyle(SOLID_FILL,magenta);
		          bar(getx,gety,getx+it->fscale-it->fsep,
					    gety+it->fscale-it->fsep);
		          moverel(it->fscale,0);
                       }
		       continue;
		    }
		    /*no difference*/
                    same=0;
                    if (value_range==2){
		       if (get_bit(state1,jj*i2d+ii)==
			  get_bit(state1,jj*i2d +(ii-i2d/2))) same=1; /*same*/
                    }
                    else{
		       if (get_value(state1,jj*i2d+ii)==
			  get_value(state1,jj*i2d +(ii-i2d/2))) same=1;
                    }

                    if (same==1){
                       if (stp){
		             if (bground=='w') diffcolor=darkgray;
		             else if (bground=='b') diffcolor=white;
                       }
                    }              
		    /*cell is different*/
		    else{
		       dp->damage_count+=1;
		       isdiff=1;
		       diffcolor=magenta;
		    }
                    if (stp){
		       setfillstyle(SOLID_FILL,diffcolor);
		       bar(getx,gety,getx+it->fscale-it->fsep,
					    gety+it->fscale-it->fsep);
                    }
		    if (diff_plot>=2 && isdiff==1)/*set damage*/
			   set_value(tempState,jj*i2d+ii,1);
		    if (stp) moverel(it->fscale,0);
                    
		 }
		 if (stp) moveto(eg->topleftx,gety+it->fscale);
	      }
	   }
	   /*draw 1d difference pattern*/
	   else if (twod==0){
              if (stp){
	         moveto((lineL+it->diffgap)*it->fscale+vgax(10),gety);
#                if __UNIX__ /*draw to pixmap*/
		    *current_draw = *it->offscreen_pixmap;
#                endif
              }
	      for (n=lineL-1;n>=lineL/2;n--){
		 isdiff=0;
		 /*cell already damaged*/
		 if (diff_plot>=2 &&  /*retain damage*/
			    get_value(tempState,n)==1){
		    dp->damage_count+=1;
                    if (stp){
		       setfillstyle(SOLID_FILL,magenta);
		       bar(getx,gety,getx+it->fscale-it->fsep,
					    gety+it->fscale-it->fsep);
		       moverel(it->fscale,0);
                    }
		    continue;
		 }
                 same=0;
		 /*no difference*/
                 if (value_range==2){
		   if (get_bit(state1,n)==get_bit(state1,n-(lineL/2))) same=1;
		 }
                 else{
		    if (get_value(state1,n)==get_value(state1,n-(lineL/2))) same=1;
                 }
	         if (same==1){
                    if (stp){
		       if (bground=='w') diffcolor=darkgray;
		       else if (bground=='b') diffcolor=white;
                    }
                 }
		 /*cell is different*/
		 else{
		    dp->damage_count+=1;
		    isdiff=1;
		    if (stp) diffcolor=magenta;
		 }
                 if (stp){
		    setfillstyle(SOLID_FILL,diffcolor);
		    bar(getx,gety,getx+it->fscale-it->fsep,gety+it->fscale-it->fsep);
                 }
		 if (diff_plot>=2 && isdiff==1) /*set damage*/
			   set_value(tempState,n,1);
		 if (stp) moverel(it->fscale,0);
	      }
              if (stp){
#                if __UNIX__
		    *current_draw = W; /*draw to window*/
#                endif
              }
	   }

	   xbox=Maxx-vgax(160);
	   draw_box(-1,xbox-3,2+CHeight+vgay(6),
		   Maxx-2,2+(CHeight+vgay(6))*2,1,0);
	   moveto(xbox,gety);
	   dp->percent_damage=
                      100.0*(float)dp->damage_count/(lineL/2);
           sprintf(textb[0],"damage=%lu/%d=%.2f%%",
		 dp->damage_count,lineL/2,dp->percent_damage);
	   outtext(textb[0]);
	   
	   /*statistical damage sample*/	   
	   if (diff_plot==3 || diff_plot==4){
	      if (dp->old_damage_count==dp->damage_count){
		 if (dp->damage_count==0)
			  dp->same_count=dp->same_limit+1;
		 else if (it->ittcount>dp->d_ittcount)
			  dp->same_count+=1;
	      }
	      else dp->same_count=0;
              
	      if (dp->same_count>dp->same_limit &&
				it->ittcount>dp->d_ittcount){
				
		 show_diff_plot(0,dp); /*update the graph*/

	         /*set new duplicate random seeds*/
		 it->color1=random_seed(it->color1,100,0);

		 /*clear the difference plot buffer*/
		 clear_diff_plot;
	         if (show_ss_matrixF==1)
		     show_statespace_matrix(NULL);
		 dp->diff_sample_count+=1;
		 dp->old_damage_count=
		     dp->damage_count=dp->same_count=0;
		 it->ittcount=0;
	      }
	      dp->old_damage_count=dp->damage_count;
	   }
	   moveto(tempdiffx,tempdiffy);
}
 

/**********************  frozen skeleton histogram ***********************/
void show_frozen_skel_hist(sk_att *sk,
			   diff_var *dp,
			   int_stp *it,signed int stpwidth){

 char newbox,sortit,temp_pause=0;;
 signed int z,zz;
 unsigned int tempdiffx,tempdiffy,
                z1,z2,zu1,
                sk_Ham,/*Hamming distance from skeleton types*/
                this_att_type,
                att_box_height;                   
 char att_match,sortneeded;

           scale=it->fscale; /*to rescale inset skeleton pattern if size changed*/
           dp->damage_count=dp->percent_damage=0;
	   tempdiffx=getx;
	   tempdiffy=gety;
	   setcolor(white);
           /*check if this frozen_buff is the same as previous*/
           if (memcmp(sk->frozen_buff,sk->ref_buff,bytesL)==0){
               dp->same_count+=1;
	   }
           /*if not, check how different -- Ham distance -- 
                                     may still be close enough*/
           else if (sk->percent_frozen_diff<100
		 || memcmp(state1,all_0s,bytesL)==0 /*all 0s*/
                 || memcmp(state1,all_1s,bytesL)==0){  /*all 1s*/
              sk_Ham=0;
	      for (z1=0;z1<=bytesL-1;z1++){
		 if (memcmp(sk->frozen_buff+z1,sk->ref_buff+z1,1)!=0){
		    for (z2=0;z2<=7;z2++){
                       if (get_bit((sk->frozen_buff+z1),z2)!=
			       get_bit((sk->ref_buff+z1),z2)){
			  sk_Ham+=1;
                         
                       }
                       
		    }
		 }
                 if (sk_Ham>(signed int)
			   (((100.0-sk->percent_frozen_diff)/100)*lineL))
		    break;	 
	      }
              if (sk_Ham>(signed int)
		 (((100.0-sk->percent_frozen_diff)/100)*lineL)) dp->same_count=0;
	      else dp->same_count+=1;
            
	   }	   
	   else dp->same_count=0;

	   /*if the skeleton has remained stable enough, long enough*/
	   if (dp->same_count>dp->same_limit){ 
                  /*show skeleton type histogram*/       
		  att_match=0;
		  sk_Ham=0;
		  if (dp->att_types>0){
                        /*check skeleton against existing skeleton types*/
			for (zz=1;zz<=dp->att_types;zz++){
			   if (memcmp(sk->frozen_buff,sk->att_type_state[zz],bytesL)==0){
			      att_match=1;
			      break;
			   }
			}
                        /*compute Hamming distance*/
                        if (sk->percent_match<100){
			   for (zz=1;zz<=dp->att_types;zz++){
			      for (z1=0;z1<=bytesL-1;z1++){
			         if (memcmp(sk->frozen_buff+z1,
					  sk->att_type_state[zz]+z1,1)!=0){
				     /*if bytes not same count diff bits*/
				     for (z2=0;z2<=7;z2++){
                                       if (get_bit((sk->frozen_buff+z1),z2)!=
					     get_bit((sk->att_type_state[zz]+z1),z2)){
					  sk_Ham+=1;
                                       }
				    }
			         }
                                 if (sk_Ham>(signed int)
				     (((100.0-sk->percent_match)/100)*lineL))
			            break;
			      }			      
                              if (sk_Ham>(signed int)
				  (((100.0-sk->percent_match)/100)*lineL)){
                                  sk_Ham=0;
				  continue;
			      }
                              else{
				 att_match=1;
				 break;
			      }
			   }                            
			}
			if (att_match==1){ 
			   sk->att_type_no[zz]++;                           
			   sk->att_type_avtrans[zz]=
			     ( sk->att_type_avtrans[zz]*(sk->att_type_no[zz]-1)
			          +it->ittcount-dp->same_count)/sk->att_type_no[zz];
                           this_att_type=zz;
			}
                        if (stp){
			   moveto(trboxw,Maxy/7);
 		           if (sk->skel_val==0) sprintf(textb[0],"%s","0s only");
                           else if (sk->skel_val==1) sprintf(textb[0],"%s","1s only");
                           else if (sk->skel_val==2) sprintf(textb[0],"%s","0s or 1s");
                           outtext(textb[0]);                 	
			   moveto(trboxw,Maxy/7+CHeight*1.5);
			   if (twod) print_current_state_twod(sk->frozen_buff,white,1);
			   else print_current_state(sk->frozen_buff,white);
                        }
		  }
	        
                  /*new skeleton found - add new type*/
		  if (att_match==0 || dp->att_types==0){ /*add new  type*/
		     if (dp->att_types==0 && stp){
                        moveto(trboxw,Maxy/7);
 		        if (sk->skel_val==0) sprintf(textb[0],"%s","0s only");
                        else if (sk->skel_val==1) sprintf(textb[0],"%s","1s only");
                        else if (sk->skel_val==2) sprintf(textb[0],"%s","0s or 1s");
                        outtext(textb[0]); 
		        moveto(trboxw,Maxy/7+CHeight*1.5);
			if (twod) print_current_state_twod(sk->frozen_buff,white,1);
			else print_current_state(sk->frozen_buff,white);
		     }
		     dp->att_types++;
                     this_att_type=dp->att_types;

		     if((sk->att_type_state=(char**)
			realloc(sk->att_type_state,
			     sizeof(char*)*(dp->att_types+1)))
				 ==NULL) outof_memory("sk->att_type_state");
		     sprintf(textb[0],"sk->att_type_state[%d]",dp->att_types);
		     if ((sk->att_type_state[dp->att_types]=(char *)
			calloc(bytesL,sizeof(char)))
				    ==NULL) outof_memory(textb[0]);
		     memmove(sk->att_type_state[dp->att_types],sk->frozen_buff,bytesL);

                     if((sk->att_type_no=(unsigned long*)
		          realloc(sk->att_type_no,
		                    sizeof(unsigned long)*(dp->att_types+1)))
		                         ==NULL) outof_memory("line 1435 sk->att_type_no");

		     sk->att_type_no[this_att_type]=1;

		     if((sk->type_fr0s=(float*)
			   realloc(sk->type_fr0s,
			      sizeof(float)*(dp->att_types+1)))
				 ==NULL) outof_memory("sk->type_fr0s");
		     sk->type_fr0s[this_att_type]=((float)(sk->frozen_0s*100))/lineL; 
                     if((sk->type_fr1s=(float*)
			   realloc(sk->type_fr1s,
			      sizeof(float)*(dp->att_types+1)))
				 ==NULL) outof_memory("sk->type_fr1s");
		     sk->type_fr1s[this_att_type]=((float)(sk->frozen_1s*100))/lineL; 
                     
		     if((sk->att_type_avtrans=(float*)
			   realloc(sk->att_type_avtrans,
			      sizeof(float)*(dp->att_types+1)))
			      ==NULL) outof_memory("sk->att_type_avtrans");

		     sk->att_type_avtrans[this_att_type]=it->ittcount-dp->same_count; 
		  }
                  dp->damage_count=this_att_type;
                  dp->damage_buf=sk->att_type_no;		  
                  sk->att_sample_no+=1;
                  dp->diff_sample_count=sk->att_sample_no;  
                 
                  /***************pause sk hist**********************/
                  start_pause_histogram:
                  if (dp->pause_dam_hist==1){
                    signed int xbox;

                     /*restore area below hist options box*/
# define              restore_below_hist_options {\
                        sprintf(textb[9],"%s","textb[9]");\
                        putimage(trboxw,2+CHeight+vgay(6),\
                                          boximage[21],COPY_PUT,textb[9]);\
                        freeimage(boximage[21]);\
		     }

                     setcolor(white);
                     xbox=draw_box(21,trboxw,2+CHeight+vgay(6),
				      Maxx-2,2+CHeight+vgay(6)+CHeight*2.5,1,0); 

                     outtext("skeletons histogram: hist-h stp-q data-d");
                     moveto(xbox,gety+CHeight); 		  
		     outtext("redraw-r sort-s undo-pause-u next-ret:");
                     input_string(1,0);
                    
                     if (is[0]=='d'){
                        if ((dp->att_types+2)*CHeight<Maxy-vgax(2))
                              att_box_height=(dp->att_types+4)*CHeight;
			else att_box_height=Maxy-2;
                        newbox=1;
                        xbox=(Maxx*5)/7;
                        draw_box(12,xbox-vgax(2),2,Maxx-2,att_box_height,1,0);
                        for (z=1;z<=dp->att_types;z++){
                           if (newbox==1){
                               moveto(xbox,gety);

                               if (sk->skel_val==0) outtext("0s ");
                               else if (sk->skel_val==1) outtext("1s ");
			       else if (sk->skel_val==2) outtext("0s & 1s ");
			       sprintf(textb[0],
		                "skeleton types so far=%d sample=%lu",
                                           dp->att_types,sk->att_sample_no);
		               outtext(textb[0]);
                               moveto(xbox,gety+CHeight);
                               
                               //set_medium_font();
                               outtext("type");
                               
                               moveto(xbox+Maxx/20,gety);
                               outtext("no");
                               moveto(xbox+(Maxx/20)*2,gety);
                               outtext("freq");
                               moveto(xbox+(Maxx/20)*3,gety);
                               outtext("%fr-0s-1s");
                               moveto(xbox+(Maxx/20)*4.5,gety);
			       outtext("avtrans");
			       moveto(xbox,gety+CHeight);
			   }
			   newbox=0;
			   sprintf(textb[0],"%d",z);
                           outtext(textb[0]);
                           moveto(xbox+Maxx/20,gety);
                           sprintf(textb[0],"%lu",sk->att_type_no[z]);
                           outtext(textb[0]);
                           moveto(xbox+(Maxx/20)*2,gety);
			   sprintf(textb[0],"%.4f",
				   (float)sk->att_type_no[z]/sk->att_sample_no);
                           outtext(textb[0]);
                           moveto(xbox+(Maxx/20)*3,gety);
			   
                           sprintf(textb[0],"%.1f",sk->type_fr0s[z]);
		           outtext(textb[0]);
                           moveto(xbox+(Maxx/20)*3+CWidth*4,gety);
                           sprintf(textb[0],"%.1f",sk->type_fr1s[z]);
		           outtext(textb[0]);
			   
			   moveto(xbox+(Maxx/20)*4.5,gety);
                           sprintf(textb[0],"%.1f",sk->att_type_avtrans[z]);
                           outtext(textb[0]);
                           moveto(xbox,gety+CHeight);
                           if (gety>=Maxy-vgax(2)-CHeight*2 ||
			                       z==dp->att_types){
                              newbox=1;
			      if (z==dp->att_types)
				  outtext("cont-ret jump-j:");
                              else outtext("more-ret quit-q jump-j:");
                              input_string(1,0);
                              if (is[0]=='q' ||
				     (z==dp->att_types && is[0]==13)) break;
			      /*jump to new skeleton type*/
                              else if (is[0]=='j'){ 
                                 sprintf(textb[0],
				     " index (%d-1):",dp->att_types);
                                 outtext(textb[0]);
                                 sprintf(textb[0],"%d",dp->att_types);
                                 input_string(strlen(textb[0]),0);
                                 if (atoi(is)>=0 && atoi(is)<=dp->att_types){
				    z=atoi(is)-1;
                                    draw_box(-1,xbox-vgax(2),2,Maxx-2,
					     att_box_height,1,0);
				    continue;
                                 }
                              }	
                              draw_box(-1,xbox-vgax(2),2,Maxx-2,att_box_height,1,0);
                           }
                        }
                        //restore_def_font();
                        sprintf(textb[9],"%s","boximage[12]");	    
                        putimage(xbox-vgax(2),2,boximage[12],COPY_PUT,textb[9]);
	                freeimage(boximage[12]);
                        is[0]=0;
                        restore_below_hist_options;
                        goto start_pause_histogram;
                     }

                     else if (is[0]=='r'){ /*redraw histogram - in case covered by stp-1d*/
                        dp->pause_dam_hist=0;
                        show_diff_plot(1,dp);
                        dp->pause_dam_hist=1;
                        restore_below_hist_options;
                        goto start_pause_histogram;
		     } 		                         
                     
		     else if (is[0]=='s'){ /*sort all buffers by frequency */
		       char *temppoint;
                       unsigned long templ;
                       float tempfloat;
	               
                         draw_prompt_box(1);		  
		         outtext(
		          "sort by: frozen-0-1-b  avtrans-t frequency-def:");
                         input_string(1,0);
                        
			 while(1){
                           sortneeded=0;
                             
		           for (z=2;z<=dp->att_types;z++){
                              sortit=0; 
                              if (is[0]=='0'){
                                  if (sk->type_fr0s[z-1]<
                                    sk->type_fr0s[z]) sortit=1;
			      }
                              else if (is[0]=='1'){
                                  if (sk->type_fr1s[z-1]<
                                    sk->type_fr1s[z]) sortit=1;
			      }
			       else if (is[0]=='b'){
                                  if ((sk->type_fr0s[z-1]+sk->type_fr1s[z-1])<
                                    (sk->type_fr0s[z]+sk->type_fr1s[z-1])) sortit=1;
			      }
			      else if (is[0]=='t'){
                                  if (sk->att_type_avtrans[z-1]<
                                     sk->att_type_avtrans[z]) sortit=1;
			      }			      
			      else{
				  if (sk->att_type_no[z-1]<
				     sk->att_type_no[z]) sortit=1;
                              }
			      if (sortit==1){  
                                 templ=sk->att_type_no[z-1];
                                 sk->att_type_no[z-1]=sk->att_type_no[z];
			         sk->att_type_no[z]=templ;
                                 
			         temppoint=sk->att_type_state[z-1];
                                 sk->att_type_state[z-1]=sk->att_type_state[z];
			         sk->att_type_state[z]=temppoint;

				 tempfloat=sk->type_fr0s[z-1];
				 sk->type_fr0s[z-1]=sk->type_fr0s[z];
                                 sk->type_fr0s[z]=tempfloat;


				 tempfloat=sk->type_fr1s[z-1];
				 sk->type_fr1s[z-1]=sk->type_fr1s[z];
                                 sk->type_fr1s[z]=tempfloat;

				 tempfloat=sk->att_type_avtrans[z-1];
				 sk->att_type_avtrans[z-1]=sk->att_type_avtrans[z];
                                 sk->att_type_avtrans[z]=tempfloat;

				 sortneeded=1;
			      }	
			   }
                           if (sortneeded==0) break;
			}
                        dp->pause_dam_hist=0;
                        show_diff_plot(1,dp);/*redraw histogram after sorting*/
                        dp->pause_dam_hist=1;
                        restore_below_hist_options;
                        goto start_pause_histogram;
		     } 
							    
                     else if (is[0]=='h'){
                         show_diff_plot(1,dp);
                         restore_below_hist_options;
                         goto start_pause_histogram;
                     }
                     else if (is[0]=='u'){
                        restore_below_hist_options;
                        dp->pause_dam_hist=0; /*continue -- don't pause*/
                     }
                     else if (is[0]=='q'){ /*main pause options - backtrack*/
                        restore_below_hist_options;
                        return; 
                     }
                     else restore_below_hist_options;
                  }
                  is[0]=0;
                  /*update the histogram*/                  
                  if (dp->att_types>0){
                     temp_pause=dp->pause_dam_hist;
                     dp->pause_dam_hist=0;
		     show_diff_plot(0,dp); /*draw the histogram*/
                     dp->pause_dam_hist=temp_pause;
                     draw_prompt_box(1);
		     sprintf(textb[0],
		        "types=%d this=%d avtrans=%.1f",
			    dp->att_types,this_att_type,
			       sk->att_type_avtrans[this_att_type]);
		     outtext(textb[0]);

                     outtext(" \%fr:");
                     sprintf(textb[0],"1s=%.1f 0s=%.1f",
                       (float)(sk->frozen_1s*100)/lineL,
		          (float)(sk->frozen_0s*100)/lineL);
                     outtext(textb[0]);
	          }
                  
                  if (stp && !twod) it->screenend=1;

		  /*set random seed*/
		  /*it->color1=random_seed(it->color1,100,0); has fixed density*/
                  for (zu1=lineL-1;zu1!=Maxu;zu1--){ /*unbiased*/
                     set_bit(state1,zu1,(myrand()%100)/50);
                  }
 
                  if (show_ss_matrixF==1)
		       show_statespace_matrix(NULL);
		  dp->damage_count=dp->same_count=0;
		  it->ittcount=0;
	   }
           if (dp->same_count==0) memmove(sk->ref_buff,sk->frozen_buff,bytesL); 
           free(sk->frozen_buff); /*reset sk->frozen_buff*/
           if ((sk->frozen_buff=(char *)calloc(bytesL,sizeof(char)))
			      ==NULL) outof_memory("sk->frozen_buff");
	   moveto(tempdiffx,tempdiffy);
}

/*********************** show attractor type histogram **************************/
void show_att_type_hist(sk_att *sk,diff_var *dp,int_stp *it,
                                        signed int stpwidth){

 char att_match, newbox,temp_pause=0;
 unsigned int this_att_type,att_box_height;
 signed int z,zz;                  
 
                  if (dp->att_types==0){
                     if ((m_att=(char***) calloc(1,sizeof(char**)))
                                  ==NULL) outof_memory("m_att***");
                     if ((m_att[0]=(char**) calloc(1,sizeof(char*)))
                                  ==NULL) outof_memory("m_att**");

                     if ((m_att[0][0]=(char *)calloc(1,sizeof(char)))
				  ==NULL) outof_memory("m_att*");

		     if (att_trans==1){
                        if ((m_trans=(char***) calloc(1,sizeof(char**)))
                                  ==NULL) outof_memory("m_trans***");
                        if ((m_trans[0]=(char**) calloc(1,sizeof(char*)))
                                  ==NULL) outof_memory("m_trans**");
                        if ((m_trans[0][0]=(char *)calloc(1,sizeof(char)))
				  ==NULL) outof_memory("m_trans*");
                     }
                  }

		  att_match=0;
		  if (dp->att_types>0){
                      /*check att cycle against ex att_types*/
		      for (z=1;z<=attperiod;z++){
			for (zz=1;zz<=dp->att_types;zz++){
			   if (memcmp(att[z],sk->att_type_state[zz],bytesL)==0){
			      att_match=1;
			      break;
			   }
			}
			if (att_match==1){
			   sk->att_type_no[zz]++;
                           
			   sk->att_type_avtrans[zz]=
			   ( sk->att_type_avtrans[zz]*(sk->att_type_no[zz]-1)
				+it->ittcount-attperiod )/sk->att_type_no[zz];
                           this_att_type=zz;
			   break;
			}
		     }
		  }

                  /*for existing attractor zz add new transients*/
                  if (att_trans==1 && att_match==1 && sk->this_trans_length>0){
                    signed int extra_length=0;
                    char **extra_trans,match_found; 
                      if ((extra_trans=(char **)calloc(1,sizeof(char*)))
				  ==NULL) outof_memory("extra_trans**");
		      /*check any overlap between new and with existing transient*/
                      for (z=0;z<=sk->this_trans_length;z++){ /*new*/
                         match_found=0;
                         for (zz=0;zz<=sk->att_type_trans_length[this_att_type];zz++){ /*exist*/
			   if (memcmp(sk->trans_states[z],
				      m_trans[this_att_type][zz],bytesL)==0){
                              match_found=1;
                              break;
                           }                      
                         }

                         if (match_found==0){ /*no match, so add trans state to temp buff*/
                              /*increase no of trans states*/
			      extra_length+=1;
                              if ((extra_trans=(char **)realloc(extra_trans,
				    sizeof(char*)*(extra_length+1)))
				      ==NULL) outof_memory("extra_trans*");                              
                              /*allocate mem to new trans state*/
                              if ((extra_trans[extra_length]=
                                     (char *)calloc(bytesL,sizeof(char)))
				              ==NULL) outof_memory("extra_trans*");

                              memmove(extra_trans[extra_length],sk->trans_states[z],bytesL);
			 }                                                  
		      }
                      if (extra_length>0){
                        signed int old_trans_length;
                         
			 old_trans_length=sk->att_type_trans_length[this_att_type];
			 sk->att_type_trans_length[this_att_type]+=extra_length;
                         /*increase no of transients by extra_length*/
                         if((m_trans[this_att_type]=(char**) realloc(m_trans[this_att_type],
			    sizeof(char*)*(sk->att_type_trans_length[this_att_type]+1)))
				        ==NULL) outof_memory("m_trans[this_att_type]");
                         /*allocate mem to new trans states*/
			 for (z=old_trans_length+1;
                              z<=sk->att_type_trans_length[this_att_type];z++){
                            if ((m_trans[this_att_type][z]=(char *)calloc(bytesL,sizeof(char)))
				              ==NULL) outof_memory("m_trans*");

                            memmove(m_trans[this_att_type][z],
				   extra_trans[z-old_trans_length],bytesL);
			 }                        
		      }
		      for (z=1;z<=extra_length;z++) free(extra_trans[z]);
                      free(extra_trans);
                  }

                  /*new attractor found - add new type*/
		  if (att_match==0 || dp->att_types==0){ /*add new type*/
		     dp->att_types++;
                     this_att_type=dp->att_types;
	            /*------------------------------------------------*/
                     /*update record of each attractor's cycle states for jumpgraph*/      
                     if ((m_att=(char***) realloc(
                            m_att,sizeof(char**)*(this_att_type+1)))
				       ==NULL) outof_memory("m_att***");
              
                     if ((m_att[this_att_type]=(char **)
                                   calloc(attperiod+1,sizeof(char*)))
				     ==NULL) outof_memory("m_att**");
 
                     if ((m_att[this_att_type][0]=(char *)calloc(1,sizeof(char)))
	                             ==NULL) outof_memory("m_att*");

                     for (z=1;z<=attperiod;z++){
	                if ((m_att[this_att_type][z]=
                               (char *)calloc(bytesL,sizeof(char)))
				     ==NULL) outof_memory("m_att*");
                        memmove(m_att[this_att_type][z],att[z],bytesL);
                     }
                     /*-----------------------------------------------*/

		     if((sk->att_type_state=(char**)
			realloc(sk->att_type_state,
			     sizeof(char*)*(dp->att_types+1)))
				 ==NULL) outof_memory("sk->att_type_state");

		     sprintf(textb[0],"sk->att_type_state[%d]",dp->att_types);
		     if ((sk->att_type_state[dp->att_types]=(char *)
			calloc(bytesL,sizeof(char)))
				    ==NULL) outof_memory(textb[0]);
		     memmove(sk->att_type_state[dp->att_types],state1,bytesL);
		     
                     if((sk->att_type_no=(unsigned long*) 
			realloc(sk->att_type_no,
			   sizeof(unsigned long)*(dp->att_types+1)))
			      ==NULL) outof_memory("sk->att_type_no");

		     sk->att_type_no[this_att_type]=1;
		     if((sk->att_type_period=(unsigned int*)
			realloc(sk->att_type_period,
			   sizeof(unsigned int)*(dp->att_types+1)))
				 ==NULL) outof_memory("sk->att_type_period");

		     sk->att_type_period[this_att_type]=attperiod;
		     if((sk->att_type_avtrans=(float*)
			   realloc(sk->att_type_avtrans,
			      sizeof(float)*(dp->att_types+1)))
				 ==NULL) outof_memory("sk->att_type_avtrans");

		     sk->att_type_avtrans[this_att_type]=it->ittcount-attperiod;

                    /*-----------------------------------------------------------*/
                    if (att_trans==1){                    
                        /********------------realloc m_trans--------*********/
                        if ((m_trans=(char***) realloc(
                            m_trans,sizeof(char**)*(this_att_type+1)))
				       ==NULL) outof_memory("m_trans***");
              
                        if ((m_trans[this_att_type]=(char **)
                                   calloc(sk->this_trans_length+1,sizeof(char*)))
				     ==NULL) outof_memory("m_trans**");
                        /******* record new transient  ***********************/
                        /*transient index starts from 0 */
                        for (z=0;z<=sk->this_trans_length;z++){
	                   if ((m_trans[this_att_type][z]=
                               (char *)calloc(bytesL,sizeof(char)))
				     ==NULL) outof_memory("m_trans*");
                           memmove(m_trans[this_att_type][z],sk->trans_states[z],bytesL);
                        }
                        /*record first transient length for new att type*/ 
                        if((sk->att_type_trans_length=(unsigned int*)
			   realloc(sk->att_type_trans_length,
			      sizeof(unsigned int)*(this_att_type+1)))
				 ==NULL) outof_memory("sk->att_type_trans_length");

		        sk->att_type_trans_length[this_att_type]=sk->this_trans_length;
                    }
                    /*-----------------------------------------------------------*/
                  } /*from: if (att_match==0 || dp->att_types==0) ------add new type*/

                  dp->damage_count=this_att_type;
                  dp->damage_buf=sk->att_type_no;
                  sk->att_sample_no+=1;
                  dp->diff_sample_count=sk->att_sample_no;

                  /*to keep track of seed density totals leading 
                    to all 0s and all 1s point attractors, 
                    to check fittness of the density rules*/
                  if (att_seed_dens==1 && value_range==2){ /*binary only*/
                     if (sk->att_type_period[this_att_type]==1){
                        signed int thispoint;
                        unsigned int zu, this_dens;

                        if (memcmp(sk->att_type_state[this_att_type],
                           all_0s,bytesL)==0) thispoint=0;
                        else if ( memcmp(sk->att_type_state[this_att_type],
                           all_1s,bytesL)==0) thispoint=1;
                        else goto skip;
		        /*check seed density*/
                        this_dens=0;
                        for (zu=0;zu<=lineL-1;zu++){
                           if (get_bit(firstseed,zu)==1) this_dens+=1;
                        }
                        /* [0]=less [1]=more [2]=50%*/
                        if (lineL%2==0 && this_dens==L/2) 
                                          sk->dens_seed[thispoint][2]+=1;
                        else if (this_dens>lineL/2) 
                                          sk->dens_seed[thispoint][1]+=1;
                        else sk->dens_seed[thispoint][0]+=1;

                        /*fprintf(stderr,"\n a=%d d=%d 0=%d 1=%d eq=%d",
                                thispoint,
                                this_dens,
				sk->dens_seed[thispoint][0],
				sk->dens_seed[thispoint][1],
                                sk->dens_seed[thispoint][2]);*/
		        skip:;
                     }
                  }

		  /***************pause att hist**********************/
                 start_pause_histogram:
                  if (dp->pause_dam_hist==1){
                    signed int xbox;

                     /*restore area below hist opions box*/
# define              restore_below_hist_options {\
                        sprintf(textb[9],"%s","textb[9]");\
                        putimage(trboxw,2+CHeight+vgay(6),\
                                          boximage[21],COPY_PUT,textb[9]);\
                        freeimage(boximage[21]);\
		     }
                  		     
                     setcolor(white); 
                     xbox=draw_box(21,trboxw,2+CHeight+vgay(6),
				      Maxx-2,2+CHeight+vgay(6)+CHeight*2.5,1,0); 	
                     	  
		     outtext("attractors histogram: hist-h stp-q, data:show-d print-p save-S");
                     moveto(xbox,gety+CHeight); 
	             outtext("redraw-r sort-s undo-pause-u next-ret jump-graph-j:");
                     input_string(2,0);

                     if (is[0]=='p' || is[0]=='S' ){/*print or save data*/
                       unsigned int zu,zzu,zcount,za;                      
                       char dowhat,*linebuf,att_trans_match;
                       unsigned int tot_trans_found=0;

                       if ((linebuf=(char *)calloc(lineL+2,sizeof(char)))
				     ==NULL) outof_memory("linebuf");

                       if (is[0]=='p') dowhat='p';
                       if (is[0]=='S'){
                          signed int fid;
                          char file_ret;   
                            dowhat='S';                    
 	                   file_ret=select_filename("SAVE","DATA","*.dat","my_data");
	                   if (file_ret=='q'){
                              restore_below_hist_options;
                              goto start_pause_histogram;
                           }
	                   memmove(filename_data,filename,13);
                           fid=myopen(filename_data,1,1);
                           if (fid==-1) file_error(filename_data);
	                   close(fid);
	               }
                       
                       if (oned) sprintf(textb[0],"\n1d net=%d v=%d",lineL,value_range);
                       else sprintf(textb[0],"\n2d net=%dx%d v=%d",i2d,j2d,value_range);
                       if (nhood_mixed) sprintf(textb[1]," k=%d-%d",nhood_lb,nhood_ub);
                       else sprintf(textb[1]," k=%d",nhood);
                       if (!nonlocal) sprintf(textb[2]," local wiring");
                       else sprintf(textb[2]," rand-wiring");
     
                       sprintf(textb[3]," %s%s%s att-types=%d sample=%lu\n",
                           textb[0],textb[1],textb[2],dp->att_types,sk->att_sample_no);
                       
                       if (dowhat=='p') print_out(textb[3]);
                       if (dowhat=='S') save_data(textb[3]);

		       for (zu=1;zu<=dp->att_types;zu++){
			  tot_trans_found=0;

                          /*saving is slow - progress message*/
			  if (zu < dp->att_types){ 
                             sprintf(textb[8],"%d/%d saving wait...",zu,dp->att_types); 
			     inset_prompt_box(0,20,textb[8],'m');
		          }
			  else{
                            sprintf(textb[8],"%d/%d saving complete",zu,dp->att_types);
                            inset_prompt_box(0,20,textb[8],'m');
                          }

                          sprintf(textb[0],
                    "\natt-type %d: freq=%lu/%lu=%.4f period=%d av-trans=%.1f",
			      zu,sk->att_type_no[zu],sk->att_sample_no,
                                   ((float)sk->att_type_no[zu]/sk->att_sample_no),
				  sk->att_type_period[zu],sk->att_type_avtrans[zu]);

                          /*if (att_trans==1){
                            sprintf(textb[1],
			      " disclosure=%d",sk->att_type_trans_length[zu]);
                          }
                          else sprintf(textb[1],"");*/

                          if (oned) sprintf(textb[0],"%s%s\n",textb[0],textb[1]);
                          if (dowhat=='p') print_out(textb[0]);
                          if (dowhat=='S') save_data(textb[0]);
                          if (oned){
                             /*************** att data ***************/
                             for (z=1;z<=sk->att_type_period[zu];z++){ 
			        for (zzu=lineL-1;zzu!=Maxu;zzu--){
			           if (zzu==lineL-1) zcount=0;
                                   zcount++;
                                   /*for ascii*/     
                                   linebuf[zcount-1]=get_value(m_att[zu][z],zzu)+48; 
                                }
                                linebuf[lineL]=10; /*line feed*/
                             
                                if (dowhat=='p') print_out(linebuf);
                                if (dowhat=='S') save_data(linebuf); 
                             }
                             
                             /*************** trans data ***************/
                             if (att_trans==1){                              
                               sprintf(textb[0],
                                  "transients to att-type %d\n",zu);
                               if (dowhat=='p') print_out(textb[0]);
                               if (dowhat=='S') save_data(textb[0]);

                               if (sk->att_type_trans_length[zu]>=1){
				  tot_trans_found=0;				 
			          for (z=0;z<=sk->att_type_trans_length[zu];z++){
				    // for (z=1;z<=sk->att_type_trans_length[zu];z++){ 
                                     /*************** exclude att states from trans data ***************/
                                     att_trans_match=0;
                                     tot_trans_found++;
                                     for (za=1;za<=sk->att_type_period[zu];za++){
				        
				        if (memcmp(m_att[zu][za],m_trans[zu][z],bytesL)==0){ 
                                           att_trans_match=1;
                                           tot_trans_found--;
                                           break;
                                        }
                                     }
				     if (att_trans_match==1) continue;

			             for (zzu=lineL-1;zzu!=Maxu;zzu--){
			                if (zzu==lineL-1) zcount=0;
                                        zcount++;
                                        /*for ascii*/     
                                        linebuf[zcount-1]=
                                          get_value(m_trans[zu][z],zzu)+48; 
                                     }
                                     linebuf[lineL]=10; /*line feed*/
                             
                                     if (dowhat=='p') print_out(linebuf);
                                     if (dowhat=='S') save_data(linebuf);
                                     
				  }                                 
			       
                                  sprintf(textb[0],
                                  "transients att-type %d: %d so far, basin=%d\n",
					  zu,tot_trans_found,
                                             sk->att_type_period[zu]+tot_trans_found);

                                  if (dowhat=='p') print_out(textb[0]);
                                  if (dowhat=='S') save_data(textb[0]);
			       }
                             }
                             /********************************************/ 
			  }                                 
                       }
                       free(linebuf);
                       restore_below_hist_options;
                       goto start_pause_histogram; 
                     }
		     
                     if (is[0]=='j'){
		        jump_graph_table(dp->att_types,sk,'a');
                        restore_below_hist_options;
                        goto start_pause_histogram;
		     }
                     if (is[0]=='d'){
                        if ((dp->att_types+2)*CHeight<Maxy-vgax(2))
                              att_box_height=(dp->att_types+4)*CHeight;
			else att_box_height=Maxy-2;
                        newbox=1;
                        if (att_seed_dens==1) xbox=(Maxx*4)/7;
                        else xbox=(Maxx*5)/7;
                        
                        draw_box(12,xbox-vgax(2),2,Maxx-2,att_box_height,1,0);
                        for (z=1;z<=dp->att_types;z++){
                           if (newbox==1){
                               moveto(xbox,gety);
			       sprintf(textb[0],
		                "attractor types so far=%d sample=%lu",dp->att_types,sk->att_sample_no);
		               outtext(textb[0]);
                               moveto(xbox,gety+CHeight);

                               //set_medium_font();
                               outtext("type");

                               moveto(xbox+Maxx/20,gety);
                               outtext("no");
                               moveto(xbox+(Maxx/20)*2,gety);
                               outtext("freq");           
                                moveto(xbox+(Maxx/20)*3,gety);
                               outtext("period");
                               if (att_seed_dens==1){   
                                  moveto(xbox+(Maxx/20)*4.1,gety);
                                  outtext("dens-/50%/+");
                                  moveto(xbox+(Maxx/20)*6.5,gety);
                               }
                               else moveto(xbox+(Maxx/20)*4.1,gety);  
			       outtext("trans");
			       moveto(xbox,gety+CHeight);
			   }
                           newbox=0;
			   sprintf(textb[0],"%d",z);
                           outtext(textb[0]);
                           moveto(xbox+Maxx/20,gety);
                           sprintf(textb[0],"%lu",sk->att_type_no[z]);
                           outtext(textb[0]);
                           moveto(xbox+(Maxx/20)*2,gety);
			   sprintf(textb[0],"%.4f",
				   (float)sk->att_type_no[z]/sk->att_sample_no);
                           outtext(textb[0]);
                           moveto(xbox+(Maxx/20)*3,gety);
                           sprintf(textb[0],"%d",sk->att_type_period[z]);
                           outtext(textb[0]);
                           if (att_seed_dens==1){                              
                              if (sk->att_type_period[z]==1){
				set_medium_font();
                                 if (memcmp(sk->att_type_state[z],
                                           all_0s,bytesL)==0){
                                     outtext("(all 0s)");
                                     moveto(xbox+(Maxx/20)*4.1,gety);
                                     sprintf(textb[0],"%d/%d/%d e=%d%%",
                                      sk->dens_seed[0][0],sk->dens_seed[0][2],
                                        sk->dens_seed[0][1],
                                          (signed int)(100*
                                            (float)sk->dens_seed[0][1]/
                                              sk->att_type_no[z]));
                                     outtext(textb[0]);
                                 }
			         else if (memcmp(sk->att_type_state[z],
                                           all_1s,bytesL)==0){ 
                                    outtext("(all 1s)");
                                    moveto(xbox+(Maxx/20)*4.1,gety);
                                    sprintf(textb[0],"%d/%d/%d e=%d%%",
                                      sk->dens_seed[1][0],
                                       sk->dens_seed[1][2],
                                        sk->dens_seed[1][1],
                                          (signed int)(100*
                                            (float)sk->dens_seed[1][0]/
                                             sk->att_type_no[z]));
                                    outtext(textb[0]);
                                 }
                                 restore_def_font();
			      }
                              moveto(xbox+(Maxx/20)*6.5,gety);
                           }
                           else moveto(xbox+(Maxx/20)*4,gety);
                           sprintf(textb[0],"%.1f",sk->att_type_avtrans[z]);
                           outtext(textb[0]);
                           moveto(xbox,gety+CHeight);
                           if (gety>=Maxy-vgax(3)-CHeight*2 ||
			                       z==dp->att_types){
                              newbox=1;
			      if (z==dp->att_types)
				  outtext("cont-ret jump-j:");
                              else outtext("more-ret quit-q jump-j:");
                              input_string(1,0);
                              if (is[0]=='q' ||
				  (z==dp->att_types && is[0]==13)) break;
                              
			      /*jump to new att type*/
                              else if (is[0]=='j'){ 
                                 sprintf(textb[0],
				     " index (%d-1):",dp->att_types);
                                 outtext(textb[0]);
                                 sprintf(textb[0],"%d",dp->att_types);
                                 input_string(strlen(textb[0]),0);
                                 if (atoi(is)>=0 && atoi(is)<=dp->att_types){
				    z=atoi(is)-1;
                                    draw_box(-1,xbox-vgax(2),2,Maxx-2,
					     att_box_height,1,0);
				    continue;
                                 }
                              }	
                              draw_box(-1,xbox-vgax(2),2,Maxx-2,att_box_height,1,0);
                           }
                        }
                        sprintf(textb[9],"%s","boximage[12]");	    
                        putimage(xbox-vgax(2),2,boximage[12],COPY_PUT,textb[9]);
	                freeimage(boximage[12]);
                        is[0]=0;
                        restore_below_hist_options;
                        goto start_pause_histogram;
                     }
                     /*redraw histogram - in case covered by stp-1d*/
                     else if (is[0]=='r'){ 
                        dp->pause_dam_hist=0;
                        show_diff_plot(1,dp);
                        dp->pause_dam_hist=1;
                        restore_below_hist_options;
                        goto start_pause_histogram;
		     }
		                         
                     /*sort all buffers by frequency, attperiod, or avtrans */
		     else if (is[0]=='s'){  
                        char **temp_m_point,*temppoint,sortneeded,sortit;
                        /*these are just values*/
                        unsigned long templ;
                        unsigned int tempus;         
                        float tempfloat;

                        unsigned int zu;
     
                         draw_prompt_box(1);		  
		         outtext(
		          "sort by: attperiod-a avtrans-t frequency-def:");
                         input_string(1,0);

			 while(1){
                           sortneeded=0;                            
		           for (zu=2;zu<=dp->att_types;zu++){
                              sortit=0;
			      if (is[0]=='a'){
                                  if (sk->att_type_period[zu-1]<
                                     sk->att_type_period[zu]) sortit=1;
			      }  
                              else if (is[0]=='t'){
                                  if (sk->att_type_avtrans[zu-1]<
                                     sk->att_type_avtrans[zu]) sortit=1;
			      }  
			      else{
				  if (sk->att_type_no[zu-1]<
				     sk->att_type_no[zu]) sortit=1;
                              }
			      if (sortit==1){
				 temp_m_point=m_att[zu-1];
                                 m_att[zu-1]=m_att[zu];
                                 m_att[zu]=temp_m_point;
                                 
                                 templ=sk->att_type_no[zu-1];/*templ is unsigned long*/
                                 sk->att_type_no[zu-1]=sk->att_type_no[zu];
			         sk->att_type_no[zu]=templ;
      
                                 tempus=sk->att_type_period[zu-1];
                                 sk->att_type_period[zu-1]=sk->att_type_period[zu];
			         sk->att_type_period[zu]=tempus;
                                 
                                 /*array of one att state for each att type*/
			         temppoint=sk->att_type_state[zu-1];
                                 sk->att_type_state[zu-1]=sk->att_type_state[zu];
			         sk->att_type_state[zu]=temppoint;

                                 tempfloat=sk->att_type_avtrans[zu-1];
				 sk->att_type_avtrans[zu-1]=sk->att_type_avtrans[zu];
                                 sk->att_type_avtrans[zu]=tempfloat;

                                 /*---------- sort trans-------------------*/
                                 if (att_trans==1){ 
                                    temp_m_point=m_trans[zu-1];
                                    m_trans[zu-1]=m_trans[zu];
                                    m_trans[zu]=temp_m_point;

                                    tempus=sk->att_type_trans_length[zu-1];
                                    sk->att_type_trans_length[zu-1]=
                                                      sk->att_type_trans_length[zu];
                                    sk->att_type_trans_length[zu]=tempus;
                                 }
                                 /*------------------------------------------------*/
				 sortneeded=1;
			      }	
			   }
                           if (sortneeded==0) break;
			}
			dp->pause_dam_hist=0;
                        show_diff_plot(1,dp);/*redraw histogram after sorting*/
                        dp->pause_dam_hist=1;
                        restore_below_hist_options;
                        goto start_pause_histogram;
		     }                      
		    
                     else if (is[0]=='h'){
                         show_diff_plot(1,dp);
                         restore_below_hist_options;                         
                         goto start_pause_histogram;
                     }
                     else if (is[0]=='u'){
                        restore_below_hist_options; 
                        dp->pause_dam_hist=0; /*continue -- don't pause*/
                     }
                     else if (is[0]=='q'){ /*main pause options - backtrack*/
		        //erase_prompt_box(2); /*or continue -- and pause*/
                        restore_below_hist_options;
                        return; 
                     }
                     else restore_below_hist_options;

                  } //if (dp->pause_dam_hist==1){

                  is[0]=0;
		  
                  /*update the histogram, for attractors*/                  
                  if (dp->att_types>0){
		     temp_pause=dp->pause_dam_hist;
                     dp->pause_dam_hist=0;
		     show_diff_plot(0,dp); /*draw the histogram*/
                     dp->pause_dam_hist=temp_pause;
                     if (stp==1 /*&& dp->pause_dam_hist==0*/){
                        draw_prompt_box(1);
		        sprintf(textb[0],
		           "types=%d this=%d attperiod=%d avtrans=%.1f",
			     dp->att_types,this_att_type,
			      sk->att_type_period[this_att_type],
			       sk->att_type_avtrans[this_att_type]);
		        outtext(textb[0]);
                     }
		     
		     //show transient bins in terminal
		     //trans:bins-b, to sort trans length into bins -- need work so hidden
		     //see drpara outtext(" histogram, cancel-q, trans:data/bins-t/b, cont-ret:");
		     if (bin_trans==1){
		       signed int zb,Tabove=0; 
		       fprintf(stderr,"\n%d %d: ",this_att_type,
			       (signed int)sk->att_type_avtrans[this_att_type]);
		       for (zb=0;zb<=9;zb++){
			 //bins <100 <200 .... <1000			  
			 //if (zb<10 && sk->att_type_avtrans[this_att_type]<zb*100+100){
			 //bins <5 <10 <15.... <50
			 if (zb<sk->att_type_avtrans[this_att_type]<zb*5 && sk->att_type_avtrans[this_att_type]<zb*5+5){   
			     transient_bin[zb]+=1;
			     break;
		          }		
                          if (zb==10 && sk->att_type_avtrans[this_att_type]>=zb*5+5) transient_bin[10]+=1; //bigger than 50
		        }  
		        for (zb=0;zb<=10;zb++){
		           fprintf(stderr,"%d ",transient_bin[zb]);
			   if (zb>=4) Tabove+=transient_bin[zb];	
		        }	
		        fprintf(stderr,":%d/%d=%.3f",Tabove,this_att_type,(float)Tabove/this_att_type);
		     }
	          }
}

/**************** draw 2d frame (and for diffplot) ****************/
/*if plotting difference between 2 equalsize/shape networks
      draw 2 frames seperated by a 3 cell gap*/

void draw_2d_frame(ent_eeg *eg, int_stp *it){

#     if __WATCOM__
	  setcolor(white);                             
	  if (diff_plot){                              
	      rectangle(0,0,it->fscale*(i2d/2)+1,it->fscale*j2d+1);
              rectangle(it->fscale*(i2d/2)+it->fscale*it->diffgap-1,0, 
                   it->fscale*i2d+it->fscale*3+1,it->fscale*j2d+1);
	      eg->topleftx=(it->fscale*(i2d+it->diffgap))/4;
	      eg->toplefty=it->fscale*(j2d+it->diffgap);
	      rectangle(eg->topleftx-1,eg->toplefty-1,
		eg->topleftx+it->fscale*(i2d/2),eg->toplefty+it->fscale*j2d);
	  }
          if (twod && d_mode==2 && it->slant_even_k==1 && it->fscale>=3){ /*hex 2d*/
                  signed int z;
                  it->rect_h=0;
		  for (z=1;z<=j2d;z++)
		    /*it->rect_h+=(((double)it->fscale)/2)/tan(PI/6);*/
                    it->rect_h+=(double)it->fscale * cos(PI/6); 
                  rectangle(0,0,it->fscale*i2d+((double)it->fscale)/2+1,
                                           it->rect_h+it->fscale/2);
          }
	  else rectangle(0,0,it->fscale*i2d+
                    ((double)it->fscale)/2+1,it->fscale*j2d+1);
      
#     elif __UNIX__
	  /* *current_draw = *it->offscreen_pixmap;*/
	  setcolor(white); 
	  if (diff_plot){ 
	      rectangle(0,0,it->fscale*(i2d/2)+1,it->fscale*j2d+1);
	      rectangle(it->fscale*(i2d/2)+it->fscale*it->diffgap-1,0,
		   it->fscale*i2d+it->fscale*3+1,it->fscale*j2d+1); 
	  }
	  else{
	      if (twod && d_mode==2 && it->slant_even_k==1 && it->fscale>=3){
                  signed int z;
                  it->rect_h=0;
		  for (z=1;z<=j2d;z++)
		      /*it->rect_h+=(((double)it->fscale)/2)/tan(PI/6);*/
		      it->rect_h+=(double)it->fscale * cos(PI/6);
                  rectangle(0,0,it->fscale*i2d+((double)it->fscale)/2+1,
                                           it->rect_h+it->fscale/2);
              }
	      /*else rectangle(0,0,it->fscale*i2d+((double)it->fscale)/2+1,
		                                      it->fscale*j2d+1);*/
              else{ /*for small scale, bottom and right side only*/
		line(0,it->fscale*j2d+1,
                     it->fscale*i2d+((double)it->fscale)/2+1,it->fscale*j2d+1);
                line(it->fscale*i2d+((double)it->fscale)/2+1,it->fscale*j2d+1,
                     it->fscale*i2d+((double)it->fscale)/2+1,0);
              }
          }
	  /* *current_draw = W;*/
	  if (diff_plot){ 
	     eg->topleftx=(it->fscale*(i2d+it->diffgap))/4;
	     eg->toplefty=it->fscale*(j2d+it->diffgap);
	     rectangle(eg->topleftx-1,eg->toplefty-1,
		eg->topleftx+it->fscale*(i2d/2),eg->toplefty+it->fscale*j2d);
	  }
      
#     endif
}

/************ setup diff statistical sample plot *************/
void setup_diff_plot(diff_var *dp){

 signed int xbox;
 unsigned int zu;
unsigned long zul; 
      
      dp->diff_sample_count=1;
      dp->old_damage_count=0;

      if (att_hist) goto skip1;
      
      /*memory for damage statistical sample*/
    start:
      xbox=draw_prompt_box(4); 
     /*actual or bins chosen in drpara, forward_only_para()*/
     outtext("Damage Spread Histogram");

      /*outtext("Damage Spread: binned-b, actual-def:");
      input_string(1,0);
      if (is[0]=='q'){
         erase_prompt_box(4);
         return;
      }*/
      
      /*if (is[0]=='b') dp->d_bin_type='b';
	else dp->d_bin_type='n';*/

      if (diff_plot==3)  dp->d_bin_type='n';
      else if (diff_plot==4)  dp->d_bin_type='b';

      moveto(xbox,gety+CHeight);
      dp->max_d_hist=lineL/2;
      dp->min_d_hist=10;
      if (dp->min_d_hist>dp->max_d_hist) 
           dp->min_d_hist=dp->max_d_hist;

      if (dp->d_bin_type=='b'){
         if (dp->max_d_hist>=100) dp->d_histno=100;
         else dp->d_histno=dp->max_d_hist;
	 sprintf(textb[0],
	   "no of bins (min %d, def %d):",
				  dp->min_d_hist,dp->d_histno);
	 outtext(textb[0]);
	 input_string(5,0);
         //if (is[0]=='q') goto start;
         if (is[0]=='q'){
            erase_prompt_box(4);
            return;
         }
	 if (atoi(is)>=dp->min_d_hist && atoi(is)<=dp->max_d_hist) 
                      dp->d_histno=atoi(is);
	 /*buffer for no of frequency bins*/	 
         if ((dp->damage_buf=(unsigned long *)
	     calloc(dp->d_histno+1,sizeof(unsigned long)))
	 		   ==NULL) outof_memory("dp->damage_buf");
      }
      else {
	 dp->d_histno=dp->max_d_hist;
	 sprintf(textb[0],
	   "cut-off size (min 20 default %d):",
					       dp->max_d_hist);
	 outtext(textb[0]);
	 input_string(5,0);
         //if (is[0]=='q') goto start;
         if (is[0]=='q'){
            erase_prompt_box(4);
            return;
         }
	 if (atoi(is)>=20 && atoi(is)<=dp->max_d_hist) 
                       dp->d_histno=atoi(is);

         if ((dp->damage_buf=(unsigned long*)
	         calloc(dp->max_d_hist+1,sizeof(unsigned long)))
	            ==NULL) outof_memory("dp->damage_buf");
      }
     
      moveto(xbox,gety+CHeight);
      dp->d_ittcount=0;
      outtext(
          "delay damage, time-steps before damage start (def 0):");
      input_string(5,0);
      if (is[0]=='q'){ 
         free(dp->damage_buf);
         goto start;
      }
      if (is[0]!=13 && atoi(is)!=Maxu) dp->d_ittcount=atoi(is);
      moveto(xbox,gety+CHeight);
      dp->same_limit=5;
      sprintf(textb[0],"define damage, time-steps same damage (def %d):",
                                            dp->same_limit);
      outtext(textb[0]);
      input_string(5,0);
      if (is[0]=='q'){ 
         free(dp->damage_buf);
         goto start;
      }
      if (is[0]!=13 && atoi(is)!=Maxu) dp->same_limit=atoi(is);   
      erase_prompt_box(4);
      
    skip1: 
      draw_diff_graphframe(dp,1,0,0);
      setcolor(lightred);
      /*label x axis*/
      for (zu=0;zu<=dp->d_histno;zu++){         
         if (dp->d_histno<=10 || 
                 zu%((unsigned int)((float)dp->d_histno/10))==0 ){
            line(dp->d_leftx+zu*dp->d_divx,dp->d_boty+1,
	    dp->d_leftx+zu*dp->d_divx,dp->d_boty+vgay(4));
	    moveto(dp->d_leftx+zu*dp->d_divx,dp->d_boty+vgay(4));
	    sprintf(textb[0],"%d",zu);
	    outtext(textb[0]);
         }
         else if (dp->d_histno<=201) 
           line(dp->d_leftx+zu*dp->d_divx,dp->d_boty+1,
		   dp->d_leftx+zu*dp->d_divx,dp->d_boty+vgay(2));
      }      
      /*label y axis*/
      for (zul=0;zul<=dp->d_maxy;zul++){
	 if (zul%((unsigned long)((double)dp->d_maxy/4))==0){
            moveto(dp->d_leftx-1,dp->d_boty-zul*dp->d_divy);     
            linerel(-vgax(3),0);
	    sprintf(textb[0],"%lu",zul);
            moverel(-(strlen(textb[0])*CWidth+vgax(3)),-vgay(4));
	    outtext(textb[0]);
         }
      }
}

/************ draw diff statistical sample plot, attractor or skeleton hist  *************/
void show_diff_plot(char redraw,diff_var *dp){
  signed int xbox,tempx,tempy;
  unsigned int zu,thismax_histno,
                 buf_index,damage_extra=0;
  unsigned long zul,buf_total,max_bin;
  char tobe_rescaled=0,xlog=0,ylog=0,tempcolor;
  double thisdivx;
  /*for saving and loading data files*/
  /*unsigned int filebytes;
    char file_ret,load_save;
     signed int fid,tempx1,tempy1;*/
  
        if (diff_plot==3 || diff_plot==4){ /*dammage spread histogram*/
           /*save % damage to buffer*/
           if (dp->d_bin_type=='b') buf_index=(unsigned int)
		      ((dp->percent_damage/100.0)*dp->d_histno);
	   else if (dp->d_bin_type=='n') buf_index=dp->damage_count;
           if (buf_index>dp->d_histno) damage_extra+=1;
           else dp->damage_buf[buf_index]+=1;
        }
        else if (att_hist){ /*attractor or skeleton histogram*/
	   buf_index=dp->damage_count;
           dp->max_d_hist=dp->d_histno;
	   if (dp->att_types>dp->d_histno){
	       dp->d_histno=dp->att_types*1.25;           
               dp->d_divx=dp->d_width/(dp->d_histno+2);
               tobe_rescaled=1;
           }
	}

       /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
       rescale:/*rescale x axis if reset, show sample count*/

        if (diff_plot==3 || diff_plot==4) /*dammage spread histogram*/
           thismax_histno=dp->d_histno;        
        else if (att_hist) /*attractor or skeleton histogram*/
           thismax_histno=dp->att_types;
        /*ammend width of bars*/
        if ((signed int)dp->d_divx>=vgax(4)) thisdivx=dp->d_divx-2;
        else if (dp->d_divx>=1) thisdivx=dp->d_divx-1;
        else thisdivx=0;
        /*show damage histogram*/
        /*rescale y axis bigger*/
        if (((double)dp->damage_buf[buf_index]*dp->d_divy) >
                       dp->d_height || tobe_rescaled==1 || redraw==1){
           /*rescale y axis and redraw graph*/
           if (xlog==0 && tobe_rescaled==0 && redraw==0) dp->d_divy*=.75;
           tobe_rescaled=0;

	   dp->d_maxy=(unsigned long)(dp->d_height/dp->d_divy);
           draw_diff_graphframe(dp,0,xlog,ylog);

           /*ammend width of bars*/
           if ((signed int)dp->d_divx>=vgax(4)) 
                                   thisdivx=dp->d_divx-2;
           else if (dp->d_divx>=1) thisdivx=dp->d_divx-1;
           else thisdivx=0;
           setcolor(lightred);

           if (1){
              //draw-label y axis
              for (zul=0;zul<=dp->d_maxy;zul++){
                 if (zul%((unsigned long)((double) dp->d_maxy/4))==0){
                    if (ylog==0) moveto(dp->d_leftx-1,dp->d_boty-zul*dp->d_divy);
                    else if (ylog==1) moveto(dp->d_leftx-1,
                       dp->d_boty - dp->d_height*
                          log2(( (double)zul/dp->d_maxy)*dp->d_height +1)/
                                 log2(dp->d_height));
		    linerel(-vgax(3),0);
		    sprintf(textb[0],"%lu",zul);
		    moverel(-(strlen(textb[0])*CWidth+vgax(3)),-vgay(4));
		    outtext(textb[0]);
	         }
	      }

              //draw-label x axis
              tempcolor=getcolor();
              //setcolor(yellow);
	      for (zu=0;zu<=dp->d_histno;zu++){
                 if (xlog==0) moveto(dp->d_leftx+zu*dp->d_divx,dp->d_boty+1);
                 else if (xlog==1){ 
                    moveto(dp->d_leftx+
                     (unsigned int)( ((double)dp->d_histno*dp->d_divx) *
                       ( log2((double)zu*dp->d_divx +1.0)/ /*+1 to prevent neg or -inf*/
                         log2((double)dp->d_histno*dp->d_divx) ) ),dp->d_boty+1);
                 }
                 tempx=getx;
                 tempy=gety;
                 if (dp->d_histno<=200) linerel(0,vgay(2));
                 /*if (xlog==0) fprintf(stderr,"\n%d",zu);
                 if (xlog==1){
                    fprintf(stderr,"\n xlog=%d zu=%d total=%d  divx=%.2f %.2f/%.2f=%.2f",
		    xlog,
                    zu,
                    dp->d_histno,
                    dp->d_divx,
		    log2((double)zu*dp->d_divx +1.0), //+1 to prevent neg or -inf
                    log2((double)dp->d_histno*dp->d_divx),
                    (double)dp->d_histno*dp->d_divx *
		      ( log2((double)zu*dp->d_divx +1.0)/ //+1 to prevent neg or -inf
                       log2((double)dp->d_histno*dp->d_divx) )   );
                 }*/
	         if (xlog==0 && zu%(unsigned int)((float) dp->d_histno/10)==0){
		         line(tempx,tempy,tempx,tempy+vgay(4)); 
		         sprintf(textb[0],"%d",zu);
		         outtext(textb[0]);
	         }
		 else if (xlog==1){
                     if  ( zu<10 || zu%(unsigned int)((float)dp->d_histno/4)==0) {
                         line(tempx,tempy,tempx,tempy+vgay(4)); 
		         sprintf(textb[0],"%d",zu);
		         outtext(textb[0]);
		     }
                 }	  
	       }
	       //setcolor(tempcolor);	       
           }          
	   
           if (1){
              //draw histogram    
	      for (zu=0;zu<=thismax_histno;zu++){
                 buf_total=dp->damage_buf[zu];
	         if (buf_total==0) continue;
                 if (zu==0) setfillstyle(SOLID_FILL,red);
	         //else setfillstyle(SOLID_FILL,white);
                 else setfillstyle(SOLID_FILL,green);
                 if (xlog==0){
		       tempx=dp->d_leftx+dp->d_divx*zu;
                       tempy=dp->d_boty;

                       if (ylog==0) bar(tempx,tempy-buf_total*dp->d_divy,
					  tempx+thisdivx,tempy);
                       else if (ylog==1) bar(tempx,tempy-dp->d_height* 
		         (log2((double)buf_total +1.0)/ /*+1 to prevent neg or -inf*/
                           (double)log2(dp->d_maxy)), 
                                          tempx+thisdivx,tempy);
                 } 
	         
                 else if (xlog==1){
                    tempx=dp->d_leftx+
                      (unsigned int)(((double)dp->d_histno*dp->d_divx) *
			( log2((double)zu*dp->d_divx +1.0)/ /*+1 to prevent neg or -inf*/
                           log2((double)dp->d_histno*dp->d_divx)));

                    if (ylog==0) tempy=dp->d_boty-buf_total*dp->d_divy;
                    else if (ylog==1) tempy=dp->d_boty-dp->d_height* 
		     (log2((double)buf_total +1.0)/ /*+1 to prevent neg or -inf*/
                       (double)log2(dp->d_maxy));

                    bar(tempx-1,tempy-1,tempx+1,tempy+1);
                    putpixel(tempx,tempy,white);
  	    
                 }     
              }   
	   }
	   /*show extra*/
	   if (damage_extra>0 && xlog==0 && (diff_plot==3 || diff_plot==4)){
	      setfillstyle(SOLID_FILL,yellow);
	      moveto(dp->d_leftx+dp->d_divx*(thismax_histno+1),
                                                 dp->d_boty);
              if (ylog==1){
                    bar(getx,gety-dp->d_height* 
                      log2(((double)damage_extra/max_bin)*
                             dp->d_height)/log2(dp->d_height),
				       getx+thisdivx,gety); 
              }
              else{
                 if ((damage_extra*dp->d_divy) < dp->d_height)
		    bar(getx,gety-damage_extra*dp->d_divy,
					getx+thisdivx,gety);
	         else bar(getx,gety-dp->d_height,getx+thisdivx,gety);
	      }
	   }
        }
        else if (buf_index<=thismax_histno){
           if (buf_index==0) setfillstyle(SOLID_FILL,red);
	   else setfillstyle(SOLID_FILL,white);
           moveto(dp->d_leftx+dp->d_divx*buf_index,dp->d_boty);
	   bar(getx,gety-dp->damage_buf[buf_index]*dp->d_divy,
					getx+thisdivx,gety);
        }
        /*show extra*/
        else if (damage_extra>0 && !xlog && (diff_plot==3 || diff_plot==4)){
           setfillstyle(SOLID_FILL,yellow);
           moveto(dp->d_leftx+dp->d_divx*(thismax_histno+1),
                                                 dp->d_boty);
           if (damage_extra*dp->d_divy<dp->d_height)
			  bar(getx,gety-damage_extra*dp->d_divy,
					getx+thisdivx,gety);
           else bar(getx,gety-dp->d_height,getx+thisdivx,gety);
        }
        /* show sample and type */
        setcolor(white);
        moveto(dp->d_leftx,dp->d_topy-vgay(25)+CHeight);
        outtext("sample no=");        
        setfillstyle(SOLID_FILL,black);
        bar(getx,gety,getx+CWidth*6,gety+CHeight);
        sprintf(textb[0],"%lu ",dp->diff_sample_count);
        outtext(textb[0]);
               
        if (xlog==1 || ylog==1){
           setcolor(white);
           draw_prompt_box(1);
           if (ylog==1 && xlog==0) outtext("y-axis log2, cont-ret:"); 
           else if (ylog==0 && xlog==1) 
                 outtext("x-axis log2, cont-ret:");
           else outtext(
               "xy-axes log2, cont-ret:");
           input_string(1,0);
           
           xlog=ylog=0;
           tobe_rescaled=1;
	   goto rescale;
        }

        if (dp->pause_dam_hist==1){ /*was interrupted*/
           setcolor(white);
	   xbox=draw_prompt_box(2);
           xlog=ylog=0;
           
	   if (diff_plot==3 || diff_plot==4) outtext(
              "stp-q undo-pause-u save/load-s/l next-ret, damage: delay-d same-m");
           else if (att_hist) outtext(
                     "save/load-s/l undo-pause-u cont-ret"); 
	    moveto(xbox,gety+CHeight);
            if (diff_plot==4) outtext("redraw-r logx-X logy-y log-both-b:");
            else if (diff_plot==3) outtext("redraw-r xcut-off-X logx-x logy-y log-both-b:");
            //else outtext("redraw-r x-axis-x logx-X logy-y log-both-b:");
            else outtext("x-axis-X logx-x logy-y log-both-b:");

	   input_string(1,0);
	   erase_prompt_box(2);
	   if (is[0]=='u'){ 
              xlog=ylog=0;
              dp->pause_dam_hist=0;
              tobe_rescaled=1;             
	   }
           else if (is[0]=='r'/* && dp->d_bin_type=='n'*/){ //??
              xlog=ylog=0;
              tobe_rescaled=1;
	      goto rescale;
	   }
	   else if (is[0]=='X' && dp->d_bin_type=='n'){	     
              if (diff_plot==3 || diff_plot==4) dp->d_histno=dp->max_d_hist;
	      xbox=draw_prompt_box(1);
	      sprintf(textb[0],
                    "revise x-cut-off, now %d (min 20, def %d):",
					  dp->d_histno,dp->max_d_hist);
	      outtext(textb[0]);
	      input_string(5,0);
	      if (atoi(is)>=20 && atoi(is)<=dp->max_d_hist)
						dp->d_histno=atoi(is);
	      dp->d_divx=dp->d_width/(dp->d_histno+2);
	      /*reset extra*/
	      damage_extra=0;
	      if (dp->max_d_hist>dp->d_histno){
	         for (zu=dp->d_histno+1;zu<=dp->max_d_hist;zu++)
				 damage_extra+=dp->damage_buf[zu];
	      }
              xlog=ylog=0;
	      erase_prompt_box(1);
              tobe_rescaled=1;
	      goto rescale;
	   }
           else if ((is[0]=='x' || is[0]=='b') /*&& dp->d_bin_type=='n'*/){ //??
	      if (is[0]=='x'){
                 xlog=1;
                 ylog=0;
              }
              else if (is[0]=='b') xlog=ylog=1;
              //dp->d_histno=dp->max_d_hist;
              tobe_rescaled=1;
	      goto rescale;
           }
           else if (is[0]=='y' /*&& dp->d_bin_type=='n'*/){ //??
              ylog=1;
              xlog=0;
              tobe_rescaled=1;
	      goto rescale;
           }
           else if (is[0]=='d' && (diff_plot==3 || diff_plot==4)){
              xbox=draw_prompt_box(1);
              sprintf(textb[0],
                "no itterations before damage starts (now %d):",
                                                 dp->d_ittcount);
              outtext(textb[0]);
              input_string(5,0);
              if (is[0]!=13 && atoi(is)!=Maxu) 
                                     dp->d_ittcount=atoi(is);
              erase_prompt_box(1);
              tobe_rescaled=1;
              goto rescale;
           }
           else if (is[0]=='m' && (diff_plot==3  || diff_plot==4)){
              xbox=draw_prompt_box(1);
              dp->same_limit=5;
              sprintf(textb[0],
                  "no itterations same damage (def %d):",
                                               dp->same_limit);
              outtext(textb[0]);
              input_string(5,0);
              if (is[0]!=13 && atoi(is)!=Maxu) 
                                       dp->same_limit=atoi(is);   
              erase_prompt_box(1);
              tobe_rescaled=1;
              goto rescale;
	   }         
           else if (is[0]=='s' || is[0]=='l'){
             unsigned int *temp_buf,zu;
	      /*restrict to unsigned  int*/
              if ((temp_buf=(unsigned int *)
	          calloc(dp->d_histno+1,sizeof(unsigned int)))
	 		   ==NULL) outof_memory("temp_buf");

              for (zu=0;zu<=thismax_histno;zu++)
		temp_buf[zu]=(unsigned int)dp->damage_buf[zu];

	      hist_save_load(thismax_histno,temp_buf);            
              tobe_rescaled=1;
              xlog=ylog=0;
              goto rescale;
           }
	   else{ 
              xlog=ylog=0;
              tobe_rescaled=1; 
	   }                   
        }
}
/******** save/load *.his unsigned int histogram data  *************/
void hist_save_load(unsigned int thismax_histno,
                              unsigned int *this_hist){

   unsigned int *temp_buf;
   unsigned int load_histno,
                   filebytes,zu;
    char file_ret,load_save;
    signed int fid,tempx1,tempy1;
    
              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 ");
              }   
       
              file_ret=select_filename(textb[4],
	                  "HIST-DATA", "*.his","my_hist"); 
              if (file_ret=='q'){ 
                 moveto(tempx1,tempy1);
                 return;
              }
              else{
                 if (load_save=='l'){
		    fid=myopen(filename,0,0);		    
                    filebytes= filelength(fid);
                    load_histno=filebytes/(sizeof(unsigned int))-1;
                    if ((temp_buf=(unsigned int*)
		        calloc(filebytes,sizeof(unsigned int)))
			   ==NULL) outof_memory("temp_buf");

	         }
	         if (load_save=='s') fid=myopen(filename,1,0);
		 if (fid==-1){
		    file_error(filename);
	            close(fid);
                    moveto(tempx1,tempy1);
	            return;
	         }
              }

              if (load_save=='s'){
		 vret=write(fid,this_hist,
		       (thismax_histno+1)*sizeof(unsigned int));
                 fprintf(stderr,
                     "\nhistogram: 1+%d columns\n",
                                                  thismax_histno);
                 for (zu=0;zu<=thismax_histno;zu++){
		      fprintf(stderr,"%d ",this_hist[zu]);
                 }
              }
              else if (load_save=='l'){
                 vret=read(fid,temp_buf,filebytes);
                 fprintf(stderr, 
                     "\nhistogram: 1+%d columns\n",load_histno);
                 for (zu=0;zu<=thismax_histno;zu++){
		      fprintf(stderr,"%d ",this_hist[zu]);
                 }
                 free(temp_buf);               
              }
              close(fid);
              moveto(tempx1,tempy1);

}
/******** draw diff plot graph outline and titles and info  *************/
void draw_diff_graphframe(diff_var *dp,
                          char first,char xlog,char ylog){
   unsigned int tempx,tempy;

      tempx=getx;
      tempy=gety;
      if (twod){
	 dp->d_leftx=vgax(50);
         dp->d_width=(float)vgax(430);
      }
      else{
	 dp->d_leftx=vgax(50+150);
         dp->d_width=(float)vgax(430-150);
      } 
      dp->d_boty=Maxy-vgay(30);
      dp->d_divx=dp->d_width/(dp->d_histno+2);
      dp->d_height=(double)vgay(100);
      dp->d_topy=dp->d_boty-dp->d_height;
      if (first==1) dp->d_divy=dp->d_height/vgay(10);
      dp->d_maxy=(unsigned long)(dp->d_height/dp->d_divy);      
      setfillstyle(SOLID_FILL,black);
      setcolor(lightred);
      bar3d(dp->d_leftx-vgax(48),dp->d_topy-vgay(30),
        dp->d_leftx+dp->d_width+vgax(20),dp->d_boty+vgay(28),0,0);
      bar3d(dp->d_leftx-1,dp->d_topy-1,
			dp->d_leftx+dp->d_width+1,dp->d_boty,0,0);
      moveto(dp->d_leftx,dp->d_topy-vgay(25));                    
      setcolor(white);
      setfillstyle(SOLID_FILL,white);
      if (diff_plot==3 || diff_plot==4) outtext("Damage Histogram ");
      else if (att_hist==1)
	     outtext("Attractor Freq Hist");
      else if (att_hist==2){
	     outtext("Frozen Skeleton Freq Hist ");
      }             
     
      if (diff_plot==3 || diff_plot==4)
          sprintf(textb[0],
             " start=%d same=%d pause/reset-=",
                                   dp->d_ittcount,dp->same_limit);
      else if (att_hist) sprintf(textb[0]," pause/reset-=");
      outtext(textb[0]);

      if (att_hist==2){ /*the skeleton parameters*/
             set_medium_font();
             outtext(dp->textbuf);
             restore_def_font();	     
      }    

      moveto(dp->d_leftx+CWidth*12,gety+CHeight);
       if (diff_plot==3 || diff_plot==4){ 
         if (twod)      sprintf(textb[0],"         net=%dx%d",i2d/2,j2d);
         else if (oned) sprintf(textb[0],"         1d net=%d",lineL/2);
      }
      if (att_hist){
         if (twod)      sprintf(textb[0],"         net=%dx%d",i2d,j2d);
         else if (oned) sprintf(textb[0],"         1d net=%d",lineL);
      }
      outtext(textb[0]);
      sprintf(textb[0]," v=%d",value_range); 
      if (nhood_mixed) sprintf(textb[0]," k=%d-%d",nhood_lb,nhood_ub);
      else sprintf(textb[0]," k=%d",nhood);
      outtext(textb[0]);
      if (nonlocal==0 || regular2d) outtext(" local wiring");
      else outtext(" rand-wiring");
      if (zonesize && nonlocal && !(twod==0 && zonesize==lineL)){ 
         sprintf(textb[0]," zone-diam=%d",zonesize);
         outtext(textb[0]);
      }

      /*--- add up canalising inputs -- in case network was loaded from file ----*/
      if (cinputfreq==0 && rulemix==1 && tot_only==0){ 
       unsigned long inputtotal=0,cinputnet=0;
       unsigned int poss;

         for (poss=lineL-1;poss!=Maxu;poss--){
            if (nhood_mixed) inputtotal+=nhoodm[poss];
            canalyzing(nhoodm[poss],0,carule[poss]);      
            if (canaltotal>0) cinputnet+=canaltotal;
         }
         if (!nhood_mixed) inputtotal=lineL*nhood;
         cinputfreq=(float)cinputnet/inputtotal;
      }
      /*--------------------------------------------------------------------------*/

      if (cinputfreq){ 
         sprintf(textb[0]," C-in=%.2f%%",cinputfreq*100);
         outtext(textb[0]);
      }
     
      moveto(dp->d_leftx+dp->d_width/4,dp->d_boty+vgay(15));
      if (dp->d_bin_type=='n'){
         if (diff_plot==3 || diff_plot==4) outtext("Damage value");
         else if (att_hist==1) outtext("Attractor type");
         else if (att_hist==2) outtext("Skeleton type");
         if (xlog==1) outtext(" - log2");
      }
      else if (dp->d_bin_type=='b'){
         sprintf(textb[0],"Damage bin=%.2f%%",100.0/dp->d_histno);
         outtext(textb[0]);
      }
      /*moveto(dp->d_leftx-vgax(35),dp->d_boty-dp->d_height/2+CHeight/2);
      outtext("Freq-");
      moveto(dp->d_leftx-vgax(35),gety+CHeight);
      outtext("uency");*/

      moveto(dp->d_leftx-vgax(45),dp->d_boty-dp->d_height/2+CHeight*.8);
      outtext("Frequency");

      if (ylog){
         moveto(dp->d_leftx-vgax(45),gety+CHeight);
	 outtext("log2");
      }
      moveto(tempx,tempy);
}


/******** draw entropy - density plots etc, modify for isotropic Feb2020 ********/
void entropy_eeg_plot(
       auto_ent *ae, 
       ent_eeg *eg,
       int_stp *it,
       unsigned char nhdcolor){

 double eegratio,lookupratio;
 signed int xbox,ybox,z,zz,yy,zv,
              twotempy,xpix,xspace;
 unsigned int zu;
 //unsigned long tot_lookupcount;
 unsigned int tot_lookupcount;
 double lu_entropy;
 float pixposx,pixposy;
 char automatic_was_set=0;
 signed int highest_in_group,
	      hist_group_count,
              move_col;

#  if __WATCOM__
      unsigned char backc;	   
#  elif  __UNIX__ 
      //unsigned long backc;
      unsigned int backc;
#  endif


#  if __WATCOM__  
      backc=black;  
#  elif  __UNIX__           /*for getpixel()*/
      if (bground=='b') backc=0;  /*black background*/
      else backc=Color_Table[0];  /*white background*/
      /*the value of the white background varies on different computers
        on Dell=65535, on Lenovo=16777215, this should give the right value for any!?*/      
#  endif

   if (eg->showeeg==1 || eg->lookup_entropy){
      for (zv=0;zv<=value_range-1;zv++){ 
         if (single_entropy==0){
            for (zu=0; zu<=lineL-1; zu++){
	       if (get_value(state1,zu)==zv) eg->eegcount[zv][0]+=1;
            }
            /* density not 0 */
            /* or pick any color */
            /*if (get_value(state1,zu)==value_range-1) eg->eegcount[0]+=1;*/      
	 }
         else{ /*single cell only*/
            if (get_value(state1,entropy_poss)==zv) eg->eegcount[zv][0]+=1;
	 }
         eg->tot_eegcount=0;

         for (zz=0;zz<=eg->actgens-1;zz++){ 
            eg->tot_eegcount+=(double)eg->eegcount[zv][zz];
            if (single_entropy==0)
	        eegratio=eg->tot_eegcount/(double)(lineL*eg->actgens);
            else eegratio=eg->tot_eegcount/eg->actgens;
            /*note:eg->tot_eegcount is now a double (Nov 03) 
	         to fix bug for large 2d networks*/
         }

         /*print or save eeg in value_range cols starting at 0*/
	 /* if (eg->showeeg==1){ 
            if (zv==0) fprintf(stdout,"\n"); //for Ed
	    fprintf(stdout,"%f ",eegratio);
	 }*/
         
         if (eg->showeeg==1){
            setcolor(color_v[zv]);
            if (getcolor()==black) setcolor(darkgray);
            if (d_mode==1 || (d_mode==2 && scrolling==1)){
	       moveto(eg->stpwidth+(signed int)ceil
	          (eg->eegwidth*eg->eegratiobefore[zv]),gety-it->fscale);
#              if __UNIX__ /*draw to pixmap*/
                  *current_draw = *it->offscreen_pixmap;
#              endif
               if (it->ittcount==1) putpixel(eg->stpwidth+(signed int)ceil
		     (eg->eegwidth*eegratio),gety+it->fscale,getcolor());
	       else if (it->ittcount>1) 
                   lineto(eg->stpwidth+(signed int)ceil
		       (eg->eegwidth*eegratio),gety+it->fscale);
#              if __UNIX__ /*draw to screen*/
                  *current_draw = W; /*draw to window*/
#              endif		     
            }
            else{ /* for 2d or 3d*/
	       twotempy=gety;         
	       moveto(getx,eg->twodgy);
               moveto(eg->stpwidth+(signed int)ceil
	         (eg->eegwidth*eg->eegratiobefore[zv]),gety-1);
               if (getx<eg->stpwidth) moveto(eg->stpwidth,gety);
               /*putpixel(eg->stpwidth+(signed int)ceil
		 (eg->eegwidth*eegratio),gety+1,getcolor());*/
               lineto(eg->stpwidth+(signed int)ceil
		        (eg->eegwidth*eegratio),gety+1); 
               moveto(getx,twotempy);
            }    
         }
         /*shunt generations*/
         for (zz=eg->actgens-1;zz>=1;zz--){
            eg->eegcount[zv][zz]=eg->eegcount[zv][zz-1];
         }
         eg->eegcount[zv][0]=0; /*clear current*/
         eg->eegratiobefore[zv]=eegratio;
      }
   }
   if (eg->showeeg==1) return;
   /*-----------------------------------------------------*/
     
   if (eg->showlookupfreq || eg->lookup_entropy){      
      lu_entropy=0;
      for (z=it->tablemax; z>=0; z--){
         /*superimposed graph of lookupfrquency-time*/	
	nhdcolor=set_nhdcolor(eg->ent_nhood,z);
	if (nhdcolor==0 || nhdcolor==darkgray)
	                              nhdcolor=white;
         tot_lookupcount=0; 
         for (zz=0;zz<=eg->actgens-1;zz++){
	    tot_lookupcount+=eg->lookupcount[zz][z];
         }
         if (single_entropy==0)
	    lookupratio=((double)tot_lookupcount)/(lineL*eg->actgens);
         else lookupratio=((double)tot_lookupcount)/eg->actgens;
         eg->newbar=eg->stpwidth+ 
	    (signed int)ceil(eg->lookupfreqwidth*lookupratio);
         if (eg->newbar==0 && tot_lookupcount>0) eg->newbar=eg->stpwidth+1;
         /*show superimposed lookupfrequency-time plot*/
	 if (eg->showlookupfuz>0){ 
            if (d_mode==1 || (d_mode==2 && scrolling==1)){
#              if __UNIX__ /*draw to pixmap */
                  *current_draw = *it->offscreen_pixmap;
#              endif
               if (it->fscale==1 || it->ittcount==1) 
                         putpixel(eg->newbar,gety,nhdcolor);
	       else if (it->fscale>1){
	          setcolor(nhdcolor);
	          line(eg->newbar,gety,eg->newbar,gety+it->fscale);
	       }
#              if __UNIX__ /*draw to pixmap*/
                  *current_draw = W;
#              endif
            }                   
            else{ /* for 2d or 3d*/
	       twotempy=gety;
	       moveto(getx,eg->twodgy);
	       putpixel(eg->newbar,gety,nhdcolor);
               moveto(getx,twotempy);
	    }
         } 
	 if (lookupratio!=0.0)
		   lu_entropy+=(lookupratio*log(lookupratio));
      }
      /*plot entropy*/      
      setcolor(lightred);
      eg->newbar=eg->stpwidth+(signed int)(eg->lookupfreqwidth*
			 (lu_entropy/log(1.0/(it->tablemax+1))));

      /*print or save lookup_entropy*/
      /*if (eg->showlookupfreq || eg->lookup_entropy){
	 //fprintf(stdout,"\n%f ",lu_entropy/log(1.0/(it->tablemax+1))); //for Ed
	 //to dynamically show the input-entropy, and normalised input entropy
	 fprintf(stderr,"\n%f %f",-lu_entropy,lu_entropy/log(1.0/(it->tablemax+1))); 
       }*/

      /*showlookupfuz==0 show entropy
                      ==1 dont show entropy
                      ==2 show both*/ 
      if (eg->showlookupfuz!=1){ 
	 if (d_mode==1 || (d_mode==2 && scrolling==1)){	    	      
#           if __UNIX__ /*draw to pixmap*/
               *current_draw = *it->offscreen_pixmap;
#           endif
            if (it->ittcount==1) 
              putpixel(eg->newbar,gety,getcolor());
	    else line(eg->newbar0,gety-it->fscale,eg->newbar,gety);
#           if __UNIX__ /*draw to window*/
              *current_draw = W;
#           endif
         }
         else{		
            twotempy=gety;
            if (it->ittcount==1){
               moveto(getx,eg->twodgy);
               putpixel(eg->newbar,gety,getcolor());
            }
            else line(eg->newbar0,eg->twodgy-1,eg->newbar,eg->twodgy);
            moveto(getx,twotempy);
         } 
      }      
      eg->newbar0=eg->newbar;
      if (eg->showlookupfreq==1 || eg->new_hist==1){
         /*for classic histogram, or new single line histogram,
           start at top of box*/ 
         ybox=eg->startybox;
	 xbox=eg->startxbox;
      }
      else if (eg->showlookupfreq==2){
	/*for histogram+time-graph move right-down by 1 pixel*/ 
	 if (it->ittcount==1){
	    eg->thisxbox=eg->startxbox-1;
	    eg->thisybox=eg->startybox-1;
	 }
	 eg->thisxbox+=1;
	 eg->thisybox+=1;
	 xbox=eg->thisxbox;
	 ybox=eg->thisybox;
      }
      //xbox is start of input-histogram frame
      /*********************draw lookup histogram****************************/
      if (eg->new_hist==1){
        highest_in_group=0;
        hist_group_count=0;        
      }
      move_col=0;
      /*title for: print copies of the lookup frequency in rule-table layout, 64 across,
            within each successive  window of time-steps*/ 
      /*fprintf(stderr,"\n max=%dx%d x %dgens=%d\n", i2d,j2d,eg->actgens,i2d*j2d*eg->actgens);*/
      for (z=it->tablemax; z>=0; z--){  
	 if (eg->new_hist==0 && 
                z!=it->tablemax && z!=0 && (it->tablemax-z)%eg->barno==0){
	   /*xbox+=(signed int) (eg->lookupfreqwidth/(
	     ((double)(it->tablemax+1)) /eg->barno));*/
	    move_col+=1;
            xbox=eg->startxbox+(signed int)
	      eg->lookupfreqwidth*((float)move_col/((float)it->tablemax/eg->barno));


	    if (eg->showlookupfreq==2) ybox=eg->thisybox;
	    else ybox=eg->startybox;
	 }
	 tot_lookupcount=0;

         /* limit size of unsigned long */	  
	 for (zz=0;zz<=eg->actgens-1;zz++){
	    tot_lookupcount+=eg->lookupcount[zz][z];
            if (tot_lookupcount==Maxint) break;
	 }
         /*keep track of histogram bar size in order to filter colors*/
         hist_order[z]=tot_lookupcount;
	 if (single_entropy==0){
	    /*eg->hist_bar_factor amplifies the hist0gram*/
	    if (eg->hist_bar_factor>=1) eg->newbar=(signed int)
	         ((eg->hist_bar_factor*eg->lookupfreqwidth*tot_lookupcount)/(lineL*eg->actgens));
	    else{
	      signed int row_number;
	       row_number=(ceil) ((double)(it->tablemax+1)/eg->barno);
	       eg->newbar=(ceil)//show as log2
		 ((eg->lookupfreqwidth*log2((double)tot_lookupcount)/log2((double)(lineL*eg->actgens)))
		                   /row_number);
               if (eg->newbar<=0) eg->newbar=0; //otherwise eg->newbar=-2147483648 (-2^31)
               //fprintf(stderr," %d,%d ",eg->newbar,row_number);  
            }
	    //fprintf(stderr," %d,%f",eg->newbar,eg->hist_bar_factor);
           
            /*fprintf(stderr,"\n %d = %f * %f * %lu / (%d * %d)", 
		    eg->newbar,eg->hist_bar_factor,eg->lookupfreqwidth,
		    tot_lookupcount,lineL,eg->actgens);*/
            if (eg->newbar==0 && tot_lookupcount>0){
                 eg->newbar=1;
                 
            }
            /*fprintf(stderr,"%lu-%d ",tot_lookupcount,eg->newbar);*/            
            /*print the input frequency histogram*/            
            /*fprintf(stderr,"\n%f",(float)tot_lookupcount/(lineL*eg->actgens));
	      if (z==0) fprintf(stderr,"\n");*/

            /*fprintf(stderr,"%3d ",tot_lookupcount);
	      if (z%64==0) fprintf(stderr," :%d\n",z);*/
            
            /*print copies of the lookup frequency in rule-table layout, 64 across,
            within each successive window of time-steps*/ 
            /*if (tot_lookupcount==0) fprintf(stderr,"- ");
            else if ((signed int)ceil(log2(tot_lookupcount))>9) fprintf(stderr,"M ");
            else fprintf(stderr,"%d ",(signed int)ceil(log2(tot_lookupcount)));
            if (z%64==0) fprintf(stderr," :%d\n",z);*/

            
         }

	 else{
             eg->newbar=(signed int)eg->lookupfreqwidth*eg->hist_bar_factor*
		((float)tot_lookupcount/eg->actgens);
             if (eg->newbar==0 && tot_lookupcount>0) eg->newbar=1;
         }
 
        /*eg->barlength now = (signed int)eg.lookupfreqwidth in for.c*/
	 if (eg->newbar>eg->barlength)eg->newbar=eg->barlength;
         
         if (eg->new_hist==1){ 
            hist_group_count++;
            eg->hist_group[hist_group_count]=eg->newbar;
         }
        
	 if (stp){
	      /*histogram with colored horizontal cols*/              
	       if (eg->new_hist==0 && eg->showlookupfreq==1){
	    
		  /*place/remove black block to indicate filtered nhood*/
		  if (get_bit(color_filter,z)==1) 
                                     setfillstyle(SOLID_FILL,white);
                  else if (get_bit(color_filter,z)==0)
                                     setfillstyle(SOLID_FILL,black);                  
                  bar(xbox-vgax(5),
                           ybox,
                           xbox-vgax(3),
		           ybox+(signed int)eg->barw-eg->barsep);

                  /*place/remove red block to indicate filtered nhood*/
                  if (get_bit(mutation_filter,z)==1) 
                                     setfillstyle(SOLID_FILL,red);
                  else if (get_bit(mutation_filter,z)==0) 
                                     setfillstyle(SOLID_FILL,black);
                  bar(xbox-vgax(8),
                           ybox,
                           xbox-vgax(6),
		           ybox+(signed int)eg->barw-eg->barsep);
		
                  /*set histogram colors*/
                  if (z==(signed int)pow(value_range,
                           (double)eg->ent_nhood)-1) nhdcolor=white;
                      
                  else{
		        nhdcolor=set_nhdcolor(eg->ent_nhood,z);
			if (nhdcolor==black) nhdcolor=white;
                  }
		  
                  /*to make sure that any occurance will show up
		    as a line on the histogram*/
                  if (eg->newbar==1){ 
		     setfillstyle(SOLID_FILL,black);
		     bar(xbox,ybox,
		      xbox+eg->oldbar[z],
                       ybox+(signed int)eg->barw-eg->barsep);
                     setfillstyle(SOLID_FILL,nhdcolor);
                      bar(xbox,ybox,xbox,
		           ybox+(signed int)eg->barw-eg->barsep);
		  }
                  /*else if (eg->newbar==0){ 
                     setfillstyle(SOLID_FILL,black);
		     bar(xbox,ybox,
		      xbox+eg->oldbar[z],
                       ybox+(signed int)eg->barw-eg->barsep);
		  }*/
		  /*if new<old erase old, erase difference*/
		   else if (eg->newbar<eg->oldbar[z]){ 
		     setfillstyle(SOLID_FILL,black);
		     bar(xbox+eg->newbar,ybox,
		      xbox+eg->oldbar[z],
                       ybox+(signed int)eg->barw-eg->barsep);
		  }
		  /*draw the whole bar (was.. if new>old add difference)*/
		  else if (eg->newbar>eg->oldbar[z]){             
		     setfillstyle(SOLID_FILL,nhdcolor);
                      bar(xbox,ybox,xbox+eg->newbar,
		           ybox+(signed int)eg->barw-eg->barsep);
		      /*bar(xbox+eg->oldbar[z],ybox,xbox+eg->newbar,
			ybox+(signed int)eg->barw-eg->barsep);*/                     
		  }
	       }

               /*new: histogram with 1 pix cols, and max in group if group required*/
               else if (eg->new_hist==1){ 
                     if (eg->hist_group[hist_group_count]>eg->hist_group[hist_group_count-1])
		            highest_in_group=eg->hist_group[hist_group_count];
		     if (hist_group_count==eg->col_group_size ||
			 (eg->lastgroup_size>0 && z==0)){

                        setcolor(black); /*erase prev bar*/                        
                        line(xbox,ybox,
			     xbox+(signed int)eg->lookupfreqwidth,ybox);
                        if (highest_in_group>0){
                           setcolor(white);
                           line(xbox,ybox,xbox+highest_in_group,ybox);
                           /*fprintf(stderr,"\n z=%d hcount=%d xbox=%d ybox=%d h_in_group=%d",
			     z,eg.hist_group_count, xbox,ybox, highest_in_group);*/ 
                        }
                        
                        highest_in_group=0;
                        hist_group_count=0;
                        for (yy=1; yy<=eg->col_group_size; yy++) eg->hist_group[yy]=0;
                        if (ybox<Maxy-1) ybox++;
	             }                     
               }

               /*axonometric of histogram bars; 
                 i.e. histogram+time, max lookup-table=64 only*/ 
               else if (eg->showlookupfreq==2){                  
		  if (eg->newbar>=3){
		     /*draw line as series of dots*/
		     for (xpix=xbox+1;
                           xpix<=xbox+eg->newbar-1;xpix++){
		       if (getpixel(xpix,ybox)==backc)
			      putpixel(xpix,ybox,darkgray);
                        
		     }
		  }
		  setcolor(white);
		  if (getpixel(xbox,ybox)==backc)
				    putpixel(xbox,ybox,white);
		  /*draw line as series of dots only on 0 background*/
		  xspace=xbox+eg->newbar-(xbox-1+eg->oldbar[z]);
		  pixposx=xbox-1+eg->oldbar[z];
		  pixposy=ybox-1;
		  for (xpix=0;xpix<=abs(xspace);xpix++){
		     if (getpixel(pixposx,pixposy)==backc)
				putpixel(pixposx,pixposy,white);
		     if (abs(xspace)!=0){
			pixposx+=xspace/abs(xspace);
			pixposy+=1.0/abs(xspace);
		     }
		  }
	       }
         }/*if stp*/
	 
         /*move down for next bar*/
	 if (eg->new_hist==0)  ybox+=(signed int)eg->barw;
	 eg->oldbar[z]=eg->newbar;

	 /*shunt generations*/
	 for (zz=eg->actgens-1;zz>=1;zz--){	 
	   eg->lookupcount[zz][z]=eg->lookupcount[zz-1][z];
         }
	 eg->lookupcount[0][z]=0; /*clear current*/
      }
   }

   /************** entropy-density plot (density of value_range-1) ***/
   /*note: "show density return-map" is in forx.c*/
   if (eg->lookup_entropy){
     signed int this_ent_den_plot[2],tempx,tempy;
     unsigned char temp_color;
      if (ae->show_edata==0 || ae->show_edata==1){
	  tempx=getx;
          tempy=gety;
          temp_color=getcolor();
          setcolor(eg->ecolor);	 
	    /*putpixel(eg->stpwidth+vgax(100)+2+vgax(10)+
	      eegratio*vgax(200),Maxy-2-vgax(10)-
	         (lu_entropy/log(1.0/(it->tablemax+1)))*vgay(200),
		   eg->ecolor);*/
	    this_ent_den_plot[0]=eg->stpwidth+vgax(100)+2+vgax(10)+eegratio*vgax(200);
            this_ent_den_plot[1]=Maxy-2-vgax(10)-(lu_entropy/log(1.0/(it->tablemax+1)))*vgay(200);

            moveto(this_ent_den_plot[0],this_ent_den_plot[1]);
	    putpixel(getx,gety,getcolor());
            if (eg->history_lines_in_plots==1){
               if (eg->ent_den_plot_before[0]>0 && eg->ent_den_plot_before[1]>0)
	           lineto(eg->ent_den_plot_before[0],eg->ent_den_plot_before[1]);
            }
            eg->ent_den_plot_before[0]=this_ent_den_plot[0];
            eg->ent_den_plot_before[1]=this_ent_den_plot[1];
            moveto(tempx,tempy);
            setcolor(temp_color);
              
      }
      //-----------------------
      /*show details of lu_entropy at each (or averaged over eg->actgens) time-step -- 
            to automatically measure pulsing in terminal*/
      if (ae->show_edata==0 && it->track_pulsing==1 /*&& totalistic==2 && tot_only==1*/){
	float small_div,waveheight;
	char e_latest,temp_pdata,temp_filedata;
         unsigned long emin_wave_length,emax_wave_length,this_emin,this_emax,
                       startstep=50;
         
         if (it->ittcount==1){
            it->etempent=it->old_etempent=0;
            small_div=0.02;
            fprintf(stderr,"\n\nNEW RULE");
            
            fprintf(stderr,"\nv%dk%d kcodeSize=%d",
                              value_range,nhood,v_tablecodemax[nhood]);
            if (it->time_step_density_plot==2){
                sprintf(textb[0],"\nv%dk%d kcodeSize=%d",
                              value_range,nhood,v_tablecodemax[nhood]);
                save_data(textb[0]);
            }
            fprintf(stderr,"\n(hex)");
	    temp_pdata=pdata;
            temp_filedata=filedata;
            pdata=1;
	    if (it->time_step_density_plot==2) filedata=1; /*save hex of rule*/
            print_current_bitstring_hexbytes(0,3,v_code[0],nhood,Maxx,white,3);
            pdata=temp_pdata;
	    filedata=temp_filedata;
            fprintf(stderr," w=%d",gens);
            if (it->time_step_density_plot==2){
                sprintf(textb[0]," w=%d",gens);
                save_data(textb[0]);
            }
            it->wave_sample=0;
            it->wave_total=0;
            it->wave_height_sample=0;
            it->wave_height_total=0;
         }
         
         if (it->ittcount>startstep){	     
               it->etempent = (float)(lu_entropy/log(1.0/(it->tablemax+1)));
               //fprintf(stderr,"\n %lu: %f ",it->ittcount,it->etempent);
               if (it->old_etempent>0 && it->old_etempent<1){ 
                  if (it->emax_ent<it->old_etempent) it->emax_ent=it->old_etempent; //max entropy so far
                  if (it->emin_ent>it->old_etempent) it->emin_ent=it->old_etempent; //min entropy so far
               }
               if (it->ittcount>startstep+1){
		 if (it->etempent - it->old_etempent > small_div){  //going up
                     it->e_up=1;
                     e_latest='u';  
                 }
                 if (it->old_etempent - it->etempent > small_div){ //going down
                     it->e_down=1;
                     e_latest='d';
                 }
               }
               
               //fprintf(stderr," %c up=%d down=%d",e_latest,it->e_up,it->e_down);
               if (it->e_up==1 && it->e_down==1){ //change direction
		  it->e_down=it->e_up=0;
		  if (e_latest=='u'){ 
		        //fprintf(stderr," min=%lu",it->ittcount-1);
                        fprintf(stderr,"\nmin=%lu",it->ittcount-1);
                        if (it->time_step_density_plot==2){
                           sprintf(textb[0],"\nmin=%lu",it->ittcount-1);
                           save_data(textb[0]);
                        }
                        this_emin=it->ittcount-1;
                        emin_wave_length=this_emin - it->old_this_emin;
                        waveheight=it->emax_ent-it->emin_ent;
                        if (this_emin>it->old_this_emin){
                          it->wave_height_sample+=1; /*keep track of average wavelength*/
                          it->wave_height_total+=waveheight;
                          it->av_wave_height=it->wave_height_total/it->wave_height_sample;
			  //fprintf(stderr," wl=%lu-%lu=%lu",this_emin,it->old_this_emin, emin_wave_length);
			  fprintf(stderr," wl=%lu wh=%.3f",emin_wave_length,waveheight);
                          if (it->time_step_density_plot==2){
			      sprintf(textb[0]," wl=%lu wh=%.3f",emin_wave_length,waveheight);
                               save_data(textb[0]);
                          }
                        }
                        it->old_this_emin=this_emin;
                        
                        it->emax_ent=.01; //reset
                        it->emin_ent=.99;  
		  }
                  else if (e_latest=='d'){ 
		        //fprintf(stderr," max=%lu",it->ittcount-1);
                        fprintf(stderr,"\nmax=%lu",it->ittcount-1);
                        if (it->time_step_density_plot==2){
                            sprintf(textb[0],"\nmax=%lu",it->ittcount-1);
                            save_data(textb[0]);
                        }

                        this_emax=it->ittcount-1;
                        emax_wave_length=this_emax - it->old_this_emax;
                        if (this_emax>it->old_this_emax){
			  //fprintf(stderr," wl=%lu-%lu=%lu",this_emax,it->old_this_emax, emax_wave_length);
                            fprintf(stderr," wl=%lu",emax_wave_length);
                            if (it->time_step_density_plot==2){
                                sprintf(textb[0]," wl=%lu",emax_wave_length);
                                save_data(textb[0]);
                            }
                            it->wave_sample+=1; /*keep track of average wavelength*/
                            it->wave_total+=emax_wave_length;
                            it->av_wave_length=(float)it->wave_total/it->wave_sample;
                        } 
                        it->old_this_emax= this_emax;
                  }
                  e_latest=0;
               }
               it->old_etempent=it->etempent; 
	 }                    
      }
      //-----------------------

      /*save lu_entropy to calculate statistics*/
      if (ae->show_edata==1 || ae->show_edata==2){
	 if (it->ittcount==1){
	    for (z=1;z<=eg->estep-eg->sstep+1;z++)
                                     ae->edata[z]=0;
	 }
         if (it->ittcount>=eg->sstep){
	     if (it->ittcount==eg->estep+1){ /*end of time-step sequence*/
               ae->sample_sofar+=1;
               if (tot_only==0){
                  if (set_iso_input_histogram==1)
                       automatic_was_set=moment(ae,eg,it,iso_rule);
                  else automatic_was_set=moment(ae,eg,it,carule[0]);
               }
               else if (tot_only==1){
                  if (totalistic==1) automatic_was_set=
                              moment(ae,eg,it,cacode[0]);
                  else if (totalistic==2) automatic_was_set=
                              moment(ae,eg,it,v_code[0]);
               }
	       if (automatic_was_set>=1){
	          ae->show_edata=2;
	          it->keyindex=0;
	          ae->edataruleno=0;
	          if (automatic_was_set==2) ae->file_edata=1;
	       }
	       it->screenend=1;
	       it->ittcount=0;
               if (eg->ecolor==yellow) eg->ecolor=lightred;
	       else if (eg->ecolor==lightred)
                                       eg->ecolor=lightcyan;
	       else if (eg->ecolor==lightcyan) eg->ecolor=green;
	       else if (eg->ecolor==green) eg->ecolor=white;
	       else if (eg->ecolor==white) eg->ecolor=yellow;

               /*set new random seed*/
	       random_seed(it->color1,100,0);
               
  
               if (ae->sample_sofar==ae->sample_size)
			           ae->sample_sofar=0;
	       if (ae->show_edata==2){    
	          if (automatic_was_set==0){ 
		     if (ae->sample_sofar==1 || ae->sample_size==1)
                                           ae->edataruleno+=1;
		     moveto(Maxx-vgax(160),vgay(3));                     
		     setcolor(white);
                     outtext("rule count=");
                     setfillstyle(SOLID_FILL,black);
                     bar(getx,gety,getx+CWidth*8,gety+CHeight);
		     sprintf(textb[0],"%lu",ae->edataruleno);                     
		     outtext(textb[0]);
                     outtext(" tog pause-p");
		  }
	       }
	       automatic_was_set=0;
	       memmove(state2,state1,bytesL);
	    }
	   
	    else{
	       if (min_max_entropy==1){ /*min-max entropy, max upslope*/
                  if (it->ittcount==eg->sstep){
                     minmin=1;
                     tempent=old_tempent=tempmin=tempmax=maxmax
		        =tempminmax=minmax=0;
                     if (ae->sample_sofar==0) max_minmax=0;
                     /*fprintf(stderr,"\n NEW sample_sofar=%d %lu %f,%f %f %f %f %f %f %f\n",
			     ae->sample_sofar,it->ittcount,
                                  max_minmax,tempent,old_tempent,tempmin,tempmax,maxmax,
				  tempminmax,minmax);*/
                  }
                  tempent = (float)(lu_entropy/log(1.0/(it->tablemax+1)));
                  /*fprintf(stderr,"\n %lu: %f ",it->ittcount,tempent);*/

                  if (old_tempent>0 && tempent>old_tempent){ /*if on upslope only*/ 
		     tempmin=tempent;
                     tempmax=tempent;
                     if (minmin>tempmin) minmin=tempmin;
                     if (maxmax<tempmin) maxmax=tempmin;
                     tempminmax= maxmax-minmin;

                     tempminmax=tempmax-minmin;
                     /*fprintf(stderr," - %lu: %f - %f, ",it->ittcount,tempmax,minmin);
		       fprintf(stderr," = tmm=%f",tempminmax);*/
                     if (minmax<tempminmax){
                        minmax=tempminmax;
                        /*fprintf(stderr," - minmax=%f",minmax);*/
                     }
                     old_tempent=tempent;
                     if (max_minmax<minmax){ 
                        max_minmax=minmax;
                        /*fprintf(stderr," - max_minmax=%f",max_minmax);*/
                     }
                  }
                  else{
                     minmin=1;
                     tempmin=tempmax=maxmax=tempminmax=minmax=0;
                  }
                  old_tempent=tempent;
	       }
               /*save entropy for each time-step from start to end*/
               ae->edata[it->ittcount-eg->sstep+1]=
		    (float)(lu_entropy/log(1.0/(it->tablemax+1)));
	    }
               
         }
      }
   }
}

/********************** variance etc ********************/
char moment(auto_ent *ae,
	    ent_eeg *eg,
	    int_stp *it,
	    char *thisrule){

  /*n =number of steps*/
  /*given array data[1...n] computes mean              =ave,
				    average deviation =adev,
				    standard deviation=sdev,
				    varience          =svar,
				    skewness          =skew,
				    kurtosis          =curt*/

 float ave,adev,sdev,svar,skew,curt;
 signed int n,j,xbox,tempx,tempy,tablemax,rulebytes,z;
 float s,p;
 unsigned char *buf,char_ave,char_sdev;
 char automatic_was_set=0,file_e=0,isrule;

   if (tot_only==0){ 
        if (set_iso_input_histogram==1) tablemax= iso_tablemax;
        else tablemax= (signed int)pow(value_range,(double)nhood)-1;
   }
   else if (tot_only==1){
      if (totalistic==1) tablemax=nhood*(value_range-1);
      else if (totalistic==2) tablemax=v_tablecodemax[nhood];
   }
   rulebytes=(signed int)ceil(value_bits * (double)(tablemax+1)/8);

   n=eg->estep-eg->sstep+1;
   s=adev=sdev=svar=skew=curt=0.0;
   if (ae->sample_sofar==1)
       ae->ave=ae->adev=ae->sdev=ae->svar=ae->skew=ae->curt=0.0;

   for (j=1;j<=n;j++) s+=ae->edata[j];
   ave=s/n;

   if (min_max_entropy==1) ae->sdev=sdev=max_minmax;
   else{
      for (j=1;j<=n;j++){
         adev += fabs(s=(float)ae->edata[j]-ave);
         svar += (p=s*s);
         /*skew += (p *= s);
	   curt += (p *= s);*/
      }
      adev /= n;
      svar /= (n-1);
      sdev=sqrt(svar);

      /*if (svar){
         skew /= (n*svar*sdev);
         curt=curt/(n*svar*svar)-3.0;
	 }*/
   }

   /*running average*/   
   ae->ave = (ae->ave *(ae->sample_sofar-1) + ave) /ae->sample_sofar;

   if (min_max_entropy==0){
      ae->adev= (ae->adev*(ae->sample_sofar-1) + adev)/ae->sample_sofar;
      ae->sdev= (ae->sdev*(ae->sample_sofar-1) + sdev)/ae->sample_sofar;
      /*ae->svar= (ae->svar*(ae->sample_sofar-1) + svar)/ae->sample_sofar;
      ae->skew= (ae->skew*(ae->sample_sofar-1) + skew)/ae->sample_sofar;
      ae->curt= (ae->curt*(ae->sample_sofar-1) + curt)/ae->sample_sofar;*/
   }
   /*else nrerror("No skew/kurtosis when varience = 0
                                      (in MOMENT)");*/   

   tempx=getx;
   tempy=gety;
   setcolor(white);

   if (stp && (
        (ae->auto_sample_pause==1 && ae->show_edata==2) 
          || ae->show_edata==1)){
      xbox=draw_prompt_box(4);
      /*to print correct type of rule in hex*/
      if (tot_only==0){
           
	  if (set_iso_input_histogram==1){ 
             isrule=4;
             sprintf(textb[1],"iso_rule");
          }
          else{
             isrule=1;
             sprintf(textb[1],"rcode");
          }

      }
      else{
          if (totalistic==1){
             isrule=2;
             sprintf(textb[1],"tcode");
          }
          else if (totalistic==2){
             isrule=3;
             sprintf(textb[1],"kcode");
          }
      } 
      
      if (ae->show_edata==2) moveto(xbox,gety+CHeight);
      sprintf(textb[0],"run=%d/%d",
                        ae->sample_sofar,ae->sample_size);
      outtext(textb[0]);
      if (single_entropy) sprintf(textb[0]," single=%d v%dk%d-%s=",
		entropy_poss,value_range,eg->ent_nhood,textb[1]);
      else sprintf(textb[0]," v%dk%d-%s=",
                  value_range,eg->ent_nhood,textb[1]);
      outtext(textb[0]);

      if (max_dec_rule(tablemax,value_range)>0){
         sprintf(textb[0],"(dec)%lu ",
	    dec_equiv(thisrule,(signed int)pow(2,
                           (float)eg->ent_nhood)-1));
         outtext(textb[0]);
      }      
      
      if (rulebytes<=15){
         sprintf(textb[0],"(hex)");
         outtext(textb[0]);
         print_current_bitstring_hexbytes(1,isrule,thisrule,
			       eg->ent_nhood,Maxx,white,0);
      }

      moveto(xbox,gety+CHeight);
      if (min_max_entropy==1){
         if (ae->sample_sofar==ae->sample_size) sprintf(textb[0],
            "mean=%f, minmax=%f",ae->ave,max_minmax/2);
         else
            sprintf(textb[0],"mean=%f, minmax=%f",ave,max_minmax/2);
      }
      else{
         if (ae->sample_sofar==ae->sample_size) sprintf(textb[0],
            "mean=%f, sdev=%f",
	          ae->ave,ae->sdev);
         else sprintf(textb[0],
	    "mean=%f, sdev=%f",ave,sdev);
      }
      outtext(textb[0]);
     /*
      moveto(xbox,gety+CHeight);
      if (ae->sample_sofar==ae->sample_size)
           sprintf(textb[0],"varience=%f, skewness=%f, kurtosis=%f",
	              ae->svar,ae->skew,ae->curt);
      else sprintf(textb[0],"varience=%f, skewness=%f, kurtosis=%f",
	              svar,skew,curt);
      outtext(textb[0]);
      */
   }
   
   if (ae->sample_sofar<ae->sample_size){

       /*if (min_max_entropy==1){
         fprintf(stderr,"\nmoment: sample_sofar=%d: max_minmax=%f",
                       ae->sample_sofar,max_minmax);
      }*/
      tempmin=1;
      tempmin=tempmax=maxmax=tempminmax=minmax=0;
      moveto(tempx,tempy);
      return(automatic_was_set);
   }

   /*save statistical data to file*/
   /*rule,mean entropy,standard dev,...all as chars*/
   if (ae->file_edata==1){
       /*buffer to append to file*/
       if ((buf=(unsigned char *)calloc(rulebytes+2,sizeof(unsigned char)))
				       ==NULL) outof_memory("buf");

       if (min_max_entropy==1) ae->sdev=max_minmax/2; 
       /*max_minmax varies between 0-1*/
      
       memmove(buf,thisrule,rulebytes);
       if (ae->sdev>.18) ae->sdev=0.18;
       /*fprintf(stderr,"\n max_minmax=%f",max_minmax);*/

       char_ave=ae->ave*255;
       char_sdev=(ae->sdev/.18)*255;
       buf[rulebytes]=char_ave;
       buf[rulebytes+1]=char_sdev;

       /*check values */
       /*
       xbox=draw_prompt_box(3);
       sprintf(textb[0],"strlen=%d",strlen(buf));
       outtext(textb[0]);
       moveto(xbox,gety+CHeight);
       sprintf(textb[0],"%.3f=%d=%.3f, %.4f=%d=%.4f",
	   ae->ave,char_ave,((float)char_ave)/255,
	      ae->sdev,char_sdev,((float)char_sdev*.18)/255);

       outtext(textb[0]);
       moveto(xbox,gety+CHeight);
       for (z=0;z<=rulebytes+1;z++){
	   sprintf(textb[0],"%c",buf[z]);
	   outtext(textb[0]);
       }
       input_string(1,0);
       */
       save_binary_data(buf,(unsigned long)rulebytes+2);
       free(buf);
   }

   /*pause for each new rule -- test*/
   if (ae->show_edata==1){
      is[1]=0; /*clear is[1]*/
      moveto(xbox,gety+CHeight);
      outtext(
        "automatic-a glider+g, next rule: glider-g same-s rnd-def:");
      /*note: for 2d v2k9, -ag for 3 rules:Life, X-rule, and Sapin - file is g_v2k9.r_s*/ 
      input_string(2,0);
      if (is[0]=='g') glider_rule(NULL);
      else if (is[0]=='s');

      else if (is[0]=='a'){
	 if (is[1]=='g') auto_glider_sample=1;
         /*fprintf(stderr,"\nis[1]=%c auto_glider_sample=%d",
	                       is[1],auto_glider_sample);*/

         moveto(xbox,gety+CHeight);/*revise the sample for each rule if required*/ 
         sprintf(textb[0],"sample for each rule (def %d):",
		                                 ae->sample_size);
         outtext(textb[0]);
		 input_string(4,0);
		 if (atoi(is)>0 && 
                       is[0]!=13 && is[0]!='q') ae->sample_size=atoi(is);

	 ae->show_edata=2;
	 erase_box(Maxx-vgax(130)-3,Maxy-vgay(420),Maxx-2,Maxy-2);
	 automatic_was_set=1;
	 draw_entgraph_frame(1,eg->stpwidth,ae->show_edata,0);
	 file_e=select_stat_filename(ae);
	 if (file_e==1) automatic_was_set=2;
      }
      //else it->color1=bit_flip('r',it->color1);/*set new random rule*/

      /*set new rnd or biased rule*/
      else set_new_rnd_or_biased_rule(ae,it,sdev);
      /*reset ent-den graph*/
      draw_entgraph_frame(1,eg->stpwidth,ae->show_edata,0);
   }

   /*automatic next random rule*/
   else if (ae->show_edata==2){
                     moveto(Maxx-vgax(160),vgay(3));                     
		     setcolor(white);
                     outtext("rule count=");
                     setfillstyle(SOLID_FILL,black);
                     bar(getx,gety,getx+CWidth*8,gety+CHeight);
		     sprintf(textb[0],"%lu",ae->edataruleno);
		     outtext(textb[0]);
                     outtext(" tog pause-p:");

                     //stop sample at set number
                     //if (ae->edataruleno==50000) input_string(1,0);
      
      /*plot red square with black outline for current, 
               blue pixel or small square for last*/
      statx=eg->stpwidth+vgax(100)+2+vgax(10)+
		     ae->sdev*10*vgax((signed int)(256*10.0/18));
      staty=Maxy-2-vgax(10)-ae->ave*vgay(200);
      /*if (ae->edataruleno>1 && ae->sample_sofar>=ae->sample_size){*/
      if (ae->sample_sofar>=ae->sample_size){
#     if __UNIX__
         if (*statblock != 0)
#     endif
         sprintf(textb[9],"%s","statblock");    
	 putimage(oldstatx-vgax(2),oldstaty-vgay(2),statblock,COPY_PUT,textb[9]);
         if (Maxx<=639) putpixel(oldstatx,oldstaty,yellow);
         else {
              setfillstyle(SOLID_FILL,yellow);           
              bar(oldstatx,oldstaty,oldstatx+vgax(1),oldstaty+vgay(1));
         }
      }

      getimage(statx-vgax(2),staty-vgay(2),statx+vgax(2),staty+vgay(2),statblock);
      setfillstyle(SOLID_FILL,lightred);
      bar3d(statx-vgax(2),staty-vgay(2),statx+vgax(2),staty+vgay(2),1,0);
      oldstatx=statx;
      oldstaty=staty;
      /* pause after each rule*/
      if (ae->auto_sample_pause==1){
         input_string(1,0);
         if (is[0]=='p') ae->auto_sample_pause=0;
      }
      /*fprintf(stderr,"\nin auto: auto_glider_sample=%d",
	                              auto_glider_sample);*/
      if (auto_glider_sample==1)
         glider_rule(NULL); /*for valid glider sample, e.g. g_v2k9.r_s*/
      else set_new_rnd_or_biased_rule(ae,it,sdev);        
   }
    
   max_minmax=0;/*reset max_minmax for next rule*/
 
   erase_prompt_box(4);
   moveto(tempx,tempy);
   return(automatic_was_set);
}

/*************************** new rule -- rnd or biased Oct 2010 ***********/
void set_new_rnd_or_biased_rule(auto_ent *ae,int_stp *it, float sdev){

  signed int tablemax;
    
      /*set new random rule,with or without bias
      isomorphic, %/values, random, then all0s->0, allVs-V*/

      //fprintf(stderr,"\nset_new_rnd_or_biased_rule");

      if (tot_only==0){ 
        if (set_iso_input_histogram==1) tablemax= iso_tablemax;
        else tablemax= (signed int)pow(value_range,(double)nhood)-1;
     }
      else if (tot_only==1){
         if (totalistic==1) tablemax=nhood*(value_range-1);
         else if (totalistic==2) tablemax=v_tablecodemax[nhood];
      }

      if (ae->bias_isomorphic==2 && max_dec_rule(tablemax,value_range)>0){
	  //consecutive dec rules for small rule-space, i.e. v3k3=59048
	  //restrictions: all0s->0, all colors must be present

	unsigned long codedec;
        int z; 
        char cz,*no_each_value,*tempbuf,reject_rule=0;
        signed int tablebytes;

	 //fprintf(stderr,"\nmax=%lu ",max_dec_rule(tablemax,value_range));
         if ((no_each_value=(char*)calloc(value_range,sizeof(char)))
				       ==NULL) outof_memory("no_each_value");
         tablebytes=(signed int)ceil(value_bits * (double)(tablemax+1)/8);
         if ((tempbuf=(char *)calloc(tablebytes,sizeof(char)))
				       ==NULL) outof_memory("carule[0]");
         
        top:
	 auto_sample_rule_count+=1;         
         fprintf(stderr," %lu",auto_sample_rule_count);
         //if (auto_sample_rule_count==59048)  goto exit_consec; //for v3k3
         //if (auto_sample_rule_count>=max_dec_rule(tablemax,value_range)-1) goto exit_consec;
         if (auto_sample_rule_count>=max_dec_rule(tablemax,value_range)){
            draw_prompt_box(1);
	    sprintf(textb[0],"consec rule-space %lu complete, any key to continue:",auto_sample_rule_count);
            outtext(textb[0]);
            input_string(0,1);
            is[0]='q';
            goto exit_consec;
         }
         dec_to_value_line(tempbuf,auto_sample_rule_count,tablemax+1);
         if (tot_only==0){
            if (set_iso_input_histogram==1) memmove(iso_rule,tempbuf,tablebytes);
            else memmove(carule[0],tempbuf,tablebytes);
         }
         else if (tot_only==1){
	   if (totalistic==1) memmove(cacode[0],tempbuf,tablebytes);
	   if (totalistic==2) memmove(v_code[0],tempbuf,tablebytes);
         }

         if (get_value(tempbuf,0)!=0){
               goto top; //all0s->0 >reject
         }
         for (z=0;z<=tablemax;z++){
	    for (cz=0;cz<value_range;cz++){
		 if (get_value(tempbuf,z)==cz) no_each_value[cz]+=1;
            }
         }
         for (cz=0;cz<value_range;cz++){
	   if (no_each_value[cz]==0){ 
               goto top; //some values not present >reject
           }
         }
         free(no_each_value);
         free(tempbuf);
        exit_consec:
         return;         
      }     

      else if (ae->bias_isomorphic==1){ /*new isomorphic (isoytropic!)rule*/
             fprintf(stderr,"\nbias_isomorphic");
             bit_flip('[',it->color1);          
      }      

      /*bias v3k6 sample  was  0    1    2   
                              13    5    8
                              48%  19%  33% */

      else if (ae->bias_rnd_rules==1 && 
                (bias_percent_rule[8]=='p' || bias_percent_rule[8]=='v')){
	 //fprintf(stderr,"\nbias rnd rule:implement_fraction_values");
	 if (tot_only==0){
           if (set_iso_input_histogram==1){
	       signed int zz,s;
                 implement_fraction_values(1,0,iso_rule,tablemax+1);
                 /*fprintf(stderr,"\nbias_rnd_rules, after implement_fraction_values:");
                 for (zz=tablemax;zz>=0;zz--){
                       fprintf(stderr,"%d",get_value(iso_rule,zz));
                      //modify carule[0] accordingly
                      for (s=1;s<=glbl_iso_list[zz][0];s++)
		              set_value(carule[0],glbl_iso_list[zz][s],get_value(iso_rule,zz));
		 }*/
           } 
           else implement_fraction_values(1,0,carule[0],tablemax+1);
	 }
         else if (tot_only==1){
	   if (totalistic==1) implement_fraction_values(1,0,cacode[0],tablemax+1);
	   if (totalistic==2) implement_fraction_values(1,0,v_code[0],tablemax+1);
         }
      }

      else if (set_iso_input_histogram==1){
            bit_flip('r',it->color1);
      }

      else it->color1=bit_flip('R',it->color1); /*new random rule -no bias*/

      /*this overrides the rule just set, all0s->0 and allVs-V */ 
      if (ae->bias_all020==1) /*change all0s->0*/  
                     it->color1=bit_flip('b',it->color1);    
                
      if (ae->bias_allV2V==1) /*change allVs->V*/  
                     it->color1=bit_flip('B',it->color1); 
      if (set_iso_input_histogram==1){
	  signed int zz,s;
	   //fprintf(stderr,"\nfinal>iso-table:");
           for (zz=tablemax;zz>=0;zz--){
	      //fprintf(stderr,"%d",get_value(iso_rule,zz));
              //modify carule[0] accordingly
              for (s=1;s<=glbl_iso_list[zz][0];s++)
		   set_value(carule[0],glbl_iso_list[zz][s],get_value(iso_rule,zz));
           }
           //fprintf(stderr,"\nfinal:(%d)>iso-hex=",iso_tablemax+1);
           //print_current_bitstring_hexbytes(16,4,iso_rule,nhood,Maxx,black,6);
       }      
}

/********************** load a rule from the glider file *********/
void glider_rule(int_stp *it){
 signed int rulebytes,tablemax,
	  fileno, /*no of glider rule files for loading*/
	  tempx,tempy;
 unsigned char tempcolor;

   tempcolor=getcolor();
   setcolor(white);
   tempx=getx;
   tempy=gety;
   
   if (no_glider_rules[value_range][nhoodm[0]]<=0)
          inset_prompt_box(0,20,"glider sample not available",'m');
   else{       
      if (glider_rule_order==-1){ /*rnd selection*/
         while (1){
            fileno=myrand()%(no_glider_rules[value_range][nhoodm[0]]);
            if (fileno>0) break;
         }
      }
      
      else{  /*seq selection*/
	  glider_rule_order+=1;
          fileno=glider_rule_order;
          if (fileno>=no_glider_rules[value_range][nhoodm[0]]-1)
	      glider_rule_order=0;
      }
      /*fprintf(stderr,"\nglider_rule_order=%d fileno=%d",
	                         glider_rule_order,fileno);*/
      if (tot_only==0){
         if (set_iso_input_histogram==1) tablemax= iso_tablemax;
         else tablemax= (signed int)pow(value_range,(double)nhoodm[0])-1;
       
         rulebytes=(signed int)ceil(value_bits * (double)(tablemax+1)/8);         

         if (value_range==2 && glider_buf[0]!=2)
              /*old type rulemix file, with 5 (not 6) leading bytes
                glider_buf[0]=nhood, new glider_buf[0]=value_range*/  
              memmove(carule[0],glider_buf+5+fileno*rulebytes,rulebytes);
         else memmove(carule[0],glider_buf+6+fileno*rulebytes,rulebytes);


      }
      else if (totalistic==2){
	 /*signed int z;*/
         tablemax= v_tablecodemax[nhood];
         rulebytes=(signed int) /*bytes for k-code, min=1*/
            ceil(value_bits * (double)(tablemax+1)/8);
         memmove(v_code[0],glider_buf+6+fileno*rulebytes,rulebytes);
        
         /*fprintf(stderr,"\n fileno=%d:",fileno);
         for (z=tablemax;z>=0;z--){
            fprintf(stderr,"%d",get_value(v_code[0],z));
	 }*/
      }

      if (tot_only==0){
         if (set_iso_input_histogram==1) 
              sprintf(textb[0],"rcode v%dk%d, 1d cplx sample(%d)=%d",value_range,nhood,
                         no_glider_rules[value_range][(signed int)nhood]-1,fileno);
         else sprintf(textb[0],"rcode v%dk%d, 1d cplx sample(%d)=%d",value_range,nhood,
                         no_glider_rules[value_range][(signed int)nhoodm[0]]-1,fileno);
      }
      else if (totalistic==2)
            sprintf(textb[0],"kcode v%dk%d, 2d cplx sample(%d)=%d",
                     value_range,
                         nhood,no_glider_rules[value_range][(signed int)nhoodm[0]]-1,fileno);
	        
      draw_rule_box(170,textb[0],nhoodm[0]);	 
   }
   moveto(tempx,tempy);
   setcolor(tempcolor);
}

/***************** load a rule from the sample file *********/
unsigned long stat_rule(char autostat,unsigned long statrule_index,
                                   int_stp *it, signed int stpwidth){
 signed int rulebytes,tablemax;
 unsigned long ruleindex=0;
 
   if (tot_only==0){ 
        if (set_iso_input_histogram==1) tablemax= iso_tablemax;
        else tablemax= (signed int)pow(value_range,(double)nhood)-1;
     }
   else if (tot_only==1){
      if (totalistic==1) tablemax=nhood*(value_range-1);
      else if (totalistic==2) tablemax=v_tablecodemax[nhood];
   }
   rulebytes=(signed int)ceil(value_bits * (double)(tablemax+1)/8);

   if (autostat==0){
      draw_prompt_box(1);
      if (totstatrules==0){

         min_max_entropy=1;
         setcolor(white);
         draw_prompt_box(1);
         sprintf(textb[0],
               "load sample: entropy variability, sdev-s,  min-max -(def):");
         outtext(textb[0]);
         input_string(1,0);
         if (is[0]=='s') min_max_entropy=0;
         erase_prompt_box(1);
         load_rule_stats(0,stpwidth);
         return(ruleindex);
      }
 
      draw_prompt_box(1);
      setcolor(white);
      stat_patch=0;
      sprintf(textb[0], //a new sample here can cause seg fault (maybe ok, so restored Aug2021)
	      "rule sample: load new-n, rule index/scan 1-%lu (%lu-def):",
	                             totstatrules,statrule_index);
              /*"rule sample: rule index/scan 1-%lu (%lu-def):",
		                          totstatrules,statrule_index);*/
      outtext(textb[0]);
      input_string(5,0);
      if (is[0]=='q') return(ruleindex);

      if (is[0]=='n'){
         min_max_entropy=1;
         draw_prompt_box(1);
         sprintf(textb[0],
               "entropy variability, sdev-s, min-max -(def):");
         outtext(textb[0]);
         input_string(1,0);
         if (is[0]=='s') min_max_entropy=0;
         erase_prompt_box(1);

	 load_rule_stats(0,stpwidth);
	 if (is[0]=='q' || totstatrules==0) return(ruleindex);
      }      
      else
      if (is[0]==13) ruleindex=statrule_index;
      else if (atol(is)>0 && atol(is)<=totstatrules) ruleindex=atol(is);
      else ruleindex=1;

      it->a_index_sample=0;
      
      draw_prompt_box(1);
      sprintf(textb[0],
       "scan time-blocks from index %lu: incr-i keep-k no-blocks-def:",
                            ruleindex);
						    
      outtext(textb[0]);
      input_string(1,0);
      
      if (is[0]=='i' || is[0]=='k'){
         it->keep_index=0;
	 if (is[0]=='k') it->keep_index=1;
         /*advance -- increase index for each new time block, with new seed,
         if keep_index=1 dont change index, in forx.c*/
         it->a_index_sample=1; 
         it->ittcount=0;     
         it->a_sample_ht=150;
         draw_prompt_box(1);
         sprintf(textb[0]," set time-block (def %d):",it->a_sample_ht);
         outtext(textb[0]);
         input_string(3,0);
         if (is[0]==13); /*do nothing*/
         else if (atoi(is)>0) it->a_sample_ht=atoi(is);
         else it->a_sample_ht=150;
         it->seedORblock=0; /*def 0=seed all, v=block, 5/6=singleton
                              when scanning  rule samples in time-step blocks*/
         sprintf(textb[0]," seedtype: block-v single-5/6 (def all):");
         outtext(textb[0]);
         input_string(1,0);
         if (is[0]=='v') it->seedORblock='v';
         else if (is[0]=='5') it->seedORblock='5';
         else if (is[0]=='6') it->seedORblock='6';
      }
   }

   else if (autostat==1) ruleindex=statrule_index;
   erase_prompt_box(1);
 

   if (tot_only==0){
      if (set_iso_input_histogram==1) memmove(iso_rule,
                    statbuf+(ruleindex-1)*(rulebytes+2),rulebytes);
      else memmove(carule[0],
                    statbuf+(ruleindex-1)*(rulebytes+2),rulebytes);
   }
   else if (tot_only==1){
      if (totalistic==1) memmove(cacode[0],
                    statbuf+(ruleindex-1)*(rulebytes+2),rulebytes);
      else if (totalistic==2) memmove(v_code[0],
                    statbuf+(ruleindex-1)*(rulebytes+2),rulebytes);
   }

   if (tot_only==0){
      if (set_iso_input_histogram==1) sprintf(textb[1],"iso_rule v%dk%d: ",value_range,nhood);
      else sprintf(textb[1],"rcode v%dk%d: ",value_range,nhood);
   }
   else{
     if (totalistic==1) sprintf(textb[1],"tcode v%dk%d: ",value_range,nhood);
     else if (totalistic==2) sprintf(textb[1],"kcode v%dk%d: ",value_range,nhood);
   }
   if (min_max_entropy==1) sprintf(textb[4],"mm");
   else sprintf(textb[4],"sdev"); 

   sprintf(textb[2],"s=%lu ",ruleindex);

   /*sprintf(textb[3],"me=%.4f %s=%.4f",
      ((float)statbuf[(ruleindex-1)*(rulebytes+2)+rulebytes]*.18)/255,
      textb[4],
      ((float)statbuf[(ruleindex-1)*(rulebytes+2)+rulebytes+1]*.18)/255);*/

   /*changed to give co-ords of the rule on 256x256 grid, not the actual value*/
   sprintf(textb[3],"me=%d %s=%d",
      statbuf[(ruleindex-1)*(rulebytes+2)+rulebytes],textb[4],
                 statbuf[(ruleindex-1)*(rulebytes+2)+rulebytes+1]);
   if (xstat1==0 && ystat1==0 && xstat2==0 && ystat2==0)
              sprintf(textb[4]," nopatch");
   else if (stat_patch==1) sprintf(textb[4]," patch-ON (%d %d %d %d)",
                                         xstat1,ystat1,xstat2,ystat2);
   else sprintf(textb[4]," patch-OFF");
   sprintf(textb[0],"%s%s%s%s",textb[1],textb[2],textb[3],textb[4]);
   //draw_rule_box(250,textb[0],nhood); too wide for diagonal scrolling
   //input_string(1,0);
   draw_rule_box(170,textb[0],nhood);
   if (set_iso_input_histogram==1){
	 signed int zz,s;
	   //fprintf(stderr,"\nrule-from-sample(%d):",tablemax); 
           for (zz=tablemax;zz>=0;zz--){
	        //fprintf(stderr,"%d",get_value(iso_rule,zz));
                      //modify carule[0] accordingly
                      for (s=1;s<=glbl_iso_list[zz][0];s++)
		              set_value(carule[0],glbl_iso_list[zz][s],get_value(iso_rule,zz));
            }
	   //input_string(1,0);q
   }
   return(ruleindex);
}

/******* draw axomometric plane for 2-d space-time patterns, Jan 94 ******/
void draw_axon_plane(float fscale,signed int tempy, char draw_3d_grid){
  signed int this_tempx,this_tempy,tempx,z,this_i2d,this_j2d,zz;
 float axo_cell_h,wx,aa,bot;
 unsigned char tempcolor,grid_color;

    this_tempx=getx;
    this_tempy=gety;
    tempcolor=getcolor();

    tempx=getx;
    if (d_mode==2 && scrolling==1) tempx=tempy; 
    moveto(tempx,tempy);

    if (d_mode==3 || (d_mode==2 && scrolling)){
	this_i2d=i2d;
	this_j2d=j2d;
	bot=Maxy-1;
    }
    else if (d_mode==4){
	this_i2d=i3d;
	this_j2d=j3d;
	bot=tempy+h3d*fscale;
    }
	/* | aa|  wx  |
	---    3------4
	      /      /|
	aa   /      / |
 tempx	    /      /  |
 tempy --- 1------2   |
	   |      |   7
	   |      |   /
	   |      |  /
	   |      | /
 Maxy-1 __ |______|/
 bot	   5      6   |
	   | wx   | aa|
	   tempx  */

    axo_cell_h=sin(PI/4)*fscale;
    wx=fscale*this_i2d;
    aa=(signed int)(axo_cell_h*this_j2d);

    if (d_mode==4){ /*grid slows 3d stp*/
        if (fscale<3) goto skip; /*too small to show grid*/
        if (i3d>40 || j3d>40 || h3d>40){
	  if (draw_3d_grid==0) goto skip;/*otherwize too slow*/
        }
        else if (draw_3d_grid==0) goto skip;
        
	setfillstyle(SOLID_FILL,black);
	bar(tempx,tempy-aa,tempx+aa+wx,bot);
    }

   /*set line colors - these were more subtle but now superseeded*/
/*#  if __UNIX__
      if (bground=='w') XSetForeground(D,Gc,(unsigned long)Color_Table[Light_Steel_Blue]);
      else XSetForeground(D,Gc,(unsigned long)Color_Table[Dark_Slate_Blue]);
#  elif __WATCOM__
      setcolor(darkgray);
#  endif*/

   if (bground=='w') grid_color=lightgray;
   else grid_color=darkgray;

   setcolor(grid_color);  /*for 3d wiring graphic*/
   if (wiring_postscript) color_ps(wiring_postscript-1,grid_color);

   /*for hires Dell 3200x1800 --while(event_ready()==0) break; added
       unpredictable screen lines missing without this - ??
		          though line_ps( was ok*/
   /*top: vertical lines*/
   for (z=1;z<=this_i2d-1;z++){
      if (!(fscale==1 && z%2==1)){
         if (d_mode==2 && scrolling)
             line(tempx+fscale*z,tempy,tempx+fscale*z,tempy+fscale*this_j2d);           
         else{
	     if (wiring_postscript) 
	       line_ps(tempx+fscale*z,tempy,tempx+fscale*z+aa,tempy-aa);
             line(tempx+fscale*z,tempy,tempx+fscale*z+aa,tempy-aa);
	     while(event_ready()==0) break;             
         }
      }
   }     
   /*top: horiz lines*/
   for (z=1;z<=this_j2d-1;z++){
      if (!(fscale==1 && z%2==1)){
         if (d_mode==2 && scrolling)
            line(tempx,tempy+fscale*z,tempx+fscale*this_i2d,tempy+fscale*z);
         else{
	    if (wiring_postscript) 
                line_ps(tempx+axo_cell_h*z,tempy-axo_cell_h*z,
	           tempx+axo_cell_h*z+wx,tempy-axo_cell_h*z);
            line(tempx+axo_cell_h*z,tempy-axo_cell_h*z,
	           tempx+axo_cell_h*z+wx,tempy-axo_cell_h*z);
	    while(event_ready()==0) break;            
         }
      }
   }

   if (d_mode==4){
      for (z=1;z<=h3d-1;z++){
	 /*horiz lines, back face*/
	 if (wiring_postscript) 
                line_ps(tempx,tempy+fscale*z,tempx+i3d*fscale,tempy+fscale*z);
	 line(tempx,tempy+fscale*z,tempx+i3d*fscale,tempy+fscale*z);
	 while(event_ready()==0) break;
	 /*diag lines, side face*/
	 if (wiring_postscript) line_ps(tempx+i3d*fscale,tempy+fscale*z,
	                         tempx+i3d*fscale+j3d*fscale*sin(PI/4),
		                      tempy+fscale*z-j3d*fscale*sin(PI/4));
	 line(tempx+i3d*fscale,tempy+fscale*z,
	      tempx+i3d*fscale+j3d*fscale*sin(PI/4),
		   tempy+fscale*z-j3d*fscale*sin(PI/4));
	 while(event_ready()==0) break;
      }
      for (z=1;z<=i3d-1;z++){
	 /*vertical lines, back face*/	 
         if (wiring_postscript) 
              line_ps(tempx+fscale*z,tempy,tempx+fscale*z,tempy+h3d*fscale);
	 line(tempx+fscale*z,tempy,tempx+fscale*z,tempy+h3d*fscale);
	 while(event_ready()==0) break;
      }
      for (z=1;z<=j3d;z++){
	 /*vertical lines, side face*/
	 if (wiring_postscript) line_ps(tempx+i3d*fscale+fscale*z*sin(PI/4),
	                                  tempy-z*fscale*sin(PI/4),
	                                    tempx+i3d*fscale+fscale*z*sin(PI/4),
		                              tempy-z*fscale*sin(PI/4)+h3d*fscale);
	 line(tempx+i3d*fscale+fscale*z*sin(PI/4),
	     tempy-z*fscale*sin(PI/4),
	       tempx+i3d*fscale+fscale*z*sin(PI/4),
		 tempy-z*fscale*sin(PI/4)+h3d*fscale);
	 while(event_ready()==0) break;
      }
   }

   skip:;
   setcolor(white);
   if (wiring_postscript) color_ps(wiring_postscript-1,white);/*for 3d wiring graphic*/
   if (d_mode==2 && scrolling){
      /*draw outline*/
      line(tempx,tempy,tempx+fscale*this_i2d,tempy);    /*1-2*/            
      line(tempx+fscale*this_i2d,tempy,                 /*     1----2  */
           tempx+fscale*this_i2d,tempx+fscale*this_j2d);/*1-3  |    |  */
      line(tempx+fscale*this_i2d,tempx+fscale*this_j2d, /*     |    |  */
	   tempx,tempx+fscale*this_j2d);                /*3-4  4--- 3  */
      line(tempx,tempx+fscale*this_j2d,tempx,tempx);    /*4-1*/
   }

   else{
      /*draw outline*/
      line(tempx,tempy,tempx+wx,tempy);             /*1-2*/
      if (wiring_postscript) line_ps(tempx,tempy,tempx+wx,tempy);
      line(tempx,tempy,tempx+aa,tempy-aa);          /*1-3*/
      if (wiring_postscript) line_ps(tempx,tempy,tempx+aa,tempy-aa);
      line(tempx+aa,tempy-aa,tempx+aa+wx,tempy-aa); /*3-4*/
      if (wiring_postscript) line_ps(tempx+aa,tempy-aa,tempx+aa+wx,tempy-aa);
      line(tempx+wx,tempy,tempx+wx+aa,tempy-aa);    /*2-4*/
      if (wiring_postscript) line_ps(tempx+wx,tempy,tempx+wx+aa,tempy-aa);
      /*draw axo frame*/
      if (d_mode==4 || (tempy-axo_cell_h*this_j2d)<2){
         line(tempx,tempy,tempx,bot);                /*1-5*/
         if (wiring_postscript) line_ps(tempx,tempy,tempx,bot);
         line(tempx,bot,tempx+wx,bot);               /*5-6*/
         if (wiring_postscript) line_ps(tempx,bot,tempx+wx,bot);
         line(tempx+wx,bot,tempx+wx,tempy);          /*6-2*/
         if (wiring_postscript) line_ps(tempx+wx,bot,tempx+wx,tempy);
         line(tempx+wx,bot,tempx+wx+aa,bot-aa);      /*6-7*/
         if (wiring_postscript) line_ps(tempx+wx,bot,tempx+wx+aa,bot-aa);
         line(tempx+wx+aa,bot-aa,tempx+wx+aa,tempy-aa); /*7-4*/
         if (wiring_postscript) line_ps(tempx+wx+aa,bot-aa,tempx+wx+aa,tempy-aa);
      }
   }
   moveto(this_tempx,this_tempy);
   setcolor(tempcolor);
}

/**************** set colors acc to nhoods, Oct 93, revised June 2020 *****************/
signed int set_nhdcolor(char tnhood, signed int z){
  signed int nhdcolor=0,i;
  signed int temp,tablesize;
  double v_t,div_tsize;
  char set_white=0;

           if (tot_only==0){ 
	      if (z==(signed int)pow(value_range,(double)tnhood)-1){
		 nhdcolor=white;
                 set_white=1;
                 goto end_set_nhdcolor;
              } 
	      if (set_iso_input_histogram==1) tablesize=iso_tablemax+1;
              else tablesize=(signed int)pow(value_range,(double)tnhood);              
           }
           else if (tot_only==1){
	      if (totalistic==1){
                 if (z==tnhood*(value_range-1)){
                    nhdcolor=white;
                    set_white=1;
                    goto end_set_nhdcolor;
                 }
                 tablesize=nhood*(value_range-1)+1;
              }
              if (totalistic==2){
		 tablesize=v_tablecodemax[nhood];
                 if (z==v_tablecodemax[nhood]){
                     nhdcolor=white;
                     set_white=1;
                     goto end_set_nhdcolor;
                 }
              }
           }

	   /*lookup-freq histogram bars: max and zero is black, 
             otherwise cycle 15 colors, including black*/

           /*space-time colors, will match exept zero which is white*/

           if (tablesize<=15) nhdcolor=nhd_color_order[z];
           else nhdcolor=nhd_color_order[z%15];

       end_set_nhdcolor:

	   //check if this still works for DOS
#       if __WATCOM__
	   return(nhdcolor);
#       elif __UNIX__
           if (set_white==1) return(nhdcolor);
	   else return(oldcolor[nhdcolor]);/*xwindows*/
#       endif
        
}
/******************* draw frame for eeggraph, Oct 93 ********/
void draw_stpframe(signed int stpwidth,float framewidth){
  char z,tempcolor;

        if (stpgraph==0 || (d_mode==2 && scrolling==1)) return;
        /*if (twod==2 && !(stpgraph>1)) return;*/
	tempcolor=getcolor();
	/*clear space*/
	setfillstyle(SOLID_FILL,black);
        bar(stpwidth,0,stpwidth+framewidth,Maxy);
                     
        /*draw frame*/
	setcolor(red);
	setfillstyle(SOLID_FILL,black);
       
	bar3d(stpwidth,0,stpwidth+framewidth,Maxy,0,0);
	if (stpgraph==1){
	   moveto(stpwidth+(signed int)(framewidth/4),0);
	   for (z=1;z<=3;z++){
		lineto(getx,Maxy);
		moveto(getx+(signed int)(framewidth/4),0);
	   }
	}
        setcolor(black);
        line(stpwidth+1,Maxy,stpwidth+framewidth,Maxy);
	moveto(0,0);
	setcolor(tempcolor);
   
}

/******* draw or erase graph frame for eeg-entropy, Aug 95 ******/
void draw_entgraph_frame(char draw_clear,
	    signed int stpwidth,char show_edata,char ylabel){
  signed int rightedge,tempx,tempy,
	       tempx1,tempy1,tempx2,z,xaxismax;
  unsigned char existcolor;
  float xinterval;

      /*if (stpgraph==0 || (d_mode==2 && scrolling==1)) return;*/
      if (d_mode==2 && scrolling==1) return;
      tempx=getx;
      tempy=gety;

      if (stpgraph==1 || show_edata==0 || show_edata==1)
	  rightedge=stpwidth+vgax(100)+2+vgax(200)+vgax(10);
      else if (show_edata==2){
	  rightedge=stpwidth+vgax(100)+2+vgax(256)+vgax(10);
      }
      /*clear space*/
      draw_box(-1,stpwidth+vgax(100)+1,Maxy-2-vgay(200)-vgax(10),
	 rightedge+vgax(10),Maxy-1,0,0);

      if (draw_clear==0){
	 moveto(tempx,tempy);
	 return;
      }

      existcolor=getcolor();
      setcolor(lightred);
      /*draw graph outline*/
      draw_box(-1,stpwidth+vgax(100)+2+vgax(10),Maxy-2-vgay(200)-vgax(10),
	 rightedge,Maxy-2-vgax(10),1,0);


      /*draw x axis divisions*/
      moveto(stpwidth+vgax(100)+2+vgax(10),Maxy-2-vgax(10));
      if (show_edata==0 || show_edata==1){
	 xaxismax=9;
	 xinterval=20;
      }
      if (show_edata==2){
	 xaxismax=18;
	 xinterval=256.0/18;
      }
      tempx1=getx;
      tempy1=gety;

      for (z=1;z<=xaxismax-1;z++){
	 moveto(tempx1+vgax((signed int)(xinterval*z)),tempy1);
	 linerel(0,vgay(3));
      }
      /*draw y axis divisions*/
      moveto(stpwidth+vgax(100)+2+vgax(10),Maxy-2-vgax(10));
      tempx1=getx;
      for (z=1;z<=9;z++){
	 moveto(tempx1,gety-vgay(20));
	 linerel(-vgax(3),0);
      }

      /*label x axis*/
      moveto(stpwidth+vgax(102)+vgax(10),Maxy-vgay(10));
      outtext("0");
      moveto(stpwidth+vgax(102)+vgax(10)+vgax(80),Maxy-vgay(10));
      if (stpgraph==1){
         moveto(stpwidth+vgax(102)+vgax(10)+vgax(80),Maxy-vgay(10));
	 outtext("density t0");
	 moveto(stpwidth+vgax(100)+vgax(10)+vgax(200),Maxy-vgay(10));
	 outtext("1");
      }

      else if (show_edata==0 || show_edata==1){
	 moveto(stpwidth+vgax(102)+vgax(10)+vgax(80),Maxy-vgay(10));
	 outtext("density");
	 moveto(stpwidth+vgax(100)+vgax(10)+vgax(200),Maxy-vgay(10));
	 outtext("1");
      }
      else  if (show_edata==2){
	 moveto(stpwidth+vgax(102)+vgax(10)+vgax(25),Maxy-vgay(10));
         if (min_max_entropy==0) outtext ("standard deviation");
         else outtext ("min-max entropy");
	 moveto(stpwidth+vgax(102)+vgax(10)+
	    vgax((signed int)(xinterval*10))-vgax(5),Maxy-vgay(10));
	 outtext("0.1");
	 moveto(stpwidth+vgax(100)+vgax(10)+
	    vgax((signed int)(xinterval*18))-vgax(10),Maxy-vgay(10));
	 outtext("0.18");
      }

      /*centre y axis title*/
      moveto(stpwidth+vgax(106),Maxy-vgay(17));
      outtext("0");

      moveto(stpwidth+vgax(98),Maxy-vgay(130));
      if (stpgraph==1){
         sprintf(textb[0],"%s","density t-1");
      }

      else if (show_edata==0 || show_edata==1){
	 sprintf(textb[0],"%s","entropy");
      }
      else if (show_edata==2){
	 if (ylabel==0) sprintf(textb[0],"mean entropy");
	 else if (ylabel==1) sprintf(textb[0],"Z parameter");
	 else if (ylabel==2) sprintf(textb[0],"lambda ratio");
      }

	 moveto(getx+CWidth,gety);
	 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(stpwidth+vgax(106),Maxy-vgay(13)-vgay(200));
	 outtext("1");

      setcolor(existcolor);
      moveto(tempx,tempy);
}
/************** draw graph for Derrida plot  *************/
void draw_Hamming_plot(char draw_clear,signed int stpwidth){
  signed int z,rightedge,tempx,tempy, tempx1,tempy1,
	       xaxismax;
  unsigned char existcolor;
  float xinterval;

      tempx=getx;
      tempy=gety;
      
      rightedge=stpwidth+vgax(100)+2+vgax(200)+vgax(10);
      
      /*clear space*/
      draw_box(-1,stpwidth+vgax(100)+1,Maxy-2-vgay(200)-vgax(10),
	 rightedge,Maxy-1,0,0);

      if (draw_clear==0){
	 moveto(tempx,tempy);
	 return;
      }
      existcolor=getcolor();
      setcolor(lightred);
      /*draw graph outline*/
      draw_box(-1,stpwidth+vgax(100)+2+vgax(10),Maxy-2-vgay(200)-vgax(10),
	 rightedge,Maxy-2-vgax(10),1,0);

      /*draw x axis divisions*/
      moveto(stpwidth+vgax(100)+2+vgax(10),Maxy-2-vgax(10));
     
      xaxismax=9;
      xinterval=20;
            
      tempx1=getx;
      tempy1=gety;

      for (z=1;z<=xaxismax-1;z++){
	 moveto(tempx1+vgax((signed int)(xinterval*z)),tempy1);
	 linerel(0,vgay(3));
      }
      /*draw y axis divisions*/
      moveto(stpwidth+vgax(100)+2+vgax(10),Maxy-2-vgax(10));
      tempx1=getx;
      for (z=1;z<=9;z++){
	 moveto(tempx1,gety-vgay(20));
	 linerel(-vgax(3),0);
      }

      /*label x axis*/
      moveto(stpwidth+vgax(100)+2+vgax(10),Maxy-2-vgax(10));
      outtext("0");      
      moveto(stpwidth+vgax(100)+2+vgax(10)+vgax(80),Maxy-2-vgax(10));
      /*outtext("Hamming distance (t+1)");*/
      outtext("return map t");
      moveto(stpwidth+vgax(100)+1+vgax(10)+vgax(200),Maxy-2-vgax(10));
      /*outtext("1");*/
      outtext("2");
      moveto(stpwidth+vgax(103),gety-vgax(5));
      outtext("0");
      /*centre y axis title*/
      moveto(stpwidth+vgax(103),Maxy-vgay(130));
      outtext("t");
      moveto(stpwidth+vgax(103),gety+CHeight);
      outtext("+");
      moveto(stpwidth+vgax(103),gety+CHeight);
      outtext("1");
      moveto(stpwidth+vgax(103),Maxy-vgax(14)-vgay(200));      
      /*outtext("1");*/
      outtext("2");
      setcolor(existcolor);
      moveto(tempx,tempy);
}

/******************* select file name for statistical data *******/
char select_stat_filename(auto_ent *ae){
   char file_ret,file_e;
   signed int fid;


     file_ret=select_filename("SAVE","STAT-SAMPLE","*.sta","my_stat");
     if (file_ret=='q') file_e=0;
     else file_e=1;

     memmove(filename_data,filename,13);

     draw_prompt_box(1);
     sprintf(textb[0],"%s: append data-a, new file-(def), add + to pause:",
					 filename_data);
     outtext(textb[0]);
     is[0]=0;
     ae->auto_sample_pause=0;
     input_string(1,0);
     if (is[0]=='+' || is[1]=='+') ae->auto_sample_pause=1; 
     if (is[0]=='a') fid=myopen(filename_data,1,1);
     else fid=myopen(filename_data,1,0);		
    
     if (fid==-1) file_error(filename_data);
     close(fid);
     return(file_e);
}

/***************** load statistical data ********************/
unsigned int load_rule_stats(char repeat_sample, signed int stpwidth){ 

 signed int tempx,tempy,fid,rulebytes,tablemax;
 char file_ret,listbox,show_list=0,unsorted,graphtype,smalldots;
 unsigned int datachunk;
 unsigned long filebytes,lz;
 char *rulebuf;
 unsigned char *Zbuf,*lambdabuf,*chunkbuf,*chunkbuf1;
 float ave,sdev;
 unsigned char sdev_char;
 unsigned char m_ent_box,sdev_box;
 signed int xbox,rightedge,tlx,tly;
 float sintot; 
 /*char sublist=0;/*not setting 0 caused a bug in ddlabz05*/

  sublist=0;
 
  tempx=getx;
  tempy=gety;
  
  rightedge=stpwidth+vgax(100)+2+vgax(256)+vgax(10);
  /*if (rightedge>Maxx-2) rightedge=Maxx-2;*/

  /*load new rule sample*/
  if (repeat_sample==0){
     sprintf(textb[4],"LOAD ");
     file_ret=select_filename(textb[4],"STAT-SAMPLE","*.sta","my_stat");

     if (file_ret=='q'){
	moveto(tempx,tempy);
	is[0]='q';
	return(0);
     }
     fid=myopen(filename,0,0);
 
     filebytes=(unsigned long) filelength(fid);
     if (fid==-1 || filebytes==0){
        file_error(filename);      
	moveto(tempx,tempy);
	is[0]='q';
	close(fid);
	return(0);
     }

     free(statbuf);
     /*nominaly calloced in allocx.c*/
     if ((statbuf=(unsigned char *)calloc(filebytes,
	   sizeof(unsigned char)))==NULL) outof_memory("statbuf");
     sizeof_statbuf=filebytes;
     vret=read(fid,statbuf,filebytes);
     /*statbuf remains during forward run to allow loading rules
       from a rule sample*/
     close(fid);
  }
  else filebytes=sizeof_statbuf;

  if (tot_only==0){ 
        if (set_iso_input_histogram==1) tablemax= iso_tablemax;
        else tablemax= (signed int)pow(value_range,(double)nhood)-1;
     }
  else if (tot_only==1){
      if (totalistic==1) tablemax=nhood*(value_range-1);
      else if (totalistic==2) tablemax=v_tablecodemax[nhood];
  }
  rulebytes=(signed int)ceil(value_bits * (double)(tablemax+1)/8);

  /*rule buffer*/
  if ((rulebuf=(char *)calloc(rulebytes,sizeof(char)))
				  ==NULL) outof_memory("rulebuf");
  datachunk=rulebytes+2;
 
  totstatrules=filebytes/datachunk;
  if ((Zbuf=(unsigned char *)calloc(totstatrules+1,sizeof(unsigned char)))
				  ==NULL) outof_memory("Zbuf");
  if ((lambdabuf=(unsigned char *)calloc(totstatrules+1,sizeof(unsigned char)))
				  ==NULL) outof_memory("lambdabuf");
 start:
  show_list=listbox=graphtype=0;
  get_prompt_box(11,2);/*get area under prompt box, 2 lines*/
  xbox=draw_prompt_box(2);
  setcolor(white);
  if (stat_patch==1) sprintf(textb[0],
       "list: all-l patch/save-p/P coords-c sort-s backtrack-q");
  else sprintf(textb[0],
       "list: all-l coords-c  sort-s backtrack-q");
  sprintf(textb[2]," (sublist-S save-SS)");
  if (tot_only==0 && set_iso_input_histogram==0)  sprintf(textb[3],"lda-L Z-Z"); 
  else sprintf(textb[3]," ");
  if (min_max_entropy==1) sprintf(textb[4],"min-max plot");
  else sprintf(textb[4],"sdev plot: plot"); 
  if (Maxx<=639) sprintf(textb[1],
    "%s: %s ent-(def) bigdots+d:",textb[4],textb[3]);
  else sprintf(textb[1],
    "%s: %s ent-(def) smalldots+d:",textb[4],textb[3]);
  outtext(textb[0]);
  set_medium_font();
  outtext(textb[2]);
  restore_def_font();
  moveto(xbox,gety+CHeight);
  outtext(textb[1]);
  input_string(2,0);
  //erase_prompt_box(2);
  uncover_free_prompt_box(11);

  if (is[0]=='q'){
      is[0]=0;
      free(rulebuf);
      free(Zbuf);
      free(lambdabuf);
      moveto(tempx,tempy);
      return(filebytes);
  }
  if (is[0]=='s'){ 
    /*char file_ret,file_e;
      signed int fid;*/     
      if ((chunkbuf=(unsigned char *)calloc(datachunk,sizeof(unsigned char)))
				   ==NULL) outof_memory("chunkbuf");
      if ((chunkbuf1=(unsigned char *)calloc(datachunk,sizeof(unsigned char)))
				   ==NULL) outof_memory("chunkbuf1");
      /*sort by standard deviation (or min-max) from high to low*/
      unsorted=1;
      while(unsorted==1){
	 unsorted=0;
	 for (lz=0;lz<=filebytes-1;lz+=datachunk){
	    if (statbuf[lz+rulebytes+1]<statbuf[lz+rulebytes+1+datachunk]){
	       unsorted=1;
	       /*swap chunks*/
	       memmove(chunkbuf,statbuf+lz,datachunk);
	       memmove(chunkbuf1,statbuf+lz+datachunk,datachunk);
	       memmove(statbuf+lz,chunkbuf1,datachunk);
	       memmove(statbuf+lz+datachunk,chunkbuf,datachunk);
	    }
	 }
      }
      /*sort each standard deviation by av entropy from high to low*/
      unsorted=1;
      while(unsorted==1){
	 unsorted=0;
         sdev_char=255;
	 for (lz=0;lz<=filebytes-1;lz+=datachunk){
            if (statbuf[lz+rulebytes+1+datachunk]<sdev_char){
               sdev_char-=1;
               continue;
            }           
	    if (statbuf[lz+rulebytes]<statbuf[lz+rulebytes+datachunk]){
	       unsorted=1;
	       /*swap chunks*/
	       memmove(chunkbuf,statbuf+lz,datachunk);
	       memmove(chunkbuf1,statbuf+lz+datachunk,datachunk);
	       memmove(statbuf+lz,chunkbuf1,datachunk);
	       memmove(statbuf+lz+datachunk,chunkbuf,datachunk);
	    }
         }
      }
      
      file_ret=select_filename("SAVE","STAT-SAMPLE","*.sta","my_stat");
      fid=myopen(filename,1,0);
      if (fid==-1) file_error(filename);	
      else vret=write(fid,statbuf,filebytes);
      close(fid);

      free(chunkbuf1);
      free(chunkbuf);      
  }

  else if (is[0]=='l' || is[0]=='c' || is[0]=='S' || ((is[0]=='p'|| is[0]=='P') && stat_patch==1)){
      sublist=0;
      show_list=1; /*list all rules*/
      if (is[0]=='S'){ /*show and save a preselected list*/
	 sublist=1; /*filter by sublist*/
         if (is[1]=='S') sublist=2; /*save the sublist new.sta file*/
      }
      if ((is[0]=='p' || is[0]=='P') && stat_patch==1){
	   listbox=2; /*list just the rules in a patch*/
	   if (is[0]=='P') sublist=3; /*save the rules inside the patmch*/
      }
      if (is[0]=='c'){
         listbox=1; /*list just the rules in a defined position*/
         draw_prompt_box(1);
         sprintf(textb[0],
                 "mean entropy 0-255:");
         outtext(textb[0]);
         input_string(3,0);
         if (is[0]!=13 && atoi(is)<=255) m_ent_box=atoi(is);
         if (min_max_entropy==1) sprintf(textb[0]," min-max 0-255:");
         else sprintf(textb[0]," sdev 0-255:");
         outtext(textb[0]);
         input_string(3,0);
         if (is[0]!=13 && atoi(is)<=255) sdev_box=atoi(is);         
      }
  }
  else if (is[0]=='Z' && tot_only==0 && set_iso_input_histogram==0){ /*show plot Z para - stan dev*/
     show_list=2;
     graphtype=1;
  }
  else if (is[0]=='L'){ /*show plot lanbda para  - stan dev*/
     show_list=2;
     graphtype=2;
  }
  else show_list=2; /*show plot mean entropy - stan dev*/

  if (show_list==2){
      unsigned char tcolor;

      tcolor=getcolor();
      setcolor(lightred);
      moverel(0,-CHeight);
      outtext(" -wait"); 
      setcolor(tcolor);
      if (Maxx<=639) smalldots=1; /*size of dotts in scatter plot*/
      else smalldots=0;           /*small 1 pixel, otherwize 2x2*/
      if (is[0]=='d' || is[1]=='d') smalldots=abs(smalldots-1);      
  }
  if (show_list){
     if (show_list==2){        
           /*box for rule sample scatter plot*/
	   draw_box(11,stpwidth+vgax(100)+1,Maxy-2-vgay(200)-vgax(10),
	       rightedge+vgax(10),Maxy-1,0,0);
           /*box for 3d plot of above, dont clear area*/
           sintot=(float)vgax(256/2);
           tlx=rightedge-vgax(256);
           tly=Maxy-2-vgay(10)-vgay(203)-sintot;
           draw_box(8,tlx-sintot,tly-vgay(100),
		       tlx+vgax(256),tly+sintot,0,-1);
     }

     show_list_rules( smalldots,
                      show_list,
		      listbox,
		      graphtype,
		      stpwidth,
		      rulebytes,
		      filebytes,
		      datachunk,
		      rulebuf,
		      Zbuf,
		      lambdabuf,
		      ave,
                      sdev,
                      m_ent_box,
		      sdev_box);     
  }

  if (show_list==2){
     highlight_box(stpwidth+vgax(100)+2+vgax(10),
		      Maxy-2-vgay(200)-vgax(10),
	              rightedge,
		      Maxy-2-vgax(10),
		      show_list,
		      listbox,
		      graphtype,
		      stpwidth,
		      rulebytes,
		      filebytes,
		      datachunk,
		      rulebuf,
		      Zbuf,
		      lambdabuf,
		      ave,
                      sdev);
                           
    start_show_list:
           
     draw_prompt_box(1);
     if (tot_only==0){
       if (set_iso_input_histogram==1) sprintf(textb[1],"iso_rule");
       else sprintf(textb[1],"rcode");
     }
     else{
       if (totalistic==1) sprintf(textb[1],"tcode");
       else if (totalistic==2) sprintf(textb[1],"kcode");
     }
     sprintf(textb[0],
     "%lu v%dk%d %s: pile-up histogram-f, cont-ret:",
	     totstatrules,value_range,nhood,textb[1]);
     setcolor(white);//in case barcolor was set to zero ?? 
     outtext(textb[0]);
     
     input_string(1,0);
     //erase_prompt_box(1);
     if (is[0]=='f'){	 
	ent_3d(Zbuf,lambdabuf,filebytes,graphtype,stpwidth);
	goto start_show_list;
     }
  }

  if (show_list==2){       
           /*restore box for rule sample scatter plot*/
           sprintf(textb[9],"%s","boximage[11]");
	   putimage(stpwidth+vgax(100)+1,Maxy-2-vgay(200)-vgax(10),
                                         boximage[11],COPY_PUT,textb[9]);
	   freeimage(boximage[11]);
           /*restore box for 3d plot of above*/
           sprintf(textb[9],"%s","boximage[8]");
           putimage(tlx-sintot,tly-vgay(100),boximage[8],COPY_PUT,textb[9]);
           freeimage(boximage[8]);
  } 
  goto start;
}

/**************** list_rules or show scatter plot ****************/
void show_list_rules(char smalldots,
                     char show_list,
		     char listbox,
		     char graphtype,
		     signed int stpwidth,
		     signed int rulebytes,
		     unsigned long filebytes,
		     unsigned int datachunk,
		     char *rulebuf,
		     unsigned char *Zbuf,
		     unsigned char *lambdabuf,
		     float ave,
                     float sdev,
                     unsigned char m_ent_box,
		     unsigned char sdev_box){
		      
  signed int boxw,xlistbox,sx,sy,tablemax;
  unsigned long lz,ruleindex=0;
  char part_list,box_rad=1;
  unsigned int **histbuf, blockno, maxbuf,z,newindex;
  unsigned char c_sdev,c_ave;

     current_sample_index=0;/*global variable: keep track of current sample index*/
     if (tot_only==0){ 
        if (set_iso_input_histogram==1) tablemax= iso_tablemax;
        else tablemax= (signed int)pow(value_range,(double)nhood)-1;
     }
     else if (tot_only==1){
        if (totalistic==1) tablemax=nhood*(value_range-1);
        else if (totalistic==2) tablemax=v_tablecodemax[nhood];
     }
     rulebytes=(signed int)ceil(value_bits * (double)(tablemax+1)/8);
     if (show_list==2){
        /*hist buffers*/
        blockno=256;
        sprintf(textb[0],"histbuf");
        if ((histbuf=(unsigned int**)calloc(blockno,sizeof(unsigned int*)))
				  ==NULL) outof_memory(textb[0]);
        for (z=0;z<=blockno-1;z++){
           sprintf(textb[0],"histbuf[%d]",z);
           if ((histbuf[z]=
                (unsigned int *)calloc(blockno,sizeof(unsigned int)))
				  ==NULL) outof_memory(textb[0]);
        }     
        maxbuf=0;
        /*note frequency at each point in 256x256 grid*/
        for (lz=0;lz<=filebytes-1;lz+=datachunk){
           if (graphtype){ /*lambda or Z parameter*/
              memmove(rulebuf,statbuf+lz,rulebytes);
              if (tot_only==0 && set_iso_input_histogram==0){
	         if (value_range==2) z_parameter_all(nhood,0,rulebuf);
                 else z_parameter_all_mvalue(nhood,0,rulebuf);
              }
	      if (graphtype==1) c_ave=(unsigned char)(255*zparam[0]);
	      else c_ave=(unsigned char)(255*lratio);	      
           }
           else c_ave=statbuf[lz+rulebytes]; /*mean entropy*/
	   c_sdev=statbuf[lz+rulebytes+1];   /*standard deviation*/
           histbuf[c_ave][c_sdev]+=1;
           if (maxbuf<histbuf[c_ave][c_sdev]) maxbuf=histbuf[c_ave][c_sdev];
        }
     }
     
     if (rulebytes<=16) boxw=CWidth*rulebytes*2;
     else boxw=CWidth*16*2;
     if (boxw<vgax(160)) boxw=vgax(160);   
     xlistbox=Maxx-boxw;

     if (show_list==1)
	   draw_box(10,xlistbox-3,2,Maxx-2,2*Maxy/3,0,-1);

     start:
     part_list=0;
     if (show_list==1){
        draw_box(-1,xlistbox-3,2,Maxx-2,2*Maxy/3,1,0);   
	moveto(xlistbox,2);
        if (listbox==1) 
          sprintf(textb[0],"%lu v%dk%d rules y=%d x=%d rad=%d",
		   totstatrules,value_range,nhood,m_ent_box,sdev_box,box_rad);
	else{
          if (min_max_entropy==0) 
                  sprintf(textb[0],"%lu v%dk%d rules  mean sdev",
                                                 totstatrules,value_range,nhood);
          else sprintf(textb[0],"%lu v%dk%d rules  mean minmax",
		                                 totstatrules,value_range,nhood);
        }
	outtext(textb[0]);
	moveto(xlistbox,gety+CHeight);
	if (listbox==1){
	   outtext("left mouse button to select"); 
	   moveto(xlistbox,gety+CHeight);
	}
     }
     else if (show_list==2)       
	draw_entgraph_frame(1,stpwidth,2,graphtype);
     
     ruleindex=0;
     
     if (sublist){
       if (sublist==2 || sublist==3){  /*select name to save sublist as new.sta file, or append*/
	                               /*sublist==2 for list by hand, sublist==3 for patch*/
          char file_ret,file_e;
          signed int fid;
	  
	   if (sublist==2) file_ret=select_filename("SAVE","STAT-SUB-SAMPLE","*.sta","my_subst");
	   if (sublist==3) file_ret=select_filename("SAVE","STAT-PATCH","*.sta","my_patch");
           if (file_ret=='q') file_e=0;
           else file_e=1;

           memmove(filename_data,filename,13);

           draw_prompt_box(1);
           sprintf(textb[0],"%s: append data-a, new file-(def):",
					 filename_data);
           outtext(textb[0]);
           is[0]=0;
           input_string(1,0);
           if (is[0]=='a') fid=myopen(filename_data,1,1);
           else fid=myopen(filename_data,1,0);		
    
           if (fid==-1) file_error(filename_data);
           close(fid);
        }
        newindex=0;
     }
     for (lz=0;lz<=filebytes-1;lz+=datachunk){
	ruleindex+=1;
        /********** create sublist, to be entered by hand *************/
        /*this example for the 2d v2k9 short list, searching for the X-rule*/ 
        if (sublist==1 || sublist==2){//1 to filter, 2 to also save
           if (
ruleindex== 3416
|| ruleindex== 3700
|| ruleindex==5520
|| ruleindex==6932
|| ruleindex==7145
|| ruleindex==7449
|| ruleindex==8072
|| ruleindex==9073
|| ruleindex==9575
|| ruleindex==10089
|| ruleindex==12939
|| ruleindex==12949
|| ruleindex==17038
|| ruleindex==17043
|| ruleindex==19070
|| ruleindex==21610
|| ruleindex==28586
|| ruleindex==28593
|| ruleindex==28606
|| ruleindex==33289
|| ruleindex==33296
|| ruleindex==43534
|| ruleindex==43538
|| ruleindex==43540
|| ruleindex==47999
|| ruleindex==48053
|| ruleindex==48059
|| ruleindex==48065
|| ruleindex==48076
|| ruleindex==48077
|| ruleindex==48083
|| ruleindex==48084
|| ruleindex==51422
|| ruleindex==51431
|| ruleindex==51433
|| ruleindex==51434
|| ruleindex==51436
|| ruleindex==51442
|| ruleindex==53286
|| ruleindex==53299
|| ruleindex==53301
|| ruleindex==54012
|| ruleindex==54025
|| ruleindex==54026
|| ruleindex==54035
|| ruleindex==54041
|| ruleindex==54045
|| ruleindex==54048
|| ruleindex==54051
|| ruleindex==54330
|| ruleindex==54340
|| ruleindex==54359
|| ruleindex==54368
|| ruleindex==54369
|| ruleindex==54372
|| ruleindex==54400
|| ruleindex==54402
|| ruleindex==54407
|| ruleindex==54410
|| ruleindex==54411
|| ruleindex==54412
|| ruleindex==54416
|| ruleindex==54420
|| ruleindex==54421
|| ruleindex==54425
|| ruleindex==54427
|| ruleindex==54428
|| ruleindex==54425
|| ruleindex==54431
|| ruleindex==54437
|| ruleindex==55068){
	     newindex+=1;
             if (sublist==2){ /*save sublist as new.sta file*/
                memmove(rulebuf,statbuf+lz,datachunk);
                save_binary_data(rulebuf,(unsigned long)datachunk);
             }             
           }
           else continue;
        }
        /************** end create sublist *******************/
 
        if (listbox==1){  /*list just the rules in a defined position, +/-*/
           unsigned char vaxis;
           /*filter standard deviation*/
           if (statbuf[lz+rulebytes+1]<sdev_box-box_rad ||
	       statbuf[lz+rulebytes+1]>sdev_box+box_rad) continue;
           
           if (graphtype){
              memmove(rulebuf,statbuf+lz,rulebytes);
              if (tot_only==0 && set_iso_input_histogram==0){
	         if (value_range==2) z_parameter_all(nhood,0,rulebuf);
                 else z_parameter_all_mvalue(nhood,0,rulebuf);
              }
	      if (graphtype==1) vaxis=(unsigned char)(255*zparam[0]);	      
	      else vaxis=(unsigned char)(255*lratio);	      
	   }
           else vaxis=statbuf[lz+rulebytes];
           /*filter vertical axis depending on av entrope, Z or lanbda*/
           if (vaxis<m_ent_box-box_rad ||
	       vaxis>m_ent_box+box_rad) continue;
        }

        else if (listbox==2){ /*list just the rules in a patch*/
           unsigned char vaxis;
           /*filter standard deviation*/
           if (stat_patch==1){
	       if (stat_patch==1){	       
                  c_ave=statbuf[lz+rulebytes]; /*mean entropy*/
                  c_sdev=statbuf[lz+rulebytes+1]; /*standard deviation or minmax*/
 
		 
                   if (c_ave > ystat1 || c_ave < ystat2
		       || c_sdev > xstat1 || c_sdev < xstat2)
			     continue;
	       }	       
	       if (sublist==3){ //if 'P' was entered
		   //save the rules in the patch that are listed so far in the top-righ window 
		   memmove(rulebuf,statbuf+lz,datachunk);
                   save_binary_data(rulebuf,(unsigned long)datachunk);
	       }	   
	   }
           if (graphtype){
              memmove(rulebuf,statbuf+lz,rulebytes);
              if (tot_only==0 && set_iso_input_histogram==0){
	         if (value_range==2) z_parameter_all(nhood,0,rulebuf);
                 else z_parameter_all_mvalue(nhood,0,rulebuf);
              }
	      if (graphtype==1) vaxis=(unsigned char)(255*zparam[0]);	      
	      else vaxis=(unsigned char)(255*lratio);	      
	   }
           else vaxis=statbuf[lz+rulebytes];
           /*filter vertical axis depending on av entrope, Z or lanbda*/
           if (stat_patch==1){
               if (vaxis > ystat1 || vaxis < ystat2) continue;
	   }
        }

        memmove(rulebuf,statbuf+lz,rulebytes);
        if (graphtype){ /*lambda or Z parameter*/
              if (tot_only==0 && set_iso_input_histogram==0){
	         if (value_range==2) z_parameter_all(nhood,0,rulebuf);
                 else z_parameter_all_mvalue(nhood,0,rulebuf);
              }
	      if (graphtype==1) c_ave=(unsigned char)(255*zparam[0]);
	      else c_ave=(unsigned char)(255*lratio);	      
        }
        else{
           ave=((float)statbuf[lz+rulebytes])/255;
           c_ave=statbuf[lz+rulebytes]; /*mean entropy*/
        }
	sdev=((float)statbuf[lz+rulebytes+1]*.18)/255;
        c_sdev=statbuf[lz+rulebytes+1];

        if (show_list==1){
	   sprintf(textb[2],"%lu  ",ruleindex);
	   outtext(textb[2]);
	   
           /*show the 2d hist co-ords on 256x256 grid, not the actual value*/
	   moveto(getx+CWidth,gety);
           /*sprintf(textb[0],"%.3f",ave);
	     outtext(textb[0]+1);*/
           sprintf(textb[0],"\%d",c_ave);
	   outtext(textb[0]);
           /*sprintf(textb[0],"%.4f  ",sdev);
	   moveto(getx+CWidth,gety);
	   outtext(textb[0]+1);*/
	   sprintf(textb[0],"%d  ",c_sdev);
	   moveto(getx+CWidth,gety);
	   outtext(textb[0]);

          if (rulebytes>512) set_small_font(); 
          else set_medium_font();
          if (tot_only==0){ 
	    if (set_iso_input_histogram==1)
                 print_current_bitstring_hexbytes(1,4,rulebuf,nhood,
	                              Maxx,lightcyan,5);
            else print_current_bitstring_hexbytes(1,1,rulebuf,nhood,
	                              Maxx,lightcyan,5);
	  }
           else if (tot_only==1){
              if (totalistic==1) 
                print_current_bitstring_hexbytes(1,2,rulebuf,nhood,Maxx,lightcyan,5);
	      else if (totalistic==2) 
                print_current_bitstring_hexbytes(1,3,rulebuf,nhood,Maxx,lightcyan,5);
	   }
           restore_def_font();
           setcolor(white);

	   moveto(xlistbox,gety+CHeight);

           if (statbuf[lz+rulebytes+1]!=
	           statbuf[lz+rulebytes+1+datachunk]){
              setcolor(lightred); 
              line(xlistbox-3,gety,Maxx-2,gety);
              setcolor(white);
           }
	   
	   //dont pause if saving (sublist!=3)
	   if ((sublist!=3 && gety>2*Maxy/3-CHeight*5) || ruleindex==totstatrules){

	      /*outtext("printbox-p");*/ /*superceded -- can be done with on-the-fly @ */
	      moveto(xlistbox,gety+CHeight);

	      sprintf(textb[0],"%lu\n",ruleindex);
	      outtext(textb[0]);
	      if (ruleindex==totstatrules) outtext("jump-j quit-ret:");
	      else{
		  outtext("more-ret jump-j quit/select-q:");
		  part_list=1;
	      }
	      input_string(1,0);
	      if (is[0]=='q' || (ruleindex==totstatrules && is[0]==13)) break;
	      else if (is[0]=='s') save_screen();
	      else if (is[0]=='p'){
	         /*print list box*/
#                if __WATCOM__
		    printimage('L',0,0,xlistbox-3,2,Maxx-2,2*Maxy/3);
#                elif __UNIX__
                    printimage();/*xwindows*/
#                endif
              }
              else if (is[0]=='j'){
		 moveto(xlistbox,gety+CHeight);
		 sprintf(textb[0],"enter rule index 1-%lu:",totstatrules);
		 outtext(textb[0]);
		 input_string(5,0);
		 if (atol(is)>0 && atol(is)<totstatrules){
		    lz=(atol(is)-2)*datachunk;
		    ruleindex=atol(is)-1;
                    current_sample_index=ruleindex;/*keep track*/
		    draw_box(-1,xlistbox-3,2,Maxx-2,2*Maxy/3,1,0);
		    moveto(xlistbox,2);
                                     
		    if (min_max_entropy==0) sprintf(textb[0],
                           "%lu v%dk%d rules  mean sdev",
					 totstatrules,value_range,nhood);
                    else sprintf(textb[0],
                           "%lu v%dk%d rules  mean minmax",
					 totstatrules,value_range,nhood);
		    outtext(textb[0]);
		    moveto(xlistbox,gety+CHeight);
		    continue;
		 }
	      }
	      if (ruleindex!=totstatrules){
		 draw_box(-1,xlistbox-3,2,Maxx-2,2*Maxy/3,1,0);
		 moveto(xlistbox,2);
		 if (min_max_entropy==0) sprintf(textb[0],
                            "%lu v%dk=%d rules  mean sdev",
					      totstatrules,value_range,nhood);
                 else sprintf(textb[0],
                            "%lu v%dk=%d rules  mean minmax",
					      totstatrules,value_range,nhood);
		 outtext(textb[0]);
		 moveto(xlistbox,gety+CHeight);
	      }
	   }
	   //if 'P' was entered to save the rules in the patch 
	   //keep refilling the rules in the patch in the top-righ window -- until complete  
	   else if ((sublist==3 && gety>2*Maxy/3-CHeight*5) && ruleindex<totstatrules){
	       erase_box(xlistbox-3,2,Maxx-2,2*Maxy/3); 
	       draw_box(-1,xlistbox-3,2,Maxx-2,2*Maxy/3,0,-1);
               moveto(xlistbox,CHeight);
	   }
	     
	}        
        if (show_list==2){
	   //signed int zz;
           unsigned char thiscolor;
           unsigned int freq;
	   /*spot color acc to freq*/
           freq=histbuf[c_ave][c_sdev];

           /*draw_prompt_box(1);  //show the scatter plot colors          
           for (zz=8; zz>=0; zz--){
              freq=(signed int)pow(2,zz);
              fprintf(stderr,"%d:%d ",zz,freq);*/

              if (freq==1) thiscolor=white;
              else if (freq==2) thiscolor=yellow;
              else if (freq<=4) thiscolor=lightblue;
              else if (freq<=8) thiscolor=brown;
              else if (freq<=16) thiscolor=cyan;
              else if (freq<=32) thiscolor=blue;
              else if (freq<=64) thiscolor=lightcyan;
              else if (freq<=128) thiscolor=magenta;
              else  thiscolor=lightred;
	   
              /*setfillstyle(SOLID_FILL,thiscolor);           
              bar(getx,gety,getx+vgax(10),gety+vgay(10));
              moveto(getx+vgax(10),gety);              
	   }
           moveto(getx+vgax(10),gety);
           input_string(1,0);*/

	   /*standard deviation*/	    
	   sx=stpwidth+vgax(100)+2+vgax(10)+
		   sdev*10*vgax((signed int)(256*10.0/18));
	   if (graphtype){
	      if (tot_only==0 && set_iso_input_histogram==0){
	         if (value_range==2) z_parameter_all(nhood,0,rulebuf);
                 else z_parameter_all_mvalue(nhood,0,rulebuf);
              }
	      if (graphtype==1){
                 if (tot_only==0 && set_iso_input_histogram==0){
		    sy=Maxy-2-vgax(10)-zparam[0]*vgay(200);
		    Zbuf[ruleindex]=(unsigned char)(255*zparam[0]);
                 }
	      }
	      else {
		 sy=Maxy-2-vgax(10)-lratio*vgay(200);
		 lambdabuf[ruleindex]=(unsigned char)(255*lratio);
	      }
	   }
	   /*mean entropy*/
	   else sy=Maxy-2-vgax(10)-ave*vgay(200);

	   //draw small squares or dots
	   if (smalldots==1) putpixel(sx,sy,thiscolor);
           else {
              setfillstyle(SOLID_FILL,thiscolor);           
              bar(sx,sy,sx+vgax(1),sy+vgay(1));
           }           
        }
     }/* loop --- for (lz=0;lz<=filebytes-1;lz+=datachunk){ */

     if (show_list!=2){       
	box_rad=1;
	moveto(xlistbox,gety+CHeight);
	
	if (part_list==0)
	    outtext("4631 quit-q select-s");
	else outtext("4631 part list, quit-q select-s");
        if (listbox==1) outtext(" rad-(max 9):");
        else outtext(":");
        input_string(1,0);
	if (is[0]=='q' || is[0]==13) goto endFunc;
	if (is[0]=='s'){	
           sprintf(textb[0],"enter rule index 1-%lu:",totstatrules);
	   moveto(xlistbox,gety+CHeight);
           outtext(textb[0]);
           input_string(5,0);
           if (atol(is)>0 && atol(is)<=totstatrules){
	      ruleindex=atol(is);
              current_sample_index=ruleindex;/*to keep track of sample_index*/
              if (tot_only==0){
                 if (set_iso_input_histogram==1)
                    memmove(iso_rule,statbuf+(ruleindex-1)*(rulebytes+2),rulebytes);
                 else memmove(carule[0],statbuf+(ruleindex-1)*(rulebytes+2),rulebytes);
              }
              else if (tot_only==1){
                 if (totalistic==1) memmove(cacode[0],
                       statbuf+(ruleindex-1)*(rulebytes+2),rulebytes);
                 else if (totalistic==2) memmove(v_code[0],
                       statbuf+(ruleindex-1)*(rulebytes+2),rulebytes);
              }
              is[0]='q';
	      goto endFunc;
	   }
	   else{
	      sublist=0;
              goto start;
           }       
        }
	else if (atoi(is)>=1 && atoi(is)<=9){
	    box_rad=atoi(is);
            if (box_rad>0){
                 sublist=0;
                 goto start;
            }
	}
     }
   endFunc:
     sublist=0;
     if (show_list==2){
	for (z=0;z<=blockno-1;z++) free(histbuf[z]);
	free(histbuf);
     }
     if (show_list==1){
           sprintf(textb[9],"%s","boximage[10]");
	   putimage(xlistbox-3,2,boximage[10],COPY_PUT,textb[9]);
	   freeimage(boximage[10]);
     }
     
}
/** probe/select rule with mouse, or restrict to patch (July2013) for on-the-fly 'w'****/
void highlight_box(signed int X1,signed int Y1,
		   signed int X2,signed int Y2,
		     char show_list,
		     char listbox,
		     char graphtype,
		     signed int stpwidth,
		     signed int rulebytes,
		     unsigned long filebytes,
		     unsigned int datachunk,
		     char *rulebuf,
		     unsigned char *Zbuf,
		     unsigned char *lambdabuf,
		     float ave,
		     float sdev){

 signed int tempx,tempy,xbox;
 unsigned char test=0;
 unsigned char m_ent_box,sdev_box;
 char click_turn=1,tempcolor;
 signed int right_clicks=0,tempv,m_x0, m_y0, m_x1, m_y1; //to draw rectangle

#  if __WATCOM__
 signed int mxtemp,mytemp;
      if (mouse_found){	
	 /*confine mouse in rectangle*/
	 mouse_call(7,0,X1,X2);
	 mouse_call(8,0,Y1,Y2);
      }
#  endif

   stat_patch=0;
   get_prompt_box(11,2);/*get area under prompt box, 2 lines*/

   xbox=draw_prompt_box(2);
   outtext("select rules - point-click mouse button: probe-left, patch-right");
   moveto(xbox,gety+CHeight);
   outtext("pile-up histogram or backtrack -q:");

 
   while (1){
      if (mouse_found){
#        if __WATCOM__
	    mouse_call(1,0,0,0); /*display the mouse*/
	    mouse_call(3,0,0,0); /*mouse position*/
	    mouse_x=globcx;
	    mouse_y=globdx;
	    /*check mousemove and show co-ordinates*/
	    if ((mxtemp!=mouse_x || mytemp!=mouse_y)
		&& mouse_x>=X1 && mouse_y>=Y1
			       && mouse_x<=X2 && mouse_y<=Y2){
	       tempx=getx;
	       tempy=gety;
	       m_ent_box=255-(unsigned char)(255* (float)(mouse_y-Y1)/(Y2-Y1));
	       sdev_box=(unsigned char)(255* (float)(mouse_x-X1)/(X2-X1));
	       sprintf(textb[0],"y=%d x=%d",m_ent_box,sdev_box);
	       moveto(memory_box(0,NULL)+3,3);
	       outtext(textb[0]);
	       mxtemp=mouse_x;
	       mytemp=mouse_y;
	       moveto(tempx,tempy);
	    }
	    mouse_call(5,0,0,0); /*check left mouse button pressed*/
            if (globbx && mouse_x>=X1 && mouse_y>=Y1
			       && mouse_x<=X2 && mouse_y<=Y2){
	       
	       sdev_box=(unsigned char)(255* (float)(mouse_x-X1)/(X2-X1));
               m_ent_box=255-(unsigned char)
				    (255* (float)(mouse_y-Y1)/(Y2-Y1));

	       //-m_ent_box+255=255*(mouse_y-Y1)/(Y2-Y1); 


	       show_list_rules(0,1,1,
			       graphtype,
			       stpwidth,
			       rulebytes,
			       filebytes,
			       datachunk,
			       rulebuf,
			       Zbuf,
			       lambdabuf,
			       ave,
			       sdev,
			       m_ent_box,
			       sdev_box);
	      }
	      else{
		 test=keycheck(0);
		 if (test=='q') break;
	      }
#        elif __UNIX__
	    if (XCheckMaskEvent(D,
		      KeyPressMask|ButtonPressMask|PointerMotionMask,&Event)){
	      if (Event.type == MotionNotify){

		 mouse_x=Event.xmotion.x;
		 mouse_y=Event.xmotion.y;
		 if (mouse_x>=X1 && mouse_y>=Y1
			       && mouse_x<=X2 && mouse_y<=Y2){
		    if (inside_rect==0){
		       XDefineCursor(D,W,leftCursor);
		       inside_rect=1;
		    }
		    /*show co-ordinates*/
		    tempx=getx;
		    tempy=gety;
		    m_ent_box=255-(unsigned char)
                           (255* (float)(mouse_y-Y1)/(Y2-Y1));
		    sdev_box=(unsigned char)(255* (float)(mouse_x-X1)/(X2-X1));
		    sprintf(textb[0],"y=%d x=%d",m_ent_box,sdev_box);

		    moveto(memory_box(0,NULL)+3,3);
		    outtext(textb[0]);
		    moveto(tempx,tempy);
		 }
		 else if (inside_rect==1){
		    XDefineCursor(D,W,rightCursor);
		    inside_rect=0;
		 }
	      }

	      if (Event.type==ButtonPress){
                 
		 mouse_x=Event.xbutton.x;
		 mouse_y=Event.xbutton.y;
		 if (mouse_x>=X1 && mouse_y>=Y1
			       && mouse_x<=X2 && mouse_y<=Y2){		 
                
		    
		    sdev_box=(unsigned char)(255* (float)(mouse_x-X1)/(X2-X1));
                    m_ent_box=255-(unsigned char)
				    (255* (float)(mouse_y-Y1)/(Y2-Y1));                   

                    /*right button ==3*/
                    if (Event.xbutton.button==3){
                       click_turn=abs(click_turn-1); /*either 0 or 1*/ 
                       if (click_turn==0){ /*click to record corners of patch*/
			  right_clicks+=1;                 
                          xstat1=sdev_box;
                          ystat1=m_ent_box;
                          if (right_clicks>=2) sprintf(textb[0],
			     "patch: %d %d  %d %d, activate-p", xstat1,ystat1,xstat2,ystat2);
                          inset_prompt_box(0,30,textb[0],'m');
                          
                          m_x0=mouse_x; //co-ords to draw
                          m_y0=mouse_y;
                       }
                       else{
                          right_clicks+=1;
                          xstat2=sdev_box;
                          ystat2= m_ent_box;
                          if (right_clicks>=2) sprintf(textb[0],
			     "patch: %d %d  %d %d, activate-p", xstat1,ystat1,xstat2,ystat2);
                          inset_prompt_box(0,30,textb[0],'m');

                          m_x1=mouse_x; //co-ords to draw
                          m_y1=mouse_y;
                       }
                    }

		    /*left button*/
		    if (Event.xbutton.button==1){
		        show_list_rules(0,1,1,
				    graphtype,
				    stpwidth,
				    rulebytes,
				    filebytes,
				    datachunk,
				    rulebuf,
				    Zbuf,
				    lambdabuf,
				    ave,
				    sdev,
				    m_ent_box,
				    sdev_box);
		    }
		 }
	      }
	      else if (Event.type == KeyPress){
		     button='k';
		     test=keycheck(0);
		     if (test=='q') break;

                     if (test=='p' && right_clicks>=2){ /*set patch, also by mouse clicks*/
                        
		       //fprintf(stderr,"\na: %d %d %d %d",m_x0,m_y0,m_x1,m_y1);
                        if (m_x0>m_x1){ //swap
                           tempv=m_x0;
                           m_x0=m_x1;
                           m_x1=tempv;
                        }
                        if (m_y0>m_y1){ //swap
                           tempv=m_y0;
                           m_y0=m_y1;
                           m_y1=tempv;
                        }                  
                        //fprintf(stderr,"\nb: %d %d %d %d",m_x0,m_y0,m_x1,m_y1);
                    
                        tempcolor=getcolor(); //draw patch rectangle
                        setcolor(white);
                        rectangle(m_x0,m_y0,m_x1,m_y1);
                        setcolor(black);
                        rectangle(m_x0-1,m_y0-1,m_x1+1,m_y1+1);
                        rectangle(m_x0+1,m_y0+1,m_x1-1,m_y1-1); 
                        setcolor(tempcolor);
                        right_clicks=0;

                        xstat1=(unsigned char)(255* (float)(m_x0-X1)/(X2-X1));
                        xstat2=(unsigned char)(255* (float)(m_x1-X1)/(X2-X1));
                        ystat1=255-(unsigned char)(255* (float)(m_y0-Y1)/(Y2-Y1));
                        ystat2=255-(unsigned char)(255* (float)(m_y1-Y1)/(Y2-Y1));

                        //fprintf(stderr,"\na: %dx%d %dx%d",xstat1,ystat1,xstat2,ystat2);

                        xbox=draw_prompt_box(2);
                        sprintf(textb[0],
			    "patch coords (def %d %d %d %d) keyboard-k accept-def:",
                                          xstat1,ystat1, xstat2,ystat2);
                        outtext(textb[0]);
                        input_string(1,0);
                        if (is[0]!='k');
                        else{
                           moveto(xbox,gety+CHeight);
                           sprintf(textb[0],"keyboard: (max 255x255)  x1:");
                           outtext(textb[0]);
                           input_string(3,0);
                           if (is[0]!=13 && atoi(is)>=0 && atoi(is)<=255) xstat1=atoi(is);
                           outtext(" y1:");
                           input_string(3,0);
                           if (is[0]!=13 && atoi(is)>=0 && atoi(is)<=255) ystat1=atoi(is);
                           outtext(" x2:");
                           input_string(3,0);
                           if (is[0]!=13 && atoi(is)>=0 && atoi(is)<=255) xstat2=atoi(is);
                           outtext(" y2:");
                           input_string(3,0);              
                           if (is[0]!=13 && atoi(is)>=0 && atoi(is)<=255) ystat2=atoi(is);

                           //reverse compute to draw
                           m_x0=(signed int)((float)(xstat1*(X2-X1))/255)+X1;
                           m_y0=(signed int)((float)((255-ystat1)*(Y2-Y1))/255)+Y1; 
                           m_x1=(signed int)((float)(xstat2*(X2-X1))/255)+X1;
                           m_y1=(signed int)((float)((255-ystat2)*(Y2-Y1))/255)+Y1;

                           //fprintf(stderr,"\naa: %d %d %d %d",m_x0,m_y0,m_x1,m_y1);
                           if (m_x0>m_x1){ //swap
                              tempv=m_x0;
                              m_x0=m_x1;
                              m_x1=tempv;
                           }
                           if (m_y0>m_y1){ //swap
                              tempv=m_y0;
                              m_y0=m_y1;
                              m_y1=tempv;
                           }
                           //fprintf(stderr,"\nbb: %d %d %d %d",m_x0,m_y0,m_x1,m_y1);

                           tempcolor=getcolor(); //draw patch rectangle
                           setcolor(lightcyan);
                           rectangle(m_x0,m_y0,m_x1,m_y1);
                           setcolor(black);
                           rectangle(m_x0-1,m_y0-1,m_x1+1,m_y1+1);
                           rectangle(m_x0+1,m_y0+1,m_x1-1,m_y1-1); 
                           setcolor(tempcolor);
                 
                           //fprintf(stderr,"\nb: %d %d %d %d",m_x0,m_y0,m_x1,m_y1);
                           xstat1=(unsigned char)(255* (float)(m_x0-X1)/(X2-X1));
                           xstat2=(unsigned char)(255* (float)(m_x1-X1)/(X2-X1));
                           ystat1=255-(unsigned char)(255* (float)(m_y0-Y1)/(Y2-Y1));
                           ystat2=255-(unsigned char)(255* (float)(m_y1-Y1)/(Y2-Y1));

                           //fprintf(stderr,"\nb: %dx%d %dx%d",xstat1,ystat1,xstat2,ystat2);
                           
			}

                        //fprintf(stderr,"\nc: %dx%d %dx%d",xstat1,ystat1,xstat2,ystat2);

                        restore_def_font();
                        stat_patch=1;
                        erase_prompt_box(2);
                        break;
                     }
	      }              
	   }	      
	 
#        endif		 	     	 
         moveto(mouse_x,mouse_y);
      }      
   }

   /*this last check is unnecessary*/
   if (xstat1<xstat2){ /*adjust patch active or not*/
      tempv=xstat1;
      xstat1=xstat2;
      xstat2=tempv; /*x1>x2*/
   }                           //   255 | defining a patch
   if (ystat1<ystat2){         //       |     ------x1y1 
      tempv=ystat1;            //       |     |    |
      ystat1=ystat2;           //       |     |    |
      ystat2=tempv; /*y1>y2*/  //       | x2y2------
   }                           //    0,0|________________255
      
   if (mouse_found){
#     if __WATCOM__ 
         mouse_call(7,0,0,getmaxx());
         mouse_call(8,0,0,getmaxy());
#     elif __UNIX__
         XDefineCursor(D,W,rightCursor); /*restore cursor shape*/
#     endif
   }
   uncover_free_prompt_box(11);
}


/** draw 3d histogram of rule distribution in entropy-density plot ***/
void ent_3d(unsigned char *Zbuf, unsigned char *lambdabuf,
		 unsigned long filebytes,char graphtype,signed int stpwidth){
 signed int tempx,tempy,tempx1,tempy1,xbox,i,z,zz,blocksize,blockstep,
	      rulebytes,tablemax,rightedge,
	      tlx,tly;
 unsigned int datachunk, **histbuf, blockno,
	      maxfreq,maxheight,histheight,lastheight,eraseht;
 unsigned long lz,ruleindex;
 unsigned char ave,sdev,stepthrough=0,showgrid=0;
 signed int startx,starty,rightbar,lastrightx;
 float sinblock,sintot,
       hblock,barwidth;
 char show_height_data=0;
 //char barcolor=1, showlog=1 make these file-global
 unsigned int freq;
 unsigned char thiscolor,tempcolor;

  tempx=getx;
  tempy=gety;
  
  rightedge=stpwidth+vgax(100)+2+vgax(256)+vgax(10);
  blockno=256;
  get_prompt_box(11,2);/*get area under prompt box, 2 lines*/

  //redo:
  xbox=draw_prompt_box(2);
  sprintf(textb[0],
  "pile-up hist, subdiv (16,32,64,128,%d-(def):",blockno);
  outtext(textb[0]);
  input_string(3,0);
  if (/*atoi(is)==1||atoi(is)==2||atoi(is)==4||atoi(is)==8||*/
    atoi(is)==16 ||atoi(is)==32 ||atoi(is)==64||atoi(is)==128
    ||atoi(is)==256) blockno=atoi(is);
  moveto(xbox,gety+CHeight);
  outtext("save data-d, step-s, and show %-S:");
  is[0]=0; //clear is[0]
  input_string(1,0);
  if (is[0]=='s') stepthrough=1;
  else if (is[0]=='S') stepthrough=2;
  else if (is[0]=='d') show_height_data=1;

  blocksize=256/blockno;  
  sintot=(float)vgax(256/2);
  sinblock=sintot/blockno;  
  if (/*blockno<=64 &&*/ graphtype==0){
     is[0]=showgrid=0;
     outtext(" grid-g:");
     input_string(1,0);
     if (is[0]=='g') showgrid='g';
  }

  if (showlog==0) outtext(" tog:log(off)-l:");
  else if (showlog==1) outtext(" tog:log(on)-l:");
  input_string(1,0);
  if (is[0]=='l') showlog=abs(showlog-1);

  if (barcolor==0) outtext(" color(off)-c:");  
  else if (barcolor==1) outtext(" color(on)-c:");
  input_string(1,0);
  if (is[0]=='c') barcolor=abs(barcolor-1);
  
  //erase_prompt_box(2);
  uncover_free_prompt_box(11); 
  maxfreq=0;
  maxheight=vgay(100);

  tlx=rightedge-vgax(256);
  tly=Maxy-2-vgay(10)-vgay(203)-sintot;

  draw_box(-1,tlx-sintot,tly-vgay(100),
		tlx+vgax(256),tly+sintot,1,0);
  
  moveto(tlx,tly);
  /*fprintf(stderr,"\ncolor=%d %dx%dx%dx%d",getcolor(),tlx-sintot,tly-vgay(100),
    tlx+vgax(256),tly+sintot);*/
  setcolor(lightred);
  /*fprintf(stderr,"\ncolor=%d",getcolor());*/
  linerel(vgax(256),0);
  linerel(-sintot,sintot);
  linerel(-vgax(256),0);
  linerel(sintot,-sintot);
  setcolor(white);
  /*fprintf(stderr,"\nprint red outline, color=%d",getcolor());
    input_string(1,0);*/

   if (tot_only==0){ 
        if (set_iso_input_histogram==1) tablemax= iso_tablemax;
        else tablemax= (signed int)pow(value_range,(double)nhood)-1;
     }
   else if (tot_only==1){
      if (totalistic==1) tablemax=nhood*(value_range-1);
      else if (totalistic==2) tablemax=v_tablecodemax[nhood];
   }
   rulebytes=(signed int)ceil(value_bits * (double)(tablemax+1)/8);

  datachunk=rulebytes+2;
  totstatrules=filebytes/datachunk;

  /*hist buffers*/
  if ((histbuf=(unsigned int**)calloc(blockno,sizeof(unsigned int*)))
				  ==NULL) outof_memory("histbuf");
  for (z=0;z<=blockno-1;z++){
     sprintf(textb[0],"histbuf[%d]",z);
     if ((histbuf[z]=(unsigned int *)calloc(blockno,sizeof(unsigned int)))
				  ==NULL) outof_memory(textb[0]);
  }
  moveto(stpwidth+vgax(100)+2+vgax(10),Maxy-2-vgay(10));

  ruleindex=0;
  /*    rule (rulebytes)     av (1 byte)    sdev (1 byte) */
  /* ----------------------  ------------   ------------- */
  for (lz=0;lz<=filebytes-1;lz+=datachunk){
	if (graphtype){
	   ruleindex++;
	   if (graphtype==1) ave=Zbuf[ruleindex];
	   else ave=lambdabuf[ruleindex];
	}
	else ave=statbuf[lz+rulebytes];
	sdev=statbuf[lz+rulebytes+1];
	histbuf[ave/blocksize][sdev/blocksize]++;
	if (histbuf[ave/blocksize][sdev/blocksize]>maxfreq)
		  maxfreq=histbuf[ave/blocksize][sdev/blocksize];
  }

  if (/*blockno<=64 &&*/ graphtype==0 && showgrid=='g'){ /*show grid*/
     blockstep=0;
     setcolor(red);
     moveto(stpwidth+vgax(100)+2+vgax(10),Maxy-2-vgay(10));
     for (z=0;z<=blockno-2;z++){
	blockstep++;  /*show vertical subdiv*/
        moveto(stpwidth+vgax(100)+2+vgax(10)+vgax(blocksize*blockstep),
	           Maxy-2-vgay(10));
	linerel(0,-vgay(200));
     }
     blockstep=0;
     hblock=(float)200/blockno;
     //moveto(stpwidth+vgax(100)+2+vgax(10),Maxy-2-vgax(10));
     moveto(stpwidth+vgax(100)+2+vgax(10),Maxy-2-vgay(10));
     for (z=0;z<=blockno-2;z++){
	blockstep++;  /*show horiz subdiv*/
        moveto(stpwidth+vgax(100)+2+vgax(10),
	      Maxy-2-vgay(10)-vgay((signed int)(hblock*blockstep)));
	linerel(vgax(256),0);
     }
  }

  setfillstyle(SOLID_FILL,darkgray);
  blockstep=0;
  setcolor(white);
  barwidth=((float)vgax(256))/blockno;
 
  /*save height data*/
  if (show_height_data==1){
     signed int fid; /*to save height data*/

     select_filename("SAVE","DATA","*.dat","my_data");
     memmove(filename_data,filename,13);
     fid=myopen(filename_data,1,0);
     if (fid==-1) file_error(filename_data);     
     else{
        for (zz=blockno-1;zz>=0;zz--){           
           for (z=0;z<=blockno-1;z++){
              /*save height data*/
              sprintf(textb[0],"%d",histbuf[zz][z]);
              vret=write(fid, textb[0], strlen(textb[0]));
              vret=write(fid, " ", 1);  
           }
           vret=write(fid, "\n", 1);
        }
        close(fid);
     }
  }
 
  for (zz=blockno-1;zz>=0;zz--){
     blockstep++;
     startx=tlx-sinblock*blockstep;
     starty=tly+sinblock*blockstep;
     moveto(startx,starty);
     for (z=0;z<=blockno-1;z++){
	 lastheight=histheight;
         
	 if (histbuf[zz][z]>0){
	    if (showlog==1)
	       histheight=(unsigned int)(double)maxheight*
		       (log((double)histbuf[zz][z])/log((double)maxfreq));
	    else histheight=(unsigned int)(double)maxheight*
		       ((double)histbuf[zz][z]/(double)maxfreq); 
	    rightbar=getx+barwidth;

            /*color the histogram by frequency*/
            if (barcolor==1){
               tempcolor=getcolor();
               freq=histbuf[zz][z];
               if (freq==1) thiscolor=white;
               else if (freq==2) thiscolor=yellow;
               else if (freq<=4) thiscolor=lightblue;
               else if (freq<=8) thiscolor=brown;
               else if (freq<=16) thiscolor=cyan;
               else if (freq<=32) thiscolor=blue;
               else if (freq<=64) thiscolor=lightcyan;
               else if (freq<=128) thiscolor=magenta;
               else  thiscolor=lightred;
               setcolor(thiscolor);
            }
	    bar(getx,gety-histheight,rightbar,gety);
	    rectangle(getx,gety-histheight,rightbar,gety);
            setcolor(tempcolor);

	    if (z>0){
	       setcolor(darkgray);
	       if (lastheight<histheight) eraseht=lastheight;
	       else eraseht=histheight;
	       line(getx,gety+1,getx,gety-eraseht+1);
	       if (getx!=lastrightx)
		     line(lastrightx,gety+1,lastrightx,gety-eraseht+1);
	       setcolor(white);
	    }
	 }
	 else histheight=0;
	 lastrightx=rightbar;
	 moveto(startx+(z+1)*barwidth,gety);
     }
    
     if (stepthrough){
	if (stepthrough==2){
	   float tempfrac;
	   signed int col=0;
	   tempx1=getx;
	   tempy1=gety;
	 
           set_small_font();
  
	   if (blockno<=16) xbox=draw_prompt_box(1);
	   else if (blockno==32) xbox=draw_prompt_box(2);
	   else if (blockno==64) xbox=draw_prompt_box(4);
	   else if (blockno==128) xbox=draw_prompt_box(7);//5
	   else if (blockno==256) xbox=draw_prompt_box(14);//7
	   for (i=0;i<=blockno-1;i++){
	      if (getx>Maxx-CWidth*3.8){
		 moveto(xbox,gety+CHeight*1.2);
		 col=0;
	      } 
	      tempfrac=100*((float)histbuf[zz][i]/totstatrules);
	      if (tempfrac==0) outtext("  0 ");
	      else{
		 if (tempfrac>=10){
		    sprintf(textb[0],"%.1f ",tempfrac);
		    outtext(textb[0]);
		 }
		 else if (tempfrac>=1){
		    sprintf(textb[0],"%.2f ",tempfrac);
		    outtext(textb[0]);
		 }
		 else {
		    sprintf(textb[0],"%.3f ",tempfrac);
		    outtext(textb[0]+1);
		 }
	      }
	      col+=1;
	      moveto(xbox+col*CWidth*3.8,gety);
	   }
	   moveto(tempx1,tempy1);
	}
	input_string(1,0);
     }
     if (stepthrough==2) restore_def_font();
  }
  for (z=0;z<=blockno-1;z++) free(histbuf[z]);
  free(histbuf);
  moveto(tempx,tempy);
  
}
/*--------------------------------------------------------------*/









