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

#define LEN 16
#define BUFLEN 256

/* Three  fuctions  to compare 2 integers: */
int isGreaterThan(int a, int b)
{ return (a > b); }

int isLessThan(int a, int b)
{ return (a < b); }

int isGreaterThan_Units(int a, int b)
{ return ( (a%10) > (b%10) ); }


void swap( int * x, int * y) {
   int tmp = *x;
   *x = *y;
   *y = tmp;
}

/* argument compare  is a pointer to a fuction that returns:
 *  1: if (*compare)(arg1,arg2) >  (*compare)(arg2,arg1) 
 *  0: if (*compare)(arg1,arg2) <= (*compare)(arg2,arg1) 
 */
void bubble_sort(int data[], int size, int (* compare )(int, int))
{
  int i,j;
   
  for ( i = 1; i<size; i++) {
    for ( j = 0; j<size-i; j++) {

      if( (*compare)(data[j],data[j+1]) ) {  /* call to func (*compare) */
           swap(&data[j], &data[j+1]);
      }

    }          
  }
  return;
}

void print_array(int data[], int size ) 
{
  int i;
  for(i = 0; i<size; i++)
    printf(" %2d",data[i]); 
  printf("\n");

  return;
}

int main()
{
  /* here, 'comp' is a function pointer variable */
  int (*comp)(int,int);

  char buf[BUFLEN];
  int i;
  int data[LEN];

  srand(time(NULL)); /* seed random number generator */

  /* populate array */
  for(i = 0; i<LEN; i++)
    data[i] = rand()%100;

  /* get sort criteria from user */
  printf("'a' Descending\n");
  printf("'b' Ascending\n");
  printf("'c' Ascending, units digit\n");
  printf("Sort by:  ");
  fgets(buf,BUFLEN,stdin);

  /* set variable 'comp' */
  switch(buf[0])
  {
    case 'a':
      comp = &isLessThan;
      break;
    case 'b':
      comp = &isGreaterThan;
      break;
    case 'c':
      comp = &isGreaterThan_Units;
      break;
    default:
      printf("Enter 'a', 'b', or 'c'\n");
      return 0; 
  }

  /* print unsorted array */
  printf("\nPrinting unsorted array ...\n");
  print_array(data,LEN);

  bubble_sort(data,LEN, comp);  

  /* print sorted array */
  printf("\nPrinting sorted array ...\n");
  print_array(data,LEN);

  return 0;
}
