#include <stdio.h>
#include <string.h>
#include <math.h>
#include "util.h"
#include "vpr_types.h"
#include "vpr_utils.h"
#include "globals.h"
#include "graphics.h"
#include "path_delay.h"
#include "draw.h"
#include <assert.h>

/*************** Types local to this module *********************************/
#define MAX_BLOCK_COLOURS 5

enum e_draw_rr_toggle
{
    DRAW_NO_RR = 0,
    DRAW_ALL_RR,
    DRAW_ALL_BUT_BUFFERS_RR,
    DRAW_NODES_AND_SBOX_RR,
    DRAW_NODES_RR,
    DRAW_RR_TOGGLE_MAX
};

enum e_draw_net_type
{ ALL_NETS, HIGHLIGHTED };

enum e_edge_dir
{ FROM_X_TO_Y, FROM_Y_TO_X };	/* Chanx to chany or vice versa? */


/****************** Variables local to this module. *************************/

static boolean show_nets = FALSE;	/* Show nets of placement or routing? */

/* Controls drawing of routing resources on screen, if pic_on_screen is   *
 * ROUTING.                                                               */

/* Can toggle to DRAW_NO_RR;*/
static enum e_draw_rr_toggle draw_rr_toggle = DRAW_NO_RR;	/* UDSD by AY */

static enum e_route_type draw_route_type;

/* Controls if congestion is shown, when ROUTING is on screen. */

static boolean show_congestion = FALSE;

static boolean show_graphics;	/* Graphics enabled or not? */

static char default_message[BUFSIZE];	/* Default screen message on screen */

static int gr_automode;		/* Need user input after: 0: each t,   *
				 * 1: each place, 2: never             */

static enum pic_type pic_on_screen = NO_PICTURE;	/* What do I draw? */

static float *tile_x, *tile_y;

/* The left and bottom coordinates of each grid_tile in the FPGA.         *
 * tile_x[0..nx+1] and tile_y[0..ny+1].                         *
 * COORDINATE SYSTEM goes from (0,0) at the lower left corner to          *
 * (tile_x[nx+1]+tile_width, tile_y[ny+1]+tile_width) in the      *
 * upper right corner.                                                    */


static float tile_width, pin_size;

/* Drawn width (and height) of a grid_tile, and the half-width or half-height of *
 * a pin, respectiviely.  Set when init_draw_coords is called.         */

static enum color_types *net_color, *block_color;

/* Color in which each block and net should be drawn.      *
 * [0..num_nets-1] and [0..num_blocks-1], respectively.    */


/********************** Subroutines local to this module ********************/

static void toggle_nets(void (*drawscreen) (void));
static void toggle_rr(void (*drawscreen) (void));
static void toggle_congestion(void (*drawscreen) (void));
static void highlight_crit_path(void (*drawscreen_ptr) (void));

static void drawscreen(void);
static void redraw_screen(void);
static void drawplace(void);
static void drawnets(void);
static void drawroute(enum e_draw_net_type draw_net_type);
static void draw_congestion(void);

static void highlight_blocks(float x,
			     float y);
static void get_block_center(int bnum,
			     float *x,
			     float *y);
static void deselect_all(void);

static void draw_rr(void);
static void draw_rr_edges(int from_node);
static void draw_rr_pin(int inode,
			enum color_types color);
static void draw_rr_chanx(int inode,
			  int itrack);
static void draw_rr_chany(int inode,
			  int itrack);
static void get_rr_pin_draw_coords(int inode,
				   int iside,
				   int ioff,
				   float *xcen,
				   float *ycen);
static void draw_pin_to_chan_edge(int pin_node,
				  int chan_node);
static void draw_x(float x,
		   float y,
		   float size);
static void draw_chany_to_chany_edge(int from_node,
				     int from_track,
				     int to_node,
				     int to_track,
				     short switch_type);
static void draw_chanx_to_chanx_edge(int from_node,
				     int from_track,
				     int to_node,
				     int to_track,
				     short switch_type);
static void draw_chanx_to_chany_edge(int chanx_node,
				     int chanx_track,
				     int chany_node,
				     int chany_track,
				     enum e_edge_dir edge_dir,
				     short switch_type);
static int get_track_num(int inode,
			 int **chanx_track,
			 int **chany_track);
static void draw_rr_switch(float from_x,
			   float from_y,
			   float to_x,
			   float to_y,
			   boolean buffered);
static void draw_triangle_along_line(float xend,
				     float yend,	/* UDSD by AY */

				     float x1,
				     float x2,	/* UDSD by AY */

				     float y1,
				     float y2);	/* UDSD by AY */


/********************** Subroutine definitions ******************************/


void
set_graphics_state(boolean show_graphics_val,
		   int gr_automode_val,
		   enum e_route_type route_type)
{

    /* Sets the static show_graphics and gr_automode variables to the    *
     * desired values.  They control if graphics are enabled and, if so, *
     * how often the user is prompted for input.                         */

    show_graphics = show_graphics_val;
    gr_automode = gr_automode_val;
    draw_route_type = route_type;
}


void
update_screen(int priority,
	      char *msg,
	      enum pic_type pic_on_screen_val,
	      boolean crit_path_button_enabled)
{

    /* Updates the screen if the user has requested graphics.  The priority  *
     * value controls whether or not the Proceed button must be clicked to   *
     * continue.  Saves the pic_on_screen_val to allow pan and zoom redraws. */

    if(!show_graphics)		/* Graphics turned off */
	return;



    /* If it's the type of picture displayed has changed, set up the proper  *
     * buttons.                                                              */
    if(pic_on_screen != pic_on_screen_val)
	{
	    if(pic_on_screen_val == PLACEMENT && pic_on_screen == NO_PICTURE)
		{
		    create_button("Window", "Toggle Nets", toggle_nets);
		}
	    else if(pic_on_screen_val == ROUTING
		    && pic_on_screen == PLACEMENT)
		{
		    create_button("Toggle Nets", "Toggle RR", toggle_rr);
		    create_button("Toggle RR", "Congestion",
				  toggle_congestion);

		    if(crit_path_button_enabled)
			{
			    create_button("Congestion", "Crit. Path",
					  highlight_crit_path);
			}
		}
	    else if(pic_on_screen_val == PLACEMENT
		    && pic_on_screen == ROUTING)
		{
		    destroy_button("Toggle RR");
		    destroy_button("Congestion");

		    if(crit_path_button_enabled)
			{
			    destroy_button("Crit. Path");
			}
		}
	    else if(pic_on_screen_val == ROUTING
		    && pic_on_screen == NO_PICTURE)
		{
		    create_button("Window", "Toggle Nets", toggle_nets);
		    create_button("Toggle Nets", "Toggle RR", toggle_rr);
		    create_button("Toggle RR", "Congestion",
				  toggle_congestion);

		    if(crit_path_button_enabled)
			{
			    create_button("Congestion", "Crit. Path",
					  highlight_crit_path);
			}
		}
	}
    /* Save the main message. */

    my_strncpy(default_message, msg, BUFSIZE);

    pic_on_screen = pic_on_screen_val;
    update_message(msg);
    drawscreen();
    if(priority >= gr_automode)
	{
	    event_loop(highlight_blocks, drawscreen);
	}
    else
	{
	    flushinput();
	}
}


static void
drawscreen()
{

    /* This is the screen redrawing routine that event_loop assumes exists.  *
     * It erases whatever is on screen, then calls redraw_screen to redraw   *
     * it.                                                                   */

    clearscreen();
    redraw_screen();
}


static void
redraw_screen()
{

    /* The screen redrawing routine called by drawscreen and           *
     * highlight_blocks.  Call this routine instead of drawscreen if   *
     * you know you don't need to erase the current graphics, and want *
     * to avoid a screen "flash".                                      */

    setfontsize(20);		/* UDSD Modification by WMF */
    if(pic_on_screen == PLACEMENT)
	{
	    drawplace();
	    if(show_nets)
		{
		    drawnets();
		}
	}
    else
	{			/* ROUTING on screen */
	    drawplace();

	    if(show_nets)
		{
		    drawroute(ALL_NETS);
		}
	    else
		{
		    draw_rr();
		}

	    if(show_congestion)
		{
		    draw_congestion();
		}
	}
}


static void
toggle_nets(void (*drawscreen_ptr) (void))
{

    /* Enables/disables drawing of nets when a the user clicks on a button.    *
     * Also disables drawing of routing resources.  See graphics.c for details *
     * of how buttons work.                                                    */

    show_nets = !show_nets;
    draw_rr_toggle = DRAW_NO_RR;
    show_congestion = FALSE;

    update_message(default_message);
    drawscreen_ptr();
}


static void
toggle_rr(void (*drawscreen_ptr) (void))
{

    /* Cycles through the options for viewing the routing resources available   *
     * in an FPGA.  If a routing isn't on screen, the routing graph hasn't been *
     * built, and this routine doesn't switch the view. Otherwise, this routine *
     * switches to the routing resource view.  Clicking on the toggle cycles    *
     * through the options:  DRAW_NO_RR, DRAW_ALL_RR, DRAW_ALL_BUT_BUFFERS_RR,  *
     * DRAW_NODES_AND_SBOX_RR, and DRAW_NODES_RR.                               */

    draw_rr_toggle = (draw_rr_toggle + 1) % (DRAW_RR_TOGGLE_MAX);
    show_nets = FALSE;
    show_congestion = FALSE;

    update_message(default_message);
    drawscreen_ptr();
}


static void
toggle_congestion(void (*drawscreen_ptr) (void))
{

    /* Turns the congestion display on and off.   */
    char msg[BUFSIZE];
    int inode, num_congested;

    show_nets = FALSE;
    draw_rr_toggle = DRAW_NO_RR;
    show_congestion = !show_congestion;

    if(!show_congestion)
	{
	    update_message(default_message);
	}
    else
	{
	    num_congested = 0;
	    for(inode = 0; inode < num_rr_nodes; inode++)
		{
		    if(rr_node[inode].occ > rr_node[inode].capacity)
			{
			    num_congested++;
			}
		}

	    sprintf(msg, "%d routing resources are overused.", num_congested);
	    update_message(msg);
	}

    drawscreen_ptr();
}


static void
highlight_crit_path(void (*drawscreen_ptr) (void))
{

    /* Highlights all the blocks and nets on the critical path. */

    t_linked_int *critical_path_head, *critical_path_node;
    int inode, iblk, inet, num_nets_seen;
    static int nets_to_highlight = 1;
    char msg[BUFSIZE];

    if(nets_to_highlight == 0)
	{			/* Clear the display of all highlighting. */
	    nets_to_highlight = 1;
	    deselect_all();
	    update_message(default_message);
	    drawscreen_ptr();
	    return;
	}

    critical_path_head = allocate_and_load_critical_path();
    critical_path_node = critical_path_head;
    num_nets_seen = 0;

    while(critical_path_node != NULL)
	{
	    inode = critical_path_node->data;
	    get_tnode_block_and_output_net(inode, &iblk, &inet);

	    if(num_nets_seen == nets_to_highlight)
		{		/* Last block */
		    block_color[iblk] = MAGENTA;
		}
	    else if(num_nets_seen == nets_to_highlight - 1)
		{		/* 2nd last block */
		    block_color[iblk] = YELLOW;
		}
	    else if(num_nets_seen < nets_to_highlight)
		{		/* Earlier block */
		    block_color[iblk] = DARKGREEN;
		}

	    if(inet != OPEN)
		{
		    num_nets_seen++;

		    if(num_nets_seen < nets_to_highlight)
			{	/* First nets. */
			    net_color[inet] = DARKGREEN;
			}
		    else if(num_nets_seen == nets_to_highlight)
			{
			    net_color[inet] = CYAN;	/* Last (new) net. */
			}
		}

	    critical_path_node = critical_path_node->next;
	}

    if(nets_to_highlight == num_nets_seen)
	{
	    nets_to_highlight = 0;
	    sprintf(msg, "All %d nets on the critical path highlighted.",
		    num_nets_seen);
	}
    else
	{
	    sprintf(msg, "First %d nets on the critical path highlighted.",
		    nets_to_highlight);
	    nets_to_highlight++;
	}

    free_int_list(&critical_path_head);

    update_message(msg);
    drawscreen_ptr();
}


void
alloc_draw_structs(void)
{

    /* Allocate the structures needed to draw the placement and routing.  Set *
     * up the default colors for blocks and nets.                             */

    tile_x = (float *)my_malloc((nx + 2) * sizeof(float));
    tile_y = (float *)my_malloc((ny + 2) * sizeof(float));

    net_color = (enum color_types *)
	my_malloc(num_nets * sizeof(enum color_types));

    block_color = (enum color_types *)
	my_malloc(num_blocks * sizeof(enum color_types));

    deselect_all();		/* Set initial colors */
}


void
init_draw_coords(float width_val)
{

    /* Load the arrays containing the left and bottom coordinates of the clbs   *
     * forming the FPGA.  tile_width_val sets the width and height of a drawn    *
     * clb.                                                                     */

    int i;
    int j;

    if(!show_graphics)
	return;			/* -nodisp was selected. */

    tile_width = width_val;
    pin_size = 0.3;
    for(i = 0; i < num_types; ++i)
	{
	    pin_size =
		min(pin_size,
		    (tile_width / (4.0 * type_descriptors[i].num_pins)));
	}

    j = 0;
    for(i = 0; i < (nx + 1); i++)
	{
	    tile_x[i] = (i * tile_width) + j;
	    j += chan_width_y[i] + 1;	/* N wires need N+1 units of space */
	}
    tile_x[nx + 1] = ((nx + 1) * tile_width) + j;

    j = 0;
    for(i = 0; i < (ny + 1); ++i)
	{
	    tile_y[i] = (i * tile_width) + j;
	    j += chan_width_x[i] + 1;
	}
    tile_y[ny + 1] = ((ny + 1) * tile_width) + j;

    init_world(0.0,
	       tile_y[ny + 1] + tile_width, tile_x[nx + 1] + tile_width, 0.0);
}


static void
drawplace(void)
{

    /* Draws the blocks placed on the proper clbs.  Occupied blocks are darker colours *
     * while empty ones are lighter colours and have a dashed border.      */

    float sub_tile_step;
    float x1, y1, x2, y2;
    int i, j, k, bnum;
    int num_sub_tiles;
    int height;

    setlinewidth(0);

    for(i = 0; i <= (nx + 1); i++)
	{
	    for(j = 0; j <= (ny + 1); j++)
		{
		    /* Only the first block of a group should control drawing */
		    if(grid[i][j].offset > 0)
			continue;

		    /* Don't draw corners */
		    if(((i < 1) || (i > nx)) && ((j < 1) || (j > ny)))
			continue;

		    num_sub_tiles = grid[i][j].type->capacity;
		    sub_tile_step = tile_width / num_sub_tiles;
		    height = grid[i][j].type->height;

		    if(num_sub_tiles < 1)
			{
			    setcolor(BLACK);
			    setlinestyle(DASHED);
			    drawrect(tile_x[i], tile_y[j],
				     tile_x[i] + tile_width,
				     tile_y[j] + tile_width);
			    draw_x(tile_x[i] + (tile_width / 2),
				   tile_y[j] + (tile_width / 2),
				   (tile_width / 2));
			}

		    for(k = 0; k < num_sub_tiles; ++k)
			{
			    /* Graphics will look unusual for multiple height and capacity */
			    assert(height == 1 || num_sub_tiles == 1);
			    /* Get coords of current sub_tile */
			    if((i < 1) || (i > nx))
				{	/* left and right fringes */
				    x1 = tile_x[i];
				    y1 = tile_y[j] + (k * sub_tile_step);
				    x2 = x1 + tile_width;
				    y2 = y1 + sub_tile_step;
				}
			    else if((j < 1) || (j > ny))
				{	/* top and bottom fringes */
				    x1 = tile_x[i] + (k * sub_tile_step);
				    y1 = tile_y[j];
				    x2 = x1 + sub_tile_step;
				    y2 = y1 + tile_width;
				}
			    else
				{
				    assert(num_sub_tiles <= 1);	/* Need to change draw code to support */

				    x1 = tile_x[i];
				    y1 = tile_y[j];
				    x2 = x1 + tile_width;
				    y2 = tile_y[j + height - 1] + tile_width;
				}

			    /* Look at the tile at start of large block */
			    bnum = grid[i][j].blocks[k];


			    /* Draw background */
			    if(bnum != EMPTY)
				{
				    setcolor(block_color[bnum]);
				    fillrect(x1, y1, x2, y2);
				} else { 
					// colour empty blocks a particular colour depending on type
					if(grid[i][j].type->index < 3) {
						setcolor(WHITE);
					} else if(grid[i][j].type->index < 3 + MAX_BLOCK_COLOURS) {
						setcolor(BISQUE + grid[i][j].type->index - 3);
					} else {
						setcolor(BISQUE + MAX_BLOCK_COLOURS - 1);
					}
					fillrect(x1, y1, x2, y2);
				}

			    setcolor(BLACK);

			    setlinestyle((EMPTY == bnum) ? DASHED : SOLID);
			    drawrect(x1, y1, x2, y2);

			    /* Draw text if the space has parts of the netlist */
			    if(bnum != EMPTY)
				{
				    drawtext((x1 + x2) / 2.0, (y1 + y2) / 2.0,
					     block[bnum].name, tile_width);
				}

				/* Draw text for block type so that user knows what block */
				if(grid[i][j].offset == 0) {
					if(i > 0 && i <= nx && j > 0 && j <= ny) {
						drawtext((x1 + x2) / 2.0, y1 + (tile_width / 4.0),
							grid[i][j].type->name, tile_width);
					}
				}
			}
		}
	}
}


static void
drawnets(void)
{

    /* This routine draws the nets on the placement.  The nets have not *
     * yet been routed, so we just draw a chain showing a possible path *
     * for each net.  This gives some idea of future congestion.        */

    int inet, ipin, b1, b2;
    float x1, y1, x2, y2;

    setlinestyle(SOLID);
    setlinewidth(0);

    /* Draw the net as a star from the source to each sink. Draw from centers of *
     * blocks (or sub blocks in the case of IOs).                                */

    for(inet = 0; inet < num_nets; inet++)
	{
	    if(net[inet].is_global)
		continue;	/* Don't draw global nets. */

	    setcolor(net_color[inet]);
	    b1 = net[inet].node_block[0];	/* The DRIVER */
	    get_block_center(b1, &x1, &y1);

	    for(ipin = 1; ipin < (net[inet].num_sinks + 1); ipin++)
		{
		    b2 = net[inet].node_block[ipin];
		    get_block_center(b2, &x2, &y2);
		    drawline(x1, y1, x2, y2);

		    /* Uncomment to draw a chain instead of a star. */
		    /*      x1 = x2;  */
		    /*      y1 = y2;  */
		}
	}
}


static void
get_block_center(int bnum,
		 float *x,
		 float *y)
{

    /* This routine finds the center of block bnum in the current placement, *
     * and returns it in *x and *y.  This is used in routine shownets.       */

    int i, j, k;
    float sub_tile_step;

    i = block[bnum].x;
    j = block[bnum].y;
    k = block[bnum].z;

    sub_tile_step = tile_width / block[bnum].type->capacity;

    if((i < 1) || (i > nx))
	{			/* Left and right fringe */
	    *x = tile_x[i] + (sub_tile_step * (k + 0.5));
	}
    else
	{
	    *x = tile_x[i] + (tile_width / 2.0);
	}

    if((j < 1) || (j > ny))
	{			/* Top and bottom fringe */
	    *y = tile_y[j] + (sub_tile_step * (k + 0.5));
	}
    else
	{
	    *y = tile_y[j] + (tile_width / 2.0);
	}
}


static void
draw_congestion(void)
{

    /* Draws all the overused routing resources (i.e. congestion) in RED.   */

    int inode, itrack;

    setcolor(RED);
    setlinewidth(2);

    for(inode = 0; inode < num_rr_nodes; inode++)
	{
	    if(rr_node[inode].occ > rr_node[inode].capacity)
		{
		    switch (rr_node[inode].type)
			{
			case CHANX:
			    itrack = rr_node[inode].ptc_num;
			    draw_rr_chanx(inode, itrack);
			    break;

			case CHANY:
			    itrack = rr_node[inode].ptc_num;
			    draw_rr_chany(inode, itrack);
			    break;

			case IPIN:
			case OPIN:
			    draw_rr_pin(inode, RED);
			    break;
			}
		}
	}
}


void
draw_rr(void)
{

    /* Draws the routing resources that exist in the FPGA, if the user wants *
     * them drawn.                                                           */

    int inode, itrack;

    if(draw_rr_toggle == DRAW_NO_RR)
	{
	    setlinewidth(3);
	    drawroute(HIGHLIGHTED);
	    setlinewidth(0);
	    return;
	}

    setlinestyle(SOLID);
    setlinewidth(0);

    for(inode = 0; inode < num_rr_nodes; inode++)
	{
	    switch (rr_node[inode].type)
		{

		case SOURCE:
		case SINK:
		    break;	/* Don't draw. */

		case CHANX:
		    setcolor(BLACK);
		    itrack = rr_node[inode].ptc_num;
		    draw_rr_chanx(inode, itrack);
		    draw_rr_edges(inode);
		    break;

		case CHANY:
		    setcolor(BLACK);
		    itrack = rr_node[inode].ptc_num;
		    draw_rr_chany(inode, itrack);
		    draw_rr_edges(inode);
		    break;

		case IPIN:
		    draw_rr_pin(inode, BLUE);
		    break;

		case OPIN:
		    draw_rr_pin(inode, RED);
		    setcolor(RED);
		    draw_rr_edges(inode);
		    break;

		default:
		    printf
			("Error in draw_rr:  Unexpected rr_node type: %d.\n",
			 rr_node[inode].type);
		    exit(1);
		}
	}

    setlinewidth(3);
    drawroute(HIGHLIGHTED);
    setlinewidth(0);
}


static void
draw_rr_chanx(int inode,
	      int itrack)
{

    /* Draws an x-directed channel segment.                       */

    enum
    { BUFFSIZE = 80 };
    float x1, x2, y;
    float y1, y2;		/* UDSD by AY */
    int k;			/* UDSD by AY */
    char str[BUFFSIZE];

    /* Track 0 at bottom edge, closest to "owning" clb. */

    x1 = tile_x[rr_node[inode].xlow];
    x2 = tile_y[rr_node[inode].xhigh] + tile_width;
    y = tile_y[rr_node[inode].ylow] + tile_width + 1.0 + itrack;
    drawline(x1, y, x2, y);

    /* UDSD by AY Start */
    y1 = y - 0.25;
    y2 = y + 0.25;

    if(rr_node[inode].direction == INC_DIRECTION)
	{
	    setlinewidth(2);
	    setcolor(YELLOW);
	    drawline(x1, y1, x1, y2);	/* Draw a line at start of wire to indicate mux */

	    /* Mux balence numbers */
	    setcolor(BLACK);
	    sprintf(str, "%d", rr_node[inode].fan_in);
	    drawtext(x1, y, str, 5);

	    setcolor(BLACK);
	    setlinewidth(0);
	    draw_triangle_along_line(x2 - 0.15, y, x1, x2, y, y);

	    setcolor(LIGHTGREY);
	    /* TODO: this looks odd, why does it ignore final block? does this mean nothing appears with L=1 ? */
	    for(k = rr_node[inode].xlow; k < rr_node[inode].xhigh; k++)
		{
		    x2 = tile_x[k] + tile_width;
		    draw_triangle_along_line(x2 - 0.15, y, x1, x2, y, y);
		    x2 = tile_x[k + 1];
		    draw_triangle_along_line(x2 + 0.15, y, x1, x2, y, y);
		}
	    setcolor(BLACK);
	}
    else if(rr_node[inode].direction == DEC_DIRECTION)
	{
	    setlinewidth(2);
	    setcolor(YELLOW);
	    drawline(x2, y1, x2, y2);

	    /* Mux balance numbers */
	    setcolor(BLACK);
	    sprintf(str, "%d", rr_node[inode].fan_in);
	    drawtext(x2, y, str, 5);

	    setlinewidth(0);
	    draw_triangle_along_line(x1 + 0.15, y, x2, x1, y, y);
	    setcolor(LIGHTGREY);
	    for(k = rr_node[inode].xhigh; k > rr_node[inode].xlow; k--)
		{
		    x1 = tile_x[k];
		    draw_triangle_along_line(x1 + 0.15, y, x2, x1, y, y);
		    x1 = tile_x[k - 1] + tile_width;
		    draw_triangle_along_line(x1 - 0.15, y, x2, x1, y, y);
		}
	    setcolor(BLACK);
	}
    /* UDSD by AY End */
}


static void
draw_rr_chany(int inode,
	      int itrack)
{

    /* Draws a y-directed channel segment.                       */
    enum
    { BUFFSIZE = 80 };
    float x, y1, y2;
    float x1, x2;		/* UDSD by AY */
    int k;			/* UDSD by AY */
    char str[BUFFSIZE];

    /* Track 0 at left edge, closest to "owning" clb. */

    x = tile_x[rr_node[inode].xlow] + tile_width + 1. + itrack;
    y1 = tile_y[rr_node[inode].ylow];
    y2 = tile_y[rr_node[inode].yhigh] + tile_width;
    drawline(x, y1, x, y2);

    /* UDSD by AY Start */
    x1 = x - 0.25;
    x2 = x + 0.25;
    if(rr_node[inode].direction == INC_DIRECTION)
	{
	    setlinewidth(2);
	    setcolor(YELLOW);
	    drawline(x1, y1, x2, y1);

	    /* UDSD Modifications by WMF Begin */
	    setcolor(BLACK);
	    sprintf(str, "%d", rr_node[inode].fan_in);
	    drawtext(x, y1, str, 5);
	    setcolor(BLACK);
	    /* UDSD Modifications by WMF End */

	    setlinewidth(0);
	    draw_triangle_along_line(x, y2 - 0.15, x, x, y1, y2);
	    setcolor(LIGHTGREY);
	    for(k = rr_node[inode].ylow; k < rr_node[inode].yhigh; k++)
		{
		    y2 = tile_y[k] + tile_width;
		    draw_triangle_along_line(x, y2 - 0.15, x, x, y1, y2);
		    y2 = tile_y[k + 1];
		    draw_triangle_along_line(x, y2 + 0.15, x, x, y1, y2);
		}
	    setcolor(BLACK);
	}
    else if(rr_node[inode].direction == DEC_DIRECTION)
	{
	    setlinewidth(2);
	    setcolor(YELLOW);
	    drawline(x1, y2, x2, y2);

	    /* UDSD Modifications by WMF Begin */
	    setcolor(BLACK);
	    sprintf(str, "%d", rr_node[inode].fan_in);
	    drawtext(x, y2, str, 5);
	    setcolor(BLACK);
	    /* UDSD Modifications by WMF End */

	    setlinewidth(0);
	    draw_triangle_along_line(x, y1 + 0.15, x, x, y2, y1);
	    setcolor(LIGHTGREY);
	    for(k = rr_node[inode].yhigh; k > rr_node[inode].ylow; k--)
		{
		    y1 = tile_y[k];
		    draw_triangle_along_line(x, y1 + 0.15, x, x, y2, y1);
		    y1 = tile_y[k - 1] + tile_width;
		    draw_triangle_along_line(x, y1 - 0.15, x, x, y2, y1);
		}
	    setcolor(BLACK);
	}
    /* UDSD by AY End */
}


static void
draw_rr_edges(int inode)
{

    /* Draws all the edges that the user wants shown between inode and what it *
     * connects to.  inode is assumed to be a CHANX, CHANY, or OPIN.           */

    t_rr_type from_type, to_type;
    int iedge, to_node, from_ptc_num, to_ptc_num;
    short switch_type;

    from_type = rr_node[inode].type;

    if((draw_rr_toggle == DRAW_NODES_RR) ||
       (draw_rr_toggle == DRAW_NODES_AND_SBOX_RR && from_type == OPIN))
	{
	    return;		/* Nothing to draw. */
	}

    from_ptc_num = rr_node[inode].ptc_num;

    for(iedge = 0; iedge < rr_node[inode].num_edges; iedge++)
	{
	    to_node = rr_node[inode].edges[iedge];
	    to_type = rr_node[to_node].type;
	    to_ptc_num = rr_node[to_node].ptc_num;

	    switch (from_type)
		{

		case OPIN:
		    switch (to_type)
			{
			case CHANX:
			case CHANY:
			    setcolor(RED);
			    draw_pin_to_chan_edge(inode, to_node);
			    break;

			default:
			    printf
				("Error in draw_rr_edges:  node %d (type: %d) connects to \n"
				 "node %d (type: %d).\n", inode, from_type,
				 to_node, to_type);
			    exit(1);
			    break;
			}
		    break;

		case CHANX:	/* from_type */
		    switch (to_type)
			{
			case IPIN:
			    if(draw_rr_toggle == DRAW_NODES_AND_SBOX_RR)
				{
				    break;
				}

			    setcolor(BLUE);
			    draw_pin_to_chan_edge(to_node, inode);
			    break;

			case CHANX:
			    setcolor(DARKGREEN);
			    switch_type = rr_node[inode].switches[iedge];
			    draw_chanx_to_chanx_edge(inode, from_ptc_num,
						     to_node, to_ptc_num,
						     switch_type);
			    break;

			case CHANY:
			    setcolor(DARKGREEN);
			    switch_type = rr_node[inode].switches[iedge];
			    draw_chanx_to_chany_edge(inode, from_ptc_num,
						     to_node, to_ptc_num,
						     FROM_X_TO_Y,
						     switch_type);
			    break;

			default:
			    printf
				("Error in draw_rr_edges:  node %d (type: %d) connects to \n"
				 "node %d (type: %d).\n", inode, from_type,
				 to_node, to_type);
			    exit(1);
			    break;
			}
		    break;


		case CHANY:	/* from_type */
		    switch (to_type)
			{
			case IPIN:
			    if(draw_rr_toggle == DRAW_NODES_AND_SBOX_RR)
				{
				    break;
				}

			    setcolor(BLUE);
			    draw_pin_to_chan_edge(to_node, inode);
			    break;

			case CHANX:
			    setcolor(DARKGREEN);
			    switch_type = rr_node[inode].switches[iedge];
			    draw_chanx_to_chany_edge(to_node, to_ptc_num,
						     inode, from_ptc_num,
						     FROM_Y_TO_X,
						     switch_type);
			    break;

			case CHANY:
			    setcolor(DARKGREEN);
			    switch_type = rr_node[inode].switches[iedge];
			    draw_chany_to_chany_edge(inode, from_ptc_num,
						     to_node, to_ptc_num,
						     switch_type);
			    break;

			default:
			    printf
				("Error in draw_rr_edges:  node %d (type: %d) connects to \n"
				 "node %d (type: %d).\n", inode, from_type,
				 to_node, to_type);
			    exit(1);
			    break;
			}
		    break;

		default:	/* from_type */
		    printf
			("Error:  draw_rr_edges called with node %d of type %d.\n",
			 inode, from_type);
		    exit(1);
		    break;
		}
	}			/* End of for each edge loop */
}

static void
draw_x(float x,
       float y,
       float size)
{

    /* Draws an X centered at (x,y).  The width and height of the X are each    *
     * 2 * size.                                                                */

    drawline(x - size, y + size, x + size, y - size);
    drawline(x - size, y - size, x + size, y + size);
}


/* UDSD Modifications by WMF: Thank God Andy fixed this. */
static void
draw_chanx_to_chany_edge(int chanx_node,
			 int chanx_track,
			 int chany_node,
			 int chany_track,
			 enum e_edge_dir edge_dir,
			 short switch_type)
{

    /* Draws an edge (SBOX connection) between an x-directed channel and a    *
     * y-directed channel.                                                    */

    float x1, y1, x2, y2;
    int chanx_y, chany_x, chanx_xlow, chany_ylow;

    chanx_y = rr_node[chanx_node].ylow;
    chanx_xlow = rr_node[chanx_node].xlow;
    chany_x = rr_node[chany_node].xlow;
    chany_ylow = rr_node[chany_node].ylow;

    /* (x1,y1): point on CHANX segment, (x2,y2): point on CHANY segment. */

    y1 = tile_y[chanx_y] + tile_width + 1. + chanx_track;
    x2 = tile_x[chany_x] + tile_width + 1. + chany_track;

    if(chanx_xlow <= chany_x)
	{			/* Can draw connection going right */
	    x1 = tile_x[chany_x] + tile_width;
	    /* UDSD by AY Start */
	    if(rr_node[chanx_node].direction != BI_DIRECTION)
		{
		    if(edge_dir == FROM_X_TO_Y)
			{
			    if((chanx_track % 2) == 1)
				{	/* UDSD Modifications by WMF: If dec wire, then going left */
				    x1 = tile_x[chany_x + 1];
				}
			}
		}
	    /* UDSD by AY End */
	}
    else
	{			/* Must draw connection going left. */
	    x1 = tile_x[chanx_xlow];
	}

    if(chany_ylow <= chanx_y)
	{			/* Can draw connection going up. */
	    y2 = tile_y[chanx_y] + tile_width;
	    /* UDSD by AY Start */
	    if(rr_node[chany_node].direction != BI_DIRECTION)
		{
		    if(edge_dir == FROM_Y_TO_X)
			{
			    if((chany_track % 2) == 1)
				{	/* UDSD Modifications by WMF: If dec wire, then going down */
				    y2 = tile_y[chanx_y + 1];
				}
			}
		}
	    /* UDSD by AY End */
	}
    else
	{			/* Must draw connection going down. */
	    y2 = tile_y[chany_ylow];
	}

    drawline(x1, y1, x2, y2);

    if(draw_rr_toggle != DRAW_ALL_RR)
	return;

    if(edge_dir == FROM_X_TO_Y)
	draw_rr_switch(x1, y1, x2, y2, switch_inf[switch_type].buffered);
    else
	draw_rr_switch(x2, y2, x1, y1, switch_inf[switch_type].buffered);
}


static void
draw_chanx_to_chanx_edge(int from_node,
			 int from_track,
			 int to_node,
			 int to_track,
			 short switch_type)
{

/* Draws a connection between two x-channel segments.  Passing in the track *
 * numbers allows this routine to be used for both rr_graph and routing     *
 * drawing.                                                                 */

    float x1, x2, y1, y2;
    int from_y, to_y, from_xlow, to_xlow, from_xhigh, to_xhigh;

    from_y = rr_node[from_node].ylow;
    from_xlow = rr_node[from_node].xlow;
    from_xhigh = rr_node[from_node].xhigh;
    to_y = rr_node[to_node].ylow;
    to_xlow = rr_node[to_node].xlow;
    to_xhigh = rr_node[to_node].xhigh;

/* (x1, y1) point on from_node, (x2, y2) point on to_node. */

    y1 = tile_y[from_y] + tile_width + 1 + from_track;
    y2 = tile_y[to_y] + tile_width + 1 + to_track;


    if(to_xhigh < from_xlow)
	{			/* From right to left */
	    /* UDSD Note by WMF: could never happen for INC wires, unless U-turn. For DEC 
	     * wires this handles well */
	    x1 = tile_x[from_xlow];
	    x2 = tile_x[to_xhigh] + tile_width;
	}
    else if(to_xlow > from_xhigh)
	{			/* From left to right */
	    /* UDSD Note by WMF: could never happen for DEC wires, unless U-turn. For INC 
	     * wires this handles well */
	    x1 = tile_x[from_xhigh] + tile_width;
	    x2 = tile_x[to_xlow];
	}

/* Segments overlap in the channel.  Figure out best way to draw.  Have to  *
 * make sure the drawing is symmetric in the from rr and to rr so the edges *
 * will be drawn on top of each other for bidirectional connections.        */

    /* UDSD Modification by WMF Begin */
    else
	{
	    if(rr_node[to_node].direction != BI_DIRECTION)
		{
		    /* must connect to to_node's wire beginning at x2 */
		    if(to_track % 2 == 0)
			{	/* INC wire starts at leftmost edge */
			    assert(from_xlow < to_xlow);
			    x2 = tile_x[to_xlow];
			    /* since no U-turns from_track must be INC as well */
			    x1 = tile_x[to_xlow - 1] + tile_width;
			}
		    else
			{	/* DEC wire starts at rightmost edge */
			    assert(from_xhigh > to_xhigh);
			    x2 = tile_x[to_xhigh] + tile_width;
			    x1 = tile_x[to_xhigh + 1];
			}
		}
	    else
		{
		    if(to_xlow < from_xlow)
			{	/* Draw from left edge of one to other */
			    x1 = tile_x[from_xlow];
			    x2 = tile_x[from_xlow - 1] + tile_width;
			}
		    else if(from_xlow < to_xlow)
			{
			    x1 = tile_x[to_xlow - 1] + tile_width;
			    x2 = tile_x[to_xlow];
			}	/* The following then is executed when from_xlow == to_xlow */
		    else if(to_xhigh > from_xhigh)
			{	/* Draw from right edge of one to other */
			    x1 = tile_x[from_xhigh] + tile_width;
			    x2 = tile_x[from_xhigh + 1];
			}
		    else if(from_xhigh > to_xhigh)
			{
			    x1 = tile_x[to_xhigh + 1];
			    x2 = tile_x[to_xhigh] + tile_width;
			}
		    else
			{	/* Complete overlap: start and end both align. Draw outside the sbox */
			    x1 = tile_x[from_xlow];
			    x2 = tile_x[from_xlow] + tile_width;
			}
		}
	}
    /* UDSD Modification by WMF End */
    drawline(x1, y1, x2, y2);

    if(draw_rr_toggle == DRAW_ALL_RR)
	draw_rr_switch(x1, y1, x2, y2, switch_inf[switch_type].buffered);
}


static void
draw_chany_to_chany_edge(int from_node,
			 int from_track,
			 int to_node,
			 int to_track,
			 short switch_type)
{

/* Draws a connection between two y-channel segments.  Passing in the track *
 * numbers allows this routine to be used for both rr_graph and routing     *
 * drawing.                                                                 */

    float x1, x2, y1, y2;
    int from_x, to_x, from_ylow, to_ylow, from_yhigh, to_yhigh;

    from_x = rr_node[from_node].xlow;
    from_ylow = rr_node[from_node].ylow;
    from_yhigh = rr_node[from_node].yhigh;
    to_x = rr_node[to_node].xlow;
    to_ylow = rr_node[to_node].ylow;
    to_yhigh = rr_node[to_node].yhigh;

/* (x1, y1) point on from_node, (x2, y2) point on to_node. */

    x1 = tile_x[from_x] + tile_width + 1 + from_track;
    x2 = tile_x[to_x] + tile_width + 1 + to_track;

    if(to_yhigh < from_ylow)
	{			/* From upper to lower */
	    y1 = tile_y[from_ylow];
	    y2 = tile_y[to_yhigh] + tile_width;
	}
    else if(to_ylow > from_yhigh)
	{			/* From lower to upper */
	    y1 = tile_y[from_yhigh] + tile_width;
	    y2 = tile_y[to_ylow];
	}

/* Segments overlap in the channel.  Figure out best way to draw.  Have to  *
 * make sure the drawing is symmetric in the from rr and to rr so the edges *
 * will be drawn on top of each other for bidirectional connections.        */

    /* UDSD Modification by WMF Begin */
    else
	{
	    if(rr_node[to_node].direction != BI_DIRECTION)
		{
		    if(to_track % 2 == 0)
			{	/* INC wire starts at bottom edge */
			    assert(from_ylow < to_ylow);
			    y2 = tile_y[to_ylow];
			    /* since no U-turns from_track must be INC as well */
			    y1 = tile_y[to_ylow - 1] + tile_width;
			}
		    else
			{	/* DEC wire starts at top edge */
			    if(!(from_yhigh > to_yhigh))
				{
				    printf
					("from_yhigh (%d) !> to_yhigh (%d).\n",
					 from_yhigh, to_yhigh);
				    printf
					("from is (%d, %d) to (%d, %d) track %d.\n",
					 rr_node[from_node].xhigh,
					 rr_node[from_node].yhigh,
					 rr_node[from_node].xlow,
					 rr_node[from_node].ylow,
					 rr_node[from_node].ptc_num);
				    printf
					("to is (%d, %d) to (%d, %d) track %d.\n",
					 rr_node[to_node].xhigh,
					 rr_node[to_node].yhigh,
					 rr_node[to_node].xlow,
					 rr_node[to_node].ylow,
					 rr_node[to_node].ptc_num);
				    exit(1);
				}
			    y2 = tile_y[to_yhigh] + tile_width;
			    y1 = tile_y[to_yhigh + 1];
			}
		}
	    else
		{
		    if(to_ylow < from_ylow)
			{	/* Draw from bottom edge of one to other. */
			    y1 = tile_y[from_ylow];
			    y2 = tile_y[from_ylow - 1] + tile_width;
			}
		    else if(from_ylow < to_ylow)
			{
			    y1 = tile_y[to_ylow - 1] + tile_width;
			    y2 = tile_y[to_ylow];
			}
		    else if(to_yhigh > from_yhigh)
			{	/* Draw from top edge of one to other. */
			    y1 = tile_y[from_yhigh] + tile_width;
			    y2 = tile_y[from_yhigh + 1];
			}
		    else if(from_yhigh > to_yhigh)
			{
			    y1 = tile_y[to_yhigh + 1];
			    y2 = tile_y[to_yhigh] + tile_width;
			}
		    else
			{	/* Complete overlap: start and end both align. Draw outside the sbox */
			    y1 = tile_y[from_ylow];
			    y2 = tile_y[from_ylow] + tile_width;
			}
		}
	}
    /* UDSD Modification by WMF End */
    drawline(x1, y1, x2, y2);

    if(draw_rr_toggle == DRAW_ALL_RR)
	draw_rr_switch(x1, y1, x2, y2, switch_inf[switch_type].buffered);
}


static void
draw_rr_switch(float from_x,
	       float from_y,
	       float to_x,
	       float to_y,
	       boolean buffered)
{

/* Draws a buffer (triangle) or pass transistor (circle) on the edge        *
 * connecting from to to, depending on the status of buffered.  The drawing *
 * is closest to the from_node, since it reflects the switch type of from.  */

    const float switch_rad = 0.15;
    float magnitude, xcen, ycen, xdelta, ydelta, xbaseline, ybaseline;
    float xunit, yunit;
    t_point poly[3];

    xcen = from_x + (to_x - from_x) / 10.;
    ycen = from_y + (to_y - from_y) / 10.;

    if(!buffered)
	{			/* Draw a circle for a pass transistor */
	    drawarc(xcen, ycen, switch_rad, 0., 360.);
	}
    else
	{			/* Buffer */
	    xdelta = to_x - from_x;
	    ydelta = to_y - from_y;
	    magnitude = sqrt(xdelta * xdelta + ydelta * ydelta);
	    xunit = xdelta / magnitude;
	    yunit = ydelta / magnitude;
	    poly[0].x = xcen + xunit * switch_rad;
	    poly[0].y = ycen + yunit * switch_rad;
	    xbaseline = xcen - xunit * switch_rad;
	    ybaseline = ycen - yunit * switch_rad;

/* Recall: perpendicular vector to the unit vector along the switch (xv, yv) *
 * is (yv, -xv).                                                             */

	    poly[1].x = xbaseline + yunit * switch_rad;
	    poly[1].y = ybaseline - xunit * switch_rad;
	    poly[2].x = xbaseline - yunit * switch_rad;
	    poly[2].y = ybaseline + xunit * switch_rad;
	    fillpoly(poly, 3);
	}
}


static void
draw_rr_pin(int inode,
	    enum color_types color)
{

    /* Draws an IPIN or OPIN rr_node.  Note that the pin can appear on more    *
     * than one side of a clb.  Also note that this routine can change the     *
     * current color to BLACK.                                                 */

    int ipin, i, j, iside, iclass, ioff;
    float xcen, ycen;
    char str[BUFSIZE];
    t_type_ptr type;

    i = rr_node[inode].xlow;
    j = rr_node[inode].ylow;
    ipin = rr_node[inode].ptc_num;
    type = grid[i][j].type;
    ioff = grid[i][j].offset;

    setcolor(color);
    iclass = type->pin_class[ipin];
    /* TODO: This is where we can hide fringe physical pins and also identify globals (hide, color, show) */
    for(iside = 0; iside < 4; iside++)
	{
	    if(type->pinloc[grid[i][j].offset][iside][ipin])
		{		/* Pin exists on this side. */
		    get_rr_pin_draw_coords(inode, iside, ioff, &xcen, &ycen);
		    fillrect(xcen - pin_size, ycen - pin_size,
			     xcen + pin_size, ycen + pin_size);
		    sprintf(str, "%d", ipin);
		    setcolor(BLACK);
		    drawtext(xcen, ycen, str, 2 * pin_size);
		    setcolor(color);
		}
	}
}


static void
get_rr_pin_draw_coords(int inode,
		       int iside,
		       int ioff,
		       float *xcen,
		       float *ycen)
{

    /* Returns the coordinates at which the center of this pin should be drawn. *
     * inode gives the node number, and iside gives the side of the clb or pad  *
     * the physical pin is on.                                                  */

    int i, j, k, ipin, pins_per_sub_tile;
    float offset, xc, yc, step;
    t_type_ptr type;

    i = rr_node[inode].xlow;
    j = rr_node[inode].ylow + ioff;	/* Need correct tile of block */

    xc = tile_x[i];
    yc = tile_y[j];

    ipin = rr_node[inode].ptc_num;
    type = grid[i][j].type;
    pins_per_sub_tile = grid[i][j].type->num_pins / grid[i][j].type->capacity;
    k = ipin / pins_per_sub_tile;

    /* Since pins numbers go across all sub_tiles in a block in order
     * we can treat as a block box for this step */

    /* For each sub_tile we need and extra padding space */
    step = (float)(tile_width) / (float)(type->num_pins + type->capacity);
    offset = (ipin + k + 1) * step;

    switch (iside)
	{
	case LEFT:
	    yc += offset;
	    break;

	case RIGHT:
	    xc += tile_width;
	    yc += offset;
	    break;

	case BOTTOM:
	    xc += offset;
	    break;

	case TOP:
	    xc += offset;
	    yc += tile_width;
	    break;

	default:
	    printf("Error in get_rr_pin_draw_coords:  Unexpected iside %d.\n",
		   iside);
	    exit(1);
	    break;
	}

    *xcen = xc;
    *ycen = yc;
}


static void
drawroute(enum e_draw_net_type draw_net_type)
{

    /* Draws the nets in the positions fixed by the router.  If draw_net_type is *
     * ALL_NETS, draw all the nets.  If it is HIGHLIGHTED, draw only the nets    *
     * that are not coloured black (useful for drawing over the rr_graph).       */

    /* Next free track in each channel segment if routing is GLOBAL */

    static int **chanx_track = NULL;	/* [1..nx][0..ny] */
    static int **chany_track = NULL;	/* [0..nx][1..ny] */

    int inet, i, j, inode, prev_node, prev_track, itrack;
    short switch_type;
    struct s_trace *tptr;
    t_rr_type rr_type, prev_type;


    if(draw_route_type == GLOBAL)
	{
	    /* Allocate some temporary storage if it's not already available. */
	    if(chanx_track == NULL)
		{
		    chanx_track =
			(int **)alloc_matrix(1, nx, 0, ny, sizeof(int));
		}

	    if(chany_track == NULL)
		{
		    chany_track =
			(int **)alloc_matrix(0, nx, 1, ny, sizeof(int));
		}

	    for(i = 1; i <= nx; i++)
		for(j = 0; j <= ny; j++)
		    chanx_track[i][j] = (-1);

	    for(i = 0; i <= nx; i++)
		for(j = 1; j <= ny; j++)
		    chany_track[i][j] = (-1);
	}

    setlinestyle(SOLID);

/* Now draw each net, one by one.      */

    for(inet = 0; inet < num_nets; inet++)
	{
	    if(net[inet].is_global)	/* Don't draw global nets. */
		continue;

	    if(trace_head[inet] == NULL)	/* No routing.  Skip.  (Allows me to draw */
		continue;	/* partially complete routes).            */

	    if(draw_net_type == HIGHLIGHTED && net_color[inet] == BLACK)
		continue;

	    setcolor(net_color[inet]);
	    tptr = trace_head[inet];	/* SOURCE to start */
	    inode = tptr->index;
	    rr_type = rr_node[inode].type;


	    for(;;)
		{
		    prev_node = inode;
		    prev_type = rr_type;
		    switch_type = tptr->iswitch;
		    tptr = tptr->next;
		    inode = tptr->index;
		    rr_type = rr_node[inode].type;

		    switch (rr_type)
			{

			case OPIN:
			    draw_rr_pin(inode, net_color[inet]);
			    break;

			case IPIN:
			    draw_rr_pin(inode, net_color[inet]);
			    prev_track =
				get_track_num(prev_node, chanx_track,
					      chany_track);
			    draw_pin_to_chan_edge(inode, prev_node);
			    break;

			case CHANX:
			    if(draw_route_type == GLOBAL)
				chanx_track[rr_node[inode].
					    xlow][rr_node[inode].ylow]++;

			    itrack =
				get_track_num(inode, chanx_track,
					      chany_track);
			    draw_rr_chanx(inode, itrack);

			    switch (prev_type)
				{

				case CHANX:
				    prev_track =
					get_track_num(prev_node, chanx_track,
						      chany_track);
				    draw_chanx_to_chanx_edge(prev_node,
							     prev_track,
							     inode, itrack,
							     switch_type);
				    break;

				case CHANY:
				    prev_track =
					get_track_num(prev_node, chanx_track,
						      chany_track);
				    draw_chanx_to_chany_edge(inode, itrack,
							     prev_node,
							     prev_track,
							     FROM_Y_TO_X,
							     switch_type);
				    break;

				case OPIN:
				    draw_pin_to_chan_edge(prev_node, inode);
				    break;

				default:
				    printf
					("Error in drawroute:  Unexpected connection from an \n"
					 "rr_node of type %d to one of type %d.\n",
					 prev_type, rr_type);
				    exit(1);
				}

			    break;

			case CHANY:
			    if(draw_route_type == GLOBAL)
				chany_track[rr_node[inode].
					    xlow][rr_node[inode].ylow]++;

			    itrack =
				get_track_num(inode, chanx_track,
					      chany_track);
			    draw_rr_chany(inode, itrack);

			    switch (prev_type)
				{

				case CHANX:
				    prev_track =
					get_track_num(prev_node, chanx_track,
						      chany_track);
				    draw_chanx_to_chany_edge(prev_node,
							     prev_track,
							     inode, itrack,
							     FROM_X_TO_Y,
							     switch_type);
				    break;

				case CHANY:
				    prev_track =
					get_track_num(prev_node, chanx_track,
						      chany_track);
				    draw_chany_to_chany_edge(prev_node,
							     prev_track,
							     inode, itrack,
							     switch_type);
				    break;

				case OPIN:
				    draw_pin_to_chan_edge(prev_node, inode);

				    break;

				default:
				    printf
					("Error in drawroute:  Unexpected connection from an \n"
					 "rr_node of type %d to one of type %d.\n",
					 prev_type, rr_type);
				    exit(1);
				}

			    break;

			default:
			    break;

			}

		    if(rr_type == SINK)
			{	/* Skip the next segment */
			    tptr = tptr->next;
			    if(tptr == NULL)
				break;
			    inode = tptr->index;
			    rr_type = rr_node[inode].type;
			}

		}		/* End loop over traceback. */
	}			/* End for (each net) */
}


static int
get_track_num(int inode,
	      int **chanx_track,
	      int **chany_track)
{

/* Returns the track number of this routing resource node.   */

    int i, j;
    t_rr_type rr_type;

    if(draw_route_type == DETAILED)
	return (rr_node[inode].ptc_num);

/* GLOBAL route stuff below. */

    rr_type = rr_node[inode].type;
    i = rr_node[inode].xlow;	/* NB: Global rr graphs must have only unit */
    j = rr_node[inode].ylow;	/* length channel segments.                 */

    switch (rr_type)
	{
	case CHANX:
	    return (chanx_track[i][j]);

	case CHANY:
	    return (chany_track[i][j]);

	default:
	    printf
		("Error in get_track_num:  unexpected node type %d for node %d."
		 "\n", rr_type, inode);
	    exit(1);
	}
}


static void
highlight_blocks(float x,
		 float y)
{

    /* This routine is called when the user clicks in the graphics area. *
     * It determines if a clb was clicked on.  If one was, it is         *
     * highlighted in green, it's fanin nets and clbs are highlighted in *
     * blue and it's fanout is highlighted in red.  If no clb was        *
     * clicked on (user clicked on white space) any old highlighting is  *
     * removed.  Note that even though global nets are not drawn, their  *
     * fanins and fanouts are highlighted when you click on a block      *
     * attached to them.                                                 */

    int i, j, k, hit, bnum, ipin, netnum, fanblk;
    int iclass;
    float io_step;
    t_type_ptr type;
    char msg[BUFSIZE];
	
    deselect_all();

    hit = 0;
    for(i = 0; i <= (nx + 1) && !hit; i++)
	{
	    if(x <= tile_x[i] + tile_width)
		{
			if(x >= tile_x[i]){
			    for(j = 0; j <= (ny + 1) && !hit; j++)
				{
					if(grid[i][j].offset != 0)
						continue;
					type = grid[i][j].type;
					if(y <= tile_y[j + type->height - 1] + tile_width)
					{
						if(y >= tile_y[j])
							hit = 1;
					}
				}

			}
		}
	}
	i--;
	j--;
	
    if(!hit)
	{
	    update_message(default_message);
	    drawscreen();
	    return;
	}
    type = grid[i][j].type;
    hit = 0;

    if(EMPTY_TYPE == type)
	{
	    update_message(default_message);
	    drawscreen();
	    return;
	}

    /* The user selected the clb at location (i,j). */
    io_step = tile_width / type->capacity;

    if((i < 1) || (i > nx))	/* Vertical columns of IOs */
	k = (int)((y - tile_y[j]) / io_step);
    else
	k = (int)((x - tile_x[i]) / io_step);

    assert(k < type->capacity);
    if(grid[i][j].blocks[k] == EMPTY)
	{
	    update_message(default_message);
	    drawscreen();
	    return;
	}
    bnum = grid[i][j].blocks[k];

    /* Highlight fanin and fanout. */

    for(k = 0; k < type->num_pins; k++)
	{			/* Each pin on a FB */
	    netnum = block[bnum].nets[k];

	    if(netnum == OPEN)
		continue;

	    iclass = type->pin_class[k];

	    if(type->class_inf[iclass].type == DRIVER)
		{		/* Fanout */
		    net_color[netnum] = RED;
		    for(ipin = 1; ipin <= net[netnum].num_sinks; ipin++)
			{
			    fanblk = net[netnum].node_block[ipin];
			    block_color[fanblk] = RED;
			}
		}
	    else
		{		/* This net is fanin to the block. */
		    net_color[netnum] = BLUE;
		    fanblk = net[netnum].node_block[0];	/* DRIVER to net */
		    block_color[fanblk] = BLUE;
		}
	}

    block_color[bnum] = GREEN;	/* Selected block. */

    sprintf(msg, "Block %d (%s) at (%d, %d) selected.", bnum,
	    block[bnum].name, i, j);
    update_message(msg);
    drawscreen();		/* Need to erase screen. */
}


static void
deselect_all(void)
{
    /* Sets the color of all clbs and nets to the default.  */

    int i;

    /* Create some colour highlighting */
    for(i = 0; i < num_blocks; i++) {
		if(block[i].type->index < 3) {
			block_color[i] = LIGHTGREY;
		} else if(block[i].type->index < 3 + MAX_BLOCK_COLOURS) {
			block_color[i] = BISQUE + MAX_BLOCK_COLOURS + block[i].type->index - 3;
		} else {
			block_color[i] = BISQUE + 2 * MAX_BLOCK_COLOURS - 1;
		}
	}

    for(i = 0; i < num_nets; i++)
		net_color[i] = BLACK;
}


/* UDSD by AY Start */
static void
draw_triangle_along_line(float xend,
			 float yend,
			 float x1,
			 float x2,
			 float y1,
			 float y2)
{
    float switch_rad = 0.15;
    float xdelta, ydelta;
    float magnitude;
    float xunit, yunit;
    float xbaseline, ybaseline;
    t_point poly[3];

    xdelta = x2 - x1;
    ydelta = y2 - y1;
    magnitude = sqrt(xdelta * xdelta + ydelta * ydelta);
    xunit = xdelta / magnitude;
    yunit = ydelta / magnitude;

    poly[0].x = xend + xunit * switch_rad;
    poly[0].y = yend + yunit * switch_rad;
    xbaseline = xend - xunit * switch_rad;
    ybaseline = yend - yunit * switch_rad;
    poly[1].x = xbaseline + yunit * switch_rad;
    poly[1].y = ybaseline - xunit * switch_rad;
    poly[2].x = xbaseline - yunit * switch_rad;
    poly[2].y = ybaseline + xunit * switch_rad;

    fillpoly(poly, 3);
}


static void
draw_pin_to_chan_edge(int pin_node,
		      int chan_node)
{

/* This routine draws an edge from the pin_node to the chan_node (CHANX or   *
 * CHANY).  The connection is made to the nearest end of the track instead   *
 * of perpundicular to the track to symbolize a single-drive connection.     *
 * If mark_conn is TRUE, draw a box where the pin connects to the track      *
 * (useful for drawing  the rr graph)                                        */

/* TODO: Fix this for global routing, currently for detailed only */

    t_rr_type chan_type;
    int grid_x, grid_y, pin_num, chan_xlow, chan_ylow, ioff, height;
    float x1, x2, y1, y2;
    int start, end, i;
    int itrack;
    float xend, yend;
    float draw_pin_off;
    enum e_direction direction;
    enum e_side iside;
    t_type_ptr type;

    direction = rr_node[chan_node].direction;
    grid_x = rr_node[pin_node].xlow;
    grid_y = rr_node[pin_node].ylow;
    pin_num = rr_node[pin_node].ptc_num;
    chan_type = rr_node[chan_node].type;
    itrack = rr_node[chan_node].ptc_num;
    type = grid[grid_x][grid_y].type;

    ioff = grid[grid_x][grid_y].offset;
    /* large block begins at primary tile (offset == 0) */
    grid_y = grid_y - ioff;
    height = grid[grid_x][grid_y].type->height;
    chan_ylow = rr_node[chan_node].ylow;
    chan_xlow = rr_node[chan_node].xlow;
    start = -1;
    end = -1;


    switch (chan_type)
	{

	case CHANX:
	    start = rr_node[chan_node].xlow;
	    end = rr_node[chan_node].xhigh;
	    if(is_opin(pin_num, type))
		{
		    if(direction == INC_DIRECTION)
			{
			    end = rr_node[chan_node].xlow;
			}
		    else if(direction == DEC_DIRECTION)
			{
			    start = rr_node[chan_node].xhigh;
			}
		}

	    start = max(start, grid_x);
	    end = min(end, grid_x);	/* Width is 1 always */
	    assert(end >= start);	/* Make sure we are nearby */

	    if((grid_y + height - 1) == chan_ylow)
		{
		    iside = TOP;
		    ioff = height - 1;
		    draw_pin_off = pin_size;
		}
	    else
		{
		    assert((grid_y - 1) == chan_ylow);

		    iside = BOTTOM;
		    ioff = 0;
		    draw_pin_off = -pin_size;
		}
	    assert(grid[grid_x][grid_y].type->pinloc[ioff][iside][pin_num]);

	    get_rr_pin_draw_coords(pin_node, iside, ioff, &x1, &y1);
	    y1 += draw_pin_off;

	    y2 = tile_y[rr_node[chan_node].ylow] + tile_width + 1. + itrack;
	    x2 = x1;
	    if(is_opin(pin_num, type))
		{
		    if(direction == INC_DIRECTION)
			{
			    x2 = tile_x[rr_node[chan_node].xlow];
			}
		    else if(direction == DEC_DIRECTION)
			{
			    x2 = tile_x[rr_node[chan_node].xhigh] +
				tile_width;
			}
		}
	    break;

	case CHANY:
	    start = rr_node[chan_node].ylow;
	    end = rr_node[chan_node].yhigh;
	    if(is_opin(pin_num, type))
		{
		    if(direction == INC_DIRECTION)
			{
			    end = rr_node[chan_node].ylow;
			}
		    else if(direction == DEC_DIRECTION)
			{
			    start = rr_node[chan_node].yhigh;
			}
		}

	    start = max(start, grid_y);
	    end = min(end, (grid_y + height - 1));	/* Width is 1 always */
	    assert(end >= start);	/* Make sure we are nearby */

	    if((grid_x) == chan_xlow)
		{
		    iside = RIGHT;
		    draw_pin_off = pin_size;
		}
	    else
		{
		    assert((grid_x - 1) == chan_xlow);
		    iside = LEFT;
		    draw_pin_off = -pin_size;
		}
	    for(i = start; i <= end; i++)
		{
		    ioff = i - grid_y;
		    assert(ioff >= 0 && ioff < type->height);
		    /* Once we find the location, break out, this will leave ioff pointing
		     * to the correct offset.  If an offset is not found, the assertion after
		     * this will fail.  With the correct routing graph, the assertion will not
		     * be triggered.  This also takes care of connecting a wire once to multiple
		     * physical pins on the same side. */
		    if(grid[grid_x][grid_y].type->
		       pinloc[ioff][iside][pin_num])
			{
			    break;
			}
		}
	    assert(grid[grid_x][grid_y].type->pinloc[ioff][iside][pin_num]);

	    get_rr_pin_draw_coords(pin_node, iside, ioff, &x1, &y1);
	    x1 += draw_pin_off;

	    x2 = tile_x[chan_xlow] + tile_width + 1 + itrack;
	    y2 = y1;
	    if(is_opin(pin_num, type))
		{
		    if(direction == INC_DIRECTION)
			{
			    y2 = tile_y[rr_node[chan_node].ylow];
			}
		    else if(direction == DEC_DIRECTION)
			{
			    y2 = tile_y[rr_node[chan_node].yhigh] +
				tile_width;
			}
		}
	    break;

	default:
	    printf
		("Error in draw_pin_to_chan_edge:  invalid channel node %d.\n",
		 chan_node);
	    exit(1);
	}

    drawline(x1, y1, x2, y2);
    if(direction == BI_DIRECTION || !is_opin(pin_num, type))
	{
	    draw_x(x2, y2, 0.7 * pin_size);
	}
    else
	{
	    xend = x2 + (x1 - x2) / 10.;
	    yend = y2 + (y1 - y2) / 10.;
	    draw_triangle_along_line(xend, yend, x1, x2, y1, y2);
	}
}

/* UDSD by AY End */
