#ifndef RR_GRAPH2_H
#define RR_GRAPH2_H

/************** Global variables shared only by the rr_* modules. ************/

extern boolean *rr_edge_done;	/* [0..num_rr_nodes-1].  Used to keep track  *
				 * of whether or not a node has been put in  *
				 * an edge list yet.                         */

/******************* Subroutines exported by rr_graph2.c *********************/

struct s_ivec ***alloc_and_load_rr_node_indices(INP int nodes_per_chan,
						INP int nx,
						INP int ny,
						INOUTP int *index,
						INP t_seg_details *
						seg_details);

void free_rr_node_indices(INP t_ivec *** rr_node_indices);

int get_rr_node_index(int x,
		      int y,
		      t_rr_type rr_type,
		      int ptc,
		      t_ivec *** rr_node_indices);

void free_seg_details(t_seg_details * seg_details,
		      int nodes_per_chan);

t_seg_details *alloc_and_load_seg_details(INOUTP int *nodes_per_chan,
					  INP int max_len,
					  INP int num_seg_types,
					  INP t_segment_inf * segment_inf,
					  INP boolean use_full_seg_groups,
					  INP boolean is_global_graph,
					  INP enum e_directionality
					  directionality);

void dump_seg_details(t_seg_details * seg_details,
		      int nodes_per_chan,
		      char *fname);

int get_seg_start(INP t_seg_details * seg_details,
		  INP int itrack,
		  INP int chan_num,
		  INP int seg_num);

int get_seg_end(INP t_seg_details * seg_details,
		INP int itrack,
		INP int istart,
		INP int chan_num,
		INP int seg_max);

boolean is_cbox(INP int chan,
		INP int seg,
		INP int track,
		INP t_seg_details * seg_details,
		INP enum e_directionality directionality);

boolean is_sbox(INP int chan,
		INP int wire_seg,
		INP int sb_seg,
		INP int track,
		INP t_seg_details * seg_details,
		INP enum e_directionality directionality);

int get_bidir_opin_connections(INP int i,
			       INP int j,
			       INP int ipin,
			       INP struct s_linked_edge **edge_list,
			       INP int *****opin_to_track_map,
			       INP int Fc,
			       INP boolean * rr_edge_done,
			       INP t_ivec *** rr_node_indices,
			       INP t_seg_details * seg_details);

int get_unidir_opin_connections(INP int chan,
				INP int seg,
				INP int Fc,
				INP t_rr_type chan_type,
				INP t_seg_details * seg_details,
				INOUTP t_linked_edge ** edge_list_ptr,
				INOUTP int **Fc_ofs,
				INOUTP boolean * rr_edge_done,
				INP int max_len,
				INP int nodes_per_chan,
				INP t_ivec *** rr_node_indices,
				OUTP boolean * Fc_clipped);

int get_track_to_ipins(int seg,
		       int chan,
		       int track,
		       t_linked_edge ** edge_list_ptr,
		       t_ivec *** rr_node_indices,
		       struct s_ivec ****track_to_ipin_lookup,
		       t_seg_details * seg_details,
		       enum e_rr_type chan_type,
		       int chan_length,
		       int wire_to_ipin_switch,
		       enum e_directionality directionality);

int get_track_to_tracks(INP int from_chan,
			INP int from_seg,
			INP int from_track,
			INP t_rr_type from_type,
			INP int to_seg,
			INP t_rr_type to_type,
			INP int chan_len,
			INP int nodes_per_chan,
			INP int *opin_mux_size,
			INP int Fs_per_side,
			INP short *****sblock_pattern,
			INOUTP struct s_linked_edge **edge_list,
			INP t_seg_details * seg_details,
			INP enum e_directionality directionality,
			INP t_ivec *** rr_node_indices,
			INOUTP boolean * rr_edge_done,
			INP struct s_ivec ***switch_block_conn);

short *****alloc_sblock_pattern_lookup(INP int nx,
				       INP int ny,
				       INP int nodes_per_chan);
void free_sblock_pattern_lookup(INOUTP short *****sblock_pattern);
void load_sblock_pattern_lookup(INP int i,
				INP int j,
				INP int nodes_per_chan,
				INP t_seg_details * seg_details,
				INP int Fs,
				INP enum e_switch_block_type switch_block_type,
				INOUTP short *****sblock_pattern);

#endif

