/************************************************************************/
/*	VPath2.c - 6/11/94						*/
/*									*/
/*	This program reads in a Vista script and generates tween	*/
/*	positions based on the key positions already present in the	*/
/*	file. Multiple keys supported.					*/
/************************************************************************/


/* Standard Library Headers */
/* ************************ */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/* Globals */
/* ******* */
#define EOL '\n'

FILE *infile ;
FILE *outfile ;

enum SettingHeadings {CamX, CamY, CamZ, Bank, Heading, Pitch} ;
enum WhichSettings   {Start, End, Delta} ;
enum SpareSets	     {Base, Running} ;

int settings[6][3] ;	 /* Coords etc */
float setting_spares[6][2] ;/* Remainders after divides */


/* Function Prototypes */
/* ******************* */
void process_file(void) ;
void extract_settings(char *string, int keyframe) ;
void calc_deltas(int frame_count) ;
void check_header(char *input_line) ;
void display_frame_info(int key_no, char *data, char *title, char *direction) ;

/* Main Program */
/* ************ */
void main(int argc, char *argv[])
{
	/* Check argument count */
	/* ******************** */
	if (argc != 3)
	{
		printf("\n%s Usage: %s Keyframefile Newfile\n\n",
							argv[0], argv[0]) ;
		exit (0) ;
	}


	/* Open Files */
	/* ********** */
	infile = fopen(argv[1], "r") ;
	if (infile == NULL)
	{
		printf("\aCannot open %s for input\n\n", argv[1]) ;
		exit(100) ;
	}

	outfile = fopen(argv[2], "w") ;
	if (outfile == NULL)
	{
		printf("\aCannot open %s for output\n\n", argv[2]) ;
		fclose(infile) ;
		exit(200) ;
	}


	printf("\nVPath - Steve Pullinger Nov 94\n"
		 "==============================\n\n") ;
	
		
	process_file() ;



	/* All done, close files */
	/* ********************* */
	fclose(outfile) ;
	fclose(infile) ;
	
	/* Say goodbye */
	/* *********** */
	printf("\nOK all done..\n") ;
	printf("Thankyou and goodnight.\n\n") ;
	
}
/* Function Definitions */
/* ******************** */
void process_file(void)
{
	/****************************************************************/
	/*		     PROCESS FILE FUNCTION			*/
	/*		     *********************			*/
	/* NAME:	process_file()					*/
	/*								*/
	/* DESCRIPTION: This function creates the tween positions in the*/
	/*		new Vista script.				*/
	/*								*/
	/* SYNOPSIS:	stdio.h 					*/
	/*		string.h					*/
	/*		void process_file(void) 			*/
	/*								*/
	/* EXAMPLE:	process_file() ;				*/
	/****************************************************************/

	char start_line[81] ; /* Read buffer position */
	char end_line[81] ;
	char output_line[81] ; /* Write buffer */
	int count ;
	char key_frame_heading[81] ;
	int num_frames ;
	int difference ;
	int current ;
	int num_keys ;
	int current_key ;

	/* Make sure it's a Vista file */
	/* *************************** */
	check_header(key_frame_heading) ;


	/* Count key positions */
	/* ******************* */
	num_keys = 0 ;
	while (!feof(infile))
	{
		fgets(start_line, 81, infile) ;
		if (!feof(infile))
		{
			if (strchr (start_line, ',') != 0)
				num_keys++ ;
		}
	}
	if (num_keys > 1)
		printf("\n** File contains %d key frames. **\n", num_keys) ;
	else
	{
		printf("\aScript doesn't have enough key frames\n") ;
		fclose (outfile) ;
		fclose(infile) ;
		exit(100) ;
	}

	/* Reset file pointer for re-reading */
	/* ********************************* */
	rewind(infile) ;
	fgets(start_line, 81, infile) ;
	fgets(start_line, 81, infile) ;

	current_key = 1 ;
	while (current_key < num_keys)
	{
		/* Read first key position */
		/* *********************** */
		if (current_key == 1)
		{
			fgets(start_line, 81, infile) ;
			fprintf(outfile, "%s", start_line) ; /* Copy key pos
								to new file */

			
			
			extract_settings(start_line, Start) ; /* Store
							 settings in array */
			
			display_frame_info(current_key,
				start_line, key_frame_heading, "From") ;
			
			
		}
		else
		{
			for (count = CamX; count <= Pitch; count++)
			{
				settings[count][Start] = settings[count][End] ;
			
			}
			
			display_frame_info(current_key,
				end_line, key_frame_heading, "From") ;
		
		}
		

		/* Read next key position */
		/* ********************** */
		fgets(end_line, 81, infile) ;
		extract_settings(end_line, End) ;

		display_frame_info(current_key + 1, end_line,
				 key_frame_heading, "To") ;

		
		/* Request number of frames */
		/* ************************ */
		num_frames = 0 ;
		do
		{
			printf("\nHow many frames from key frame %d"
				" to key frame %d ? (Minimum 3): ",
				current_key, current_key + 1) ;

			fflush(stdin) ;

		} while ((scanf("%d", &num_frames) != 1) || (num_frames < 3)) ;

		printf("Computing %d frames...\n", num_frames) ;
		
		/* Calculate deltas */
		/* **************** */
		calc_deltas(num_frames) ;


		/* Write tween frames to new file */
		/* ****************************** */
		for (count = 2; count < num_frames; count++)
		{

			for (current = CamX; current <= Pitch; current++)
			{
				/* Calculate tween positions */
				/* ************************* */
				settings[current][Start] =
					settings[current][Start] +
					settings[current][Delta] ;

				setting_spares[current][Running] =
					setting_spares[current][Running] +
					setting_spares[current][Base] ;

				if (abs((int)setting_spares[current]
							[Running]) >= 1)
				{
					difference = (int)setting_spares
								[current]
								[Running] ;

					settings[current][Start] =
						settings[current][Start] +
						difference ;

					setting_spares[current][Running] =
						setting_spares[current]
						[Running] - difference ;

				}

			}
			/* Build outputline */
			/* **************** */
			strcpy(output_line, "") ;
			sprintf(output_line, "%5d, %5d, %5d, %4d, %4d, %4d,\n"
				,settings[CamX][Start], settings[CamY][Start],
				settings[CamZ][Start], settings[Bank][Start],
				settings[Heading][Start],
				settings[Pitch][Start]) ;

			/* Write line to new file */
			/* ********************** */
			fprintf(outfile, "%s", output_line) ;

		}

		/* Write last frame */
		/* **************** */
		fprintf(outfile, "%s", end_line) ;

		current_key++ ;
	}
}


void display_frame_info(int key_no, char *data, char *title, char *direction)
{

	printf("\n %s Keyframe: %5d\n", direction, key_no) ;
	printf("%s", title) ;
	printf(" =====================================\n") ;
	printf("%s\n", data) ;
}

void extract_settings(char *string, int keyframe)
{
	int count ;
	int which_setting ;
	char temp[10] ;
	int temp_count ;

	which_setting = CamX ;
	for (count = 0; count < strlen(string); count++)
	{
		/* Store number in temp as a string */
		temp_count = 0 ;
		while ((string[count] != ',') && (string[count] != EOL))
		{
			temp[temp_count] = string[count] ;
			count++ ;
			temp_count++ ;
		}
		temp[temp_count] = '\0' ;

		/* Convert temp to number */
		if (which_setting <= Pitch)
		{
			settings[which_setting][keyframe] = atoi(temp) ;
			which_setting++ ;
		}
	}
}

void calc_deltas(int frame_count)
{
	int current ;

	/* Calculate differences */
	frame_count-- ;
	for (current = CamX; current <= Pitch; current++)
	{
		settings[current][Delta] =
			settings[current][End] - settings[current][Start] ;
	}

	/* Calculate Steps */
	for (current = CamX; current <= Pitch; current++)
	{
		setting_spares[current][Base] =
			(float)settings[current][Delta] / (float)frame_count ;

		/* Split float to int and decimal remainder */
		settings[current][Delta] =
			(int)setting_spares[current][Base] ;

		setting_spares[current][Base] =
			setting_spares[current][Base] -
			settings[current][Delta] ;
	}
}

void check_header(char *input_line)
{

	int count ;

	/* Copy file header */
	for (count = 0; count < 2; count++)
	{
		fgets(input_line, 81, infile) ;
		if (count == 0)
		{
			if (strcmp(input_line, "Vista Script File\n") != 0)
			{
				printf("\aERROR: Not a Vista File1\n") ;
				fclose(outfile) ;
				fclose(infile) ;
				exit (100) ;
			}
		}
		fprintf(outfile, "%s", input_line) ;
	}
}
