/**********************************************************************
 * hw2.cc
 * Tom Kelliher
 *
 * This program codes a string which is given as a command line
 * argument.  The "tricky" coding algorithm is to swap halves of the 
 * string, repeating recursively on each of the halves.  It sounds like
 * a great scheme, but it doesn't do a good job.
 **********************************************************************/


#include <string.h>
#include <stdlib.h>
#include <iostream.h>


const int MAX_STRING = 80;   // Max length of a string.


// Prototype.
void code(char str[], int start, int len);


/**********************************************************************
 * main
 **********************************************************************/

int main(int argc, char* argv[])
{
   char str[MAX_STRING];   // The string to be coded.

   if (argc != 2)   // string to be coded read from the command line
   {
      cout << "String expected.\n";
      exit(1);
   }

   if (strlen(argv[1]) > MAX_STRING -1)   // check for storage space
   {
      cout << "Input too long";
      exit(1);
   }

   strcpy(str, argv[1]);   // Make a local, modifiable copy of the string.
   cout << "Original String: " << str << endl;
   code(str, 0, strlen(str));
   cout << "Coded String:    " << str << endl;

   return 0;
}


/**********************************************************************
 * code --- code a string
 *
 * This function recursively codes a string by swapping halves and
 * then recursively coding the halves.  str is the name of the array
 * containing the string.  start is the position at which to begin
 * coding, and len is the length of the string to code.
 **********************************************************************/

void code(char str[], int start, int len)
{
   // basis
   if (len < 2)
      return;

   /*
   Length of half string is (len / 2).  If len is odd, the middle
   character will not be moved, explaining the computation of mid.
   */
   int nextLen = len / 2;
   int mid = start + (len + 1) / 2;

   // swap halves
   for (int i = start, j = mid, count = 0; count < nextLen;
        ++count, ++i, ++j)
   {
      char tmp;
   
      tmp = str[i];
      str[i] = str[j];
      str[j] = tmp;
   }

   // recursively code the halves
   code(str, start, nextLen);
   code(str, mid, nextLen);
}
