#include <stdio.h>
#include <dos.h>
#include <bios.h>
#include <limits.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <io.h>
#include <fcntl.h>
#include <malloc.h>

#include "layout.h"

// #define VERSION         0x0004

#define MAX_SECTORS     100

void * allocate_layout( unsigned size ) {
        void    *x ;

	if( ( x = calloc( 1, size ) ) == NULL ) {
        printf( "Core pool depleted !" ) ;
        exit( 3 ) ;
	}
	*(unsigned *)x = size ;
	return( x ) ;
}

void * load_layout( FILE *in ) {
	int     len ;
	void    *layout ;

	len = getw( in ) ;
	if( feof( in ) )
        return( NULL ) ;
	if( ( layout = malloc( len ) ) == NULL ){
        printf( "Core pool depleted !" ) ;
        exit( 3 ) ;
	}
	*(unsigned *)layout = len ;
	if( fread( (char *)layout + sizeof( int ), len - sizeof( int ), 1, in ) != 1 ){
        printf( "Input file damaged !" ) ;
        exit( 3 ) ;
	}
	return( layout ) ;
}

void * reallocate_layout( void *layout, unsigned size ) {
	void    *x ;

	if( ( x = realloc( layout, size ) ) == NULL ){
        printf( "Core pool depleted !" ) ;
        exit( 3 ) ;
	}
	*(unsigned *)x = size ;
	return( x ) ;
}

void shuffle_data( TRACK_LAYOUT *track, SECTOR_LAYOUT **sectors ) {
	SECTOR_INFO     temp_info[ MAX_SECTORS ] ;
	SECTOR_LAYOUT   *temp_secs[ MAX_SECTORS ] ;
	int             i ;
	long            temp ;
	int             insec ;

	if( track->count == 0 )
        return ;
	memcpy( temp_info, track->sectors, sizeof( SECTOR_INFO ) * track->count ) ;
	memcpy( temp_secs, sectors, sizeof( SECTOR_LAYOUT * ) * track->count ) ;
	for( i = 0, insec = 0 ; i < track->count ; i += 2, insec++ ){
        sectors[ i ] = temp_secs[ insec ] ;
        temp = track->sectors[ i ].time_diff ;
        track->sectors[ i ] = temp_info[ insec ] ;
        track->sectors[ i ].time_diff = temp ;
	}
	for( i = 1 ; i < track->count ; i += 2, insec++ ){
        sectors[ i ] = temp_secs[ insec ] ;
        temp = track->sectors[ i ].time_diff ;
        track->sectors[ i ] = temp_info[ insec ] ;
        track->sectors[ i ].time_diff = temp ;
	}
}

int main( int argc, char *argv[] )
{
	FILE            *in ;
	FILE            *out ;
	TRACK_LAYOUT    *track ;
	SECTOR_LAYOUT   *sectors[ MAX_SECTORS ] ;
	SECTOR_LAYOUT   **p ;
	int             i ;

	if( argc != 3 ){
        printf( "Usage is : shuffle infile outfile" ) ;
        return 3 ;
	}
	if( ( in = fopen( argv[ 1 ], "rb" ) ) == NULL ){
        perror( argv[ 1 ] ) ;
        return 3 ;
	}
	if( ( out = fopen( argv[ 2 ], "wb" ) ) == NULL ){
        perror( argv[ 2 ] ) ;
        return 3 ;
	}
	while( ( track = load_layout( in ) ) != NULL ){
        if( track->id != TRACK_ID ){
                printf( "Input file damaged !" ) ;
                return 3 ;
		}
        for( i = 0 ; i < track->count ; i++ ){
			if( ( sectors[ i ] = load_layout( in ) ) == NULL ){
				printf( "Unexpected EOF on input data read !" ) ;
				return 3 ;
			}
			if( sectors[ i ]->id != SECTOR_ID ){
				printf( "Input file damaged !" ) ;
				return 3 ;
			}
		}
        shuffle_data( track, sectors ) ;
        if( fwrite( track, track->length, 1, out ) != 1 ){
			printf( "Output write error - disk full ?" ) ;
			return 3 ;
		}
        if( track->count != 0 ){
                /*
                 *      Writting sector data
                 */
			for( i = 0, p = sectors ; i < track->count ; i++, p++ ){
				(*p)->id = SECTOR_ID ;
				if( fwrite( *p, (*p)->length, 1, out ) != 1 ){
					printf( "Output write error - disk full ?" ) ;
					return 3 ;
				}
				free( *p ) ;
			}
		}
        free( track ) ;
	}
	return 0 ;
}
