/*
 *	normal_surfaces.h
 */

#ifndef _normal_surfaces_
#define _normal_surfaces_

#include "SnapPea.h"

/*
 *	What is a normal surface?
 *
 *	Embedded surfaces will be described using normal surface theory.
 *	A given normal surface intersects each ideal tetrahedron in a (possibly
 *	empty) disjoint collection of topological squares and triangles.
 *	                 
 *							       /|\       
 *							      / | \      
 *							     /  |  \     
 *							    /   |   \    
 *							   /####|####\   
 *							  / ####|#### \  
 *							 /  ####|####  \ 
 *							 ---####|####--- 
 *							 \  ####|####  / 
 *							  \ ####|#### /  
 *							   \####|####/   
 *							    \   |   /    
 *							     \  |  /     
 *							      \ | /      
 *							       \|/       
 *							                 
 *	Each square cuts across the ideal tetrahedron as shown above, so as to
 *	separate the ideal tetrahedron's ideal vertices into two groups of two
 *	ideal vertices each.  There are three ways to do this, but a given ideal
 *	tetrahedron may contain squares of only one type, because the surface
 *	is embedded.
 *							                 
 *							       /|\       
 *							      / | \      
 *							     /  |  \     
 *							    /###|###\    
 *							   /  ##|##  \   
 *							  /    #|#    \  
 *							 /      |      \ 
 *							 -------|------- 
 *							 \      |      / 
 *							  \     |     /  
 *							   \    |    /   
 *							    \   |   /    
 *							     \  |  /     
 *							      \ | /      
 *							       \|/       
 *							                 
 *	Each triangle cuts across the ideal tetrahedron as shown above,
 *	so as to separate one ideal vertex from the other three.  There are
 *	four ways to do this, and triangles of all four types may be present
 *	simultaneously, because they don't intersect each other or the squares.
 *
 *
 *	How is a normal surface modelled in a Triangulation?
 *
 *	The squares and triangles are modelled in the Tetrahedron data structure
 *	as follows.  The field tet->parallel_edge contains the EdgeIndex
 *	(= 0, 1 or 2) of an edge which does not intersect the squares.  The
 *	opposite edge (= 5, 4 or 3, respectively) will lie on the opposite
 *	side of the squares, and all remaining edges will intersect the squares.
 *	The field tet->num_squares tells how many (parallel) squares lie in
 *	the Tetrahedron.  The fields tet->num_triangles[v] tell how many
 *	(parallel) triangles lie near the ideal vertex of VertexIndex v.
 *	When several surfaces must be available simultaneously, the parallel_edge,
 *	num_squares and num_triangles[] fields are copied to the corresponding
 *	fields of a NormalSurface structure (below).
 */

/*
 *	SnapPea.h contains an opaque typedef for a NormalSurfaceList.
 *	Here we make a typedef for a NormalSurface, so the NormalSurfaceList
 *	can refer to it.
 */
typedef struct NormalSurface	NormalSurface;


struct NormalSurfaceList
{
	/*
	 *	The normal surfaces all share the same underlying triangulation.
	 *	This triangulation is obtained from the user's triangulation
	 *	by filling in all closed cusps.
	 */
	Triangulation	*triangulation;
	
	/*
	 *	The NormalSurfaces are kept on an array.
	 */
	int				num_normal_surfaces;
	NormalSurface	*list;
};

struct NormalSurface
{
	/*
	 *	The UI should report the information on orientability, two-sidedness
	 *	and Euler characteristic to the user.  In the present implementation
	 *	of find_normal_surfaces(), is_connected will always be TRUE.
	 */
	Boolean		is_connected,
				is_orientable,
				is_two_sided;
	int			Euler_characteristic;
	
	/*
	 *	The following fields describe the normal surface.
	 *	In the i-th Tetrahedron of the Triangulation, the squares (if any)
	 *	are parallel to the edge of EdgeIndex parallel_edge[i]
	 *	(= 0, 1 or 2).  The number of such squares is num_squares[i].
	 *	The number of triangles at vertex v is num_triangles[i][v].
	 *	These fields record the values of the corresponding fields
	 *	in the Tetrahedron data structure.
	 */
	EdgeIndex	*parallel_edge;
	int			*num_squares,
				(*num_triangles)[4];

	/*
	 *	find_normal_surfaces() temporarily keeps the NormalSurfaces on
	 *	a NULL-terminated singly linked list.  As soon as it know how
	 *	many it has found, it transfers them to an array, and this
	 *	"next" field is ignored from then on.
	 */
	NormalSurface	*next;	/* used locally within find_normal_surfaces() */
};

#endif
