/*
 *	covers.h
 *
 *	SnapPea constructs an n-sheeted cover of a given manifold as follows.
 *	First it creates n copies of a fundamental domain.  For convenience it
 *	uses the fundamental domain defined in choose_generators.c, which is
 *	a union of the triangulation's tetrahedra.  It assigns to each generator
 *	(defined in choose_generators.c) a permutation of the n sheets, and
 *	glues the sheets accordingly.  The product of the permutations
 *	surrounding an edge class must, of course, be the identity.
 *	Algebraically this is equivalent to finding transitive representations
 *	of the fundamental group into S(n), the symmetric group on n letters.
 *	("Transitive" means that the corresponding covering space is connected.)
 *	
 *	The algorithm for computing all connected n-sheeted covers of a
 *	given manifold consists of two parts:
 *
 *	(1)	Find all transitive representations of the manifold's fundamental
 *		group into S(n).  [cf. representations.c]
 *
 *	(2)	For each representation, construct the corresponding cover.
 *		[cover.c]
 *
 *	This naive algorithm can, of course, be simplified.  For example,
 *	representations which are conjugate by an element of S(n) yield
 *	equivalent covering spaces.  The file representations.c describes
 *	these optimizations.
 */

/*
 *	This file (covers.h) is intended solely for inclusion in SnapPea.h.
 */

/*
 *	A covering is "regular" iff for any two lifts of a point in the base
 *	manifold, there is a covering transformation taking one to the other.
 *	(An alternative definition is that the cover's fundamental group
 *	projects down to a normal subgroup of the base manifold's fundamental
 *	group.  For a proof that the two definitions are equivalent, please
 *	see page 362 of Rolfsen's Knots and Links.)
 *
 *	All cyclic coverings are regular.
 */
typedef int CoveringType;
enum
{
	unknown_cover,
	irregular_cover,
	regular_cover,
	cyclic_cover
};


typedef struct RepresentationIntoSn		RepresentationIntoSn;

typedef struct
{
	/*
	 *	How many face pairs does the fundamental domain
	 *	(defined in choose_generators.c) have?
	 */
	int						num_generators;

	/*
	 *	How many sheets does the covering have?
	 */
	int						num_sheets;

	/*
	 *	How many cusps (filled or unfilled) does the manifold have?
	 *	(For use with primitive_Dehn_image below.)
	 */
	int						num_cusps;

	/*
	 *	The representations themselves are kept on a NULL-terminated
	 *	singly linked list.
	 */
	RepresentationIntoSn	*list;

} RepresentationList;

struct RepresentationIntoSn
{
	/*
	 *	The permutation corresponding to generator i takes sheet j
	 *	of the cover to sheet image[i][j].
	 *
	 *	Note that the size of the image array depends on both the
	 *	num_generators and the num_sheets defined in the RepresentationList.
	 */
	int						**image;

	/*
	 *	The algorithm in construct_cover() in cover.c would like to know
	 *	the permutation assigned to each "primitive" Dehn filling curve.
	 *	If the Dehn filling coefficients are (a,b), the primitive Dehn
	 *	filling curve is defined to be (a/c, b/c), where c = gcd(a,b).
	 *	(When the Dehn filling coefficients are relative prime -- as is
	 *	always the case for a manifold -- the primitive Dehn filling curve
	 *	is just the Dehn filling curve itself, and the assigned permutation
	 *	is perforce the identity.  The concept of a primitive Dehn filling
	 *	curve is useful only for orbifolds.)
	 *
	 *	The permutation corresponding to the primitive Dehn filling curve
	 *	on cusp i takes sheet j of the cover to sheet Dehn_image[i][j].
	 *	(For unfilled cusps, the identity permutation is given instead.)
	 */
	int						**primitive_Dehn_image;

	/*
	 *	Is the cover defined by this representation irregular,
	 *	regular or cyclic?
	 */
	CoveringType			covering_type;

	/*
	 *	The RepresentationList keeps RepresentationIntoSn's on
	 *	a NULL-terminated singly linked list.
	 */
	RepresentationIntoSn	*next;
};


/*
 *	find_representations() takes a PermutationSubgroup parameter
 *	specifying the subgroup of the symmetric group S(n) into which
 *	the representations are to be found.
 */
typedef int PermutationSubgroup;
enum
{
	permutation_subgroup_Zn,	/* finds cyclic covers only */
	permutation_subgroup_Sn		/* finds all n-fold covers  */
	/* eventually an option for dihedral covers could be added */
};
