/****************************************************************************/
/*                                                                          */
/*  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_io.c
 *		      Author: Rick Avila and Lisa Sobierajski
 *			Date: 02/01/92
 *		 Description: Input/Output Routines Of VolVis
 *	Modification History:
 *
 *		Who?		When?		Why?
 *	--------------------------------------------------------------------
 *
 */

#include <stdio.h>
#include <stdlib.h>	/* For malloc() and strtod() */
#include <fcntl.h>	/* For open()   */

#include "C_volvis.h"

#define C_MAX_FUN_DEGREE	10

extern	C_World		world;
extern	C_View		view;
extern  C_ImageTable	image_table;

int C_save_file( filename, filetype , entry_number)
char		*filename;
C_FileType	filetype;
int		entry_number;
{

	extern int C_write_image_to_file();
	extern int C_write_slc_to_file();

	char		string[200];
	int		active_object;

	switch ( filetype )
	{
	  case C_IMAGE_FILE:

		C_write_image_to_file( 
		    image_table.image_entry[entry_number]->image, 
		    filename );

		break;

	  case C_SLICE_FILE:

		C_write_volume_to_file( 
		    world.volume[entry_number], filename );
		break;

	  case C_ANIMATION_FILE:
		
		C_error_message("Can't save animation files yet!!!\n");
		break;

	  case C_TEXTURE_FILE:

		C_error_message("Can't save texture files yet!!!\n");
		break;

	  case C_GEOMETRIC_FILE:
	
		C_error_message("Can't save geometric files yet!!!\n");
		break;

	  case C_FUNCTION_FILE:
	
		C_error_message("Can't save function files yet!!!\n");
		break;

	  case C_ENVIRONMENT_FILE:

		C_write_env_to_file( filename );
		break;

	  default:

		C_error_message("Unknown File Type!!!\n");
		return C_ERROR;
	}

	return C_OK;
}


int C_load_file( filename, filetype )
char		*filename;
C_FileType	filetype;

{
	extern int	C_read_image_from_file();
	extern int	C_read_slc_from_file();
	extern void 	C_update_world_extent();
        extern void    	nav_update();
        extern void     update_oco_active_opt();
	extern int	C_input_function();
	extern void	C_free_volume();
	extern void	C_update_system();

        char            volume_name[80];
        char            image_name[80];
        char            tmp_string[80];
	char		string[200];
        int             loop;
        int             index;
        int             status;
        C_Volume        *volume;
	C_VolTexture	*texture;
	C_VolTexture	*new_texture;
	C_Image		*image;
	int		parc_level;

	switch ( filetype )
	{
	  case C_IMAGE_FILE:

		image = C_New( C_Image );

		if ( C_read_image_from_file( image, filename ) == C_OK )
		{

		  index = 0;

        	  for (loop = (strlen(filename) - 1); loop >= 0; loop--)
        	  {
                	if (*(filename+loop) == '/')  break;

                	if (*(filename+loop) == '.')
                       		index = 0;
                	else
                	{
                       		tmp_string[index] = *(filename+loop);
                       		index++;
                	}
        	  }

        	  for (loop = 0; loop < index; loop++)
                	image_name[loop] = tmp_string[index-loop-1];

        	  image_name[index] = NULL;

		  C_enter_image( &image_table, image, image_name, 
				 filename );

		}

		break;
	
	  case C_SLICE_FILE:

		if( world.num_volumes == C_MAX_VOLUMES )
		{
			C_error_message("Too Many Volumes!!!");
			return;
		}

        	status = 
			C_create_volume( &volume, C_SINGLE_COLOR, 
				         C_SIMPLE_SHADE );


        	if( status == C_ERROR )
        	{
                	C_error_message("Can't Create Volume.");
                	return C_ERROR;
        	}

        	status = C_read_slc_from_file( volume, filename );


        	if ( status == C_ERROR )
        	{
                	C_error_message("Can't Read Slice File.");
			C_free_volume( volume );
                	return C_ERROR;
        	}


        	index = 0;

        	for (loop = (strlen(filename) - 1); loop >= 0; loop--)
        	{
                	if (*(filename+loop) == '/')  break;

                	if (*(filename+loop) == '.')
                        	index = 0;
                	else
                	{
                        	tmp_string[index] = *(filename+loop);
                        	index++;
                	}
        	}

        	for (loop = 0; loop < index; loop++)
                	volume_name[loop] = tmp_string[index-loop-1];

        	volume_name[index] = NULL;

		/* Create The PARC Subdivision List */
		C_parc_subdivide( volume, 4 );

        	status = 
		    C_enter_volume( &world, volume, volume_name, filename );

        	if( status == C_ERROR )
        	{
                    C_error_message("Can't Enter Volume in Volume Table. \n");
		    C_free_volume( volume );
                    return C_ERROR;
        	}
	
		break;

	  case C_ANIMATION_FILE:
		
		C_error_message("Can't read animation files yet!!!\n");
		break;

	  case C_TEXTURE_FILE:

		new_texture = C_New( C_VolTexture );

		if ( (C_read_volume_texture( filename, new_texture )) ==
			C_ERROR ) 
		{
			free ( new_texture );
			return C_ERROR;
		}

		new_texture->references = 0;

		for (loop = 0; loop < world.num_volumes; loop++)
		{

		    if ( world.volume[loop]->modifiable )
		    {
			volume = world.volume[loop];

			switch ( volume->color_type )
			{
			  case C_SINGLE_COLOR:
				
			    break;

			  case C_COLOR_ARRAY:
	
			    break;

			  case C_TEXTURE_COLOR:
		
			    switch ( volume->texture_type )
			    {
			      case C_VOLUME_TEXTURE:
				
				texture = volume->texture.voltex;
	
				(texture->references)--;

				if ( texture->references == 0 )
				{

				    free ( texture->red );
				    free ( texture->green );
				    free ( texture->blue );

				    free ( texture );
				}

				break;

			      case C_RAD_TEXTURE:

				texture = volume->texture.radtex;

				(texture->references)--;

				if ( texture->references == 0 )
				{
				    free ( texture->red );
				    free ( texture->green );
				    free ( texture->blue );

				    free ( texture );
				}

				break;
			    }
			}

			volume->color_type = C_TEXTURE_COLOR;
			volume->texture_type = C_VOLUME_TEXTURE;
			volume->texture.voltex = new_texture;

			(new_texture->references)++;
		    }
		}

		C_update_system( C_VOLUME_MODIFIED );
		break;

	  case C_GEOMETRIC_FILE:
	
		C_error_message("Can't read geometric files yet!!!\n");
		break;

	  case C_FUNCTION_FILE:

		C_message("Loading Function\n");

        	status = 
			C_create_volume( &volume, C_SINGLE_COLOR, 
				         C_SIMPLE_SHADE );

        	if( status == C_ERROR )
        	{
                	C_error_message("Can't Create Volume. \n");
                	return C_ERROR;
        	}

        	status = C_input_function( filename, volume );

        	index = 0;

        	for (loop = (strlen(filename) - 1); loop >= 0; loop--)
        	{
                	if (*(filename+loop) == '/')  break;

                	if (*(filename+loop) == '.')
                        	index = 0;
                	else
                	{
                        	tmp_string[index] = *(filename+loop);
                        	index++;
                	}
        	}

        	for (loop = 0; loop < index; loop++)
                	volume_name[loop] = tmp_string[index-loop-1];

        	volume_name[index] = NULL;

        	status = 
		    C_enter_volume( &world, volume, volume_name, filename );

        	if( status == C_ERROR )
        	{
                    C_error_message("Can't Enter Volume in Volume Table. \n");
		    C_free_volume( volume );
                    return C_ERROR;
        	}
	
        	if ( status == C_ERROR )
        	{
                	C_error_message("Can't Read Function File.\n");
                	return C_ERROR;
        	}

		/* Create The PARC Subdivision List */
		C_parc_subdivide( volume, 4 );

		break;
	
	case C_ENVIRONMENT_FILE:

		C_read_env_from_file( filename, TRUE );

		break;		

	}

	return C_OK;
}
 

/************************************************************************/
/*									*/
/*		Confocal Microscope Data File Input			*/
/*									*/
/************************************************************************/
/*
int C_write_volume_to_file( volume, filename )
C_Volume	*volume;
char		*filename;
{
	int		fd;
	C_Voxel_8bit	*dptr;
	int		y, z;
	float		x_units, y_units, z_units;
	int		x_voxels, y_voxels, z_voxels;
	int		magic_num = C_SLICE_MAGIC;

	switch ( volume->data_type )
	{
	    case C_GEOMETRIC_DATA:

		C_error_message("You can't save geometric data yet!!!\n");
		break;

	    case C_SCALAR_DATA_8BIT:

		fd = open( filename, O_WRONLY | O_CREAT, 0644 );
		if ( fd < 0 )
		{
			C_error_message("Can't open file!!!\n");
			return C_ERROR;
		}

		write( fd, &(magic_num), sizeof(int) );
		x_voxels = volume->x_size_voxels - 2;
		y_voxels = volume->y_size_voxels - 2;
		z_voxels = volume->z_size_voxels - 2;
		write( fd, &(x_voxels), sizeof(int) );
		write( fd, &(y_voxels), sizeof(int) );
		write( fd, &(z_voxels), sizeof(int) );
		x_units = volume->x_size_units / 
			(float) (volume->x_size_voxels-1);	
		y_units = volume->y_size_units / 
			(float) (volume->y_size_voxels-1);	
		z_units = volume->z_size_units / 
			(float) (volume->z_size_voxels-1);	
		write( fd, &(x_units), sizeof(float) );
		write( fd, &(y_units), sizeof(float) );
		write( fd, &(z_units), sizeof(float) );
		write( fd, &(volume->unit_type), sizeof(C_UnitType) );

		dptr = volume->data.scalar_data_8bit->scalar_data;

		dptr += volume->x_size_voxels * volume->y_size_voxels;

		for ( z = 1; z < volume->z_size_voxels - 1; z++ )
		{
		  dptr += volume->x_size_voxels;
		  for ( y = 1; y < volume->y_size_voxels - 1; y++ )
		  {
		    dptr += 1;
		    write( fd, dptr, (volume->x_size_voxels - 2) *
					sizeof( C_Voxel_8bit ) );
		    dptr += volume->x_size_voxels-1;
		  }
		  dptr += volume->x_size_voxels;
		}

		close( fd );
		break;

	}
		
}
*/
