/****************************************************************************/
/*                                                                          */
/*  VolVis is a volume visualization system for investigating, manipulating */
/*  and rendering geometric and volumetric data.                            */
/*                                                                          */
/*  Copyright (C) 1993 by the Research Foundation of the State University   */
/*                            of New York                                   */
/*                                                                          */
/*  This program is free software; you can redistribute it and/or modify    */
/*  it under the terms of the GNU General Public License as published by    */
/*  the Free Software Foundation; either version 1, or (at your option)     */
/*  any later version.                                                      */
/*                                                                          */
/*  This program is distributed in the hope that it will be useful,         */
/*  but WITHOUT ANY WARRANTY; without even the implied warranty of          */
/*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           */
/*  GNU General Public License for more details.                            */
/*                                                                          */
/*  You should have received a copy of the GNU General Public License       */
/*  along with this program; if not, write to the Free Software             */
/*  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.               */
/*                                                                          */
/*  For information on VolVis, contact us at:                               */
/*                                                                          */
/*                volvis@cs.sunysb.edu                         (email)      */
/*                                                                          */
/*                Lisa Sobierajski & Ricardo Avila             (US Mail)    */
/*                Department of Computer Science                            */
/*                State University of New York at Stony Brook               */
/*                Stony Brook, New York  11794-4400                         */
/*                                                                          */
/****************************************************************************/



/*
 *			File: C_create_animation.c
 *		      Author: Lisa Sobierajski 
 *			Date: 
 *		 Description: Animation Routines Of VolVis
 *	Modification History:
 *
 *		Who?		When?		Why?
 *	--------------------------------------------------------------------
 *
 */


# include <stdio.h>
# include <math.h>
# include <string.h>


#include <netdb.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>


# include "C_volvis.h"
# include "C_navigator.h"
# include "C_animate.h"


void C_setup_animation( filename, basename, start, out_fd, start_num )
char 		*filename;
char		*basename;
int		start;
int		*out_fd;
int		*start_num;
{
	extern			C_identity3D();
	extern			C_create_volume_matrices();
	extern			C_create_plane_equations();
	extern C_ReturnStatus	C_read_env_from_file();

	void			ani_restore_world_state();

	extern  C_View		view;
	extern  C_World		world;

	int			fd;
	int			loop;
	float			rx, ry, rz;
	float			tx, ty, tz;
	char			tmp_string[80];
	float			finfo[50];
	int			findex;
	C_PointLight		*plight;
	C_Byte			starting_new;
	int			object;
	C_Volume		*volume;
	C_Matrix		fly_matrix;
	char			final_filename[256];
	C_ReturnStatus		return_status;

	float			anim_time;

	sprintf( final_filename, "%s.env", filename );
	if ( world.num_volumes == 0 )
		return_status = C_read_env_from_file( final_filename, TRUE );
	else
		return_status = C_read_env_from_file( final_filename, FALSE );

	if ( return_status == C_MISMATCH_STATUS )	
	{
		printf("mismatch - trying again\n");
		C_read_env_from_file( final_filename, TRUE );
	}
	else if ( return_status == C_ERROR_STATUS )
	{
		return;
	}

	sprintf( final_filename, "%s.flt", filename );
	fd = open( final_filename, O_RDONLY );
	if (fd < 0)
	{
		C_error_message("Could not open animation file!\n");
		close(fd);
		return;
	}

	*start_num = 0;

	for ( loop = 0; loop < start; loop++ )
	{
		read( fd, &anim_time, sizeof(float) );

		if( read( fd, &(fly_matrix.matrix), (16 * sizeof(float)) ) <
		    (16 * sizeof(float)) )
			return;

		*start_num += 1;

		C_matrix_multiply( C_POST_MULTIPLY,
				   &(view.transform), &(fly_matrix) );

		C_transform_c_sys( &(view.orig_c_sys), &(view.c_sys),
				   &(view.transform) );

		C_create_view_matrices( &view );
	}

	*out_fd = fd;
}

void C_view_animation( start, end, fd, filename, basename, 
		       start_num, create_anim )
int		start;
int		end;
int		fd;
char		*filename;
char		*basename;
int		start_num;
int		create_anim;
{

	extern int	C_write_image_to_file();
	extern C_ReturnStatus	C_cast_rays();
	extern C_View	view;
	extern C_ImageTable	image_table;
	extern C_World		world;

	extern void	ani_update_process_info();
	extern void	C_copy_c_sys();


	int		loop;
	int		iloop;
	C_Matrix	fly_matrix;
	C_View		tmp_view;
	C_Image		*image;
	char		image_name[80];
	char		image_file[80];
	int		image_num;
	C_Byte		*rptr, *gptr, *bptr;
	float		anim_time;
	C_ReturnStatus	status;

/****
	tmp_view.fov = view.fov;
	tmp_view.width_units = view.width_units;
	tmp_view.height_units = view.height_units;
	tmp_view.width_pixels = view.width_pixels;
	tmp_view.height_pixels = view.height_pixels;
****/

	if ( create_anim )
	{
	    image = C_New( C_Image );
            C_create_image_from_view( image, &view );

	    sprintf( image_name, "Anim_Image" );	
	    C_enter_image( &image_table, image, image_name, (char *)NULL );

	    if (view.display_during_projection)
                create_ivi_display_window( image_table.num_images - 1);
 
	    image_num = start_num;
	}

	for (loop = 0; loop < end - start; loop++)
	{
		/* Read Animation Frame Timing */
		read( fd, &anim_time, sizeof(float) );

		/* Read The Transform To Be Applied To The View */
		if( read( fd, &(fly_matrix.matrix), (16 * sizeof(float)) ) <
		    (16 * sizeof(float)) )
			return;

		/* Create A Temp View Identical To The Current View */
/***
		C_copy_c_sys( &(view.orig_c_sys), &(tmp_view.orig_c_sys) );
		C_copy_c_sys( &(view.c_sys), &(tmp_view.c_sys) );
		C_copy_matrix( &(view.transform), &(tmp_view.transform) );
****/

		C_matrix_multiply( C_POST_MULTIPLY,
				   &(view.transform), &(fly_matrix) );

		C_transform_c_sys( &(view.orig_c_sys), &(view.c_sys),
				   &(view.transform) );

		C_create_view_matrices( &view );

		C_update_system( C_VIEW_MODIFIED );

		if( create_anim )
		{
		      rptr = image->red;
		      gptr = image->green;
		      bptr = image->blue;

		      for(iloop=0; iloop < image->width*image->height; iloop++)
		      {
			  *(rptr++) = 0;
			  *(gptr++) = 0;
			  *(bptr++) = 0;
		      }

		      switch( view.projection_type )
		      {
		        case C_PARC:
			  status = C_cast_rays(&world, &view, image, TRUE );
			  break;
		        case C_RAY_TRACE:
			  status = C_cast_rays(&world, &view, image, FALSE );
			  break;
		      }

                      if ( status == C_ERROR_STATUS ||
                             status == C_CANCEL_STATUS )
                      {
                                return;
                      }


		      sprintf( image_file, "%s.%d.img", basename, image_num );

printf("trying to write file\n");
		      C_write_image_to_file( image, image_file); 

		      image_num++;
		}
	}
}

