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

#define MAX_FRAME_SIZE 10
#define MIN_FRAME_SIZE 2

#define BUFFER_SIZE 50

struct frame {
    char data[MAX_FRAME_SIZE];
    int seq_no;
};

int main () {

    struct frame queue[BUFFER_SIZE/MIN_FRAME_SIZE + 1]; // don't ponder
    char buffer[BUFFER_SIZE];
    int frame_size, no_of_frames, i, j, k;

    printf ("Enter a message: ");
    fgets (buffer, BUFFER_SIZE, stdin);
    //remove the trailing newline
    buffer[strlen (buffer)-1] = '\0';

    printf ("Enter frame size (%d - %d)\n", MIN_FRAME_SIZE, MAX_FRAME_SIZE);
    scanf ("%d", &frame_size);
    
    if (frame_size > MAX_FRAME_SIZE || frame_size < MIN_FRAME_SIZE)
	abort(); // no reason eh?

    no_of_frames = 0;

    //now divide the message according to the frame size.
    for (i = 0; i < strlen (buffer); i += frame_size) {
	//copy substring to frame
	for (j = 0, k = i; j < frame_size && k < strlen(buffer); j++, k++)
	    queue[no_of_frames].data[j] = buffer[k];
	queue[no_of_frames].data[j] = '\0';
	queue[no_of_frames].seq_no = no_of_frames; //set original sequence number
	no_of_frames++;
    }

    //print the raw frames
    printf ("Raw frames:\n");
    for (i = 0; i < no_of_frames; i++)
	printf ("Frame %d: %s\n", i, queue[i].data);

    //now scramble the frames
    srandom (time (NULL));
    for (k = 0; k < 10; k++) {
	i = random()%no_of_frames;
	j = random()%no_of_frames;
	struct frame temp;
	temp = queue[i];
	queue[i] = queue[j];
	queue[j] = temp;
    }

    //print the scrambled frames
    printf ("Scrambled frames:\n");
    for (i = 0; i < no_of_frames; i++)
	printf ("Frame %d: %s\n", i, queue[i].data);
	
    //now sort the frames based on the seq_no
    for (i = 0; i < no_of_frames; i++) {
	k = i; // k is the smallest known
	for (j = i+1; j < no_of_frames; j++)
	    if (queue[j].seq_no < queue[k].seq_no)
		k = j;
	//swap queue[k] and queue[i]
	struct frame temp;
	temp = queue[i];
	queue[i] = queue[k];
	queue[k] = temp;
    }
    //print the re-sorted frames
    printf ("Resorted frames:\n");
    for (i = 0; i < no_of_frames; i++)
	printf ("Frame %d: %s\n", i, queue[i].data);

    //print the recovered message
    for (i = 0; i < no_of_frames; i++)
	printf ("%s", queue[i].data);
    printf ("\n");

    return 0;
}

