/* does a columnar transposition of the letters in a file */

#include <stdio.h>
#include <stdlib.h>

#define MaxLength 100000


int main(int argc, char *argv[])
{
  int	L, l, x, i, h, pain_in_butt;
  char	in[MaxLength], out[MaxLength];
  char  c;
  FILE	*ifp, *ofp;
  
  
/* x = number of columns in the transformation */
  printf ("columns?");
  scanf (" %d", &x);

  if (argc != 3)
  {
     printf("\n%s%s%s\n\n", "Usage: ", argv[0], " # of columns infile  outfile");
     exit(1);
  }
  
  for (i = 0; i <= MaxLength; i++)
  {
  in[i] = 'Z';
  out[i] = 'Z';
  }


  ifp = fopen(argv[1], "r");
  ofp = fopen(argv[2], "w");
  
  L = 0;
  l = 0;
  
  /* L is the real length of the text l is an imaginary length we use
  during the transpostion to get the heights of the columns correct */

  i = 0;
  h = 1;

 /* x = number of columns in the transformation */
  
  for (h = 0; (c = getc(ifp)) != EOF; h++)
  {
  
    if ((c == ' ') || (c == '\t'))
    {
      c = '\n';
    }

         
    if ((c != '\n') && (h <= (MaxLength - 1)))
    {
      i = i + 1;
      in[i] = c;
    }
  }
 
fprintf(ofp, "\n\n");

  L = i;
  
  /* i is the length of the input file minus spaces, newlines, and tabs */


/*  imaginary length equals (Length + number-of-columns - 
	(number-of-columns - Length%number-of-columns) */


  l = (L + (x - L%x));

/* Some columns will be taller than others. This figures the imaginary
length of the text and sets the warning flag. The flag gets
turned off if the text turns out to be an easy to manage length. */


  if ((L%x) == (x-1) || (L%x) == (0)) 
  {
    l = L;
  }

/* for testing purposes:

fprintf(ofp, "\n\nl is %d\n", l);
fprintf(ofp, "L is %d\n", L);
fprintf(ofp, "x is %d\n", x);

   testing is finished  */


/* below is the transformation function */
  
  i = 1;
  h = 1;
  
  for (h = 1; h <= L; h++)
  {
    out[h] = in[i];


/* for testing purposes: 

fprintf(ofp, "when h is %d, i is %d\n", h, i);

 testing is finished  */

    
/* ok, so we start with the first column. would having a starting number
added to i work? Sounds too easy. */

    i = i + x;
    
    if ((i > L) && (i <= l))
      i = i + x;
    
    if ((i > l) && (i > L))
 	i = i - (l - 1);
  }

/* time to print to file */
  
  for (i = 1; i <= L; i++)
  {
    if ((i%60) == 0 && (i != 0))
    putc('\n', ofp);
    
    fprintf(ofp, "%c", out[i]);
  }
  
  fclose(ifp);
  fclose(ofp);
  return 0;

}

