#include <unistd.h>   
#include <sys/types.h>                                                          
#include <sys/stat.h>                                                           
#include <fcntl.h>                                                              
#include <string.h>                                                             
#include <sys/time.h>                                                           
#include <dirent.h>                                                             
#include <limits.h>  
#include <errno.h> 
#include <stdlib.h>
#include <stdio.h>


#define MAXBUFF 4410000
#define MAXX 441000

typedef struct var {
    int from;
    int to;
  } evpp;

int tween(int to, int from){
  int x;
  if (to<from) x=to+(rand()%(from-to));
  else x=from+(rand()%(to-from));
  return x;
}

void shuffle(evpp *evp, int length){
  int k,n=length;
  evpp tmp;
  while (n>1)
    {
      k=rand()%n;
      --n;                  
      tmp = evp[n];  
      evp[n] = evp[k];
      evp[k] = tmp;
    }
}

int main(int argc, char **argv) {

  int x,y,yy,lenny,tmp,trr;
  int too=atoi(argv[1]), from=atoi(argv[2]), window=atoi(argv[3]), overlap=atoi(argv[4]);

  evpp evp[MAXX];
  unsigned char xx,zm=0;

  unsigned char *buffer=malloc(MAXBUFF);
  unsigned char *evpbuf=malloc(MAXBUFF);


  while(zm==0){

    for (x=0;x<window;x++){
    
      if ((trr=getchar())==EOF) {
	//	printf("EOF");
      x=window;
      zm=1;
    }
      buffer[x]=trr;
    }

    /*

At A, the "From" and "To" segment lengths are equal, or there is no
check mark before To. The Overlap option is deactivated. All segments
are of equal length and are located seamlessly one after another
without overlapping each other. The segments start at positions which
are a multiple of the "From" length.

    */

    y=0;
    lenny=window/from;

    if (from==too && overlap==0){
      for (x=0;x<window;x+=from){
	evp[y].from=x; evp[y].to=x+from;
	y++;
      }
    }
 
   /*

At B, the "To" segment length is less than the "From" segment
length. Thus, the segment length randomly varies between these two
values. Since Overlap is switched off, the segments again start at
positions which are a multiple of the "From" length.

    */

    else if (too<from && overlap==0){
      for (x=0;x<window;x+=from){
	evp[y].from=x; evp[y].to=x+tween(too,from);
	y++;
      }
  }
  /*

Also at C, the Overlap option is switched off, and the segments again
start at positions which are a multiple of the "From" length. However,
this time the "To" segment length is greater than the "From" segment
length, which - in spite of the deactivated Overlap option - may
result in operlapping, which is the case when the end of a segment
lies behind the beginning of the following segment.

  */

    else if (too>from && overlap==0){
      for (x=0;x<window;x+=from){
	evp[y].from=x; evp[y].to=x+tween(from,too)-1;
	y++;
      }

  }

  /*

At D and E, the Overlap option is now switched on. This causes that
now the segments dont necessarily start at positions which are a
multiple of the From length, but they can be distributed across the
whole recording at arbitrary positions. Through this, overlappings are
possible for both constant segment lengths (D) and variable segment
lengths (E).
		    
  */	    
    else if (overlap!=0 && from!=too ) {
		        for (x=0;x<window;x+=from){
			  tmp=rand()%window;
			  evp[y].from=tmp; evp[y].to=tmp+tween(too,from)-1;
			  y++;
			}
		    }

		                shuffle(evp, y);

      y=0;yy=0;
    for (x=0;x<window;x++){
      evpbuf[x]=buffer[evp[y].from+yy];
      yy++;
      if (evp[y].from+yy>evp[y].to){
	yy=0;
	y++;
      }
    }


// 4-> STDOUT processed buffer

    for (x=0;x<window;x++){
          putchar(evpbuf[x]);
    }
}
}

