/*********************************** Top-level Summary *************************************
 This is VPR's main graphics application program. The program interacts with graphics.c, 
 which provides an API for displaying graphics on both X11 and Win32. The most important
 subroutine in this file is drawscreen(), which is a callback function that X11 or Win32
 will call whenever the screen needs to be updated. Then, drawscreen() will decide what 
 drawing subroutines to call depending on whether PLACEMENT or ROUTING is shown on screen 
 and whether any of the menu buttons has been triggered. As a note, looks into draw_global.c
 for understanding the data structures associated with drawing.
 
 Authors: Vaughn Betz, Long Yu (Mike) Wang
 Last updated: August 2013
 */

#include <cstdio>
#include <cfloat>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <sstream>
#include <array>
using namespace std;

#include "vtr_assert.h"
#include "vtr_matrix.h"
#include "vtr_ndoffsetmatrix.h"
#include "vtr_memory.h"
#include "vtr_log.h"
#include "vtr_color_map.h"

#include "vpr_utils.h"
#include "vpr_error.h"

#include "globals.h"
#include "graphics.h"
#include "path_delay.h"
#include "draw.h"
#include "read_xml_arch_file.h"
#include "draw_global.h"
#include "intra_logic_block.h"
#include "atom_netlist.h"
#include "tatum/report/TimingPathCollector.hpp"
#include "hsl.h"

#ifdef WIN32 /* For runtime tracking in WIN32. The clock() function defined in time.h will *
			  * track CPU runtime.														   */
#include <time.h>
#else /* For X11. The clock() function in time.h will not output correct time difference   *
	   * for X11, because the graphics is processed by the Xserver rather than local CPU,  *
	   * which means tracking CPU time will not be the same as the actual wall clock time. *
	   * Thus, so use gettimeofday() in sys/time.h to track actual calendar time.          */
#include <sys/time.h>
#endif

#include "rr_graph.h"

/****************************** Define Macros *******************************/

#define DEFAULT_RR_NODE_COLOR BLACK
//#define TIME_DRAWSCREEN /* Enable if want to track runtime for drawscreen() */

//The arrow head position for turning/straight-thru connections in a switch box
constexpr float SB_EDGE_TURN_ARROW_POSITION = 0.2;
constexpr float SB_EDGE_STRAIGHT_ARROW_POSITION = 0.95;

constexpr float EMPTY_BLOCK_LIGHTEN_FACTOR = 0.10;

//Kelly's maximum contrast colors are selected to be easily distinguishable as described in:
//  Kenneth Kelly, "Twenty-Two Colors of Maximum Contrast", Color Eng. 3(6), 1943
//We use these to highlight a relatively small number of things (e.g. stages in a critical path, 
//a subset of selected net) where it is important for them to be visually distinct.
const std::vector<t_color> kelly_max_contrast_colors = {
    //t_color(242, 243, 244), //white: skip white since it doesn't contrast well with VPR's light background
    t_color( 34,  34,  34), //black
    t_color(243, 195,   0), //yellow
    t_color(135,  86, 146), //purple
    t_color(243, 132,   0), //orange
    t_color(161, 202, 241), //light blue
    t_color(190,   0,  50), //red
    t_color(194, 178, 128), //buf
    t_color(132, 132, 130), //gray
    t_color(  0, 136,  86), //green
    t_color(230, 143, 172), //purplish pink
    t_color(  0, 103, 165), //blue
    t_color(249, 147, 121), //yellowish pink
    t_color( 96,  78, 151), //violet
    t_color(246, 166,   0), //orange yellow
    t_color(179,  68, 108), //purplish red
    t_color(220, 211,   0), //greenish yellow
    t_color(136,  45,  23), //redish brown
    t_color(141, 182,   0), //yellow green
    t_color(101,  69,  34), //yellowish brown
    t_color(226,  88,  34), //reddish orange
    t_color( 43,  61,  38)  //olive green
};

//The colours used to draw block types
const std::vector<color_types> block_type_colors = {
    //This first set of colours is somewhat curated to yield
    //a nice colour pallette
    BISQUE, //EMPTY type is usually the type with index 0, so this colour
            //usually unused
    LIGHTGREY,
    LIGHTSKYBLUE,
    THISTLE,
    KHAKI,
    CORAL,
    TURQUOISE,
    MEDIUMPURPLE,
    DARKSLATEBLUE,
    DARKKHAKI,
    LIGHTMEDIUMBLUE,
    SADDLEBROWN,
    FIREBRICK,
    LIMEGREEN,
    PLUM,

    //However, if we have lots of block types we just assign arbitrary HTML 
    //colours. Note that these are shuffled (instead of in alphabetical order)
    //since some colours which are alphabetically close are also close in 
    //shade (making them difficult to distinguish)
    DARKGREEN,
    PALEVIOLETRED,
    BLUE,
    FORESTGREEN,
    WHEAT,
    GOLD,
    MOCCASIN,
    MEDIUMORCHID,
    SKYBLUE,
    WHITESMOKE,
    LIME,
    MEDIUMSLATEBLUE,
    TOMATO,
    CYAN,
    OLIVE,
    LIGHTGRAY,
    STEELBLUE,
    LIGHTCORAL,
    IVORY,
    MEDIUMVIOLETRED,
    SNOW,
    DARKGRAY,
    GREY,
    GRAY,
    YELLOW,
    REBECCAPURPLE,
    DARKCYAN,
    MIDNIGHTBLUE,
    ROSYBROWN,
    CORNSILK,
    NAVAJOWHITE,
    BLANCHEDALMOND,
    ORCHID,
    LIGHTGOLDENRODYELLOW,
    MAROON,
    GREENYELLOW,
    SILVER,
    PALEGOLDENROD,
    LAWNGREEN,
    DIMGREY,
    DARKVIOLET,
    DARKTURQUOISE,
    INDIGO,
    DARKORANGE,
    PAPAYAWHIP,
    MINTCREAM,
    GREEN,
    DARKMAGENTA,
    MAGENTA,
    LIGHTSLATEGRAY,
    CHARTREUSE,
    GHOSTWHITE,
    LIGHTCYAN,
    SIENNA,
    GOLDENROD,
    DARKSLATEGRAY,
    OLDLACE,
    SEASHELL,
    SPRINGGREEN,
    MEDIUMTURQUOISE,
    LEMONCHIFFON,
    MISTYROSE,
    OLIVEDRAB,
    LIGHTBLUE,
    CHOCOLATE,
    SEAGREEN,
    DEEPPINK,
    LIGHTSEAGREEN,
    FLORALWHITE,
    CADETBLUE,
    AZURE,
    BURLYWOOD,
    AQUAMARINE,
    BROWN,
    POWDERBLUE,
    HOTPINK,
    MEDIUMBLUE,
    BLUEVIOLET,
    GREY75,
    PURPLE,
    TEAL,
    ANTIQUEWHITE,
    DEEPSKYBLUE,
    SLATEGRAY,
    SALMON,
    SLATEBLUE,
    DARKORCHID,
    LIGHTPINK,
    DARKBLUE,
    PEACHPUFF,
    PALEGREEN,
    DARKSALMON,
    DARKOLIVEGREEN,
    DARKSEAGREEN,
    VIOLET,
    RED,
    DARKSLATEGREY,
    PALETURQUOISE,
    DARKRED,
    SLATEGREY,
    HONEYDEW,
    AQUA,
    LIGHTSTEELBLUE,
    DODGERBLUE,
    MEDIUMSPRINGGREEN,
    NAVY,
    GAINSBORO,
    LIGHTYELLOW,
    CRIMSON,
    FUCHSIA,
    DARKGOLDENROD,
    SANDYBROWN,
    BEIGE,
    LINEN,
    ORANGERED,
    ROYALBLUE,
    LAVENDER,
    TAN,
    YELLOWGREEN,
    CORNFLOWERBLUE,
    LAVENDERBLUSH,
    MEDIUMSEAGREEN,
    PINK,
    GREY55,
    PERU,
    LIGHTGREEN,
    LIGHTSALMON,
    INDIANRED,
    DIMGRAY,
    LIGHTSLATEGREY,
    MEDIUMAQUAMARINE,
    DARKGREY,
    ORANGE,
    ALICEBLUE,
};

/************************** File Scope Variables ****************************/

std::string rr_highlight_message;

/********************** Subroutines local to this module ********************/

static void toggle_nets(void (*drawscreen)());
static void toggle_rr(void (*drawscreen)());
static void toggle_congestion(void (*drawscreen)());
static void toggle_routing_congestion_cost(void (*drawscreen)());
static void toggle_crit_path(void (*drawscreen_ptr)());

static void drawscreen();
static void redraw_screen();
static void drawplace();
static void drawnets();
static void drawroute(enum e_draw_net_type draw_net_type);
static void draw_congestion();
static void draw_routing_costs();
static void draw_crit_path();

static void highlight_blocks(float x, float y, t_event_buttonPressed button_info);
static void act_on_mouse_over(float x, float y);
static void deselect_all();

void draw_partial_route(const std::vector<int>& rr_nodes_to_draw);
static void draw_rr();
static void draw_rr_edges(int from_node);
static void draw_rr_pin(int inode, const t_color& color);
static void draw_rr_chan(int inode, const t_color color);
static t_bound_box draw_get_rr_chan_bbox(int inode);
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_pin_to_pin(int opin, int ipin);
static void draw_rr_switch(float from_x, float from_y, float to_x, float to_y,
						   bool buffered, bool switch_configurable);
static void draw_chany_to_chany_edge(int from_node, int to_node,
									 int to_track, short switch_type, bool configurable);
static void draw_chanx_to_chanx_edge(int from_node, int to_node,
									 int to_track, short switch_type, bool configurable);
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, bool configurable);
static int get_track_num(int inode, const vtr::OffsetMatrix<int>& chanx_track, const vtr::OffsetMatrix<int>& chany_track);
static bool draw_if_net_highlighted (ClusterNetId inet);
static void draw_highlight_fan_in_fan_out(const std::set<int>& nodes);
static void highlight_nets(char *message, int hit_node);
static int draw_check_rr_node_hit (float click_x, float click_y);
static std::set<int> draw_expand_non_configurable_rr_nodes(int hit_node);
static void draw_expand_non_configurable_rr_nodes_recurr(int from_node, std::set<int>& expanded_nodes);
static bool highlight_rr_nodes(float x, float y);
static void draw_highlight_blocks_color(t_type_ptr type, ClusterBlockId blk_id);
static void draw_reset_blk_color(ClusterBlockId blk_id);

static inline bool LOD_screen_area_test_square(float width, float screen_area_threshold);
static inline bool default_triangle_LOD_screen_area_test();
static inline bool triangle_LOD_screen_area_test(float arrow_size);

static inline void draw_mux_with_size(t_point origin, e_side orientation, float height, int size);
static inline t_bound_box draw_mux(t_point origin, e_side orientation, float height);
static inline t_bound_box draw_mux(t_point origin, e_side orientation, float height, float width, float height_scale);

static void draw_flyline_timing_edge(t_point start, t_point end, float incr_delay);
static void draw_routed_timing_edge(tatum::NodeId start_tnode, tatum::NodeId end_tnode, float incr_delay, t_color color);
static void draw_routed_timing_edge_connection(tatum::NodeId src_tnode, tatum::NodeId sink_tnode, t_color color);
static std::vector<int> trace_routed_connection_rr_nodes(const ClusterNetId net_id, const int driver_pin, const int sink_pin);
static bool trace_routed_connection_rr_nodes_recurr(const t_rt_node* rt_node, int sink_rr_node, std::vector<int>& rr_nodes_on_path);
static int find_edge(int prev_inode, int inode);

t_color to_t_color(vtr::Color<float> color);
static void draw_color_map_legend(const vtr::ColorMap& cmap);
std::vector<std::set<ClusterNetId>> collect_rr_node_nets();

t_color get_block_type_color(t_type_ptr type);
t_color lighten_color(t_color color, float amount);

/********************** Subroutine definitions ******************************/


void init_graphics_state(bool show_graphics_val, int gr_automode_val,
		enum e_route_type route_type) 
{	
	/* Call accessor functions to retrieve global variables. */
	t_draw_state* draw_state = get_draw_state_vars();

	/* 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.                         */

	draw_state->show_graphics = show_graphics_val;
	draw_state->gr_automode = gr_automode_val;
	draw_state->draw_route_type = route_type;
}

void update_screen(ScreenUpdatePriority priority, const char *msg, enum pic_type pic_on_screen_val,
		std::shared_ptr<SetupTimingInfo> setup_timing_info) {

	/* 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. */

	t_draw_state* draw_state = get_draw_state_vars();

	if (!draw_state->show_graphics) /* Graphics turned off */
		return;

	/* If it's the type of picture displayed has changed, set up the proper  *
	 * buttons.                                                              */
	if (draw_state->pic_on_screen != pic_on_screen_val) {
		if (pic_on_screen_val == PLACEMENT && draw_state->pic_on_screen == NO_PICTURE) {
			create_button("Window", "Toggle Nets", toggle_nets);
			create_button("Toggle Nets", "Blk Internal", toggle_blk_internal);
            if(setup_timing_info) {
                create_button("Blk Internal", "Crit. Path", toggle_crit_path);
            }
		} else if (pic_on_screen_val == ROUTING && draw_state->pic_on_screen == PLACEMENT) {
			create_button("Blk Internal", "Toggle RR", toggle_rr);
			create_button("Toggle RR", "Congestion", toggle_congestion);
			create_button("Congestion", "Cong. Cost", toggle_routing_congestion_cost);
		} else if (pic_on_screen_val == PLACEMENT && draw_state->pic_on_screen == ROUTING) {
			destroy_button("Toggle RR");
			destroy_button("Congestion");
			destroy_button("Cong. Cost");
            if(setup_timing_info) {
                destroy_button("Crit. Path");
            }
		} else if (pic_on_screen_val == ROUTING
				&& draw_state->pic_on_screen == NO_PICTURE) {
			create_button("Window", "Toggle Nets", toggle_nets);
			create_button("Toggle Nets", "Blk Internal", toggle_blk_internal);
			create_button("Blk Internal", "Toggle RR", toggle_rr);
			create_button("Toggle RR", "Congestion", toggle_congestion);
			create_button("Congestion", "Cong. Cost", toggle_routing_congestion_cost);
            if(setup_timing_info) {
                create_button("Cong. Cost", "Crit. Path", toggle_crit_path);
            }
		}
	}
	/* Save the main message. */

	vtr::strncpy(draw_state->default_message, msg, vtr::bufsize);

    draw_state->setup_timing_info = setup_timing_info;

	draw_state->pic_on_screen = pic_on_screen_val;
	update_message(msg);
	drawscreen();

    //Has the user asked us to pause at the next screen updated?
    bool forced_pause = g_vpr_ctx.forced_pause();

	if (int(priority) >= draw_state->gr_automode || forced_pause) {
        if (forced_pause) {
            vtr::printf("Starting interactive graphics (due to user interrupt)\n");
            g_vpr_ctx.set_forced_pause(false); //Reset pause flag
        }
        set_mouse_move_input(true); //Enable act_on_mouse_over callback
		event_loop(highlight_blocks, act_on_mouse_over, nullptr, drawscreen);
	} else {
		flushinput();
	}
}

static void drawscreen() {

#ifdef TIME_DRAWSCREEN
	/* This can be used to test how long it takes for the redrawing routing to finish   *
	 * updating the screen for a given input which would cause the screen to be redrawn.*/

#ifdef WIN32
	clock_t drawscreen_begin,drawscreen_end;
	drawscreen_begin = clock();

#else /* For X11. The clock() function in time.h does not output correct time difference *
       * in Linux, so use gettimeofday() in sys/time.h for accurate runtime tracking. */
	struct timeval begin;
	gettimeofday(&begin,NULL);  /* get start time */

	unsigned long begin_time;
	begin_time = begin.tv_sec * 1000000 + begin.tv_usec;
#endif
#endif

	/* This is the screen redrawing routine that event_loop assumes exists.  *
	 * It erases whatever is on screen, then calls redraw_screen to redraw   *
	 * it.                                                                   */

    set_drawing_buffer(OFF_SCREEN);

	clearscreen();
	redraw_screen();

    copy_off_screen_buffer_to_screen();

#ifdef TIME_DRAWSCREEN

#ifdef WIN32
	drawscreen_end = clock();

    vtr::printf_info("Drawscreen took %f seconds.\n", (float)(drawscreen_end - drawscreen_begin) / CLOCKS_PER_SEC);

#else /* X11 */
	struct timeval end;
	gettimeofday(&end,NULL);  /* get end time */

	unsigned long end_time;
	end_time = end.tv_sec * 1000000 + end.tv_usec;

	unsigned long time_diff_microsec;
	time_diff_microsec = end_time - begin_time;

	vtr::printf_info("Drawscreen took %ld microseconds\n", time_diff_microsec);
#endif /* WIN32 */
#endif /* TIME_DRAWSCREEN */
}

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".                                      */

	t_draw_state* draw_state = get_draw_state_vars();

	setfontsize(14); 

	drawplace();

	if (draw_state->show_blk_internal) {
		draw_internal_draw_subblk();
	}

	if (draw_state->pic_on_screen == PLACEMENT) {
		switch (draw_state->show_nets) {
			case DRAW_NETS:
				drawnets();
			break;
			case DRAW_LOGICAL_CONNECTIONS:
			break;
			default:
			break;
		}

        draw_crit_path();
	} else { /* ROUTING on screen */

		switch (draw_state->show_nets) {
			case DRAW_NETS:
				drawroute(ALL_NETS);
			break;
			case DRAW_LOGICAL_CONNECTIONS:
			// fall through
			default:
				draw_rr();
			break;
		}

        draw_crit_path();

		if (draw_state->show_congestion != DRAW_NO_CONGEST) {
			draw_congestion();
		}

        if (draw_state->show_routing_costs != DRAW_NO_ROUTING_COSTS) {
            draw_routing_costs(); 
        }
	}

	draw_logical_connections();
}

static void toggle_nets(void (*drawscreen_ptr)()) {

	/* 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.                                                    */
	t_draw_state* draw_state = get_draw_state_vars();

	enum e_draw_nets new_state;

	switch (draw_state->show_nets) {
		case DRAW_NO_NETS:
			new_state = DRAW_NETS;
		break;
		case DRAW_NETS:
			new_state = DRAW_LOGICAL_CONNECTIONS;
		break;
		default:
		case DRAW_LOGICAL_CONNECTIONS:
			new_state = DRAW_NO_NETS;
		break;
	}

	draw_state->reset_nets_congestion_and_rr();
	draw_state->show_nets = new_state;

	update_message(draw_state->default_message);
	drawscreen_ptr();
}

static void toggle_rr(void (*drawscreen_ptr)()) {

	/* 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.                               */

	t_draw_state* draw_state = get_draw_state_vars();

	enum e_draw_rr_toggle new_state = (enum e_draw_rr_toggle) (((int)draw_state->draw_rr_toggle + 1) 
														  % ((int)DRAW_RR_TOGGLE_MAX));
	draw_state->reset_nets_congestion_and_rr();
	draw_state->draw_rr_toggle = new_state;

	update_message(draw_state->default_message);
	drawscreen_ptr();
}

static void toggle_congestion(void (*drawscreen_ptr)()) {

	/* Turns the congestion display on and off.   */
	t_draw_state* draw_state = get_draw_state_vars();

	e_draw_congestion new_state = (enum e_draw_congestion) (((int)draw_state->show_congestion + 1) 
														  % ((int)DRAW_CONGEST_MAX));
	draw_state->reset_nets_congestion_and_rr();
	draw_state->show_congestion = new_state;

	if (draw_state->show_congestion == DRAW_NO_CONGEST) {
		update_message(draw_state->default_message);
	}

	drawscreen_ptr();
}

static void toggle_routing_congestion_cost(void (*drawscreen_ptr)()) {
    //Turns routing congestion costs on and off
	t_draw_state* draw_state = get_draw_state_vars();
	e_draw_routing_costs new_state = (enum e_draw_routing_costs) (((int)draw_state->show_routing_costs + 1) 
														  % ((int)DRAW_ROUTING_COST_MAX));

	draw_state->reset_nets_congestion_and_rr();
	draw_state->show_routing_costs = new_state;

	if (draw_state->show_routing_costs == DRAW_NO_ROUTING_COSTS) {
		update_message(draw_state->default_message);
    }
    drawscreen_ptr();
}

void toggle_blk_internal(void (*drawscreen_ptr)()) {
	t_draw_state *draw_state;

	/* Call accessor function to retrieve global variables. */
	draw_state = get_draw_state_vars();

	/* Increment the depth of sub-blocks to be shown */
	draw_state->show_blk_internal++;
	/* If depth exceeds maximum sub-block level in pb_graph, then
	 * disable internals drawing
	 */
	if (draw_state->show_blk_internal > draw_state->max_sub_blk_lvl)
		draw_state->show_blk_internal = 0;

	drawscreen_ptr();
}

static void toggle_crit_path(void (*drawscreen_ptr)()) {
	t_draw_state* draw_state = get_draw_state_vars();

    if (draw_state->pic_on_screen == PLACEMENT) {
        switch (draw_state->show_crit_path) {
            case DRAW_NO_CRIT_PATH:
                draw_state->show_crit_path = DRAW_CRIT_PATH_FLYLINES;
                break;
            case DRAW_CRIT_PATH_FLYLINES:
                draw_state->show_crit_path = DRAW_CRIT_PATH_FLYLINES_DELAYS;
                break;
            default:
                draw_state->show_crit_path = DRAW_NO_CRIT_PATH;
                break;
        };
    } else {
        VTR_ASSERT(draw_state->pic_on_screen == ROUTING);

        switch (draw_state->show_crit_path) {
            case DRAW_NO_CRIT_PATH:
                draw_state->show_crit_path = DRAW_CRIT_PATH_FLYLINES;
                break;
            case DRAW_CRIT_PATH_FLYLINES:
                draw_state->show_crit_path = DRAW_CRIT_PATH_FLYLINES_DELAYS;
                break;
            case DRAW_CRIT_PATH_FLYLINES_DELAYS:
                draw_state->show_crit_path = DRAW_CRIT_PATH_ROUTING;
                break;
            case DRAW_CRIT_PATH_ROUTING:
                draw_state->show_crit_path = DRAW_CRIT_PATH_ROUTING_DELAYS;
                break;
            default:
                draw_state->show_crit_path = DRAW_NO_CRIT_PATH;
                break;
        };
    }

	drawscreen_ptr();
}


void alloc_draw_structs(const t_arch* arch) {
	/* Call accessor functions to retrieve global variables. */
	t_draw_coords* draw_coords = get_draw_coords_vars();
	t_draw_state* draw_state = get_draw_state_vars();
    auto& device_ctx = g_vpr_ctx.device();
    auto& cluster_ctx = g_vpr_ctx.clustering();

	/* Allocate the structures needed to draw the placement and routing.  Set *
	 * up the default colors for blocks and nets.                             */

	draw_coords->tile_x = (float *) vtr::malloc(device_ctx.grid.width() * sizeof(float));
	draw_coords->tile_y = (float *) vtr::malloc(device_ctx.grid.height() * sizeof(float));

	/* For sub-block drawings inside clbs */
	draw_internal_alloc_blk();

	draw_state->net_color.resize(cluster_ctx.clb_nlist.nets().size());

	draw_state->block_color.resize(cluster_ctx.clb_nlist.blocks().size());

	/* Space is allocated for draw_rr_node but not initialized because we do *
	 * not yet know information about the routing resources.				  */
	draw_state->draw_rr_node = (t_draw_rr_node *) vtr::malloc(
									device_ctx.num_rr_nodes * sizeof(t_draw_rr_node));

    draw_state->arch_info = arch;

	deselect_all(); /* Set initial colors */
}

void free_draw_structs() {

	/* Free everything allocated by alloc_draw_structs. Called after close_graphics() *
	 * in vpr_api.c.
	 *
	 * For safety, set all the array pointers to NULL in case any data
	 * structure gets freed twice.													 */
	t_draw_state* draw_state = get_draw_state_vars();
	t_draw_coords* draw_coords = get_draw_coords_vars();

	if(draw_coords != nullptr) {
		free(draw_coords->tile_x);  
		draw_coords->tile_x = nullptr;
		free(draw_coords->tile_y);  
		draw_coords->tile_y = nullptr;		
	}

	if(draw_state != nullptr) {
		free(draw_state->draw_rr_node);	
		draw_state->draw_rr_node = nullptr;
	}
}

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.                                                                     */
	t_draw_state* draw_state = get_draw_state_vars();
	t_draw_coords* draw_coords = get_draw_coords_vars();
    auto& device_ctx = g_vpr_ctx.device();

	if (!draw_state->show_graphics)
		return; /* Graphics disabled */

	/* Each time routing is on screen, need to reallocate the color of each *
	 * rr_node, as the number of rr_nodes may change.						*/
	if (device_ctx.num_rr_nodes != 0) {
		draw_state->draw_rr_node = (t_draw_rr_node *) vtr::realloc(draw_state->draw_rr_node,
										(device_ctx.num_rr_nodes) * sizeof(t_draw_rr_node));
		for (int i = 0; i < device_ctx.num_rr_nodes; i++) {
			draw_state->draw_rr_node[i].color = DEFAULT_RR_NODE_COLOR;
			draw_state->draw_rr_node[i].node_highlighted = false;
		}
	}

	draw_coords->tile_width = width_val;
	draw_coords->pin_size = 0.3;
	for (int i = 0; i < device_ctx.num_block_types; ++i) {
		if (device_ctx.block_types[i].num_pins > 0) {
			draw_coords->pin_size = min(draw_coords->pin_size,
					(draw_coords->get_tile_width() / (4.0F * device_ctx.block_types[i].num_pins)));
		}
	}

	size_t j = 0;
	for (size_t i = 0; i < (device_ctx.grid.width() - 1); i++) {
		draw_coords->tile_x[i] = (i * draw_coords->get_tile_width()) + j;
		j += device_ctx.chan_width.y_list[i] + 1; /* N wires need N+1 units of space */
	}
	draw_coords->tile_x[device_ctx.grid.width() - 1] = ((device_ctx.grid.width() - 1) * draw_coords->get_tile_width()) + j;

	j = 0;
	for (size_t i = 0; i < (device_ctx.grid.height() - 1); ++i) {
		draw_coords->tile_y[i] = (i * draw_coords->get_tile_width()) + j;
		j += device_ctx.chan_width.x_list[i] + 1;
	}
	draw_coords->tile_y[device_ctx.grid.height() - 1] = ((device_ctx.grid.height() - 1) * draw_coords->get_tile_width()) + j;

	/* Load coordinates of sub-blocks inside the clbs */
	draw_internal_init_blk();

    //Margin beyond edge of the drawn device to extend the visible world
    //Setting this to > 0.0 means 'Zoom Fit' leave some fraction of white 
    //space around the device edges
    constexpr float VISIBLE_MARGIN = 0.01; 

    float draw_width = draw_coords->tile_x[device_ctx.grid.width() - 1] + draw_coords->get_tile_width();
    float draw_height = draw_coords->tile_y[device_ctx.grid.height() - 1] + draw_coords->get_tile_width();

	set_visible_world(
		-VISIBLE_MARGIN * draw_width,
		-VISIBLE_MARGIN * draw_height,
		(1. + VISIBLE_MARGIN) * draw_width,
		(1. + VISIBLE_MARGIN) * draw_height
	);
}

/* Draws the blocks placed on the proper clbs.  Occupied blocks are darker colours *
* while empty ones are lighter colours and have a dashed border.      */
static void drawplace() {
	t_draw_state* draw_state = get_draw_state_vars();
	t_draw_coords* draw_coords = get_draw_coords_vars();
    auto& device_ctx = g_vpr_ctx.device();
    auto& place_ctx = g_vpr_ctx.placement();

	ClusterBlockId bnum;
	int num_sub_tiles;

	setlinewidth(0);

	for (size_t i = 0; i < device_ctx.grid.width(); i++) {
		for (size_t j = 0; j < device_ctx.grid.height(); j++) {
			/* Only the first block of a group should control drawing */
			if (device_ctx.grid[i][j].width_offset > 0 || device_ctx.grid[i][j].height_offset > 0) 
				continue;


			num_sub_tiles = device_ctx.grid[i][j].type->capacity;
			/* Don't draw if tile capacity is zero. eg. corners. */
			if (num_sub_tiles == 0) {
				continue;
			}

			for (int k = 0; k < num_sub_tiles; ++k) {

				/* Look at the tile at start of large block */
				bnum = place_ctx.grid_blocks[i][j].blocks[k];

				/* Fill background for the clb. Do not fill if "show_blk_internal" 
				 * is toggled. 
				 */
                if (bnum == INVALID_BLOCK_ID) continue;

                //Determine the block color
                t_color block_color;
                if (bnum != EMPTY_BLOCK_ID) {
                    block_color = draw_state->block_color[bnum];
                } else {
                    block_color = get_block_type_color(device_ctx.grid[i][j].type);
                    block_color = lighten_color(block_color, EMPTY_BLOCK_LIGHTEN_FACTOR);
                }
                setcolor(block_color);

				/* Get coords of current sub_tile */
				t_bound_box abs_clb_bbox = draw_coords->get_absolute_clb_bbox(i,j,k);

                fillrect(abs_clb_bbox);

				setcolor(BLACK);

				setlinestyle((EMPTY_BLOCK_ID == bnum) ? DASHED : SOLID);
				drawrect(abs_clb_bbox);

				/* Draw text if the space has parts of the netlist */
				if (bnum != EMPTY_BLOCK_ID && bnum != INVALID_BLOCK_ID) {
                    auto& cluster_ctx = g_vpr_ctx.clustering();
					drawtext_in(abs_clb_bbox, cluster_ctx.clb_nlist.block_name(bnum));
				}

				/* Draw text for block type so that user knows what block */
				if (device_ctx.grid[i][j].width_offset == 0 && device_ctx.grid[i][j].height_offset == 0) {
                    drawtext(abs_clb_bbox.get_center() - t_point(0, abs_clb_bbox.get_height()/4),
                            device_ctx.grid[i][j].type->name, abs_clb_bbox);
				}
			}
		}
	}
}

static void drawnets() {
	t_draw_state* draw_state = get_draw_state_vars();
	t_draw_coords* draw_coords = get_draw_coords_vars();
	/* 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.        */

	ClusterBlockId b1, b2;
    auto& cluster_ctx = g_vpr_ctx.clustering();

	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 (auto net_id : cluster_ctx.clb_nlist.nets()) {
		if (cluster_ctx.clb_nlist.net_is_global(net_id))
			continue; /* Don't draw global nets. */

		setcolor(draw_state->net_color[net_id]);
		b1 = cluster_ctx.clb_nlist.net_driver_block(net_id);
		t_point driver_center = draw_coords->get_absolute_clb_bbox(b1, cluster_ctx.clb_nlist.block_type(b1)).get_center();

		for (auto pin_id : cluster_ctx.clb_nlist.net_sinks(net_id)) {
			b2 = cluster_ctx.clb_nlist.pin_block(pin_id);
			t_point sink_center = draw_coords->get_absolute_clb_bbox(b2, cluster_ctx.clb_nlist.block_type(b2)).get_center();
			drawline(driver_center, sink_center);

			/* Uncomment to draw a chain instead of a star. */
			/* driver_center = sink_center;  */
		}
	}
}

static void draw_congestion() {

	/* Draws all the overused routing resources (i.e. congestion) in RED.   */
	t_draw_state* draw_state = get_draw_state_vars();

    if (draw_state->show_congestion == DRAW_NO_CONGEST) {
        return;
    }

    auto& device_ctx = g_vpr_ctx.device();
    auto& route_ctx = g_vpr_ctx.routing();


    //Record min/max congestion
    float min_congestion_ratio = 1.;
    float max_congestion_ratio = min_congestion_ratio;
    std::vector<int> congested_rr_nodes;
	for (int inode = 0; inode < device_ctx.num_rr_nodes; inode++) {
		short occ = route_ctx.rr_node_route_inf[inode].occ();
        short capacity = device_ctx.rr_nodes[inode].capacity();

        float congestion_ratio = float(occ) / capacity;

        max_congestion_ratio = std::max(max_congestion_ratio, congestion_ratio);

        if (congestion_ratio > 1.) {
            congested_rr_nodes.push_back(inode);
        }
    }

    char msg[vtr::bufsize];
    if (draw_state->show_congestion == DRAW_CONGESTED) {
        sprintf(msg, "RR Node Overuse ratio range (%.2f, %.2f]", min_congestion_ratio, max_congestion_ratio);
    } else {
        VTR_ASSERT(draw_state->show_congestion == DRAW_CONGESTED_WITH_NETS);
        sprintf(msg, "RR Node Overuse ratio range (%.2f, %.2f] (and congested nets)", min_congestion_ratio, max_congestion_ratio);
    }
    update_message(msg);

    vtr::PlasmaColorMap cmap(min_congestion_ratio, max_congestion_ratio);

    //Sort the nodes in ascending order of value for drawing, this ensures high 
    //valued nodes re not overdrawn by lower value ones (e.g. when zoomed-out far)
    auto cmp_ascending_acc_cost = [&](int lhs_node, int rhs_node) {
		short lhs_occ = route_ctx.rr_node_route_inf[lhs_node].occ();
        short lhs_capacity = device_ctx.rr_nodes[lhs_node].capacity();

		short rhs_occ = route_ctx.rr_node_route_inf[rhs_node].occ();
        short rhs_capacity = device_ctx.rr_nodes[rhs_node].capacity();

        float lhs_cong_ratio = float(lhs_occ) / lhs_capacity;
        float rhs_cong_ratio = float(rhs_occ) / rhs_capacity;

        return lhs_cong_ratio < rhs_cong_ratio;
    };
    std::sort(congested_rr_nodes.begin(), congested_rr_nodes.end(), cmp_ascending_acc_cost);

    if (draw_state->show_congestion == DRAW_CONGESTED_WITH_NETS) {

        auto rr_node_nets = collect_rr_node_nets();

        for (int inode : congested_rr_nodes) {
            for (ClusterNetId net : rr_node_nets[inode]) {
                t_color color = kelly_max_contrast_colors[size_t(net) % kelly_max_contrast_colors.size()];
                draw_state->net_color[net] = color;
            }
        }
        setlinewidth(0);
        drawroute(HIGHLIGHTED);

        //Reset colors
        for (int inode : congested_rr_nodes) {
            for (ClusterNetId net : rr_node_nets[inode]) {
                draw_state->net_color[net] = DEFAULT_RR_NODE_COLOR;
            }
        }
    } else {
        setlinewidth(2);
    }

    //Draw each congested node
    for(int inode : congested_rr_nodes) {
		short occ = route_ctx.rr_node_route_inf[inode].occ();
        short capacity = device_ctx.rr_nodes[inode].capacity();

        float congestion_ratio = float(occ) / capacity;

        bool node_congested = (occ > capacity);
        VTR_ASSERT(node_congested);

        t_color color = to_t_color(cmap.color(congestion_ratio));

        switch (device_ctx.rr_nodes[inode].type()) {
            case CHANX: //fallthrough
            case CHANY:
                draw_rr_chan(inode, color);
                break;

            case IPIN: //fallthrough
            case OPIN:
                draw_rr_pin(inode, color);
                break;
            default:
                break;
        }
	}
    draw_color_map_legend(cmap);
}

static void draw_routing_costs() {

	/* Draws routing costs */

	t_draw_state* draw_state = get_draw_state_vars();

    if (draw_state->show_routing_costs == DRAW_NO_ROUTING_COSTS) {
        return;
    }

    auto& device_ctx = g_vpr_ctx.device();
    auto& route_ctx = g_vpr_ctx.routing();

	setlinewidth(2);

    VTR_ASSERT(!route_ctx.rr_node_route_inf.empty());

    float min_cost = std::numeric_limits<float>::infinity();
    float max_cost = -min_cost;
    std::vector<float> rr_node_costs(device_ctx.num_rr_nodes, 0.);
	for (int inode = 0; inode < device_ctx.num_rr_nodes; inode++) {
        float cost = 0.;
        if (   draw_state->show_routing_costs == DRAW_TOTAL_ROUTING_COSTS 
            || draw_state->show_routing_costs == DRAW_LOG_TOTAL_ROUTING_COSTS) {
            int cost_index = device_ctx.rr_nodes[inode].cost_index();
            cost =  device_ctx.rr_indexed_data[cost_index].base_cost
                  + route_ctx.rr_node_route_inf[inode].acc_cost
                  + route_ctx.rr_node_route_inf[inode].pres_cost;

        } else if (   draw_state->show_routing_costs == DRAW_BASE_ROUTING_COSTS) {
            int cost_index = device_ctx.rr_nodes[inode].cost_index();
            cost =  device_ctx.rr_indexed_data[cost_index].base_cost;

        } else if (   draw_state->show_routing_costs == DRAW_ACC_ROUTING_COSTS 
                   || draw_state->show_routing_costs == DRAW_LOG_ACC_ROUTING_COSTS) {
            cost = route_ctx.rr_node_route_inf[inode].acc_cost;

        } else {
            VTR_ASSERT(   draw_state->show_routing_costs == DRAW_PRES_ROUTING_COSTS 
                       || draw_state->show_routing_costs == DRAW_LOG_PRES_ROUTING_COSTS);
            cost = route_ctx.rr_node_route_inf[inode].pres_cost;
        }

        if (   draw_state->show_routing_costs == DRAW_LOG_TOTAL_ROUTING_COSTS
            || draw_state->show_routing_costs == DRAW_LOG_ACC_ROUTING_COSTS
            || draw_state->show_routing_costs == DRAW_LOG_PRES_ROUTING_COSTS) {
            cost = std::log(cost);
        }
        rr_node_costs[inode] = cost;
        min_cost = std::min(min_cost, cost);
        max_cost = std::max(max_cost, cost);
    }

    char msg[vtr::bufsize];
    if (draw_state->show_routing_costs == DRAW_TOTAL_ROUTING_COSTS) {
        sprintf(msg, "Total Congestion Cost Range [%g, %g]", min_cost, max_cost);
    } else if (draw_state->show_routing_costs == DRAW_LOG_TOTAL_ROUTING_COSTS) {
        sprintf(msg, "Log Total Congestion Cost Range [%g, %g]", min_cost, max_cost);
    } else if (draw_state->show_routing_costs == DRAW_BASE_ROUTING_COSTS) {
        sprintf(msg, "Base Congestion Cost Range [%g, %g]", min_cost, max_cost);
    } else if (draw_state->show_routing_costs == DRAW_ACC_ROUTING_COSTS) {
        sprintf(msg, "Accumulated (Historical) Congestion Cost Range [%g, %g]", min_cost, max_cost);
    } else if (draw_state->show_routing_costs == DRAW_LOG_ACC_ROUTING_COSTS) {
        sprintf(msg, "Log Accumulated (Historical) Congestion Cost Range [%g, %g]", min_cost, max_cost);
    } else if (draw_state->show_routing_costs == DRAW_PRES_ROUTING_COSTS) {
        sprintf(msg, "Present Congestion Cost Range [%g, %g]", min_cost, max_cost);
    } else if (draw_state->show_routing_costs == DRAW_LOG_PRES_ROUTING_COSTS) {
        sprintf(msg, "Log Present Congestion Cost Range [%g, %g]", min_cost, max_cost);
    } else {
        sprintf(msg, "Cost Range [%g, %g]", min_cost, max_cost);
    }
    update_message(msg);

    vtr::PlasmaColorMap cmap(min_cost, max_cost);

    //Draw the nodes in ascending order of value, this ensures high valued nodes
    //are not overdrawn by lower value ones (e.g. when zoomed-out far)
    std::vector<int> nodes(device_ctx.num_rr_nodes);
    std::iota(nodes.begin(), nodes.end(), 0);
    auto cmp_ascending_cost = [&](int lhs_node, int rhs_node) {
        return rr_node_costs[lhs_node] < rr_node_costs[rhs_node];
    };
    std::sort(nodes.begin(), nodes.end(), cmp_ascending_cost);

    for (int inode : nodes) {
        float cost = rr_node_costs[inode];
        if (cost == min_cost) continue; //Hide minimum cost resources

        t_color color = to_t_color(cmap.color(cost));

        switch (device_ctx.rr_nodes[inode].type()) {
            case CHANX: //fallthrough
            case CHANY:
                draw_rr_chan(inode, color);
                break;

            case IPIN: //fallthrough
            case OPIN:
                draw_rr_pin(inode, color);
                break;
            default:
                break;
        }
	}
    draw_color_map_legend(cmap);
}

void draw_rr() {

	/* Draws the routing resources that exist in the FPGA, if the user wants *
	 * them drawn.                                                           */
	t_draw_state* draw_state = get_draw_state_vars();
    auto& device_ctx = g_vpr_ctx.device();

	int inode;

	if (draw_state->draw_rr_toggle == DRAW_NO_RR || draw_state->draw_rr_toggle == DRAW_MOUSE_OVER_RR) {
		setlinewidth(3);
		drawroute(HIGHLIGHTED);
		setlinewidth(0);
		return;
	}

	setlinestyle(SOLID);

	for (inode = 0; inode < device_ctx.num_rr_nodes; inode++) {
		if (!draw_state->draw_rr_node[inode].node_highlighted) 
		{
			/* If not highlighted node, assign color based on type. */
			switch (device_ctx.rr_nodes[inode].type()) {
			case CHANX:
			case CHANY:
				draw_state->draw_rr_node[inode].color = DEFAULT_RR_NODE_COLOR;
				break;
			case OPIN:
				draw_state->draw_rr_node[inode].color = PINK;
				break;
			case IPIN:
				draw_state->draw_rr_node[inode].color = LIGHTSKYBLUE;
				break;
			default:
				break;
			}
		}

		/* Now call drawing routines to draw the node. */
		switch (device_ctx.rr_nodes[inode].type()) {

		case SOURCE:
		case SINK:
			break; /* Don't draw. */

		case CHANX:
			draw_rr_chan(inode, draw_state->draw_rr_node[inode].color);
			draw_rr_edges(inode);
			break;

		case CHANY:
			draw_rr_chan(inode, draw_state->draw_rr_node[inode].color);
			draw_rr_edges(inode);
			break;

		case IPIN:
			draw_rr_pin(inode, draw_state->draw_rr_node[inode].color);
			break;

		case OPIN:
			draw_rr_pin(inode, draw_state->draw_rr_node[inode].color);
			draw_rr_edges(inode);
			break;

		default:
			vpr_throw(VPR_ERROR_OTHER, __FILE__, __LINE__, 
					"in draw_rr: Unexpected rr_node type: %d.\n", device_ctx.rr_nodes[inode].type());
		}
	}

	drawroute(HIGHLIGHTED);
}

static void draw_rr_chan(int inode, const t_color color) {
    auto& device_ctx = g_vpr_ctx.device();

    t_rr_type type = device_ctx.rr_nodes[inode].type();

    VTR_ASSERT(type == CHANX || type == CHANY);

    t_bound_box bound_box = draw_get_rr_chan_bbox(inode);
    e_direction dir = device_ctx.rr_nodes[inode].direction();

    //We assume increasing direction, and swap if needed
    t_point start = bound_box.bottom_left();
    t_point end = bound_box.top_right();
    if (dir == DEC_DIRECTION) {
        std::swap(start, end);
    }

	setcolor(color);
	if (color != DEFAULT_RR_NODE_COLOR) {
		// If wire is highlighted, then draw with thicker linewidth.
		setlinewidth(3);
    }

    drawline(start, end);

	if (color != DEFAULT_RR_NODE_COLOR) {
		// Revert width change
		setlinewidth(0);
	}

	// draw the arrows and small lines iff zoomed in really far.
	if (default_triangle_LOD_screen_area_test() == false) {
		return;
	}

    e_side mux_dir = TOP;
    int coord_min = -1;
    int coord_max = -1;
    if (type == CHANX) {
        coord_min = device_ctx.rr_nodes[inode].xlow();
        coord_max = device_ctx.rr_nodes[inode].xhigh();
        if (dir == INC_DIRECTION) {
            mux_dir = RIGHT;
        } else {
            mux_dir = LEFT;
        }
    } else {
        VTR_ASSERT(type == CHANY);
        coord_min = device_ctx.rr_nodes[inode].ylow();
        coord_max = device_ctx.rr_nodes[inode].yhigh();
        if (dir == INC_DIRECTION) {
            mux_dir = TOP;
        } else {
            mux_dir = BOTTOM;
        }
    }

    //Draw direction indicators at the boundary of each switch block, and label them
    //with the corresponding switch point (see build_switchblocks.c for a description of switch points)
	t_draw_coords* draw_coords = get_draw_coords_vars();
    float arrow_offset = DEFAULT_ARROW_SIZE / 2;
    t_color arrow_color = LIGHTGREY;
    t_color text_color = BLACK;
    for(int k = coord_min; k <= coord_max; ++k) {

        int switchpoint_min = -1;
        int switchpoint_max = -1;
        if(dir == INC_DIRECTION) {
            switchpoint_min = k - coord_min;
            switchpoint_max = switchpoint_min + 1;
        } else {
            switchpoint_min = (coord_max + 1) - k;
            switchpoint_max = switchpoint_min - 1;
        }

        t_point arrow_loc_min;
        t_point arrow_loc_max;
        if (type == CHANX) {
            float sb_xmin = draw_coords->tile_x[k];
            arrow_loc_min = t_point(sb_xmin + arrow_offset, start.y);

            float sb_xmax = draw_coords->tile_x[k] + draw_coords->get_tile_width();
            arrow_loc_max = t_point(sb_xmax - arrow_offset, start.y);

        } else {
            float sb_ymin = draw_coords->tile_y[k];
            arrow_loc_min = t_point(start.x, sb_ymin + arrow_offset);

            float sb_ymax = draw_coords->tile_y[k] + draw_coords->get_tile_height();
            arrow_loc_max = t_point(start.x, sb_ymax - arrow_offset);
        }

        if (switchpoint_min == 0) {
            //Draw a mux at the start of each wire, labelled with it's size (#inputs)
            draw_mux_with_size(start, mux_dir, WIRE_DRAWING_WIDTH, device_ctx.rr_nodes[inode].fan_in());
        } else {
            //Draw arrows and label with switch point
            if (k == coord_min) {
                std::swap(arrow_color, text_color);
            }

            setcolor(arrow_color);
            draw_triangle_along_line(arrow_loc_min, start, end);

            setcolor(text_color);
            t_bound_box bbox(t_point(arrow_loc_min.x - DEFAULT_ARROW_SIZE/2, arrow_loc_min.y - DEFAULT_ARROW_SIZE / 4),
                             t_point(arrow_loc_min.x + DEFAULT_ARROW_SIZE/2, arrow_loc_min.y + DEFAULT_ARROW_SIZE / 4));
            drawtext_in(bbox, std::to_string(switchpoint_min));

            if (k == coord_min) {
                //Revert
                std::swap(arrow_color, text_color);
            }
        }

        if (switchpoint_max == 0) {
            //Draw a mux at the start of each wire, labelled with it's size (#inputs)
            draw_mux_with_size(start, mux_dir, WIRE_DRAWING_WIDTH, device_ctx.rr_nodes[inode].fan_in());
        } else {
            //Draw arrows and label with switch point
            if (k == coord_max) {
                std::swap(arrow_color, text_color);
            }

            setcolor(arrow_color);
            draw_triangle_along_line(arrow_loc_max, start, end);

            setcolor(text_color);
            t_bound_box bbox(t_point(arrow_loc_max.x - DEFAULT_ARROW_SIZE/2, arrow_loc_max.y - DEFAULT_ARROW_SIZE / 4),
                             t_point(arrow_loc_max.x + DEFAULT_ARROW_SIZE/2, arrow_loc_max.y + DEFAULT_ARROW_SIZE / 4));
            drawtext_in(bbox, std::to_string(switchpoint_max));

            if (k == coord_max) {
                //Revert
                std::swap(arrow_color, text_color);
            }
        }
    }
	setcolor(color); //Ensure color is still set correctly if we drew any arrows/text
}

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 IPIN.           */
	t_draw_state* draw_state = get_draw_state_vars();
    auto& device_ctx = g_vpr_ctx.device();

	t_rr_type from_type, to_type;
	int to_node, from_ptc_num, to_ptc_num;
	short switch_type;

	from_type = device_ctx.rr_nodes[inode].type();

	if ((draw_state->draw_rr_toggle == DRAW_NODES_RR)
			|| (draw_state->draw_rr_toggle == DRAW_NODES_AND_SBOX_RR && from_type == OPIN)) {
		return; /* Nothing to draw. */
	}

	from_ptc_num = device_ctx.rr_nodes[inode].ptc_num();

	for (int iedge = 0, l = device_ctx.rr_nodes[inode].num_edges(); iedge < l; iedge++) {
		to_node = device_ctx.rr_nodes[inode].edge_sink_node(iedge);
		to_type = device_ctx.rr_nodes[to_node].type();
		to_ptc_num = device_ctx.rr_nodes[to_node].ptc_num();
        bool edge_configurable = device_ctx.rr_nodes[inode].edge_is_configurable(iedge);

		switch (from_type) {

		case OPIN:
			switch (to_type) {
			case CHANX:
			case CHANY:
				if (draw_state->draw_rr_node[inode].color == MAGENTA) {
					// If OPIN was clicked on, set color to fan-out
					setcolor(draw_state->draw_rr_node[to_node].color);
				} else if (draw_state->draw_rr_node[to_node].color == MAGENTA) {
					// If CHANX or CHANY got clicked, set color to fan-in
					setcolor(draw_state->draw_rr_node[inode].color);
				} else {
					setcolor(PINK);
                }
				draw_pin_to_chan_edge(inode, to_node);
				break;
			case IPIN:
				if (draw_state->draw_rr_node[inode].color == MAGENTA) {
					setcolor(draw_state->draw_rr_node[to_node].color);
				} else if (draw_state->draw_rr_node[to_node].color == MAGENTA) {
					setcolor(draw_state->draw_rr_node[inode].color);
				} else {
					setcolor(MEDIUMPURPLE);
                }
				draw_pin_to_pin(inode, to_node);
				break;
			default:
				vpr_throw(VPR_ERROR_OTHER, __FILE__, __LINE__, 
						"in draw_rr_edges: node %d (type: %d) connects to node %d (type: %d).\n",
						inode, from_type, to_node, to_type);
				break;
			}
			break;

		case CHANX: /* from_type */
			switch (to_type) {
			case IPIN:
				if (draw_state->draw_rr_toggle == DRAW_NODES_AND_SBOX_RR) {
					break;
				}

				if (draw_state->draw_rr_node[to_node].node_highlighted &&
					draw_state->draw_rr_node[inode].color == DEFAULT_RR_NODE_COLOR) {
					// If the IPIN is clicked on, draw connection to all the CHANX
					// wire segments fanning into the pin. If a CHANX wire is clicked
					// on, draw only the connection between that wire and the IPIN, with
					// the pin fanning out from the wire.
					break;
				}

				if (draw_state->draw_rr_node[inode].color == MAGENTA) {
					setcolor(draw_state->draw_rr_node[to_node].color);
				} else if (draw_state->draw_rr_node[to_node].color == MAGENTA) {
					setcolor(draw_state->draw_rr_node[inode].color);
				} else {
					setcolor(LIGHTSKYBLUE);
                }
				draw_pin_to_chan_edge(to_node, inode);
				break;

			case CHANX:
				if (draw_state->draw_rr_node[inode].color == MAGENTA) {
					setcolor(draw_state->draw_rr_node[to_node].color);
				} else if (draw_state->draw_rr_node[to_node].color == MAGENTA) {
					setcolor(draw_state->draw_rr_node[inode].color);
				} else if (!edge_configurable) {
					setcolor(DARKGREY);
				} else {
					setcolor(DARKGREEN);
                }
				switch_type = device_ctx.rr_nodes[inode].edge_switch(iedge);
				draw_chanx_to_chanx_edge(inode, to_node,
						to_ptc_num, switch_type, edge_configurable);
				break;

			case CHANY:
				if (draw_state->draw_rr_node[inode].color == MAGENTA) {
					setcolor(draw_state->draw_rr_node[to_node].color);
				} else if (draw_state->draw_rr_node[to_node].color == MAGENTA) {
					setcolor(draw_state->draw_rr_node[inode].color);
				} else if (!edge_configurable) {
					setcolor(DARKGREY);
				} else {
					setcolor(DARKGREEN);
                }
				switch_type = device_ctx.rr_nodes[inode].edge_switch(iedge);
				draw_chanx_to_chany_edge(inode, from_ptc_num, to_node,
						to_ptc_num, FROM_X_TO_Y, switch_type, edge_configurable);
				break;

			default:
				vpr_throw(VPR_ERROR_OTHER, __FILE__, __LINE__, 
						"in draw_rr_edges: node %d (type: %d) connects to node %d (type: %d).\n",
						inode, from_type, to_node, to_type);
				break;
			}
			break;

		case CHANY: /* from_type */
			switch (to_type) {
			case IPIN:
				if (draw_state->draw_rr_toggle == DRAW_NODES_AND_SBOX_RR) {
					break;
				}

				if (draw_state->draw_rr_node[to_node].node_highlighted &&
					draw_state->draw_rr_node[inode].color == DEFAULT_RR_NODE_COLOR) {
					// If the IPIN is clicked on, draw connection to all the CHANY
					// wire segments fanning into the pin. If a CHANY wire is clicked
					// on, draw only the connection between that wire and the IPIN, with
					// the pin fanning out from the wire.
					break;
				}

				if (draw_state->draw_rr_node[inode].color == MAGENTA) {
					setcolor(draw_state->draw_rr_node[to_node].color);
				} else if (draw_state->draw_rr_node[to_node].color == MAGENTA) {
					setcolor(draw_state->draw_rr_node[inode].color);
				} else {
					setcolor(LIGHTSKYBLUE);
                }
				draw_pin_to_chan_edge(to_node, inode);
				break;

			case CHANX:
				if (draw_state->draw_rr_node[inode].color == MAGENTA) {
					setcolor(draw_state->draw_rr_node[to_node].color);
				} else if (draw_state->draw_rr_node[to_node].color == MAGENTA) {
					setcolor(draw_state->draw_rr_node[inode].color);
				} else if (!edge_configurable) {
					setcolor(DARKGREY);
				} else {
					setcolor(DARKGREEN);
                }
				switch_type = device_ctx.rr_nodes[inode].edge_switch(iedge);
				draw_chanx_to_chany_edge(to_node, to_ptc_num, inode,
						from_ptc_num, FROM_Y_TO_X, switch_type, edge_configurable);
				break;

			case CHANY:
				if (draw_state->draw_rr_node[inode].color == MAGENTA) {
					setcolor(draw_state->draw_rr_node[to_node].color);
				} else if (draw_state->draw_rr_node[to_node].color == MAGENTA) {
					setcolor(draw_state->draw_rr_node[inode].color);
				} else if (!edge_configurable) {
					setcolor(DARKGREY);
				} else {
					setcolor(DARKGREEN);
                }
				switch_type = device_ctx.rr_nodes[inode].edge_switch(iedge);
				draw_chany_to_chany_edge(inode, to_node,
						to_ptc_num, switch_type, edge_configurable);
				break;

			default:
				vpr_throw(VPR_ERROR_OTHER, __FILE__, __LINE__, 
						"in draw_rr_edges: node %d (type: %d) connects to node %d (type: %d).\n",
						inode, from_type, to_node, to_type);
				break;
			}
			break;

		default: /* from_type */
			vpr_throw(VPR_ERROR_OTHER, __FILE__, __LINE__, 
					"draw_rr_edges called with node %d of type %d.\n", 
					inode, from_type);
			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);
}


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, bool configurable) {

	t_draw_state* draw_state = get_draw_state_vars();
	t_draw_coords* draw_coords = get_draw_coords_vars();
    auto& device_ctx = g_vpr_ctx.device();

	/* Draws an edge (SBOX connection) between an x-directed channel and a    *
	 * y-directed channel.                                                    */

	float x1, y1, x2, y2;
	t_bound_box chanx_bbox, chany_bbox;
	int chanx_xlow, chany_x, chany_ylow, chanx_y;

	/* Get the coordinates of the CHANX and CHANY segments. */
	chanx_bbox = draw_get_rr_chan_bbox(chanx_node);
	chany_bbox = draw_get_rr_chan_bbox(chany_node);

	/* (x1,y1): point on CHANX segment, (x2,y2): point on CHANY segment. */

	y1 = chanx_bbox.bottom(); 
	x2 = chany_bbox.left();

	chanx_xlow = device_ctx.rr_nodes[chanx_node].xlow();
	chanx_y = device_ctx.rr_nodes[chanx_node].ylow();
	chany_x = device_ctx.rr_nodes[chany_node].xlow();
	chany_ylow = device_ctx.rr_nodes[chany_node].ylow();

	if (chanx_xlow <= chany_x) { /* Can draw connection going right */
		/* Connection not at end of the CHANX segment. */
		x1 = draw_coords->tile_x[chany_x] + draw_coords->get_tile_width();
		
		if (device_ctx.rr_nodes[chanx_node].direction() != BI_DIRECTION) {
			if (edge_dir == FROM_X_TO_Y) {
				if ((chanx_track % 2) == 1) { /* If dec wire, then going left */
					x1 = draw_coords->tile_x[chany_x + 1];
				}
			}
		}
		
	} else { /* Must draw connection going left. */
		x1 = chanx_bbox.left();
	}

	if (chany_ylow <= chanx_y) { /* Can draw connection going up. */
		/* Connection not at end of the CHANY segment. */
		y2 = draw_coords->tile_y[chanx_y] + draw_coords->get_tile_width();
		
		if (device_ctx.rr_nodes[chany_node].direction() != BI_DIRECTION) {
			if (edge_dir == FROM_Y_TO_X) {
				if ((chany_track % 2) == 1) { /* If dec wire, then going down */
					y2 = draw_coords->tile_y[chanx_y + 1];
				}
			}
		}
		
	} else { /* Must draw connection going down. */
		y2 = chany_bbox.bottom();
	}

	drawline(x1, y1, x2, y2);

	if (draw_state->draw_rr_toggle == DRAW_ALL_RR || draw_state->draw_rr_node[chanx_node].node_highlighted) {
        if (edge_dir == FROM_X_TO_Y) {
            draw_rr_switch(x1, y1, x2, y2, device_ctx.rr_switch_inf[switch_type].buffered, configurable);
        } else {
            draw_rr_switch(x2, y2, x1, y1, device_ctx.rr_switch_inf[switch_type].buffered, configurable);
        }
    }
}


static void draw_chanx_to_chanx_edge(int from_node, int to_node,
		int to_track, short switch_type, bool configurable) {

	/* 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.                                                                 */

	t_draw_state* draw_state = get_draw_state_vars();
	t_draw_coords* draw_coords = get_draw_coords_vars();
    auto& device_ctx = g_vpr_ctx.device();

	float x1, x2, y1, y2;
	t_bound_box from_chan, to_chan;
	int from_xlow, to_xlow, from_xhigh, to_xhigh;
	
	// Get the coordinates of the channel wires.
	from_chan = draw_get_rr_chan_bbox(from_node);
	to_chan = draw_get_rr_chan_bbox(to_node);

	/* (x1, y1) point on from_node, (x2, y2) point on to_node. */

	y1 = from_chan.bottom();
	y2 = to_chan.bottom();

	from_xlow = device_ctx.rr_nodes[from_node].xlow();
	from_xhigh = device_ctx.rr_nodes[from_node].xhigh();
	to_xlow = device_ctx.rr_nodes[to_node].xlow();
	to_xhigh = device_ctx.rr_nodes[to_node].xhigh();

	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 = from_chan.left();
		x2 = to_chan.right();
	} 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 = from_chan.right();
		x2 = to_chan.left();
	}

	/* 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.        */

	else {
		if (device_ctx.rr_nodes[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 */
				VTR_ASSERT(from_xlow < to_xlow);
				x2 = to_chan.left();
				/* since no U-turns from_track must be INC as well */
				x1 = draw_coords->tile_x[to_xlow - 1] + draw_coords->get_tile_width();
			} else { /* DEC wire starts at rightmost edge */
				VTR_ASSERT(from_xhigh > to_xhigh);
				x2 = to_chan.right();
				x1 = draw_coords->tile_x[to_xhigh + 1];
			}
		} else {
			if (to_xlow < from_xlow) { /* Draw from left edge of one to other */
				x1 = from_chan.left();
				x2 = draw_coords->tile_x[from_xlow - 1] + draw_coords->get_tile_width();
			} else if (from_xlow < to_xlow) {
				x1 = draw_coords->tile_x[to_xlow - 1] + draw_coords->get_tile_width();
				x2 = to_chan.left();
			} /* 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 = from_chan.right();
				x2 = draw_coords->tile_x[from_xhigh + 1];
			} else if (from_xhigh > to_xhigh) {
				x1 = draw_coords->tile_x[to_xhigh + 1];
				x2 = to_chan.right();
			} else { /* Complete overlap: start and end both align. Draw outside the sbox */
				x1 = from_chan.left();
				x2 = from_chan.left() + draw_coords->get_tile_width();
			}
		}
	}
	
	drawline(x1, y1, x2, y2);

	if (draw_state->draw_rr_toggle == DRAW_ALL_RR || draw_state->draw_rr_node[from_node].node_highlighted) {
		draw_rr_switch(x1, y1, x2, y2, device_ctx.rr_switch_inf[switch_type].buffered, configurable);
	}
}


static void draw_chany_to_chany_edge(int from_node, int to_node,
		int to_track, short switch_type, bool configurable) {

	t_draw_state* draw_state = get_draw_state_vars();
	t_draw_coords* draw_coords = get_draw_coords_vars();
    auto& device_ctx = g_vpr_ctx.device();
	
	/* 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;
	t_bound_box from_chan, to_chan;
	int from_ylow, to_ylow, from_yhigh, to_yhigh;//, from_x, to_x;

	// Get the coordinates of the channel wires.
	from_chan = draw_get_rr_chan_bbox(from_node);
	to_chan = draw_get_rr_chan_bbox(to_node);

	// from_x = device_ctx.rr_nodes[from_node].xlow();
	// to_x = device_ctx.rr_nodes[to_node].xlow();
	from_ylow = device_ctx.rr_nodes[from_node].ylow();
	from_yhigh = device_ctx.rr_nodes[from_node].yhigh();
	to_ylow = device_ctx.rr_nodes[to_node].ylow();
	to_yhigh = device_ctx.rr_nodes[to_node].yhigh();

	/* (x1, y1) point on from_node, (x2, y2) point on to_node. */

	x1 = from_chan.left();
	x2 = to_chan.left();

	if (to_yhigh < from_ylow) { /* From upper to lower */
		y1 = from_chan.bottom();
		y2 = to_chan.top();
	} else if (to_ylow > from_yhigh) { /* From lower to upper */
		y1 = from_chan.top();
		y2 = to_chan.bottom();
	}

	/* 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 (device_ctx.rr_nodes[to_node].direction() != BI_DIRECTION) {
			if (to_track % 2 == 0) { /* INC wire starts at bottom edge */

				y2 = to_chan.bottom();
				/* since no U-turns from_track must be INC as well */
				y1 = draw_coords->tile_y[to_ylow - 1] + draw_coords->get_tile_width();
			} else { /* DEC wire starts at top edge */
				
				y2 = to_chan.top();
				y1 = draw_coords->tile_y[to_yhigh + 1];
			}
		} else {
			if (to_ylow < from_ylow) { /* Draw from bottom edge of one to other. */
				y1 = from_chan.bottom();
				y2 = draw_coords->tile_y[from_ylow - 1] + draw_coords->get_tile_width();
			} else if (from_ylow < to_ylow) {
				y1 = draw_coords->tile_y[to_ylow - 1] + draw_coords->get_tile_width();
				y2 = to_chan.bottom();
			} else if (to_yhigh > from_yhigh) { /* Draw from top edge of one to other. */
				y1 = from_chan.top();
				y2 = draw_coords->tile_y[from_yhigh + 1];
			} else if (from_yhigh > to_yhigh) {
				y1 = draw_coords->tile_y[to_yhigh + 1];
				y2 = to_chan.top();
			} else { /* Complete overlap: start and end both align. Draw outside the sbox */
				y1 = from_chan.bottom();
				y2 = from_chan.bottom() + draw_coords->get_tile_width();
			}
		}
	}


	/* UDSD Modification by WMF End */
	drawline(x1, y1, x2, y2);

	if (draw_state->draw_rr_toggle == DRAW_ALL_RR || draw_state->draw_rr_node[from_node].node_highlighted) {
		draw_rr_switch(x1, y1, x2, y2, device_ctx.rr_switch_inf[switch_type].buffered, configurable);
	}
}


/* This function computes and returns the boundary coordinates of a channel
 * wire segment. This can be used for drawing a wire or determining if a 
 * wire has been clicked on by the user. 
 * TODO: Fix this for global routing, currently for detailed only. 
 */
static t_bound_box draw_get_rr_chan_bbox (int inode) {
	t_bound_box bound_box;

	t_draw_coords* draw_coords = get_draw_coords_vars();
    auto& device_ctx = g_vpr_ctx.device();

	switch (device_ctx.rr_nodes[inode].type()) {
		case CHANX:
			bound_box.left() = draw_coords->tile_x[device_ctx.rr_nodes[inode].xlow()];
	        bound_box.right() = draw_coords->tile_x[device_ctx.rr_nodes[inode].xhigh()] 
						        + draw_coords->get_tile_width();
			bound_box.bottom() = draw_coords->tile_y[device_ctx.rr_nodes[inode].ylow()] 
								+ draw_coords->get_tile_width() 
								+ (1. + device_ctx.rr_nodes[inode].ptc_num());
			bound_box.top() = draw_coords->tile_y[device_ctx.rr_nodes[inode].ylow()] 
								+ draw_coords->get_tile_width() 
								+ (1. + device_ctx.rr_nodes[inode].ptc_num());
			break;
		case CHANY:
			bound_box.left() = draw_coords->tile_x[device_ctx.rr_nodes[inode].xlow()] 
								+ draw_coords->get_tile_width() 
								+ (1. + device_ctx.rr_nodes[inode].ptc_num());
			bound_box.right() = draw_coords->tile_x[device_ctx.rr_nodes[inode].xlow()] 
								+ draw_coords->get_tile_width() 
								+ (1. + device_ctx.rr_nodes[inode].ptc_num());
			bound_box.bottom() = draw_coords->tile_y[device_ctx.rr_nodes[inode].ylow()];
			bound_box.top() = draw_coords->tile_y[device_ctx.rr_nodes[inode].yhigh()]
			                    + draw_coords->get_tile_width();
			break;
		default:
			// a problem. leave at default value (ie. zeros)
			break;
	}


	return bound_box;
}


static void draw_rr_switch(float from_x, float from_y, float to_x, float to_y, bool buffered, bool configurable) {

	/* 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.  */


    if (!buffered) {
        if (configurable) { /* Draw a circle for a pass transistor */
            float xcen = from_x + (to_x - from_x) / 10.;
            float ycen = from_y + (to_y - from_y) / 10.;
            const float switch_rad = 0.15;
            drawarc(xcen, ycen, switch_rad, 0., 360.);
        } else {
            //Pass, nothing to draw
        }
    } else { /* Buffer */
        if(from_x == to_x || from_y == to_y) {
            //Straight connection
            draw_triangle_along_line(t_point(from_x, from_y), t_point(to_x, to_y), SB_EDGE_STRAIGHT_ARROW_POSITION);
        } else {
            //Turn connection
            draw_triangle_along_line(t_point(from_x, from_y), t_point(to_x, to_y), SB_EDGE_TURN_ARROW_POSITION);
        }
    }
}

static void draw_rr_pin(int inode, const t_color& 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.                                                 */


	t_draw_coords* draw_coords = get_draw_coords_vars();

	//exit early unless zoomed in really far.
    if (LOD_screen_area_test_square(draw_coords->pin_size, MIN_VISIBLE_AREA) == false) {
        return;
    }

	float xcen, ycen;
	char str[vtr::bufsize];
    auto& device_ctx = g_vpr_ctx.device();

	int ipin = device_ctx.rr_nodes[inode].ptc_num();

	setcolor(color);

	/* TODO: This is where we can hide fringe physical pins and also identify globals (hide, color, show) */
    draw_get_rr_pin_coords(inode, &xcen, &ycen);
    fillrect(xcen - draw_coords->pin_size, ycen - draw_coords->pin_size, 
             xcen + draw_coords->pin_size, ycen + draw_coords->pin_size);
    sprintf(str, "%d", ipin);
    setcolor(BLACK);
    drawtext(xcen, ycen, str, 2 * draw_coords->pin_size, 2 * draw_coords->pin_size);
    setcolor(color);
}

/* 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.                                                  */
void draw_get_rr_pin_coords(int inode, float *xcen, float *ycen) {
    auto& device_ctx = g_vpr_ctx.device();
	draw_get_rr_pin_coords(&device_ctx.rr_nodes[inode], xcen, ycen);
}

void draw_get_rr_pin_coords(t_rr_node* node, float *xcen, float *ycen) {

	t_draw_coords* draw_coords = get_draw_coords_vars();

	int i, j, k, ipin, pins_per_sub_tile;
	float offset, xc, yc, step;
	t_type_ptr type;
    auto& device_ctx = g_vpr_ctx.device();

	i = node->xlow();
	j = node->ylow();

	xc = draw_coords->tile_x[i];
	yc = draw_coords->tile_y[j];

	ipin = node->ptc_num();
	type = device_ctx.grid[i][j].type;
	pins_per_sub_tile = type->num_pins / 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) (draw_coords->get_tile_width()) / (float) (type->num_pins + type->capacity);
	offset = (ipin + k + 1) * step;

	switch (node->side()) {
	case LEFT:
		yc += offset;
		break;

	case RIGHT:
		xc += draw_coords->get_tile_width();
		yc += offset;
		break;

	case BOTTOM:
		xc += offset;
		break;

	case TOP:
		xc += offset;
		yc += draw_coords->get_tile_width();
		break;

	default:
		vpr_throw(VPR_ERROR_OTHER, __FILE__, __LINE__, 
				"in draw_get_rr_pin_coords: Unexpected side %s.\n", node->side_string());
		break;
	}

	*xcen = xc;
	*ycen = yc;
}

/* 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).       */
static void drawroute(enum e_draw_net_type draw_net_type) {
	t_draw_state* draw_state = get_draw_state_vars();

	/* Next free track in each channel segment if routing is GLOBAL */

	int inode;
	t_trace *tptr;
    auto& cluster_ctx = g_vpr_ctx.clustering();
    auto& route_ctx = g_vpr_ctx.routing();

	setlinestyle(SOLID);

	/* Now draw each net, one by one.      */

	for (auto net_id : cluster_ctx.clb_nlist.nets()) {
		if (cluster_ctx.clb_nlist.net_is_global(net_id)) /* Don't draw global nets. */
			continue;

		if (route_ctx.trace_head[net_id] == nullptr) /* No routing.  Skip.  (Allows me to draw */
			continue; /* partially complete routes).            */

		if (draw_net_type == HIGHLIGHTED && draw_state->net_color[net_id] == BLACK)
			continue;

		tptr = route_ctx.trace_head[net_id]; /* SOURCE to start */
		inode = tptr->index;

        std::vector<int> rr_nodes_to_draw;
        rr_nodes_to_draw.push_back(inode);
		for (;;) {
			tptr = tptr->next;
			inode = tptr->index;

			if (draw_if_net_highlighted(net_id)) {
				/* If a net has been highlighted, highlight the whole net in *
				 * the same color.											 */
				draw_state->draw_rr_node[inode].color = draw_state->net_color[net_id];
				draw_state->draw_rr_node[inode].node_highlighted = true;
			} else {
				/* If not highlighted, draw the node in default color. */
				draw_state->draw_rr_node[inode].color = DEFAULT_RR_NODE_COLOR;
			}

            rr_nodes_to_draw.push_back(inode);

			if (tptr->iswitch == OPEN) { //End of branch
                draw_partial_route(rr_nodes_to_draw);
                rr_nodes_to_draw.clear();

                /* Skip the next segment */
				tptr = tptr->next;
				if (tptr == nullptr)
					break;
				inode = tptr->index;
                rr_nodes_to_draw.push_back(inode);

			}

		} /* End loop over traceback. */

        draw_partial_route(rr_nodes_to_draw);
	} /* End for (each net) */
}

//Draws the set of rr_nodes specified, using the colors set in draw_state
void draw_partial_route(const std::vector<int>& rr_nodes_to_draw) {

	t_draw_state* draw_state = get_draw_state_vars();
    auto& device_ctx = g_vpr_ctx.device();

	static vtr::OffsetMatrix<int> chanx_track; /* [1..device_ctx.grid.width() - 2][0..device_ctx.grid.height() - 2] */
	static vtr::OffsetMatrix<int> chany_track; /* [0..device_ctx.grid.width() - 2][1..device_ctx.grid.height() - 2] */
	if (draw_state->draw_route_type == GLOBAL) {
		/* Allocate some temporary storage if it's not already available. */
        size_t width = device_ctx.grid.width();
        size_t height = device_ctx.grid.height();
		if (chanx_track.empty()) {
			chanx_track = vtr::OffsetMatrix<int>({{{1, width-1}, {0, height-1}}});
		}

		if (chany_track.empty()) {
			chany_track = vtr::OffsetMatrix<int>({{{0, width-1}, {1, height-1}}});
		}

		for (size_t i = 1; i < width - 1; i++)
			for (size_t j = 0; j < height - 1; j++)
				chanx_track[i][j] = (-1);

		for (size_t i = 0; i < width - 1; i++)
			for (size_t j = 1; j < height - 1; j++)
				chany_track[i][j] = (-1);
	}

    for(size_t i = 1; i < rr_nodes_to_draw.size(); ++i) {

        int inode = rr_nodes_to_draw[i];
        auto rr_type = device_ctx.rr_nodes[inode].type();

        int prev_node = rr_nodes_to_draw[i-1];
        auto prev_type = device_ctx.rr_nodes[prev_node].type();

        int iedge = find_edge(prev_node, inode);
        auto switch_type = device_ctx.rr_nodes[prev_node].edge_switch(iedge);
        bool edge_configurable = device_ctx.rr_nodes[prev_node].edge_is_configurable(iedge);

        switch (rr_type) {

            case OPIN: {
                draw_rr_pin(inode, draw_state->draw_rr_node[inode].color);
                break;
            }
            case IPIN: {
                draw_rr_pin(inode, draw_state->draw_rr_node[inode].color);
                if(device_ctx.rr_nodes[prev_node].type() == OPIN) {
                    draw_pin_to_pin(prev_node, inode);
                } else {
                    draw_pin_to_chan_edge(inode, prev_node);
                }
                break;
            }
            case CHANX: {
                if (draw_state->draw_route_type == GLOBAL)
                    chanx_track[device_ctx.rr_nodes[inode].xlow()][device_ctx.rr_nodes[inode].ylow()]++;

                int itrack = get_track_num(inode, chanx_track, chany_track);
                draw_rr_chan(inode, draw_state->draw_rr_node[inode].color);

                switch (prev_type) {

                    case CHANX: {
                        draw_chanx_to_chanx_edge(prev_node, inode,
                                itrack, switch_type, edge_configurable);
                        break;
                    }
                    case CHANY: {
                        int 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, edge_configurable);
                        break;
                    }
                    case OPIN: {
                        draw_pin_to_chan_edge(prev_node, inode);
                        break;
                    }
                    default: {
                        vpr_throw(VPR_ERROR_OTHER, __FILE__, __LINE__, 
                                "Unexpected connection from an rr_node of type %d to one of type %d.\n",
                                prev_type, rr_type);
                    }
                }

                break;
            }
            case CHANY: {
                if (draw_state->draw_route_type == GLOBAL)
                    chany_track[device_ctx.rr_nodes[inode].xlow()][device_ctx.rr_nodes[inode].ylow()]++;

                int itrack = get_track_num(inode, chanx_track, chany_track);
                draw_rr_chan(inode, draw_state->draw_rr_node[inode].color);

                switch (prev_type) {

                    case CHANX: {
                        int 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, edge_configurable);
                        break;
                    }
                    case CHANY: {
                        draw_chany_to_chany_edge(prev_node, inode,
                                itrack, switch_type, edge_configurable);
                        break;
                    }
                    case OPIN: {
                        draw_pin_to_chan_edge(prev_node, inode);

                        break;
                    }
                    default: {
                        vpr_throw(VPR_ERROR_OTHER, __FILE__, __LINE__, 
                                "Unexpected connection from an rr_node of type %d to one of type %d.\n",
                                prev_type, rr_type);
                    }
                }

                break;
            }
            default: {
                break;
            }

        }
    }
}

static int get_track_num(int inode, const vtr::OffsetMatrix<int>& chanx_track, const vtr::OffsetMatrix<int>& chany_track) {

	/* Returns the track number of this routing resource node.   */

	int i, j;
	t_rr_type rr_type;
    auto& device_ctx = g_vpr_ctx.device();

	if (get_draw_state_vars()->draw_route_type == DETAILED)
		return (device_ctx.rr_nodes[inode].ptc_num());

	/* GLOBAL route stuff below. */

	rr_type = device_ctx.rr_nodes[inode].type();
	i = device_ctx.rr_nodes[inode].xlow(); /* NB: Global rr graphs must have only unit */
	j = device_ctx.rr_nodes[inode].ylow(); /* length channel segments.                 */

	switch (rr_type) {
	case CHANX:
		return (chanx_track[i][j]);

	case CHANY:
		return (chany_track[i][j]);

	default:
		vpr_throw(VPR_ERROR_OTHER, __FILE__, __LINE__, 
				"in get_track_num: Unexpected node type %d for node %d.\n", rr_type, inode);
		return OPEN;
	}
}


/* This helper function determines whether a net has been highlighted. The highlighting
 * could be caused by the user clicking on a routing resource, toggled, or 
 * fan-in/fan-out of a highlighted node.									
 */
static bool draw_if_net_highlighted (ClusterNetId inet) {
	t_draw_state* draw_state = get_draw_state_vars();

	if (draw_state->net_color[inet] != DEFAULT_RR_NODE_COLOR) {
        return true;
	}

    return false;
}


/* If an rr_node has been clicked on, it will be highlighted in MAGENTA.
 * If so, and toggle nets is selected, highlight the whole net in that colour.
 */
static void highlight_nets(char *message, int hit_node) {
	t_trace *tptr;
    auto& cluster_ctx = g_vpr_ctx.clustering();
    auto& route_ctx = g_vpr_ctx.routing();

	t_draw_state* draw_state = get_draw_state_vars();
	
	for (auto net_id : cluster_ctx.clb_nlist.nets()) {
		for (tptr = route_ctx.trace_head[net_id]; tptr != nullptr; tptr = tptr->next) {
			if (draw_state->draw_rr_node[tptr->index].color == MAGENTA) {
				draw_state->net_color[net_id] = draw_state->draw_rr_node[tptr->index].color;
				if (tptr->index == hit_node) {
					sprintf(message, "%s  ||  Net: %zu (%s)", message, size_t(net_id),
							cluster_ctx.clb_nlist.net_name(net_id).c_str());
				}
			}
			else if (draw_state->draw_rr_node[tptr->index].color == WHITE) {
				// If node is de-selected.
				draw_state->net_color[net_id] = BLACK;
				break;
			}
		}
	}
	update_message(message);
}


/* If an rr_node has been clicked on, it will be either highlighted in MAGENTA,
 * or de-highlighted in WHITE. If highlighted, and toggle_rr is selected, highlight 
 * fan_in into the node in blue and fan_out from the node in red. If de-highlighted,
 * de-highlight its fan_in and fan_out.
 */
static void draw_highlight_fan_in_fan_out(const std::set<int>& nodes) {
	int inode;

	t_draw_state* draw_state = get_draw_state_vars();
    auto& device_ctx = g_vpr_ctx.device();

    for (auto node : nodes) {
        /* Highlight the fanout nodes in red. */
        for (int iedge = 0, l = device_ctx.rr_nodes[node].num_edges(); iedge < l; iedge++) {
            int fanout_node = device_ctx.rr_nodes[node].edge_sink_node(iedge);

            if (draw_state->draw_rr_node[node].color == MAGENTA && draw_state->draw_rr_node[fanout_node].color != MAGENTA) {
                // If node is highlighted, highlight its fanout
                draw_state->draw_rr_node[fanout_node].color = DRIVES_IT_COLOR;
                draw_state->draw_rr_node[fanout_node].node_highlighted = true;
            } else if (draw_state->draw_rr_node[node].color == WHITE) {
                // If node is de-highlighted, de-highlight its fanout
                draw_state->draw_rr_node[fanout_node].color = DEFAULT_RR_NODE_COLOR;
                draw_state->draw_rr_node[fanout_node].node_highlighted = false;
            }
        }

        /* Highlight the nodes that can fanin to this node in blue. */
        for (inode = 0; inode < device_ctx.num_rr_nodes; inode++) {
            for (int iedge = 0, l = device_ctx.rr_nodes[inode].num_edges(); iedge < l; iedge++) {
                int fanout_node = device_ctx.rr_nodes[inode].edge_sink_node(iedge);
                if (fanout_node == node) { 
                    if (draw_state->draw_rr_node[node].color == MAGENTA && draw_state->draw_rr_node[inode].color != MAGENTA) {
                        // If node is highlighted, highlight its fanin
                        draw_state->draw_rr_node[inode].color = BLUE;  
                        draw_state->draw_rr_node[inode].node_highlighted = true;
                    }
                    else if (draw_state->draw_rr_node[node].color == WHITE) {
                        // If node is de-highlighted, de-highlight its fanin
                        draw_state->draw_rr_node[inode].color = DEFAULT_RR_NODE_COLOR;
                        draw_state->draw_rr_node[inode].node_highlighted = false;
                    }
                }
            }
        }
    }
}


/* This is a helper function for highlight_rr_nodes(). It determines whether 
 * a routing resource has been clicked on by computing a bounding box for that 
 *  and checking if the mouse click hit inside its bounding box.
 *
 *  It returns the hit RR node's ID (or OPEN if no hit)
 */
static int draw_check_rr_node_hit (float click_x, float click_y) {
	int inode;
	int hit_node = OPEN;
	t_bound_box bound_box;

	t_draw_coords* draw_coords = get_draw_coords_vars();
    auto& device_ctx = g_vpr_ctx.device();

	for (inode = 0; inode < device_ctx.num_rr_nodes; inode++) {
		switch (device_ctx.rr_nodes[inode].type()) {
			case IPIN:
			case OPIN:		
			{
				int i = device_ctx.rr_nodes[inode].xlow();
				int j = device_ctx.rr_nodes[inode].ylow();
				t_type_ptr type = device_ctx.grid[i][j].type;
				int width_offset = device_ctx.grid[i][j].width_offset;
				int height_offset = device_ctx.grid[i][j].height_offset;
				int ipin = device_ctx.rr_nodes[inode].ptc_num();
				float xcen, ycen;
				
				int iside;
				for (iside = 0; iside < 4; iside++) {
					// If pin exists on this side of the block, then get pin coordinates
					if (type->pinloc[width_offset][height_offset][iside][ipin]) {
						draw_get_rr_pin_coords(inode, &xcen, &ycen);

						// Now check if we clicked on this pin
						if (click_x >= xcen - draw_coords->pin_size &&
							click_x <= xcen + draw_coords->pin_size &&
							click_y >= ycen - draw_coords->pin_size && 
							click_y <= ycen + draw_coords->pin_size) {
							hit_node = inode;
							return hit_node;
						}
					}
				}
				break;
			}
			case CHANX:
			case CHANY:
			{
				bound_box = draw_get_rr_chan_bbox(inode);

				// Check if we clicked on this wire, with 30%
				// tolerance outside its boundary
				const float tolerance = 0.3;
				if (click_x >= bound_box.left() - tolerance &&
					click_x <= bound_box.right() + tolerance &&
					click_y >= bound_box.bottom() - tolerance && 
					click_y <= bound_box.top() + tolerance) {
					hit_node = inode;
					return hit_node;
				}
				break;
			}
			default:
				break;
		}
	}
	return hit_node;
}

static std::set<int> draw_expand_non_configurable_rr_nodes(int from_node) {
    std::set<int> expanded_nodes;
    draw_expand_non_configurable_rr_nodes_recurr(from_node, expanded_nodes);
    return expanded_nodes;
}

static void draw_expand_non_configurable_rr_nodes_recurr(int from_node, std::set<int>& expanded_nodes) {
    auto& device_ctx = g_vpr_ctx.device();

    expanded_nodes.insert(from_node);

    for (int iedge = 0; iedge < device_ctx.rr_nodes[from_node].num_edges(); ++iedge) {
        bool edge_configurable = device_ctx.rr_nodes[from_node].edge_is_configurable(iedge);
        int to_node = device_ctx.rr_nodes[from_node].edge_sink_node(iedge);

        if (!edge_configurable && !expanded_nodes.count(to_node)) {
            draw_expand_non_configurable_rr_nodes_recurr(to_node, expanded_nodes);
        }
    }
}

/* This routine is called when the routing resource graph is shown, and someone 
 * clicks outside a block. That click might represent a click on a wire -- we call
 * this routine to determine which wire (if any) was clicked on.  If a wire was
 * clicked upon, we highlight it in Magenta, and its fanout in red. 
 */
static bool highlight_rr_nodes(float x, float y) {

	t_draw_state* draw_state = get_draw_state_vars();
    auto& device_ctx = g_vpr_ctx.device();

	char message[250] = "";

	if (draw_state->draw_rr_toggle == DRAW_NO_RR && !draw_state->show_nets) {
		update_message(draw_state->default_message);
		drawscreen();
		return false; //No rr shown
	}

	// Check which rr_node (if any) was clicked on.
	int hit_node = draw_check_rr_node_hit (x, y);

	if (hit_node != OPEN) {
        auto nodes = draw_expand_non_configurable_rr_nodes(hit_node);
        for (auto node : nodes) {

            if (draw_state->draw_rr_node[node].color != MAGENTA) {
                /* If the node hasn't been clicked on before, highlight it
                 * in magenta.
                 */
                draw_state->draw_rr_node[node].color = MAGENTA;
                draw_state->draw_rr_node[node].node_highlighted = true;

            } else {
                //Using white color to represent de-highlighting (or 
                //de-selecting) of node.
                draw_state->draw_rr_node[node].color = WHITE;
                draw_state->draw_rr_node[node].node_highlighted = false;
            }

            //Print info about all nodes to terminal
            print_rr_node(stdout, device_ctx.rr_nodes, node);
        }

        //Show info about *only* hit node to graphics
        std::string info = describe_rr_node(hit_node);

        sprintf(message, "Selected %s", info.c_str());
        rr_highlight_message = message;

        if (draw_state->draw_rr_toggle != DRAW_NO_RR) {
            // If rr_graph is shown, highlight the fan-in/fan-outs for
            // this node.
            draw_highlight_fan_in_fan_out(nodes);
        }
   } else {
		update_message(draw_state->default_message);
        rr_highlight_message = "";
		drawscreen();
		return false; //No hit
	}

	if (draw_state->show_nets) {
		highlight_nets(message, hit_node);
	} else
		update_message(message);

	drawscreen();
    return true; //Hit
}


static void highlight_blocks(float abs_x, float abs_y, t_event_buttonPressed button_info) {

	/* 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.                                                 */

	t_draw_coords* draw_coords = get_draw_coords_vars();

	char msg[vtr::bufsize];
	ClusterBlockId clb_index = EMPTY_BLOCK_ID;
    auto& device_ctx = g_vpr_ctx.device();
    auto& cluster_ctx = g_vpr_ctx.clustering();
    auto& place_ctx = g_vpr_ctx.placement();

	/* Control + mouse click to select multiple nets. */
	if (!button_info.ctrl_pressed)
		deselect_all();


    //Check if we hit an rr node
    // Note that we check this before checking for a block, since pins and routing may appear overtop of a multi-width/height block
    if (highlight_rr_nodes(abs_x, abs_y)) {
        return; //Selected an rr node
    }


	/// determine block ///
	t_bound_box clb_bbox(0,0,0,0);

	// iterate over grid x
	for (size_t i = 0; i < device_ctx.grid.width(); ++i) {
		if (draw_coords->tile_x[i] > abs_x) {
			break; // we've gone to far in the x direction
		}
		// iterate over grid y
		for(size_t j = 0; j < device_ctx.grid.height(); ++j) {
			if (draw_coords->tile_y[j] > abs_y) {
				break; // we've gone to far in the y direction
			}
			// iterate over sub_blocks
			const t_grid_tile* grid_tile = &device_ctx.grid[i][j];
			for (int k = 0; k < grid_tile->type->capacity; ++k) {
				clb_index = place_ctx.grid_blocks[i][j].blocks[k];
				if (clb_index != EMPTY_BLOCK_ID) {
					clb_bbox = draw_coords->get_absolute_clb_bbox(clb_index, cluster_ctx.clb_nlist.block_type(clb_index));
					if (clb_bbox.intersects(abs_x, abs_y)) {
						break;
					} else {
						clb_index = EMPTY_BLOCK_ID;
					}
				}
			}
			if (clb_index != EMPTY_BLOCK_ID) {
				break; // we've found something
			}
		}
		if (clb_index != EMPTY_BLOCK_ID) {
			break; // we've found something
		}
	}

	if (clb_index == EMPTY_BLOCK_ID) {
        //Nothing found
		return;
	} 

	VTR_ASSERT(clb_index != EMPTY_BLOCK_ID);

	// note: this will clear the selected sub-block if show_blk_internal is 0,
	// or if it doesn't find anything
	t_point point_in_clb = t_point(abs_x, abs_y) - clb_bbox.bottom_left();
	highlight_sub_block(point_in_clb, clb_index, cluster_ctx.clb_nlist.block_pb(clb_index));
	
	if (get_selected_sub_block_info().has_selection()) {
		t_pb* selected_subblock = get_selected_sub_block_info().get_selected_pb();
		sprintf(msg, "sub-block %s (a \"%s\") selected", 
			selected_subblock->name, selected_subblock->pb_graph_node->pb_type->name);
	} else {
		/* Highlight block and fan-in/fan-outs. */
		draw_highlight_blocks_color(cluster_ctx.clb_nlist.block_type(clb_index), clb_index);
		sprintf(msg, "Block #%zu (%s) at (%d, %d) selected.", size_t(clb_index), cluster_ctx.clb_nlist.block_name(clb_index).c_str(), place_ctx.block_locs[clb_index].x, place_ctx.block_locs[clb_index].y);
	}

	update_message(msg);

	drawscreen(); /* Need to erase screen. */
}

static void act_on_mouse_over(float mouse_x, float mouse_y) {

	t_draw_state* draw_state = get_draw_state_vars();

	if (draw_state->draw_rr_toggle != DRAW_NO_RR) {

        int hit_node = draw_check_rr_node_hit(mouse_x, mouse_y);

        if(hit_node != OPEN) {
            //Update message

            std::string info = describe_rr_node(hit_node);
            std::string msg = vtr::string_fmt("Moused over %s", info.c_str());
            update_message(msg.c_str());
        } else {
            //No rr node moused over, reset message
            if(!rr_highlight_message.empty()) {
                update_message(rr_highlight_message.c_str());
            } else {
                update_message(draw_state->default_message);
            }
        }
    }
}


static void draw_highlight_blocks_color(t_type_ptr type, ClusterBlockId blk_id) {
	int k, iclass;
	ClusterBlockId fanblk;

	t_draw_state* draw_state = get_draw_state_vars();
    auto& cluster_ctx = g_vpr_ctx.clustering();

	for (k = 0; k < type->num_pins; k++) { /* Each pin on a CLB */
		ClusterNetId net_id = cluster_ctx.clb_nlist.block_net(blk_id, k);

		if (net_id == ClusterNetId::INVALID())
			continue;

		iclass = type->pin_class[k];

		if (type->class_inf[iclass].type == DRIVER) { /* Fanout */
			if (draw_state->block_color[blk_id] == SELECTED_COLOR) {
				/* If block already highlighted, de-highlight the fanout. (the deselect case)*/
				draw_state->net_color[net_id] = BLACK;
				for (auto pin_id : cluster_ctx.clb_nlist.net_sinks(net_id)) {
					fanblk = cluster_ctx.clb_nlist.pin_block(pin_id);
					draw_reset_blk_color(fanblk);
				}
			}
			else {
				/* Highlight the fanout */
				draw_state->net_color[net_id] = DRIVES_IT_COLOR;
				for (auto pin_id : cluster_ctx.clb_nlist.net_sinks(net_id)) {
					fanblk = cluster_ctx.clb_nlist.pin_block(pin_id);
					draw_state->block_color[fanblk] = DRIVES_IT_COLOR;
				}
			}
		} 
		else { /* This net is fanin to the block. */
			if (draw_state->block_color[blk_id] == SELECTED_COLOR) {
				/* If block already highlighted, de-highlight the fanin. (the deselect case)*/
				draw_state->net_color[net_id] = BLACK;
				fanblk = cluster_ctx.clb_nlist.net_driver_block(net_id); /* DRIVER to net */
				draw_reset_blk_color(fanblk);
			}
			else {
				/* Highlight the fanin */
				draw_state->net_color[net_id] = DRIVEN_BY_IT_COLOR;
				fanblk = cluster_ctx.clb_nlist.net_driver_block(net_id); /* DRIVER to net */
				draw_state->block_color[fanblk] = DRIVEN_BY_IT_COLOR;
			}
		}
	}

	if (draw_state->block_color[blk_id] == SELECTED_COLOR) {
		/* If block already highlighted, de-highlight the selected block. */
		draw_reset_blk_color(blk_id);
	}
	else { 
		/* Highlight the selected block. */
		draw_state->block_color[blk_id] = SELECTED_COLOR;
	}
}


static void deselect_all() {
	// Sets the color of all clbs, nets and rr_nodes to the default.
	// as well as clearing the highlighed sub-block


	t_draw_state* draw_state = get_draw_state_vars();
    auto& cluster_ctx = g_vpr_ctx.clustering();
    auto& device_ctx = g_vpr_ctx.device();
	int i;

	/* Create some colour highlighting */
	for (auto blk_id : cluster_ctx.clb_nlist.blocks()) {
		draw_reset_blk_color(blk_id);
	}

	for (auto net_id : cluster_ctx.clb_nlist.nets())
		draw_state->net_color[net_id] = BLACK;

	for (i = 0; i < device_ctx.num_rr_nodes; i++) {
		draw_state->draw_rr_node[i].color = DEFAULT_RR_NODE_COLOR;
		draw_state->draw_rr_node[i].node_highlighted = false;
	}

	get_selected_sub_block_info().clear();

}


static void draw_reset_blk_color(ClusterBlockId blk_id) {

	t_draw_state* draw_state = get_draw_state_vars();
    auto& cluster_ctx = g_vpr_ctx.clustering();

    draw_state->block_color[blk_id] = get_block_type_color(cluster_ctx.clb_nlist.block_type(blk_id));
}

/**
 * Draws a small triange, at a position along a line from 'start' to 'end'.
 *
 * 'relative_position' [0., 1] defines the triangles position relative to 'start'.
 *
 * A 'relative_position' of 0. draws the triangle centered at 'start'.
 * A 'relative_position' of 1. draws the triangle centered at 'end'.
 * Fractional values draw the triangle along the line
 */
void draw_triangle_along_line(t_point start, t_point end, float relative_position, float arrow_size) {
    VTR_ASSERT(relative_position >= 0. && relative_position <= 1.);
	float xdelta = end.x - start.x;
	float ydelta = end.y - start.y;

    float xtri = start.x + xdelta * relative_position;
    float ytri = start.y + ydelta * relative_position;

	draw_triangle_along_line(xtri, ytri, start.x, end.x, start.y, end.y, arrow_size);
}

/* Draws a trangle with it's center at loc, and of length & width
 * arrow_size, rotated such that it points in the direction
 * of the directed line segment start -> end.
 */
void draw_triangle_along_line(t_point loc, t_point start, t_point end, float arrow_size) {
    draw_triangle_along_line(loc.x, loc.y, start.x, end.x, start.y, end.y, arrow_size);
}

/**
 * Draws a trangle with it's center at (xend, yend), and of length & width
 * arrow_size, rotated such that it points in the direction
 * of the directed line segment (x1, y1) -> (x2, y2).
 *
 * Note that the parameters are in a strange order
 */
void draw_triangle_along_line(float xend, float yend, float x1, float x2, float y1, float y2, float arrow_size) {
	float switch_rad = arrow_size/2;
	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 inline bool LOD_screen_area_test_square(float width, float screen_area_threshold) {

    //Since world coordinates get clipped when converted to screen (at high zoom levels),
    //we can not pick an arbitrary world root coordinate for the rectange we want to test,
    //as clipping could cause it's area to go to zero when we convert from world to screen
    //coordinates.
    //
    //Instead we specify an on-screen location for the rectangle we plan to test
    t_point lower_left = scrn_to_world(t_point(0., 0.)); //Pick one corner of the screen

    //Offset by the width
    t_point upper_right = lower_left;
    upper_right.offset(width, width);

    t_bound_box world_rect = t_bound_box(lower_left, upper_right);

    return LOD_screen_area_test(world_rect, screen_area_threshold);
}

static inline bool default_triangle_LOD_screen_area_test() {
	return triangle_LOD_screen_area_test(DEFAULT_ARROW_SIZE);
}

static inline bool triangle_LOD_screen_area_test(float arrow_size) {
	return LOD_screen_area_test_square(arrow_size*0.66, MIN_VISIBLE_AREA);
}

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.     */

	/* TODO: Fix this for global routing, currently for detailed only */

	t_draw_coords* draw_coords = get_draw_coords_vars();
    auto& device_ctx = g_vpr_ctx.device();

    const t_rr_node& pin_rr = device_ctx.rr_nodes[pin_node];
    const t_rr_node& chan_rr = device_ctx.rr_nodes[chan_node];

    const t_grid_tile& grid_tile = device_ctx.grid[pin_rr.xlow()][pin_rr.ylow()];
	t_type_ptr grid_type = grid_tile.type;

    VTR_ASSERT_MSG(grid_type->pinloc[grid_tile.width_offset][grid_tile.height_offset][pin_rr.side()][pin_rr.pin_num()], 
                   "Pin coordinates should match block type pin locations");

    float draw_pin_offset;
    if (pin_rr.side() == TOP || pin_rr.side() == RIGHT) {
        draw_pin_offset = draw_coords->pin_size;
    } else {
        VTR_ASSERT(pin_rr.side() == BOTTOM || pin_rr.side() == LEFT);
        draw_pin_offset = -draw_coords->pin_size;
    }

    float x1 = 0, y1 = 0;
    draw_get_rr_pin_coords(pin_node, &x1, &y1);

    t_bound_box chan_bbox = draw_get_rr_chan_bbox(chan_node);

    float x2 = 0, y2 = 0;
	switch (chan_rr.type()) {
        case CHANX: {
            y1 += draw_pin_offset;
            y2 = chan_bbox.bottom();
            x2 = x1;
            if (is_opin(pin_rr.pin_num(), grid_type)) {
                if (chan_rr.direction() == INC_DIRECTION) {
                    x2 = chan_bbox.left();
                } else if (chan_rr.direction() == DEC_DIRECTION) {
                    x2 = chan_bbox.right();
                }
            }
            break;
    
        } case CHANY: {
            x1 += draw_pin_offset;
            x2 = chan_bbox.left();
            y2 = y1;
            if (is_opin(pin_rr.pin_num(), grid_type)) {
                if (chan_rr.direction() == INC_DIRECTION) {
                    y2 = chan_bbox.bottom();
                } else if (chan_rr.direction() == DEC_DIRECTION) {
                    y2 = chan_bbox.top();
                }
            }
            break;

        } default: {
            vpr_throw(VPR_ERROR_OTHER, __FILE__, __LINE__, 
                    "in draw_pin_to_chan_edge: Invalid channel node %d.\n", chan_node);
        }
    }

	drawline(x1, y1, x2, y2);

	//don't draw the ex, or triangle unless zoomed in really far
	if (chan_rr.direction() == BI_DIRECTION || !is_opin(pin_rr.pin_num(), grid_type)) {
		if (LOD_screen_area_test_square(draw_coords->pin_size*1.3,MIN_VISIBLE_AREA) == true) {
			draw_x(x2, y2, 0.7 * draw_coords->pin_size);
		}
	} else {
		if (default_triangle_LOD_screen_area_test() == true) {
			float xend = x2 + (x1 - x2) / 10.;
			float yend = y2 + (y1 - y2) / 10.;
			draw_triangle_along_line(xend, yend, x1, x2, y1, y2);
		}
	}
}


static void draw_pin_to_pin(int opin_node, int ipin_node) {
	
	/* This routine draws an edge from the opin rr node to the ipin rr node */
    auto& device_ctx = g_vpr_ctx.device();
	VTR_ASSERT(device_ctx.rr_nodes[opin_node].type() == OPIN);
	VTR_ASSERT(device_ctx.rr_nodes[ipin_node].type() == IPIN);

	float x1 = 0, y1 = 0;
	draw_get_rr_pin_coords(opin_node, &x1, &y1);

	float x2 = 0, y2 = 0;
	draw_get_rr_pin_coords(ipin_node, &x2, &y2);

	drawline(x1, y1, x2, y2);

    if (default_triangle_LOD_screen_area_test() == true) {
        float xend = x2 + (x1 - x2) / 10.;
        float yend = y2 + (y1 - y2) / 10.;
        draw_triangle_along_line(xend, yend, x1, x2, y1, y2);
    }
}

static inline void draw_mux_with_size(t_point origin, e_side orientation, float height, int size) {
    setcolor(YELLOW);
    auto bounds = draw_mux(origin, orientation, height);

    setcolor(BLACK);
    drawtext_in(bounds, std::to_string(size));
}

//Draws a mux
static inline t_bound_box draw_mux(t_point origin, e_side orientation, float height) {
    return draw_mux(origin, orientation, height, 0.4*height, 0.6);
}

//Draws a mux, height/width define the bounding box, scale [0.,1.] controls the slope of the muxes sides
static inline t_bound_box draw_mux(t_point origin, e_side orientation, float height, float width, float scale) {
    std::array<t_point, 4> mux_polygon;

    switch(orientation) {
        case TOP:
            //Clock-wise from bottom left
            mux_polygon[0] = t_point(origin.x - height / 2, origin.y - width / 2);
            mux_polygon[1] = t_point(origin.x - (scale * height) / 2, origin.y + width / 2);
            mux_polygon[2] = t_point(origin.x + (scale * height) / 2, origin.y + width / 2);
            mux_polygon[3] = t_point(origin.x + height / 2, origin.y - width / 2);
            break;
        case BOTTOM:
            //Clock-wise from bottom left
            mux_polygon[0] = t_point(origin.x - (scale * height) / 2, origin.y - width / 2);
            mux_polygon[1] = t_point(origin.x - height / 2, origin.y + width / 2);
            mux_polygon[2] = t_point(origin.x + height / 2, origin.y + width / 2);
            mux_polygon[3] = t_point(origin.x + (scale * height) / 2, origin.y - width / 2);
            break;
        case LEFT:
            //Clock-wise from bottom left
            mux_polygon[0] = t_point(origin.x - width / 2, origin.y - (scale * height) / 2);
            mux_polygon[1] = t_point(origin.x - width / 2, origin.y + (scale * height) / 2);
            mux_polygon[2] = t_point(origin.x + width / 2, origin.y + height / 2);
            mux_polygon[3] = t_point(origin.x + width / 2, origin.y - height / 2);
            break;
        case RIGHT:
            //Clock-wise from bottom left
            mux_polygon[0] = t_point(origin.x - width / 2, origin.y - height / 2);
            mux_polygon[1] = t_point(origin.x - width / 2, origin.y + height / 2);
            mux_polygon[2] = t_point(origin.x + width / 2, origin.y + (scale * height) / 2);
            mux_polygon[3] = t_point(origin.x + width / 2, origin.y - (scale * height) / 2);
            break;

        default:
            VTR_ASSERT_MSG(false, "Unrecognized orientation");
    }

    fillpoly(mux_polygon.data(), mux_polygon.size());

    t_point min = mux_polygon[0];
    t_point max = mux_polygon[0];
    for(const auto& point : mux_polygon) {
        min.x = std::min(min.x, point.x);
        min.y = std::min(min.y, point.y);
        max.x = std::max(max.x, point.x);
        max.y = std::max(max.y, point.y);
    }

    return t_bound_box(min, max);
}


t_point tnode_draw_coord(tatum::NodeId node) {
    auto& atom_ctx = g_vpr_ctx.atom();

    AtomPinId pin = atom_ctx.lookup.tnode_atom_pin(node);
    return atom_pin_draw_coord(pin);
}

t_point atom_pin_draw_coord(AtomPinId pin) {
    auto& atom_ctx = g_vpr_ctx.atom();

    AtomBlockId blk = atom_ctx.nlist.pin_block(pin);
    ClusterBlockId clb_index = atom_ctx.lookup.atom_clb(blk);
    const t_pb_graph_node* pg_gnode = atom_ctx.lookup.atom_pb_graph_node(blk);

	t_draw_coords* draw_coords = get_draw_coords_vars();
    t_bound_box pb_bbox = draw_coords->get_absolute_pb_bbox(clb_index, pg_gnode);

    //We place each atom pin inside it's pb bounding box
    //and distribute the pins along it's vertical centre line
	const float FRACTION_USABLE_WIDTH = 0.8;
	float width =  pb_bbox.get_width();
	float usable_width =  width  * FRACTION_USABLE_WIDTH;
	float x_offset = pb_bbox.left() + width * (1 - FRACTION_USABLE_WIDTH)/2;

    int pin_index, pin_total;
	find_pin_index_at_model_scope(pin, blk, &pin_index, &pin_total);

	const t_point point =  {
		x_offset + usable_width * pin_index / ((float)pin_total),
		pb_bbox.get_ycenter()
	};

    return point;
}

static void draw_crit_path() {
    tatum::TimingPathCollector path_collector;

    t_draw_state* draw_state = get_draw_state_vars();
    auto& timing_ctx = g_vpr_ctx.timing();

    if (draw_state->show_crit_path == DRAW_NO_CRIT_PATH) {
        return;
    }

    if (!draw_state->setup_timing_info) {
        return; //No timing to draw
    }

    //Get the worst timing path
    auto paths = path_collector.collect_worst_setup_paths(*timing_ctx.graph, *(draw_state->setup_timing_info->setup_analyzer()), 1);
    tatum::TimingPath path = paths[0];

    //Walk through the timing path drawing each edge
    tatum::NodeId prev_node;
    float prev_arr_time = std::numeric_limits<float>::quiet_NaN();
    int i = 0;
    for(tatum::TimingPathElem elem : path.data_arrival_elements()) {
        tatum::NodeId node = elem.node();
        float arr_time = elem.tag().time();

        if(prev_node) {
            //We draw each 'edge' in a different color, this allows users to identify the stages and
            //any routing which corresponds to the edge
            //
            //We pick colors from the kelly max-contrast list, for long paths there may be repeats
            t_color color = kelly_max_contrast_colors[i++ % kelly_max_contrast_colors.size()];

            float delay = arr_time - prev_arr_time;
            if (draw_state->show_crit_path == DRAW_CRIT_PATH_FLYLINES || draw_state->show_crit_path == DRAW_CRIT_PATH_FLYLINES_DELAYS) {
                setcolor(color);
                setlinestyle(SOLID);
                draw_flyline_timing_edge(tnode_draw_coord(prev_node), tnode_draw_coord(node), delay);
            } else {
                VTR_ASSERT(draw_state->show_crit_path != DRAW_NO_CRIT_PATH);

                //Draw the routed version of the timing edge
                draw_routed_timing_edge(prev_node, node, delay, color);
            }
        }
        prev_node = node;
        prev_arr_time = arr_time;
    }
}

static void draw_flyline_timing_edge(t_point start, t_point end, float incr_delay) {
    drawline(start, end);
    draw_triangle_along_line(start, end, 0.95, 40*DEFAULT_ARROW_SIZE);
    draw_triangle_along_line(start, end, 0.05, 40*DEFAULT_ARROW_SIZE);


    bool draw_delays = (get_draw_state_vars()->show_crit_path == DRAW_CRIT_PATH_FLYLINES_DELAYS
                        || get_draw_state_vars()->show_crit_path == DRAW_CRIT_PATH_ROUTING_DELAYS);
    if (draw_delays) {
        //Determine the strict bounding box based on the lines start/end
        float min_x = std::min(start.x, end.x);
        float max_x = std::max(start.x, end.x);
        float min_y = std::min(start.y, end.y);
        float max_y = std::max(start.y, end.y);

        //If we have a nearly horizontal/vertical line the bbox is too
        //small to draw the text, so widen it by a tile (i.e. CLB) width
        float tile_width = get_draw_coords_vars()->get_tile_width();
        if (max_x - min_x < tile_width) {
            max_x += tile_width / 2;
            min_x -= tile_width / 2;
        }
        if (max_y - min_y < tile_width) {
            max_y += tile_width / 2;
            min_y -= tile_width / 2;
        }

        //TODO: draw the delays nicer
        //   * rotate to match edge
        //   * offset from line
        //   * track visible in window
        t_bound_box text_bbox(min_x, min_y, max_x, max_y);

        std::stringstream ss;
        ss.precision(3);
        ss << 1e9*incr_delay; //In nanoseconds
        std::string incr_delay_str = ss.str();

        drawtext_in(text_bbox, incr_delay_str.c_str());
    }
}

static void draw_routed_timing_edge(tatum::NodeId start_tnode, tatum::NodeId end_tnode, float incr_delay, t_color color) {

    draw_routed_timing_edge_connection(start_tnode, end_tnode, color);
    
    setlinestyle(DASHED);
    setlinewidth(3);
    setcolor(color);

    draw_flyline_timing_edge(tnode_draw_coord(start_tnode), tnode_draw_coord(end_tnode), incr_delay);

    setlinewidth(0);
    setlinestyle(SOLID);
}

//Collect all the drawing locations associated with the timing edge between start and end
static void draw_routed_timing_edge_connection(tatum::NodeId src_tnode, tatum::NodeId sink_tnode, t_color color) {
    auto& atom_ctx = g_vpr_ctx.atom();
    auto& cluster_ctx = g_vpr_ctx.clustering();
    auto& timing_ctx = g_vpr_ctx.timing();

    AtomPinId atom_src_pin = atom_ctx.lookup.tnode_atom_pin(src_tnode);
    AtomPinId atom_sink_pin = atom_ctx.lookup.tnode_atom_pin(sink_tnode);

	std::vector<t_point> points;
    points.push_back(atom_pin_draw_coord(atom_src_pin));

    tatum::EdgeId tedge = timing_ctx.graph->find_edge(src_tnode, sink_tnode);
    tatum::EdgeType edge_type = timing_ctx.graph->edge_type(tedge);

	ClusterNetId net_id = ClusterNetId::INVALID();

    //We currently only trace interconnect edges in detail, and treat all others
    //as flylines
    if (edge_type == tatum::EdgeType::INTERCONNECT) {
        //All atom pins are implemented inside CLBs, so next hop is to the top-level CLB pins

        //TODO: most of this code is highly similar to code in PostClusterDelayCalculator, refactor
        //      into a common method for walking the clustered netlist, this would also (potentially)
        //      allow us to grab the component delays
        AtomBlockId atom_src_block = atom_ctx.nlist.pin_block(atom_src_pin);
        AtomBlockId atom_sink_block = atom_ctx.nlist.pin_block(atom_sink_pin);

        ClusterBlockId clb_src_block = atom_ctx.lookup.atom_clb(atom_src_block);
        VTR_ASSERT(clb_src_block != ClusterBlockId::INVALID());
		ClusterBlockId clb_sink_block = atom_ctx.lookup.atom_clb(atom_sink_block);
        VTR_ASSERT(clb_sink_block != ClusterBlockId::INVALID());

        const t_pb_graph_pin* sink_gpin = atom_ctx.lookup.atom_pin_pb_graph_pin(atom_sink_pin);
        VTR_ASSERT(sink_gpin);

        int sink_pb_route_id = sink_gpin->pin_count_in_cluster;

		int sink_block_pin_index = -1;
		int sink_net_pin_index = -1;

        std::tie(net_id, sink_block_pin_index, sink_net_pin_index) = find_pb_route_clb_input_net_pin(clb_sink_block, sink_pb_route_id);
        if(net_id != ClusterNetId::INVALID() && sink_block_pin_index != -1 && sink_net_pin_index != -1) {
            //Connection leaves the CLB
            //Now that we have the CLB source and sink pins, we need to grab all the points on the routing connecting the pins
			VTR_ASSERT(cluster_ctx.clb_nlist.net_driver_block(net_id) == clb_src_block);

			auto routed_rr_nodes = trace_routed_connection_rr_nodes(net_id, 0, sink_net_pin_index);

            //Mark all the nodes highlighted
            t_draw_state* draw_state = get_draw_state_vars();
            for (int inode : routed_rr_nodes) {
				draw_state->draw_rr_node[inode].color = color;
            }

            draw_partial_route(routed_rr_nodes);
        } else {
            //Connection entirely within the CLB, we don't draw the internal routing so treat it as a fly-line
            VTR_ASSERT(clb_src_block == clb_sink_block);
        }
    }

    points.push_back(atom_pin_draw_coord(atom_sink_pin));
}

//Returns the set of rr nodes which connect driver to sink
static std::vector<int> trace_routed_connection_rr_nodes(const ClusterNetId net_id, const int driver_pin, const int sink_pin) {
    auto& route_ctx = g_vpr_ctx.routing();

    bool allocated_route_tree_structs = alloc_route_tree_timing_structs(true); //Needed for traceback_to_route_tree

    //Conver the traceback into an easily search-able
    t_rt_node* rt_root = traceback_to_route_tree(net_id);

    VTR_ASSERT(rt_root->inode == route_ctx.net_rr_terminals[net_id][driver_pin]);

    int sink_rr_node = route_ctx.net_rr_terminals[net_id][sink_pin];

    std::vector<int> rr_nodes_on_path;

    //Collect the rr nodes
    trace_routed_connection_rr_nodes_recurr(rt_root, sink_rr_node, rr_nodes_on_path);

    //Traced from sink to source, but we want to draw from source to sink
    std::reverse(rr_nodes_on_path.begin(), rr_nodes_on_path.end()); 

    if (allocated_route_tree_structs) {
        free_route_tree_timing_structs(); //Clean-up
    }
    return rr_nodes_on_path;
}

//Helper function for trace_routed_connection_rr_nodes
//Adds the rr nodes linking rt_node to sink_rr_node to rr_nodes_on_path
//Returns true if rt_node is on the path
bool trace_routed_connection_rr_nodes_recurr(const t_rt_node* rt_node, int sink_rr_node, std::vector<int>& rr_nodes_on_path) {
    //DFS from the current rt_node to the sink_rr_node, when the sink is found trace back the used rr nodes

    if (rt_node->inode == sink_rr_node) {
        rr_nodes_on_path.push_back(sink_rr_node);
        return true;
    }

    for (t_linked_rt_edge* edge = rt_node->u.child_list; edge != nullptr; edge = edge->next) {
        t_rt_node* child_rt_node = edge->child;
        VTR_ASSERT(child_rt_node);

        bool on_path_to_sink = trace_routed_connection_rr_nodes_recurr(child_rt_node, sink_rr_node, rr_nodes_on_path);

        if (on_path_to_sink) {
            rr_nodes_on_path.push_back(rt_node->inode);
            return true;
        }
    }

    return false; //Not on path to sink
}

//Find the edge between two rr nodes
static int find_edge(int prev_inode, int inode) {
    auto& device_ctx = g_vpr_ctx.device();
    for (int iedge = 0; iedge < device_ctx.rr_nodes[prev_inode].num_edges(); ++iedge) {
        if (device_ctx.rr_nodes[prev_inode].edge_sink_node(iedge) == inode) {
            return iedge;
        }
    }
    VTR_ASSERT(false);
    return OPEN;
}

t_color to_t_color(vtr::Color<float> color) {
    return t_color(color.r*255, color.g*255, color.b*255); 
}

static void draw_color_map_legend(const vtr::ColorMap& cmap) {
    constexpr float LEGEND_WIDTH_FAC = 0.075;
    constexpr float LEGEND_VERT_OFFSET_FAC = 0.05;
    constexpr float TEXT_OFFSET = 10;
    constexpr size_t NUM_COLOR_POINTS = 1000;

    set_coordinate_system(GL_SCREEN);
    t_bound_box visible_screen = get_visible_screen();


    float width = visible_screen.get_width();
    float vert_offset = visible_screen.get_height() * LEGEND_VERT_OFFSET_FAC;

    t_bound_box legend (visible_screen.left(), visible_screen.bottom() + vert_offset, visible_screen.left() + width * LEGEND_WIDTH_FAC, visible_screen.top() - vert_offset);

    float range = cmap.max() - cmap.min();
    float height_incr = legend.get_height() / float(NUM_COLOR_POINTS);
    for (size_t i = 0; i < NUM_COLOR_POINTS; ++i) {

        float val = cmap.min() + (float(i) / NUM_COLOR_POINTS) * range;
        t_color color = to_t_color(cmap.color(val));


        t_bound_box cbox = {legend.left(), legend.bottom() + i * height_incr, 
                            legend.right(), legend.bottom() + (i+1) * height_incr};
        setcolor(color);
        fillrect(cbox);


    }

    setcolor(BLACK);

    //Min mark
    std::string str = vtr::string_fmt("%.3g", cmap.min());
    drawtext(legend.get_xcenter(), legend.bottom() + TEXT_OFFSET, str.c_str());

    //Mid marker
    str = vtr::string_fmt("%.3g", cmap.min() + (cmap.range() / 2.));
    drawtext(legend.get_xcenter(), legend.get_ycenter(), str.c_str());

    //Max marker
    str = vtr::string_fmt("%.3g", cmap.max());
    drawtext(legend.get_xcenter(), legend.top() - TEXT_OFFSET, str.c_str());


    setcolor(BLACK);
    drawrect(legend);

    set_coordinate_system(GL_WORLD);
}

std::vector<std::set<ClusterNetId>> collect_rr_node_nets() {
    auto& device_ctx = g_vpr_ctx.device();
    auto& route_ctx = g_vpr_ctx.routing();
    auto& cluster_ctx = g_vpr_ctx.clustering();

    std::vector<std::set<ClusterNetId>> rr_node_nets(device_ctx.num_rr_nodes);
    for (ClusterNetId inet : cluster_ctx.clb_nlist.nets()) {
        t_trace* trace_elem = route_ctx.trace_head[inet];
        while (trace_elem) {
            int rr_node = trace_elem->index;

            rr_node_nets[rr_node].insert(inet);
            
            trace_elem = trace_elem->next;
        }
    }
    return rr_node_nets;
}

t_color get_block_type_color(t_type_ptr type) {

    //Wrap around if there are too many blocks
    // This ensures we support an arbitrary number of types,
    // although the colours may repeat
    t_color color = block_type_colors[type->index % block_type_colors.size()];

    return color;
}

//Lightens a color's luminance [0, 1] by an aboslute 'amount'
t_color lighten_color(t_color color, float amount) {
    constexpr double MAX_LUMINANCE = 0.95; //Clip luminance so it doesn't go full white
    auto hsl = color2hsl(color);

    hsl.l = std::max(0., std::min(MAX_LUMINANCE, hsl.l + amount));

    return hsl2color(hsl);
}
