/****************************************************************************/
/*                                                                          */
/*  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                         */
/*                                                                          */
/****************************************************************************/



#include <stdio.h>
#include <math.h>
#include <fcntl.h>
#include "C_volvis.h"
#include "C_navigator.h"
#include "C_nav_draw.h"

extern	C_View		view;
extern	C_NavInfo	nav_info;
extern  C_World		world;


void nav_projection_draw( proj_type )
C_NavProjectionType	proj_type;
{
	extern 		C_View		view;
	int		vol;		/* Volume Index */
	float		v[8][3];	/* Vertices Of A 3D Rectangle */
	C_FPosition	clist[5];
	C_Volume	*volume;	/* Pointer To Current Volume */
	C_ParcSubNode	*list_ptr;	/* Pointer To Subdivision List */
	float		x_sub_dist;	/* Subvolume X Length */
	float		y_sub_dist;	/* Subvolume Y Length */
	float		z_sub_dist;	/* Subvolume Z Length */
	float		sx;		/* X Index To Subvolume */
	float		sy;		/* Y Index To Subvolume */
	float		sz;		/* Z Index To Subvolume */
	float		div;		/* # of Subdivisions */
	float		div_sq;		/* # of Subdivisions Squared */
	unsigned int	temp;

	C_FPosition	x_plane_pos;	/* Middle Of X Positive Plane */
	C_FPosition	y_plane_pos;	/* Middle Of Y Positive Plane */
	C_FPosition	z_plane_pos;	/* Middle Of Z Positive Plane */
	C_FVector	view_direction;/* Viewing Direction */

	float		n[6][3];	/* Normals For 6 Planes */

	int		i, j;
	float		pos_and_orient[4][4];
	float		ltow_mapping[4][4]; 
	static int	buffer = 0;	/* Double Buffer Toggle Variable */

	C_ExtraDrawInfo ed_info;

	C_Matrix	setup_matrix;

	extern void	nav_set_viewing();
	extern void	nav_clear_buffers();
	extern void	nav_set_lighting();
	extern void	nav_set_shading();
	extern void	nav_project_geo_volume();
	extern void	nav_unset_lighting();
	extern void	nav_unset_shading();
	extern void	nav_get_zbuffer();
	extern void	nav_setup_extra_draw_info();

	/* This Routine Should Not Be Called With For Wireframe Drawing! */
	switch( proj_type )
	{
		case C_NAV_WIREFRAME:
		case C_NAV_WIREFRAME_KEY: 
			C_error_message("Internal Error: NAV_WF_DRAW");
			return;
			break;
		case C_NAV_PROJECTION:
		case C_PARC_FRONT_PROJECTION:
		case C_PARC_BACK_PROJECTION:
			break;
	}

	/*************************************************/
	/* Don't Draw Into Window If Not Already Created */
	/*************************************************/
	if( !nav_info.pj_win_info.drawing_area )
		return;

	vol = 0;

	/*****************************************/
	/* Set Up The Navigator Viewing Matrices */
	/*****************************************/
	switch( proj_type )
	{
	   case C_NAV_PROJECTION:
		nav_set_viewing( proj_type, &nav_info, 0);
		break;
	   case C_PARC_FRONT_PROJECTION:	/* Done Per Volume */
	   case C_PARC_BACK_PROJECTION:
		break;
	}

	/*****************************************/
	/* Clear The Back ZBuffer & Frame Buffer */
	/*****************************************/
	nav_clear_buffers( proj_type );	

	/*********************************************/
	/* Set Up the navigator Lighting Environment */
	/*********************************************/
	nav_set_lighting( proj_type );

	/**********************************************/
	/* Set Up Some Extra Info Needed For Graphics */
	/**********************************************/
	nav_setup_extra_draw_info( &ed_info, proj_type, 1.0, 100.0 );

	/**********************************************************/
	/* Loop Through Volumes And Project Into Color & Z Buffer */
	/**********************************************************/
	for( vol=0; vol<world.num_volumes; vol++ )
	{
	   volume = world.volume[vol];

	   if( volume->visible )
	   {
	     /**********************************************/
	     /* Set Up Some Extra Info Needed For Graphics */
	     /**********************************************/
	     nav_setup_extra_draw_info( &ed_info, proj_type,
			nav_info.pj_win_info.near_plane[vol],
			nav_info.pj_win_info.far_plane[vol] );

	     switch( proj_type )
	     {
		case C_NAV_PROJECTION:
#ifdef C_X_GRAPHICS
nav_set_viewing( proj_type, &nav_info, vol );
#endif
			break;
		case C_PARC_FRONT_PROJECTION:
		case C_PARC_BACK_PROJECTION:
			/*****************************************/
			/* Set Up The Navigator Viewing Matrices */
			/*****************************************/
			nav_set_viewing( proj_type, &nav_info, vol );

	     		/*****************************************/
	     		/* Clear The Back ZBuffer & Frame Buffer */
	     		/*****************************************/
			nav_clear_buffers( proj_type );
	     }

	     /**********************************************/
	     /* Set Up The Color & Shading For This Volume */
	     /**********************************************/
	     nav_set_shading( proj_type, volume );

	     /* Mapping From Local To World For Each Volume */

	     C_copy_matrix( &(volume->ltow_units), &setup_matrix );
	     C_matrix_multiply( C_POST_MULTIPLY, 
			&setup_matrix, &(view.wtol_units) );
	     for( i=0; i<4; i++ )
	     for( j=0; j<4; j++ )
	     {
			ltow_mapping[i][j] = setup_matrix.matrix[j][i];

/***volume->ltow_units.matrix[j][i];****/
	     }

	     /* Setup Matrix and matrix multiplication */
	     C_Setup_Matrix(ed_info, ltow_mapping);

	     switch ( volume->data_type )
	     {
	       case C_SCALAR_DATA_8BIT:

	   	/* Set The Normal For Each Of the Six Bounding Planes */
		C_Load_Normal(n);

	   	if( volume->p_info )
	   	{

		  div = pow((2.0),(double)(volume->p_info->sub_level));
		  div_sq = div * div;

		  x_sub_dist = (volume->x_size_units)/div;
		  y_sub_dist = (volume->y_size_units)/div;
		  z_sub_dist = (volume->z_size_units)/div;

		  list_ptr = volume->p_info->sub_list;

		  /* Loop Through Every Subvolume And Project Outer Polygons */
		  while( list_ptr )
		  {
			/* Decode Subvolume Index Into X, Y, Z Subvolume Index*/
			sz = (int)( (list_ptr->index)/div_sq );
			temp  = list_ptr->index - (sz * div_sq);
			sy = (int)( temp/div );
			sx = (temp % (int)(div));

			/* Compute Subvolume Vertices */
			v[0][0]= v[3][0] = v[4][0] = v[7][0] = sx * x_sub_dist;
			v[0][1]= v[1][1] = v[4][1] = v[5][1] = sy * y_sub_dist;
			v[0][2]= v[1][2] = v[2][2] = v[3][2] = sz * z_sub_dist;

			v[1][0]= v[2][0]= v[5][0]= v[6][0]= v[0][0]+ x_sub_dist;
			v[2][1]= v[3][1]= v[6][1]= v[7][1]= v[0][1]+ y_sub_dist;
			v[4][2]= v[5][2]= v[6][2]= v[7][2]= v[0][2]+ z_sub_dist;
	
			/* Project The Negative Facing X Polygon */
			if( C_Is_Neg_X_Face(list_ptr->subnode_faces) ) 
			{
				C_Draw_Shaded_Rect(ed_info, 0,4,7,3,0);
			}

			/* Project The Positive Facing X Polygon */
                        if( C_Is_Pos_X_Face(list_ptr->subnode_faces) )
			{
				C_Draw_Shaded_Rect(ed_info, 1,1,2,6,5);
			}

			/* Project The Negative Facing Y Polygon */
			if( C_Is_Neg_Y_Face(list_ptr->subnode_faces) ) 
			{
				C_Draw_Shaded_Rect(ed_info, 2,0,1,5,4);
			}

			/* Project The Positive Facing Y Polygon */
			if( C_Is_Pos_Y_Face(list_ptr->subnode_faces) ) 
			{
				C_Draw_Shaded_Rect(ed_info, 3,3,7,6,2);
			}

			/* Project The Negative Facing Z Polygon */
			if( C_Is_Neg_Z_Face(list_ptr->subnode_faces) ) 
			{
				C_Draw_Shaded_Rect(ed_info, 4,0,3,2,1);
			}
			
			/* Project The Positive Facing Z Polygon */
			if( C_Is_Pos_Z_Face(list_ptr->subnode_faces) ) 
			{
				C_Draw_Shaded_Rect(ed_info, 5,4,5,6,7);
			}

			list_ptr = list_ptr->next;

		  } /* End Of While() */


	   	} /* End Of If() */

		break;

	      case C_GEOMETRIC_DATA:
		nav_project_geo_volume( ed_info, volume );
		break;
	    }

	    C_Pop_Matrix(ed_info, ltow_mapping);

	    /* Store The Zbuffer For The Volume */
	    switch( proj_type )
	    {
		case C_NAV_PROJECTION:
			break;
		case C_PARC_FRONT_PROJECTION:
		case C_PARC_BACK_PROJECTION:
			/****************************************/
			/* Get The Z Buffer For PARC Projection */
			/****************************************/
			nav_get_zbuffer( proj_type, vol );
	    }

	  } /* End Of Visibility If */
	} /* End Of For() */

	C_Flush_Graphics(ed_info);

	switch( proj_type )
	{
		case C_NAV_PROJECTION:
			/*************************************/
        		/* Swap Buffers For Double Buffering */
			/*************************************/

			C_Swap_Buffers(ed_info, buffer);

			break;
		case C_PARC_FRONT_PROJECTION:
		case C_PARC_BACK_PROJECTION:
			break;
	}

	/*******************************/
	/* Remove Lighting Definitions */
	/*******************************/
	nav_unset_lighting( proj_type );

	/******************************/
	/* Remove Shading Definitions */
	/******************************/
	nav_unset_shading( proj_type );
}


void nav_wireframe_draw( proj_type )
C_NavProjectionType	proj_type;
{
	int		i;
	int		j;
	int		vol;		/* Volume Loop Variable */
	int		bulb;		/* Light Loop Variable */
	C_Volume	*volume;	/* Pointer To Current Volume */
	C_Light		*light;		/* Pointer To Current Light  */
	float		v[8][3];	/* Vertices Of A 3D Rectangle */
	C_FPosition	clist[5];	/* Vertices Of A 3D Rectangle */
	C_FVector	x_vec;
	C_FVector	y_vec;
	C_FVector	z_vec;
	float		ltow_mapping[4][4]; 
	static int	buffer = 0;	/* Double Buffer Toggle Variable */
	float		view_width;
	float		view_height;
	C_ExtraDrawInfo	ed_info;
	C_Matrix	setup_matrix;

	extern C_View		view;
	extern C_NavInfo	nav_info;

	extern void	nav_set_viewing();
	extern void	nav_clear_buffers();
	extern void	nav_project_geo_volume();
	extern void	nav_get_zbuffer();
	extern void	nav_setup_extra_draw_info();

	/* This Routine Should Not Be Called For Projection Drawing! */
	switch( proj_type )
	{
	   case C_NAV_PROJECTION:
	   case C_PARC_FRONT_PROJECTION:
	   case C_PARC_BACK_PROJECTION:
		C_error_message("Internal Error: NAV_PJ_DRAW");
		return;
		break;
	   case C_NAV_WIREFRAME_KEY:
		C_error_message("Internal Error: NAV_WF_KEY_DRAW");
		return;
	}

	/*************************************************/
	/* Don't Draw Into Window If Not Already Created */
	/*************************************************/
	if( !nav_info.wf_win_info.drawing_area )
	{
		return;
	}

	vol = 0;

	/***************************************************/
	/* Set Up The Navigator Wireframe Viewing Matrices */
	/***************************************************/
	nav_set_viewing( C_NAV_WIREFRAME, &nav_info, -1 );

	/*****************************************/
	/* Clear The Back ZBuffer & Frame Buffer */
	/*****************************************/
	nav_clear_buffers( proj_type );

	/******************************/
	/* Set Up Various Line Styles */
	/******************************/
	C_Setup_Line_Styles();

	/**********************************************/
	/* Set Up Some Extra Info Needed For Graphics */
	/**********************************************/
	nav_setup_extra_draw_info( &ed_info, proj_type, 1.0, 100.0 );

	/********************************/
	/* Project The World Coord Sys  */
	/********************************/
	v[0][0] = v[0][1] = v[0][2] = 0.0;	/* Origin */
	v[1][1] = v[1][2] = 0.0; v[1][0] = 50.0;/* X Axis */
	v[2][0] = v[2][2] = 0.0; v[2][1] = 50.0;/* Y Axis */
	v[3][0] = v[3][1] = 0.0; v[3][2] = 50.0;/* Z Axis */

	/* Set The X Axis Line Color To Red */
	C_Set_Line_Color( ed_info, C_NAV_WF_RED );

	/* Draw The X Axis Line */
	C_Draw_Line( ed_info, 0, 1 );

	/* Set The Y Axis Line Color To Green */
	C_Set_Line_Color( ed_info, C_NAV_WF_GREEN );

	/* Draw The X Axis Line */
	C_Draw_Line( ed_info, 0, 2 );

	/* Set The Z Axis Line Color To Blue */
	C_Set_Line_Color( ed_info, C_NAV_WF_BLUE );

	/* Draw The X Axis Line */
	C_Draw_Line( ed_info, 0, 3 );

	/********************/
	/* Project The View */
	/********************/

	/* View Is Scaled Up 1 Times - Modify To Some Standard Number */
	if( view.fov == 0.0 )
	{			/* Parallel Projection */
		view_width = view.width_units;
		view_height = view.height_units;
	}
	else
	{			/* Perpsective Projection */
		view_width  = view.width_units  * C_PERSPECTIVE_VIEW_SCALE;
		view_height = view.height_units * C_PERSPECTIVE_VIEW_SCALE;
	}

	x_vec.x = (view_width * view.c_sys.x_axis.x);
	x_vec.y = (view_width * view.c_sys.x_axis.y);
	x_vec.z = (view_width * view.c_sys.x_axis.z);

	y_vec.x = (view_height * view.c_sys.y_axis.x);
	y_vec.y = (view_height * view.c_sys.y_axis.y);
	y_vec.z = (view_height * view.c_sys.y_axis.z);

	z_vec.x = (view_width * view.c_sys.z_axis.x);
	z_vec.y = (view_width * view.c_sys.z_axis.y);
	z_vec.z = (view_width * view.c_sys.z_axis.z);

	v[0][0] = view.c_sys.origin.x - (x_vec.x + y_vec.x)/2.0;
	v[0][1] = view.c_sys.origin.y - (x_vec.y + y_vec.y)/2.0;
	v[0][2] = view.c_sys.origin.z - (x_vec.z + y_vec.z)/2.0;

	v[1][0] = v[0][0] + x_vec.x;
	v[1][1] = v[0][1] + x_vec.y;
	v[1][2] = v[0][2] + x_vec.z;

	v[2][0] = v[1][0] + y_vec.x;
	v[2][1] = v[1][1] + y_vec.y;
	v[2][2] = v[1][2] + y_vec.z;

	v[3][0] = v[0][0] + y_vec.x;
	v[3][1] = v[0][1] + y_vec.y;
	v[3][2] = v[0][2] + y_vec.z;

	if( view.modifiable )
	{
		C_Set_Line_Color( ed_info, C_NAV_WF_PURPLE );
	}
	else
	{
		C_Set_Line_Color( ed_info, C_NAV_WF_GREY );
	}

	C_Draw_Line( ed_info, 0, 1 );
	C_Draw_Line( ed_info, 1, 2 );
	C_Draw_Line( ed_info, 2, 3 );
	C_Draw_Line( ed_info, 3, 0 );

	v[0][0] = view.c_sys.origin.x;
	v[0][1] = view.c_sys.origin.y;
	v[0][2] = view.c_sys.origin.z;

	v[1][0] = v[0][0] + x_vec.x/2.0;
	v[1][1] = v[0][1] + x_vec.y/2.0;
	v[1][2] = v[0][2] + x_vec.z/2.0;

	v[3][0] = v[0][0] + y_vec.x/2.0;
	v[3][1] = v[0][1] + y_vec.y/2.0;
	v[3][2] = v[0][2] + y_vec.z/2.0;

	v[4][0] = v[0][0] + z_vec.x/2.0;
	v[4][1] = v[0][1] + z_vec.y/2.0;
	v[4][2] = v[0][2] + z_vec.z/2.0;

	/* Set The X Axis Line Color To Red */
	C_Set_Line_Color( ed_info, C_NAV_WF_RED );

	/* Draw The X Axis Line */
	C_Draw_Line( ed_info, 0, 1 );

	/* Set The Y Axis Line Color To Green */
	C_Set_Line_Color( ed_info, C_NAV_WF_GREEN );

	/* Draw The Y Axis Line */
	C_Draw_Line( ed_info, 0, 3 );

	/* Set The Z Axis Line Color To Blue */
	C_Set_Line_Color( ed_info, C_NAV_WF_BLUE );

	/* Draw The Z Axis Line */
	C_Draw_Line( ed_info, 0, 4 );

	/************************************/
	/* Loop Through Volumes And Project */
	/************************************/
	for( vol=0; vol<world.num_volumes; vol++ )
	{
	   volume = world.volume[vol];

#ifdef C_X_GRAPHICS
nav_set_viewing( proj_type, &nav_info, vol );
#endif

	   /*****************************************/
	   /* Set Up The Line Style For This Volume */
	   /*****************************************/
	   if( volume->visible )
	   {
	   	C_Set_Line_Style( ed_info, C_NAV_SOLID_LINE );
	   }
	   else
	   {
	   	C_Set_Line_Style( ed_info, C_NAV_DASHED_LINE );
	   }

	   /***********************************************/
	   /* Mapping From Local To World For Each Volume */
	   /***********************************************/

	   C_copy_matrix( &(volume->ltow_units), &setup_matrix );
	   C_matrix_multiply( C_POST_MULTIPLY, 
		&setup_matrix, &(nav_info.wf_win_info.view.wtol_units) );
	   for( i=0; i<4; i++ )
	   for( j=0; j<4; j++ )
	   {
			ltow_mapping[i][j] = setup_matrix.matrix[j][i];

	   }

	   /* Setup Matrix and matrix multiplication */
	   C_Setup_Matrix(ed_info, ltow_mapping);

	   /* Set Volume Extent Vertices (Local Volume Coordinates) */
	   v[0][0]= v[3][0] = v[4][0] = v[7][0] = 0.0;
	   v[0][1]= v[1][1] = v[4][1] = v[5][1] = 0.0;
	   v[0][2]= v[1][2] = v[2][2] = v[3][2] = 0.0;

	   v[1][0]= v[2][0]= v[5][0]= v[6][0]= v[0][0] + volume->x_size_units;
	   v[2][1]= v[3][1]= v[6][1]= v[7][1]= v[0][1] + volume->y_size_units;
	   v[4][2]= v[5][2]= v[6][2]= v[7][2]= v[0][2] + volume->z_size_units;

	   /* Set The X Axis Line Color To Red */
	   C_Set_Line_Color( ed_info, C_NAV_WF_RED );

	   /* Draw The X Axis Line */
	   C_Draw_Line( ed_info, 0, 1 );

	   /* Set The Y Axis Line Color To Green */
	   C_Set_Line_Color( ed_info, C_NAV_WF_GREEN );

	   /* Draw The Y Axis Line */
	   C_Draw_Line( ed_info, 0, 3 );

	   /* Set The Z Axis Line Color To Blue */
	   C_Set_Line_Color( ed_info, C_NAV_WF_BLUE );

	   /* Draw The Z Axis Line */
	   C_Draw_Line( ed_info, 0, 4 );

	   if( volume->modifiable )
	   {
		C_Set_Line_Color( ed_info, C_NAV_WF_PURPLE );
	   }
	   else
	   {
		C_Set_Line_Color( ed_info, C_NAV_WF_GREY );
	   }

	   /* Project The Positive Facing X Rectangle */
	   C_Draw_Wireframe_Rect(ed_info, 1,2,6,5);

	   /* Project Additional Lines */
	   C_Draw_Line( ed_info, 2, 3 );
	   C_Draw_Line( ed_info, 6, 7 );
	   C_Draw_Line( ed_info, 4, 5 );
	   C_Draw_Line( ed_info, 3, 7 );
	   C_Draw_Line( ed_info, 7, 4 );

	   C_Pop_Matrix(ed_info, ltow_mapping);

	} /* End Of For() */

	/***********************************/
	/* Loop Through Lights And Project */
	/***********************************/
	for( bulb=0; bulb<world.num_lights; bulb++ )
	{
	   light = world.light[bulb];

	   /****************************************/
	   /* Set Up The Line Style For This Light */
	   /****************************************/
	   if( light->visible )
	   	C_Set_Line_Style( ed_info, C_NAV_SOLID_LINE );
	   else
	   	C_Set_Line_Style( ed_info, C_NAV_DASHED_LINE );

	   if( light->modifiable )
	   {
		C_Set_Line_Color( ed_info, C_NAV_WF_PURPLE );
	   }
	   else
	   {
		C_Set_Line_Color( ed_info, C_NAV_WF_GREY );
	   }

	   /* Get The Light World Coordinates */
	   switch( light->light_type )
	   {
		case C_POINT_LIGHT:
			v[0][0] = light->light.light_point->light_pos.x;
			v[0][1] = light->light.light_point->light_pos.y;
			v[0][2] = light->light.light_point->light_pos.z;
			break;
		case C_VOLUME_LIGHT:
			v[0][0] = light->light.light_volume->c_sys.origin.x;
			v[0][1] = light->light.light_volume->c_sys.origin.y;
			v[0][2] = light->light.light_volume->c_sys.origin.z;
	   }

	   /**********************************************/
	   /* Create A Jack For Displaying Light Sources */
	   /**********************************************/
	   v[1][0] = v[0][0] - 10.0;	/* X Line */
	   v[1][1] = v[0][1];
	   v[1][2] = v[0][2];

	   v[2][0] = v[0][0] + 10.0;
	   v[2][1] = v[0][1];
	   v[2][2] = v[0][2];

	   C_Draw_Line( ed_info, 1, 2 );

	   v[1][0] = v[0][0];		/* Y Line */
	   v[1][1] = v[0][1] - 10.0;
	   v[1][2] = v[0][2];

	   v[2][0] = v[0][0];
	   v[2][1] = v[0][1] + 10.0;
	   v[2][2] = v[0][2];

	   C_Draw_Line( ed_info, 1, 2 );

	   v[1][0] = v[0][0];		/* Z Line */
	   v[1][1] = v[0][1];
	   v[1][2] = v[0][2] - 10.0;

	   v[2][0] = v[0][0];
	   v[2][1] = v[0][1];
	   v[2][2] = v[0][2] + 10.0;

	   C_Draw_Line( ed_info, 1, 2 );
	}

	C_Flush_Graphics(ed_info);

	C_Swap_Buffers(ed_info, buffer);
}

void nav_wireframe_key_draw()
{
	extern void	nav_set_viewing();
	extern void	nav_clear_buffers();

	static int	buffer = 0;	/* Double Buffer Toggle Variable */
	float		v[8][3];	/* Vertices Of A 3D Rectangle */
	C_FPosition	clist[5];	/* Vertices Of A 3D Rectangle */
	int		i;
	C_ExtraDrawInfo	ed_info;

	extern C_NavInfo	nav_info;

return;
	/*************************************************/
	/* Don't Draw Into Window If Not Already Created */
	/*************************************************/
	if( !nav_info.wf_key_win_info.drawing_area )
	{
		return;
	}

	/***************************************************/
	/* Set Up The Navigator Wireframe Viewing Matrices */
	/***************************************************/
	nav_set_viewing( C_NAV_WIREFRAME_KEY, &nav_info, 0 );

	/*****************************************/
	/* Clear The Back ZBuffer & Frame Buffer */
	/*****************************************/
	nav_clear_buffers( C_NAV_WIREFRAME_KEY );

	/******************************/
	/* Set Up Various Line Styles */
	/******************************/
	C_Setup_Line_Styles();

	/* Set The Z Coordinates Of The Endpoints To Be Zero! */
	for( i=0; i<8; i++ )
		v[i][2] = 0.0;

	C_Set_Line_Color( ed_info, C_NAV_WF_WHITE );

	C_Draw_String( ed_info,  -50, 30, "Modifiable" );
	C_Draw_String( ed_info,   50, 30, "Unmodifiable" );

	C_Draw_String( ed_info, -140, 20, "Visible" );
	C_Draw_String( ed_info, -140,  0, "Invisible" );

	C_Draw_String( ed_info, -270, -20, "Coordinate" );
	C_Draw_String( ed_info, -270, -35, "  System  " );

	C_Draw_String( ed_info, -100, -28, "Light" );

	C_Draw_String( ed_info,   30, -28, "Volume" );

	C_Draw_String( ed_info,  170, -28, "View" );

	/************************************************/
	/*						*/
	/*		Show Line Styles 		*/
	/*						*/
	/************************************************/

	/**************************************/
	/* Draw A Visible And Modifiable Line */
	/**************************************/
	C_Set_Line_Color( ed_info, C_NAV_WF_PURPLE );
	C_Set_Line_Style( ed_info, C_NAV_SOLID_LINE );

	v[0][0] =  -50.0;
	v[0][1] =   20.0;
	v[1][0] =   40.0;
	v[1][1] =   20.0;

	C_Draw_Line( ed_info, 0, 1 );

	/*****************************************/
	/* Draw An Invisible And Modifiable Line */
	/*****************************************/
	C_Set_Line_Color( ed_info, C_NAV_WF_PURPLE );
	C_Set_Line_Style( ed_info, C_NAV_DASHED_LINE );

	v[0][0] =  -50.0;
	v[0][1] =    0.0;
	v[1][0] =   40.0;
	v[1][1] =    0.0;

	C_Draw_Line( ed_info, 0, 1 );

	/****************************************/
	/* Draw A Visible And Unmodifiable Line */
	/****************************************/
	C_Set_Line_Color( ed_info, C_NAV_WF_GREY );
	C_Set_Line_Style( ed_info, C_NAV_SOLID_LINE );

	v[0][0] =   50.0;
	v[0][1] =   20.0;
	v[1][0] =  140.0;
	v[1][1] =   20.0;

	C_Draw_Line( ed_info, 0, 1 );

	/*******************************************/
	/* Draw An Invisible And UnModifiable Line */
	/*******************************************/
	C_Set_Line_Color( ed_info, C_NAV_WF_GREY );
	C_Set_Line_Style( ed_info, C_NAV_DASHED_LINE );

	v[0][0] =   50.0;
	v[0][1] =    0.0;
	v[1][0] =  140.0;
	v[1][1] =    0.0;

	C_Draw_Line( ed_info, 0, 1 );

	/************************************************/
	/*						*/
	/*		Show Object Shapes 		*/
	/*						*/
	/************************************************/

	/****************************/
	/* Draw A Coordinate System */
	/****************************/
	C_Set_Line_Style( ed_info, C_NAV_SOLID_LINE );

	C_Set_Line_Color( ed_info, C_NAV_WF_RED );	/* X Axis */

	v[0][0] = -150.0;
	v[0][1] =  -35.0;
	v[1][0] = -125.0;
	v[1][1] =  -35.0;

	C_Draw_Line( ed_info, 0, 1 );
	C_Draw_String( ed_info, v[1][0], v[1][1], "X" );

	C_Set_Line_Color( ed_info, C_NAV_WF_GREEN );	/* Y Axis */

	v[0][0] = -150.0;
	v[0][1] =  -35.0;
	v[1][0] = -150.0;
	v[1][1] =  -10.0;

	C_Draw_Line( ed_info, 0, 1 );
	C_Draw_String( ed_info, (v[1][0]-10), (v[1][1]-10), "Y" );

	C_Set_Line_Color( ed_info, C_NAV_WF_BLUE );	/* Z Axis */

	v[0][0] = -150.0;
	v[0][1] =  -35.0;
	v[1][0] = -135.0;
	v[1][1] =  -20.0;

	C_Draw_Line( ed_info, 0, 1 );
	C_Draw_String( ed_info, v[1][0], v[1][1], "Z" );

	/***********************/
	/* Draw A Light Source */
	/***********************/
	C_Set_Line_Color( ed_info, C_NAV_WF_WHITE );

	v[0][0] = -25;
	v[0][1] = -25;
	v[1][0] =   0;
	v[1][1] = -25;

	C_Draw_Line( ed_info, 0, 1 );

	v[0][0] = -12;
	v[0][1] = -13;
	v[1][0] = -12;
	v[1][1] = -37;

	C_Draw_Line( ed_info, 0, 1 );

	v[0][0] = -19;
	v[0][1] = -32;
	v[1][0] =  -5;
	v[1][1] = -18;

	C_Draw_Line( ed_info, 0, 1 );

	/*****************/
	/* Draw A Volume */
	/*****************/
	C_Set_Line_Color( ed_info, C_NAV_WF_WHITE );

	v[0][0] = 100;
	v[0][1] = -32;

	v[1][0] = 112;
	v[1][1] = -32;

	v[2][0] = 112;
	v[2][1] = -20;

	v[3][0] = 100;
	v[3][1] = -20;

	for( i=4; i<8; i++ )
	{
		v[i][0] = v[i-4][0] + 5;
		v[i][1] = v[i-4][1] + 5;
	}

	C_Draw_Line( ed_info, 0, 1 );	/* Draw First Box */
	C_Draw_Line( ed_info, 1, 2 );
	C_Draw_Line( ed_info, 2, 3 );
	C_Draw_Line( ed_info, 3, 0 );

	C_Draw_Line( ed_info, 4, 5 );	/* Draw Second Box */
	C_Draw_Line( ed_info, 5, 6 );
	C_Draw_Line( ed_info, 6, 7 );
	C_Draw_Line( ed_info, 7, 4 );

	C_Draw_Line( ed_info, 0, 4 );	/* Connect The Boxes */
	C_Draw_Line( ed_info, 1, 5 );
	C_Draw_Line( ed_info, 2, 6 );
	C_Draw_Line( ed_info, 3, 7 );

	/***************/
	/* Draw A View */
	/***************/
	C_Set_Line_Color( ed_info, C_NAV_WF_WHITE );

	v[0][0] = 220;
	v[0][1] = -35;

	v[1][0] = 245;
	v[1][1] = -35;

	v[2][0] = 245;
	v[2][1] = -10;

	v[3][0] = 220;
	v[3][1] = -10;

	C_Draw_Line( ed_info, 0, 1 );
	C_Draw_Line( ed_info, 1, 2 );
	C_Draw_Line( ed_info, 2, 3 );
	C_Draw_Line( ed_info, 3, 0 );

	C_Flush_Graphics(ed_info);

	C_Swap_Buffers(ed_info, buffer);
}

