/****************************************************************************/
/*                                                                          */
/*  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_environment_io.c
 *		      Author: Lisa Sobierajski 
 *			Date: 07/20/93
 *		 Description: I/O of Environment Files 
 *	Modification History:
 *
 *		Who?		When?		Why?
 *	--------------------------------------------------------------------
 *
 */

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

#include "C_volvis.h"


int C_write_env_to_file( filename )
char		*filename;
{
	extern C_World		world;
	extern C_View		view;

	C_Volume		*volume;
	
	float			finfo[2000];
	int			findex;

	int			loop;

	C_PointLight		*plight;

	C_Polygon		*polygon;
	C_FPosition		*vptr;

	int			ploop;
	int			fd;
	int			i;

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

	findex = 0;
	
	finfo[findex++] = (float) world.num_lights;   
	finfo[findex++] = (float) world.num_volumes;  
	finfo[findex++] = world.world_shade.ambient_coef;  
	finfo[findex++] = (float) world.world_shade.ambient_color.red;   
	finfo[findex++] = (float) world.world_shade.ambient_color.green; 
	finfo[findex++] = (float) world.world_shade.ambient_color.blue;  
	finfo[findex++] = (float) world.world_shade.bkgrnd_color.red;    
	finfo[findex++] = (float) world.world_shade.bkgrnd_color.green;  
	finfo[findex++] = (float) world.world_shade.bkgrnd_color.blue;   

	write( fd, finfo, findex * sizeof(float) );

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

	    finfo[findex++] = (float) world.light[loop]->light_type;

	    finfo[findex++] = (float) world.light[loop]->visible; 
	    finfo[findex++] = (float) world.light[loop]->modifiable; 


	    switch ( world.light[loop]->light_type )
	    {
		  case C_POINT_LIGHT:

			plight = world.light[loop]->light.light_point;
			
			finfo[findex++] = plight->light_pos.x;
			finfo[findex++] = plight->light_pos.y;
			finfo[findex++] = plight->light_pos.z;
			finfo[findex++] = (float)plight->light_color.red;
			finfo[findex++] = (float)plight->light_color.green;
			finfo[findex++] = (float)plight->light_color.blue;
			finfo[findex++] = plight->light_intensity;
			
		
			break;

		  default:
	
			C_error_message("Bad light");
			return;
			break;
	    }
	
	    write( fd, finfo, findex * sizeof(float) );
	    findex = 0;

	    if ( world.light[loop]->file_name )
			finfo[findex++] = strlen(world.light[loop]->file_name);
	    else
			finfo[findex++] = 0;

	    if ( world.light[loop]->light_name )
			finfo[findex++] = strlen(world.light[loop]->light_name);
	    else
			finfo[findex++] = 0;

	    write( fd, finfo, findex * sizeof(float) );
	    findex = 0;

	    if ( world.light[loop]->file_name )
			write( fd, world.light[loop]->file_name, 
				strlen(world.light[loop]->file_name) );

	    if ( world.light[loop]->light_name )
			write( fd, world.light[loop]->light_name, 
				strlen(world.light[loop]->light_name) );

	}

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

	    finfo[findex++] = (float) world.volume[loop]->visible; 
	    finfo[findex++] = (float) world.volume[loop]->modifiable; 

	    volume = world.volume[loop];


	    if ( volume->file_name )
			finfo[findex++] = strlen(volume->file_name);
	    else
			finfo[findex++] = 0;

	    if ( volume->volume_name )
			finfo[findex++] = strlen(volume->volume_name);
	    else
			finfo[findex++] = 0;

	    write( fd, finfo, findex * sizeof(float) );

	    if ( volume->file_name )
			write( fd, volume->file_name, 
				strlen(volume->file_name) );

	    if ( volume->volume_name )
			write( fd, volume->volume_name, 
				strlen(volume->volume_name) );

	    findex = 0;

	    finfo[findex++] = volume->c_sys.origin.x; 
	    finfo[findex++] = volume->c_sys.origin.y; 
	    finfo[findex++] = volume->c_sys.origin.z; 
	    finfo[findex++] = volume->c_sys.x_axis.x; 
	    finfo[findex++] = volume->c_sys.x_axis.y; 
	    finfo[findex++] = volume->c_sys.x_axis.z; 
	    finfo[findex++] = volume->c_sys.y_axis.x; 
	    finfo[findex++] = volume->c_sys.y_axis.y; 
	    finfo[findex++] = volume->c_sys.y_axis.z; 
	    finfo[findex++] = volume->c_sys.z_axis.x; 
	    finfo[findex++] = volume->c_sys.z_axis.y; 
	    finfo[findex++] = volume->c_sys.z_axis.z; 

	    finfo[findex++] = (float) volume->data_type;

	    write( fd, finfo, findex * sizeof(float) );
	    findex = 0;

	    switch ( volume->data_type )
	    {
		  case C_SCALAR_DATA_8BIT:

		    /***  Save The Segmentation Type  ***/
		    finfo[findex++] = 
			(float)volume->data.scalar_data_8bit->seg_type;

		    /***  Save The Isosurface Value  ***/
		    finfo[findex++] = 
			  volume->data.scalar_data_8bit->seg.isovalue;

		    /***  Save The Opacity Array  ***/
		    for ( i=0; i< 256; i++ )
		    {
			    finfo[findex++] = 
				volume->data.scalar_data_8bit->
					seg.s_opacity->opacity[i];
		    }
			
		    /***  Save the reference count ***/
		    finfo[findex++] = 
			volume->data.scalar_data_8bit->references;

		    /***  Write this info to the file  ***/
		    write( fd, finfo, findex * sizeof(float) );
		    findex = 0;
		    
		    break;

		  case C_GEOMETRIC_DATA:

		    finfo[findex++] = (float) volume->data.geo_data->geo_type;
		
		    switch ( volume->data.geo_data->geo_type )
		    {
		      case C_SPHERE:
			
			break;
	
		      case C_POLYGON:
			
			polygon = volume->data.geo_data->geo_object.polygon;

			finfo[findex++] = polygon->plane.a;
			finfo[findex++] = polygon->plane.b;
			finfo[findex++] = polygon->plane.c;
			finfo[findex++] = polygon->plane.d;

			finfo[findex++] = (float) polygon->num_vertices;

			vptr = polygon->vertices;

			for (ploop = 0; ploop < polygon->num_vertices; ploop++)
			{
				finfo[findex++] = vptr->x;
				finfo[findex++] = vptr->y;
				finfo[findex++] = vptr->z;
				vptr++;
			}
			
			break;

		      default:

			C_error_message("I don't know that geo\n");
			return;
			break;
		    }
		    break;

		  default:

		    C_error_message("I can't deal with this!!!\n");
		    return;
		    break;
	    }

	    finfo[findex++] = (float) volume->x_size_voxels;
	    finfo[findex++] = (float) volume->y_size_voxels;
	    finfo[findex++] = (float) volume->z_size_voxels;
	    finfo[findex++] = volume->x_size_units;
	    finfo[findex++] = volume->y_size_units;
	    finfo[findex++] = volume->z_size_units;

	    finfo[findex++] = (float) volume->color_type;


	    /*** Save the single color info  ***/
	    finfo[findex++] = 
			(float) volume->color_data.single_color->red;
	    finfo[findex++] = 
			(float) volume->color_data.single_color->green;
	    finfo[findex++] = 
			(float) volume->color_data.single_color->blue;
			


	    /***  Save the color array info  ***/
	    for ( i = 0; i < 256; i++ )
	    {
			finfo[findex++] = 
			 (float) volume->color_data.color_array->color[i].red;
			finfo[findex++] = 
			 (float) volume->color_data.color_array->color[i].green;
			finfo[findex++] = 
			 (float) volume->color_data.color_array->color[i].blue;
	    }

	    finfo[findex++] = (float) volume->shade_type;


	    /***  Save the simple shade info  ***/
	    finfo[findex++] = 
			volume->local_shade.simple_shade->diffuse_coef;
	    finfo[findex++] = 
			volume->local_shade.simple_shade->specular_coef;
	    finfo[findex++] = 
			volume->local_shade.simple_shade->specular_power;
	    finfo[findex++] = 
			volume->local_shade.simple_shade->transmit_coef;
	    finfo[findex++] = 
			volume->local_shade.simple_shade->transmissitivity;
	    finfo[findex++] = 
			volume->local_shade.simple_shade->index_of_refraction;
			

	    finfo[findex++] = (float) volume->texture_type;

	    if ( volume->texture_type != C_NO_TEXTURE )
	    {
		finfo[findex++] = (float)
			strlen(volume->texture.voltex->texture_name);

	    	write( fd, finfo, findex * sizeof(float) );
		findex = 0;
		write( fd, volume->texture.voltex->texture_name, 
		       (int)strlen(volume->texture.voltex->texture_name) );

	    }


	    if ( volume->p_info )
	      	finfo[findex++] = volume->p_info->sub_level;
	    else
		finfo[findex++] = 0;

	    write( fd, finfo, findex * sizeof(float) );
	    findex = 0;
	}


	write( fd,  &(view.c_sys.origin.x), sizeof(float) );
	write( fd,  &(view.c_sys.origin.y), sizeof(float) );
	write( fd,  &(view.c_sys.origin.z), sizeof(float) );

	write( fd,  &(view.c_sys.x_axis.x), sizeof(float) );
	write( fd,  &(view.c_sys.x_axis.y), sizeof(float) );
	write( fd,  &(view.c_sys.x_axis.z), sizeof(float) );

	write( fd,  &(view.c_sys.y_axis.x), sizeof(float) );
	write( fd,  &(view.c_sys.y_axis.y), sizeof(float) );
	write( fd,  &(view.c_sys.y_axis.z), sizeof(float) );

	write( fd,  &(view.c_sys.z_axis.x), sizeof(float) );
	write( fd,  &(view.c_sys.z_axis.y), sizeof(float) );
	write( fd,  &(view.c_sys.z_axis.z), sizeof(float) );

	return C_OK;
}

C_ReturnStatus C_read_env_from_file( filename, overwrite_system_state )
char	*filename;
int	overwrite_system_state;
{
	extern			C_identity3D();
	extern			C_create_volume();
	extern			C_create_volume_matrices();
	extern			C_create_plane_equations();

	extern  C_View		view;
	extern  C_World		world;
	int			loop;
	float			finfo[2000];
	int			findex;
	C_PointLight		*plight;
	C_Byte			starting_new;
	int			object;
	C_Volume		*volume;
	float			tmp_float;

	C_Polygon		*polygon;
	C_FPosition		*vptr;

	int			ploop;
	int			parc_level;
	char			tmp_name[100];
	int			fd;
	int			i;
	char			texture_name[256];
char string[255];


	fd = open( filename, O_RDONLY );
	if (fd < 0)
	{
		C_error_message("Can't open environment file!");
		return C_ERROR_STATUS;
	}

	if ( overwrite_system_state )
	{
		for ( i = 0; i < world.num_lights; i++ )
			C_free_light( world.light[i] );

		for ( i = 0; i < world.num_volumes; i++ )
			C_free_volume( world.volume[i] );
	}

	read( fd, finfo, 9*sizeof(float) );
	
	findex = 0;

	if ( !overwrite_system_state )
	{
		if ( world.num_lights != (int) finfo[0] )
		{
			C_error_message("Mismatched light numbers");
			close(fd);
			return C_MISMATCH_STATUS;
		}
		if ( world.num_volumes != (int) finfo[1] )
		{
			C_error_message("Mismatched volume numbers");
			close(fd);
			return C_MISMATCH_STATUS;
		}
	}

	world.num_lights                      = (int) finfo[findex++];
	world.num_volumes                     = (int) finfo[findex++];
	world.world_shade.ambient_coef        = finfo[findex++];
	world.world_shade.ambient_color.red   = (C_Byte) finfo[findex++];
	world.world_shade.ambient_color.green = (C_Byte) finfo[findex++];
	world.world_shade.ambient_color.blue  = (C_Byte) finfo[findex++];
	world.world_shade.bkgrnd_color.red    = (C_Byte) finfo[findex++];
	world.world_shade.bkgrnd_color.green  = (C_Byte) finfo[findex++];
	world.world_shade.bkgrnd_color.blue   = (C_Byte) finfo[findex++];

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

	  read( fd, finfo, 3*sizeof(float) );
	  findex = 0;

	  if ( overwrite_system_state )
	  {
		world.light[loop] = C_New( C_Light );
		world.light[loop]->light_type = finfo[0];;
	  }
	  else if ( world.light[loop]->light_type != finfo[0] )
	  {
			C_error_message("Mismatch Light Types!!!\n");
			close(fd);
			return;
	  }
	  world.light[loop]->visible = finfo[1];;
	  world.light[loop]->modifiable = finfo[2];;

	  switch ( world.light[loop]->light_type )
	  {
		    case C_POINT_LIGHT:
		
			world.light[loop]->light.light_point = 
				C_New( C_PointLight );

	  		read( fd, finfo, 7*sizeof(float) );
	  		findex = 0;

			plight = world.light[loop]->light.light_point;
			plight->orig_light_pos.x  =
			plight->light_pos.x       = finfo[findex++];
			plight->orig_light_pos.y  =
			plight->light_pos.y       = finfo[findex++];
			plight->orig_light_pos.z  =
			plight->light_pos.z       = finfo[findex++];
			plight->light_color.red   = (C_Byte) finfo[findex++];
			plight->light_color.green = (C_Byte) finfo[findex++];
			plight->light_color.blue  = (C_Byte) finfo[findex++];
			plight->light_intensity   = finfo[findex++];

			C_identity3D( &plight->transform );

			break;
		
		    default:

			C_error_message("Internal Error - Invalid Light Type");
			return;
	  }

	  read( fd, finfo, 2*sizeof(float) );
	  findex = 0;

	  if ( !overwrite_system_state )
	  {
	    free( world.light[loop]->light_name );

	    if ( finfo[0] > 0 )
	    {
	        read( fd, tmp_name, (int)finfo[0] );
	        tmp_name[(int)finfo[0]] = 0;
	        if ( strcmp( tmp_name, world.light[loop]->file_name ) != 0 )
	        {		
		    C_error_message("Mismatch light file names\n");
		    close(fd);
		    return;
	        }
	    }
	    else
	    {
	        if ( world.light[loop]->file_name  != NULL )
	        {		
		    C_error_message("Mismatch light file names\n");
		    close(fd);
		    return;
	        }
	    }
	  }
	  else
	  {
	     world.light[loop]->file_name   = (char *) malloc((int)finfo[0]+1);
	  }

	  world.light[loop]->light_name = (char *) malloc((int)finfo[1]+1);

	  if ( finfo[0] != 0 && overwrite_system_state )
	  {
			read( fd, world.light[loop]->file_name, (int)finfo[0] );
			world.light[loop]->file_name[(int)finfo[0]] = 0;
	  }
		else
			world.light[loop]->file_name = NULL;

	  if ( finfo[1] != 0 )
	  {
			read( fd, world.light[loop]->light_name,(int)finfo[1] );
			world.light[loop]->light_name[(int)finfo[1]] = 0;
	  }
	  else
			world.light[loop]->light_name = NULL;



	}

        for ( loop = 0; loop < world.num_volumes; loop++ )
        {
	    read( fd, finfo, 2*sizeof(float) );
	    findex = 0;

	    if ( overwrite_system_state )
	    {
		C_create_volume( &world.volume[loop], C_SINGLE_COLOR, 
				 C_SIMPLE_SHADE ); 
	    }

	    volume = world.volume[loop];

	    volume->visible = finfo[0];
	    volume->modifiable = finfo[1];
	    
	    read( fd, finfo, 2 * sizeof(float) );
	    findex = 0;

	    if ( !overwrite_system_state )
	    {
		if ( volume->volume_name )
			free( volume->volume_name );


		if ( finfo[0] > 0 )
		{

		    read( fd, tmp_name, (int)finfo[0] );

		    tmp_name[(int)finfo[0]] = 0;

		    if ( strcmp( tmp_name, volume->file_name ) != 0 )
		    {		
			    C_error_message("Mismatch volume file names\n");
printf("%s vs. %s\n", tmp_name, volume->file_name );
			    close(fd);
			    return;
		    }
	     	}
		else
		{
		    if ( volume->file_name != NULL )
		    {		
			    C_error_message("Mismatch volume file names\n");
printf("%s vs. %s\n", tmp_name, volume->file_name );
			    close(fd);
			    return;
		    }
		}
	    }
	    else
	    {
	      	volume->file_name   = (char *) malloc((int)finfo[0]+1);
/***
	      	volume->file_name   = (char *) malloc((int)finfo[0]+5);
***/
	    }
		
	    volume->volume_name = (char *) malloc((int)finfo[1]+1);

	    if ( finfo[0] != 0 && overwrite_system_state )
	    {
			read( fd, volume->file_name,   (int)finfo[0] );
			volume->file_name[(int)finfo[0]] = 0;

/****
			read( fd, string ,  (int)finfo[0] );
			string[(int)finfo[0]] = 0;
			sprintf( volume->file_name, "%s.slc", string );
****/

	    }
	    else if ( finfo[0] == 0 )
			volume->file_name = NULL;

	    if ( finfo[1] != 0 )
	    {
			read( fd, volume->volume_name, (int)finfo[1] );
			volume->volume_name[(int)finfo[1]] = 0;
	    }
	    else
			volume->volume_name = NULL;

	    read( fd, finfo, 13 * sizeof(float) );
	    findex = 0;

	    volume->c_sys.origin.x = 
	    volume->orig_c_sys.origin.x = finfo[findex++];
	    volume->c_sys.origin.y = 
	    volume->orig_c_sys.origin.y = finfo[findex++];
	    volume->c_sys.origin.z = 
	    volume->orig_c_sys.origin.z = finfo[findex++];
	    volume->c_sys.x_axis.x = 
	    volume->orig_c_sys.x_axis.x = finfo[findex++];
	    volume->c_sys.x_axis.y = 
	    volume->orig_c_sys.x_axis.y = finfo[findex++];
	    volume->c_sys.x_axis.z = 
	    volume->orig_c_sys.x_axis.z = finfo[findex++];
	    volume->c_sys.y_axis.x = 
	    volume->orig_c_sys.y_axis.x = finfo[findex++];
	    volume->c_sys.y_axis.y = 
	    volume->orig_c_sys.y_axis.y = finfo[findex++];
	    volume->c_sys.y_axis.z = 
	    volume->orig_c_sys.y_axis.z = finfo[findex++];
	    volume->c_sys.z_axis.x = 
	    volume->orig_c_sys.z_axis.x = finfo[findex++];
	    volume->c_sys.z_axis.y = 
	    volume->orig_c_sys.z_axis.y = finfo[findex++];
	    volume->c_sys.z_axis.z = 
	    volume->orig_c_sys.z_axis.z = finfo[findex++];

	    if ( overwrite_system_state )
	    {
		volume->data_type = finfo[findex++];
	    }
	    else
	    {
		if ( volume->data_type != finfo[findex++] )
		{
			C_error_message("Mismatch data type\n");
			close(fd);
			return;
		}
	    }
	    switch ( volume->data_type )
	    {
		case C_SCALAR_DATA_8BIT:

		  if ( overwrite_system_state )
		  {
			C_read_slc_from_file( volume, volume->file_name );

		  }

		  read( fd, finfo, sizeof(float) );
			
		  volume->data.scalar_data_8bit->seg_type = 
							(C_SegType)finfo[0];
		  read( fd, finfo, sizeof(float) );
		  volume->data.scalar_data_8bit->seg.isovalue = finfo[0];

		  read( fd, finfo, 256*sizeof(float) );
		  for ( i = 0; i < 256; i++ )
		    volume->data.scalar_data_8bit->seg.s_opacity->opacity[i] =
				finfo[i];

		  read( fd, finfo, sizeof(float) );
		
		  volume->data.scalar_data_8bit->references = finfo[0];
		  break;

		case C_GEOMETRIC_DATA:

		  read( fd, finfo, sizeof(float) );

		  if ( overwrite_system_state )
		  {
			volume->data.geo_data = C_New( C_GeoData );
			volume->data.geo_data->geo_type = 
				(C_GeoType)finfo[0];
		  }
		  else
		  {
			if ( volume->data.geo_data->geo_type != finfo[0] )
			{
				C_error_message("Mismatch data type\n");
				close(fd);
				return;
			}
		  }

		  switch ( volume->data.geo_data->geo_type )
                  {
                      case C_SPHERE:
                       
                        break;

		      case C_POLYGON:

			read( fd, finfo, 5 * sizeof(float) );
			findex = 0;

			if ( overwrite_system_state )
			{
				volume->data.geo_data->geo_object.polygon = 
						C_New( C_Polygon );
			}

			polygon = volume->data.geo_data->geo_object.polygon;

			if ( overwrite_system_state )
			{
				polygon->plane.a = finfo[findex++];
				polygon->plane.b = finfo[findex++];
				polygon->plane.c = finfo[findex++];
				polygon->plane.d = finfo[findex++];

				polygon->num_vertices = finfo[findex++];
			}
			else
			{
				if (
				    (polygon->plane.a != finfo[0]) ||
				    (polygon->plane.b != finfo[1]) ||
				    (polygon->plane.c != finfo[2]) ||
				    (polygon->plane.d != finfo[3]) ||
				    (polygon->num_vertices != finfo[4])
				   )
				{
					C_error_message("Mismatch data type\n");
					close(fd);
					return;
				}
			}

			read(fd, finfo, polygon->num_vertices*3*sizeof(float));
			findex = 0;

			if (overwrite_system_state)
			{
				polygon->vertices = (C_FPosition *) malloc(
				  polygon->num_vertices * sizeof(C_FPosition));
			}

			vptr = polygon->vertices;
		
			for (ploop = 0; ploop < polygon->num_vertices; ploop++)
			{
				if (overwrite_system_state)
				{
					vptr->x = finfo[findex++]; 
					vptr->y = finfo[findex++]; 
					vptr->z = finfo[findex++]; 
				}
				else
				{
					if (
					    (vptr->x != finfo[findex]) ||
					    (vptr->y != finfo[findex+1]) ||
					    (vptr->z != finfo[findex+2]) 
					   )
					{
						C_error_message("Ugh!!\n");
						close(fd);
						return;
					}

					findex += 3;
				}

				vptr++;
			}

			
			break;

                      default:

                        C_error_message("I don't know that geo\n");
                        return;
                        break;
                  }


		  break;

		default:

		  C_error_message("Can't handle that data type!!\n");
		  close(fd);
		  return;
	    }	


	    read( fd, finfo, 7 * sizeof(float) );

	    if ( overwrite_system_state )
	    {
		volume->x_size_voxels = finfo[0];
		volume->y_size_voxels = finfo[1];
		volume->z_size_voxels = finfo[2];
	    }
	    else
	    {
	      	if ( volume->x_size_voxels != (int) finfo[0] ||
	             volume->y_size_voxels != (int) finfo[1] ||
	             volume->z_size_voxels != (int) finfo[2] )
	      	{
			C_error_message("Data size mismatch\n");
			close(fd);
			return;
	    	}
	    }

	    findex = 3;

	    volume->x_size_units = finfo[findex++]; 
	    volume->y_size_units = finfo[findex++]; 
	    volume->z_size_units = finfo[findex++]; 
	
	    volume->color_type = (C_ColorType) finfo[findex++];

	    read( fd, finfo, 3 * sizeof(float) );
	    findex = 0;

	    volume->color_data.single_color->red =  
				(C_Byte)finfo[findex++];
	    volume->color_data.single_color->green =  
				(C_Byte)finfo[findex++];
	    volume->color_data.single_color->blue =  
				(C_Byte)finfo[findex++];

	    read( fd, finfo, 3*256*sizeof(float) );
	    findex = 0;

	    for ( i = 0; i < 256; i++ )
	    {
		volume->color_data.color_array->color[i].red = 
			(int) finfo[findex++];
		volume->color_data.color_array->color[i].green = 
			(int) finfo[findex++];
		volume->color_data.color_array->color[i].blue = 
			(int) finfo[findex++];
	    }


	    read( fd, finfo, sizeof(float) );
	    volume->shade_type = (C_ShadeType) finfo[0];

	    read( fd, finfo, 6 * sizeof(float) );	
	    findex = 0;

	    volume->local_shade.simple_shade->diffuse_coef = 
				finfo[findex++];
	    volume->local_shade.simple_shade->specular_coef =
				finfo[findex++];
	    volume->local_shade.simple_shade->specular_power =
				finfo[findex++];
	    volume->local_shade.simple_shade->transmit_coef =
				finfo[findex++];
	    volume->local_shade.simple_shade->transmissitivity =
				finfo[findex++];
	    volume->local_shade.simple_shade->index_of_refraction =
				finfo[findex++];

	    read( fd, finfo, sizeof(float) );
	    volume->texture_type = (C_TextureType) finfo[0];

	    if ( volume->texture_type != C_NO_TEXTURE )
	    {
	       	read( fd, finfo, sizeof(float) );
		read( fd, texture_name,   
	      		(int) finfo[0] );
		texture_name[ (int) finfo[0] ] = 0;

		if ( overwrite_system_state || volume->texture.voltex == NULL )
		{
			volume->texture.voltex = C_New( C_VolTexture );

			C_read_volume_texture( texture_name,
				       	volume->texture.voltex ); 
		}
		else if ( overwrite_system_state && ( strcmp( texture_name, 
			  volume->texture.voltex->texture_name ) != 0 ) )
		{
			free( volume->texture.voltex->red );
			free( volume->texture.voltex->green );
			free( volume->texture.voltex->blue );
			free( volume->texture.voltex );

                        volume->texture.voltex = C_New( C_VolTexture );

                        C_read_volume_texture( texture_name,
                                        volume->texture.voltex );

		}
		else if ( !overwrite_system_state && ( strcmp( texture_name, 
                          volume->texture.voltex->texture_name ) != 0 ) )
		{
			C_error_message("Data texture mismatch\n");
			close(fd);
			return;
		}
		else 
		{
			printf("leaving texture alone!\n");
		}

	    }
	    else
	    {
		volume->texture.voltex = NULL;
	    }


	    C_identity3D( &(volume->transform) );

	    C_create_volume_matrices( volume );
	    C_create_plane_equations( volume );

	    read( fd, finfo, sizeof(float) );
	    findex = 0;

            /* Create The PARC Subdivision List */
	    parc_level = (int) finfo[0];

	    if ( volume->data_type == C_SCALAR_DATA_8BIT )
	    {
		if ( !volume->p_info || 
		     (volume->p_info->sub_level != parc_level) )
            	C_parc_subdivide( volume, parc_level );
	    }

	    
	}

	
	read( fd, &tmp_float, sizeof(float) );
	view.orig_c_sys.origin.x = tmp_float;
	view.c_sys.origin.x = tmp_float;
	
	read( fd, &tmp_float, sizeof(float) );
	view.orig_c_sys.origin.y = tmp_float;
	view.c_sys.origin.y = tmp_float;
	
	read( fd, &tmp_float, sizeof(float) );
	view.orig_c_sys.origin.z = tmp_float;
	view.c_sys.origin.z = tmp_float;
	
	
	read( fd, &tmp_float, sizeof(float) );
	view.orig_c_sys.x_axis.x = tmp_float;
	view.c_sys.x_axis.x = tmp_float;
	
	read( fd, &tmp_float, sizeof(float) );
	view.orig_c_sys.x_axis.y = tmp_float;
	view.c_sys.x_axis.y = tmp_float;
	
	read( fd, &tmp_float, sizeof(float) );
	view.orig_c_sys.x_axis.z = tmp_float;
	view.c_sys.x_axis.z = tmp_float;
	
	
	read( fd, &tmp_float, sizeof(float) );
	view.orig_c_sys.y_axis.x = tmp_float;
	view.c_sys.y_axis.x = tmp_float;
	
	read( fd, &tmp_float, sizeof(float) );
	view.orig_c_sys.y_axis.y = tmp_float;
	view.c_sys.y_axis.y = tmp_float;
	
	read( fd, &tmp_float, sizeof(float) );
	view.orig_c_sys.y_axis.z = tmp_float;
	view.c_sys.y_axis.z = tmp_float;
	
	
	read( fd, &tmp_float, sizeof(float) );
	view.orig_c_sys.z_axis.x = tmp_float;
	view.c_sys.z_axis.x = tmp_float;
	
	read( fd, &tmp_float, sizeof(float) );
	view.orig_c_sys.z_axis.y = tmp_float;
	view.c_sys.z_axis.y = tmp_float;
	
	read( fd, &tmp_float, sizeof(float) );
	view.orig_c_sys.z_axis.z = tmp_float;
	view.c_sys.z_axis.z = tmp_float;

	C_identity3D( &(view.transform) );

	C_create_view_matrices( &view );

	if ( overwrite_system_state )
		C_update_system( C_MAJOR_ENVIRONMENT_CHANGE );
	else
		C_update_system( C_MINOR_ENVIRONMENT_CHANGE );


	return C_OK;
}

