/****************************************************************************\
 *  grid.c - put display grid info here
 *****************************************************************************
 *  Copyright (C) 2004-2007 The Regents of the University of California.
 *  Copyright (C) 2008-2010 Lawrence Livermore National Security.
 *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
 *  Written by Danny Auble <da@llnl.gov>, et. al.
 *  CODE-OCEC-09-009. All rights reserved.
 *
 *  This file is part of Slurm, a resource management program.
 *  For details, see <https://slurm.schedmd.com/>.
 *  Please also read the included file: DISCLAIMER.
 *
 *  Slurm is free software; you can redistribute it and/or modify it under
 *  the terms of the GNU General Public License as published by the Free
 *  Software Foundation; either version 2 of the License, or (at your option)
 *  any later version.
 *
 *  In addition, as a special exception, the copyright holders give permission
 *  to link the code of portions of this program with the OpenSSL library under
 *  certain conditions as described in each individual source file, and
 *  distribute linked combinations including the two. You must obey the GNU
 *  General Public License in all respects for all of the code used other than
 *  OpenSSL. If you modify file(s) with this exception, you may extend this
 *  exception to your version of the file(s), but you are not obligated to do
 *  so. If you do not wish to do so, delete this exception statement from your
 *  version.  If you delete this exception statement from all source files in
 *  the program, then also delete it here.
 *
 *  Slurm is distributed in the hope that it will be useful, but WITHOUT ANY
 *  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 *  FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
 *  details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with Slurm; if not, write to the Free Software Foundation, Inc.,
 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA.
\*****************************************************************************/

#include "config.h"

#include "sview.h"

#define RESET_GRID -2
#define TOPO_DEBUG  0

list_t *grid_button_list = NULL;
list_t *blinking_button_list = NULL;
list_t *multi_button_list = NULL;

char *sview_colors[] = {"#0000FF", "#00FF00", "#00FFFF", "#FFFF00",
			"#FF0000", "#4D4DC6", "#F09A09", "#BDFA19",
			"#715627", "#6A8CA2", "#4C7127", "#25B9B9",
			"#A020F0", "#8293ED", "#FFA500", "#FFC0CB",
			"#8B6914", "#18A24E", "#F827FC", "#B8A40C"};
char *blank_color = "#919191";
char *white_color = "#FFFFFF";
char *topo1_color = "honeydew"; //"seashell";DarkTurquoise
char *topo2_color = "gray94";//honeydew";

int sview_colors_cnt = 20;

typedef struct {
	int node_inx_id;
	int color_inx_id;
	list_t *button_list;
} grid_foreach_t;

typedef struct {
	list_t *button_list;
	int *coord_x;
	int *coord_y;
	int default_y_offset;
	grid_button_t *grid_button;
	int *inx;
	GtkTable *table;
	int table_y;
	bool force_row_break;
} button_processor_t;

static gboolean _mouseover_node(GtkWidget *widget, GdkEventButton *event,
				grid_button_t *grid_button)
{
	gboolean rc = true;

	grid_button->last_state = gtk_widget_get_state(widget);
#ifdef GTK2_USE_TOOLTIP
	gtk_widget_set_tooltip_text(grid_button->button,
				    grid_button->node_name);
#else
	if (!grid_button->tip)
		grid_button->tip = gtk_tooltips_new();
	gtk_tooltips_set_tip(grid_button->tip,
			     grid_button->button,
			     grid_button->node_name,
			     "click for node stats");
#endif
	//g_print("on at %s\n", grid_button->node_name);
	gtk_widget_set_state(grid_button->button, GTK_STATE_PRELIGHT);

	return rc;
}

static gboolean _mouseoff_node(GtkWidget *widget, GdkEventButton *event,
			       grid_button_t *grid_button)
{
	gboolean rc = false;

	if (grid_button->last_state == GTK_STATE_ACTIVE) {
		gtk_widget_set_state(grid_button->button, GTK_STATE_ACTIVE);
		rc = true;
		//g_print("off of %s\n", grid_button->node_name);
	}
	return rc;
}

static gboolean _open_node(GtkWidget *widget, GdkEventButton *event,
			   grid_button_t *grid_button)
{
	if (event->button == 1) {
		popup_all_node_name(grid_button->node_name, INFO_PAGE, NULL);
	} else if (event->button == 3) {
		/* right click */
		admin_menu_node_name(grid_button->node_name, event);
	}

	return false;
}

/* static void _state_changed(GtkWidget *button, GtkStateType state, */
/* 			   grid_button_t *grid_button) */
/* { */
/* 	g_print("state of %s is now %d\n", grid_button->node_name, state); */
/* } */

static void _add_button_signals(grid_button_t *grid_button)
{
	/* g_signal_connect(G_OBJECT(grid_button->button), */
	/* 		 "state-changed", */
	/* 		 G_CALLBACK(_state_changed), */
	/* 		 grid_button); */
	g_signal_connect(G_OBJECT(grid_button->button),
			 "button-press-event",
			 G_CALLBACK(_open_node),
			 grid_button);
	g_signal_connect(G_OBJECT(grid_button->button),
			 "enter-notify-event",
			 G_CALLBACK(_mouseover_node),
			 grid_button);
	g_signal_connect(G_OBJECT(grid_button->button),
			 "leave-notify-event",
			 G_CALLBACK(_mouseoff_node),
			 grid_button);
}

/*
 * Comparator used for sorting buttons
 *
 * returns: -1: button_a->inx > button_b->inx
 *           0: rec_a == rec_b
 *           1: rec_a < rec_b
 *
 */
static int _sort_button_inx(void *b1, void *b2)
{
	grid_button_t *button_a = *(grid_button_t **)b1;
	grid_button_t *button_b = *(grid_button_t **)b2;
	int inx_a;
	int inx_b;

	inx_a = button_a->inx;
	inx_b = button_b->inx;

	if (inx_a < inx_b)
		return -1;
	else if (inx_a > inx_b)
		return 1;
	return 0;
}

void _put_button_as_down(grid_button_t *grid_button, int state)
{
	GtkWidget *image = NULL;
/* 	GdkColor color; */

	if (GTK_IS_EVENT_BOX(grid_button->button)) {
		//gtk_widget_set_sensitive (grid_button->button, true);
		return;
	}

	gtk_widget_destroy(grid_button->button);
	grid_button->color = NULL;
	grid_button->color_inx = MAKE_DOWN;
	grid_button->button = gtk_event_box_new();
	gtk_widget_set_size_request(grid_button->button,
				    working_sview_config.button_size,
				    working_sview_config.button_size);
	gtk_event_box_set_above_child(GTK_EVENT_BOX(grid_button->button),
				      false);
	_add_button_signals(grid_button);

/* 	if (grid_button->frame) */
/* 		gtk_container_add(GTK_CONTAINER(grid_button->frame), */
/* 				  grid_button->button); */
	if (grid_button->table)
		gtk_table_attach(grid_button->table, grid_button->button,
				 grid_button->table_x,
				 (grid_button->table_x+1),
				 grid_button->table_y,
				 (grid_button->table_y+1),
				 GTK_SHRINK, GTK_SHRINK,
				 1, 1);

	//gdk_color_parse("black", &color);
	//sview_widget_modify_bg(grid_button->button, GTK_STATE_NORMAL, color);
	//gdk_color_parse(white_color, &color);
	//sview_widget_modify_bg(grid_button->button, GTK_STATE_ACTIVE, color);
	if (state == NODE_STATE_DRAIN)
		image = gtk_image_new_from_stock(GTK_STOCK_DIALOG_ERROR,
						 GTK_ICON_SIZE_SMALL_TOOLBAR);
	else
		image = gtk_image_new_from_stock(GTK_STOCK_CANCEL,
						 GTK_ICON_SIZE_SMALL_TOOLBAR);
	gtk_container_add(GTK_CONTAINER(grid_button->button), image);
	gtk_widget_show_all(grid_button->button);
	return;
}


void _put_button_as_up(grid_button_t *grid_button)
{
	if (GTK_IS_BUTTON(grid_button->button)) {
		return;
	}
	gtk_widget_destroy(grid_button->button);
	grid_button->button = gtk_button_new();
	gtk_widget_set_size_request(grid_button->button,
				    working_sview_config.button_size,
				    working_sview_config.button_size);
	_add_button_signals(grid_button);

/* 	if (grid_button->frame) */
/* 		gtk_container_add(GTK_CONTAINER(grid_button->frame), */
/* 				  grid_button->button); */
	if (grid_button->table)
		gtk_table_attach(grid_button->table, grid_button->button,
				 grid_button->table_x,
				 (grid_button->table_x+1),
				 grid_button->table_y,
				 (grid_button->table_y+1),
				 GTK_SHRINK, GTK_SHRINK,
				 1, 1);
	gtk_widget_show_all(grid_button->button);
	return;
}

void _put_button_as_inactive(grid_button_t *grid_button)
{
	if (GTK_IS_BUTTON(grid_button->button)) {
		//gtk_widget_set_sensitive (grid_button->button, false);
		return;
	}
	gtk_widget_destroy(grid_button->button);
	grid_button->button = gtk_button_new();
	gtk_widget_set_size_request(grid_button->button,
				    working_sview_config.button_size,
				    working_sview_config.button_size);
	//gtk_widget_set_sensitive (grid_button->button, false);

	_add_button_signals(grid_button);

/* 	if (grid_button->frame) */
/* 		gtk_container_add(GTK_CONTAINER(grid_button->frame), */
/* 				  grid_button->button); */
	if (grid_button->table)
		gtk_table_attach(grid_button->table, grid_button->button,
				 grid_button->table_x,
				 (grid_button->table_x+1),
				 grid_button->table_y,
				 (grid_button->table_y+1),
				 GTK_SHRINK, GTK_SHRINK,
				 1, 1);
	gtk_widget_show_all(grid_button->button);
	return;
}

static bool _change_button_color(grid_button_t *grid_button,
				 int color_inx, char *new_col, GdkColor color,
				 bool only_change_unused,
				 enum node_states state_override)
{
	enum node_states state;
	uint16_t node_base_state;
	bool changed = 0;

	xassert(grid_button);
	if (only_change_unused && grid_button->used)
		return 0;

	grid_button->used = true;
	if (color_inx == MAKE_BLACK) {
		if (grid_button->color_inx != color_inx) {
			_put_button_as_inactive(grid_button);
			grid_button->color = new_col;
			grid_button->color_inx = color_inx;
			sview_widget_modify_bg(grid_button->button,
					       GTK_STATE_NORMAL, color);
/* 				sview_widget_modify_bg(grid_button->button,  */
/* 						       GTK_STATE_ACTIVE, */
/* 						       color); */
			changed = 1;
		}

		return changed;
	}

	if (state_override != NODE_STATE_UNKNOWN)
		state = state_override;
	else
		state = grid_button->state;

	node_base_state = state & NODE_STATE_BASE;

	if (node_base_state == NODE_STATE_DOWN) {
		_put_button_as_down(grid_button, NODE_STATE_DOWN);
	} else if (state & NODE_STATE_DRAIN) {
		_put_button_as_down(grid_button, NODE_STATE_DRAIN);
	} else if (grid_button->node_name &&
		   !xstrcmp(grid_button->node_name, "EMPTY")) {
		grid_button->color_inx = MAKE_BLACK;
//		_put_button_as_up(grid_button);
	} else if (grid_button->color_inx != color_inx) {
		_put_button_as_up(grid_button);
		grid_button->color = new_col;
		grid_button->color_inx = color_inx;
		sview_widget_modify_bg(grid_button->button,
				       GTK_STATE_NORMAL, color);
/* 			sview_widget_modify_bg(grid_button->button,  */
/* 					       GTK_STATE_ACTIVE, color); */
		changed = 1;
	}

	return changed;
}


static void _each_highlightd(GtkTreeModel *model,
			     GtkTreePath *path,
			     GtkTreeIter *iter,
			     gpointer userdata)
{
	list_itr_t *itr = NULL;
	grid_button_t *grid_button = NULL;
	int *node_inx = NULL;
	int color_inx;

	int j=0;
	GdkColor color;

	grid_foreach_t *grid_foreach = userdata;

	gtk_tree_model_get(model, iter, grid_foreach->node_inx_id,
			   &node_inx, -1);
	gtk_tree_model_get(model, iter, grid_foreach->color_inx_id,
			   &color_inx, -1);

	if (!node_inx)
		return;

	if (color_inx > sview_colors_cnt) {
		g_print("hey the color_inx from %d was set to %d > %d\n",
			grid_foreach->color_inx_id, color_inx,
			sview_colors_cnt);
		color_inx %= sview_colors_cnt;
	}
	gdk_color_parse(sview_colors[color_inx], &color);

	itr = list_iterator_create(grid_foreach->button_list);
	while ((grid_button = list_next(itr))) {
		/*For multiple selections, need to retain all selected.
		 *(previously this assumed only one selected).
		 */

		if ((node_inx[j] < 0)
		    || (grid_button->inx < node_inx[j])
		    || (grid_button->inx > node_inx[j+1]))
			continue;

		(void)_change_button_color(grid_button, color_inx,
				     sview_colors[color_inx],
				     color, 0, 0);

		if (gtk_widget_get_state(grid_button->button) != GTK_STATE_NORMAL)
			gtk_widget_set_state(grid_button->button,
					     GTK_STATE_NORMAL);

		if (grid_button->inx == node_inx[j+1])
			j+=2;

	}

	list_iterator_destroy(itr);
	return;
}

static void _each_highlight_selected(GtkTreeModel *model,
				     GtkTreePath *path,
				     GtkTreeIter *iter,
				     gpointer userdata)
{

	grid_button_t *grid_button = NULL;
	int node_inx = 0;
	bool speedup_break = true;
	grid_foreach_t *grid_foreach = userdata;
	list_itr_t *itr = NULL;

	xassert(grid_foreach);
	if (working_sview_config.grid_topological)
		speedup_break = false;

	gtk_tree_model_get(model, iter, grid_foreach->node_inx_id,
			   &node_inx, -1);

	if (node_inx < 0 || !grid_foreach->button_list)
		return;
	itr = list_iterator_create(grid_foreach->button_list);
	while ((grid_button = list_next(itr))) {
		/* For multiple selections, need to retain all selected.
		 * (previously this assumed only one selected). */
		if (grid_button->inx != node_inx)
			continue;
		else if (gtk_widget_get_state(grid_button->button)
			 != GTK_STATE_NORMAL) {
			gtk_widget_set_state(grid_button->button,
					     GTK_STATE_NORMAL);
			change_grid_color(grid_button_list, grid_button->inx,
					  grid_button->inx,
					  grid_button->inx, true, 0);
		}
		if (speedup_break)
			break;
		speedup_break = true; //allow for secondary grid button
	}
	list_iterator_destroy(itr);
	return;

}

/* Add a button for a given node. If node_ptr == NULL then fill in any gaps
 * in the grid just for a clean look. Always call with node_ptr == NULL for
 * the last call in the sequence. */
static int _add_button_to_list(node_info_t *node_ptr,
			       button_processor_t *button_processor)
{
	grid_button_t *grid_button = button_processor->grid_button;

	if (node_ptr == NULL)
		return SLURM_SUCCESS;

	if (!grid_button) {
		grid_button = xmalloc(sizeof(grid_button_t));
		grid_button->color_inx = MAKE_INIT;
		grid_button->inx = (*button_processor->inx);
		grid_button->table = button_processor->table;
		grid_button->table_x = (*button_processor->coord_x);
		grid_button->table_y = (*button_processor->coord_y);
		grid_button->button = gtk_button_new();
		grid_button->node_name = xstrdup(node_ptr->name);

		gtk_widget_set_size_request(grid_button->button,
					    working_sview_config.button_size,
					    working_sview_config.button_size);
		_add_button_signals(grid_button);
		list_append(button_processor->button_list, grid_button);

		gtk_table_attach(button_processor->table, grid_button->button,
				 (*button_processor->coord_x),
				 ((*button_processor->coord_x)+1),
				 (*button_processor->coord_y),
				 ((*button_processor->coord_y)+1),
				 GTK_SHRINK, GTK_SHRINK,
				 1, 1);
	} else {
		grid_button->table_x = (*button_processor->coord_x);
		grid_button->table_y = (*button_processor->coord_y);
		gtk_container_child_set(
			GTK_CONTAINER(button_processor->table),
			grid_button->button,
			"left-attach", (*button_processor->coord_x),
			"right-attach", ((*button_processor->coord_x)+1),
			"top-attach", (*button_processor->coord_y),
			"bottom-attach", ((*button_processor->coord_y)+1),
			NULL);
	}
	/* gtk_container_add(GTK_CONTAINER(grid_button->frame),  */
/* 				  grid_button->button); */
/* 		gtk_frame_set_shadow_type(GTK_FRAME(grid_button->frame), */
/* 					  GTK_SHADOW_ETCHED_OUT); */

	/* On linear systems we just up the x_coord until we hit the
	 * side of the table and then increment the coord_y.  We add
	 * space between each tenth row. */
	(*button_processor->coord_x)++;

	if (button_processor->force_row_break) {
		(*button_processor->coord_x) = 0;
		(*button_processor->coord_y)++;
		gtk_table_set_row_spacing(
			button_processor->table,
			(*button_processor->coord_y)-1,
			working_sview_config.gap_size);
		return SLURM_SUCCESS;
	}

	if ((*button_processor->coord_x)
	    == working_sview_config.grid_x_width) {
		(*button_processor->coord_x) = 0;
		(*button_processor->coord_y)++;
		if (!((*button_processor->coord_y)
		      % working_sview_config.grid_vert))
			gtk_table_set_row_spacing(
				button_processor->table,
				(*button_processor->coord_y)-1,
				working_sview_config.gap_size);
	}

	if ((*button_processor->coord_y) == button_processor->table_y)
		return SLURM_SUCCESS;

	if ((*button_processor->coord_x) &&
	    !((*button_processor->coord_x)
	      % working_sview_config.grid_hori))
		gtk_table_set_col_spacing(
			button_processor->table,
			(*button_processor->coord_x)-1,
			working_sview_config.gap_size);

	return SLURM_SUCCESS;
}

static int _grid_table_by_switch(button_processor_t *button_processor,
				 list_t *node_list)
{
	int rc = SLURM_SUCCESS;
	int inx = 0, ii = 0;
	switch_record_bitmaps_t *sw_nodes_bitmaps_ptr = g_switch_nodes_maps;
#if TOPO_DEBUG
	/* engage if want original display below switched */
	list_itr_t *itr = list_iterator_create(node_list);
	sview_node_info_t *sview_node_info_ptr = NULL;
#endif
	button_processor->inx = &inx;
	for (ii = 0; ii < g_switch_nodes_maps_count;
	     ii++, sw_nodes_bitmaps_ptr++) {
		int j = 0, first, last;
		first = bit_ffs(sw_nodes_bitmaps_ptr->node_bitmap);
		if (first == -1)
			continue;
		last = bit_fls(sw_nodes_bitmaps_ptr->node_bitmap);
		button_processor->inx = &j;
		button_processor->force_row_break = false;
		for (j = first; j <= last; j++) {
			if (TOPO_DEBUG)
				g_print("allocated node = %s button# %d\n",
					g_node_info_ptr->node_array[j].name,
					j);
			if (!bit_test(sw_nodes_bitmaps_ptr->node_bitmap, j))
				continue;
			/* if (!working_sview_config.show_hidden) { */
			/* 	if (!check_part_includes_node(j)) */
			/* 		continue; */
			/* } */
			if (j == last)
				button_processor->force_row_break = true;
			if ((rc = _add_button_to_list(
				     &g_node_info_ptr->node_array[j],
				     button_processor)) != SLURM_SUCCESS)
				break;
			button_processor->force_row_break = false;
		}
		rc = _add_button_to_list(NULL, button_processor);
	}

#if TOPO_DEBUG
	/* engage this if want original display below
	 * switched grid */
	 button_processor->inx = &inx;
	 while ((sview_node_info_ptr = list_next(itr))) {
		 if ((rc = _add_button_to_list(
				sview_node_info_ptr->node_ptr,
	 			button_processor)) != SLURM_SUCCESS)
			 break;
	 	inx++;
	 }
	 list_iterator_destroy(itr);
#endif

	/* This is needed to get the correct width of the grid window.
	 * If it is not given then we get a really narrow window. */
	gtk_table_set_row_spacing(button_processor->table,
				  (*button_processor->coord_y)?
				  ((*button_processor->coord_y)-1):0, 1);

	return rc;

}

static int _grid_table_by_list(button_processor_t *button_processor,
			       list_t *node_list)
{
	sview_node_info_t *sview_node_info_ptr = NULL;
	int inx = 0, rc = SLURM_SUCCESS;
	list_itr_t *itr = list_iterator_create(node_list);
	button_processor->inx = &inx;

	while ((sview_node_info_ptr = list_next(itr))) {
		/* if (!working_sview_config.show_hidden) { */
		/* 	if (!check_part_includes_node(inx)) { */
		/* 		inx++; */
		/* 		continue; */
		/* 	} */
		/* } */
		if ((rc = _add_button_to_list(
			     sview_node_info_ptr->node_ptr,
			     button_processor)) != SLURM_SUCCESS)
			break;
		inx++;
	}
	list_iterator_destroy(itr);
	rc = _add_button_to_list(NULL, button_processor);

	/* This is needed to get the correct width of the grid window.
	 * If it is not given then we get a really narrow window. */
	gtk_table_set_row_spacing(button_processor->table,
				  (*button_processor->coord_y)?
				  ((*button_processor->coord_y)-1):0, 1);


	return rc;
}

static int _init_button_processor(button_processor_t *button_processor,
				  int node_count)
{
	if (node_count == 0) {
		g_print("_init_button_processor: no nodes selected\n");
		return SLURM_ERROR;
	}

	memset(button_processor, 0, sizeof(button_processor_t));

	if (!working_sview_config.grid_x_width) {
		if (node_count < 50) {
			working_sview_config.grid_x_width = 1;
		} else if (node_count < 500) {
			working_sview_config.grid_x_width = 10;
		} else {
			working_sview_config.grid_x_width = 20;
		}
	}
	button_processor->table_y =
		(node_count / working_sview_config.grid_x_width) + 1;

	button_processor->force_row_break = false;

	return SLURM_SUCCESS;
}
/* static void _destroy_grid_foreach(void *arg) */
/* { */
/* 	grid_foreach_t *grid_foreach = (grid_foreach_t *)arg; */

/* 	if (grid_foreach) { */
/* 		xfree(grid_foreach); */
/* 	} */
/* } */

extern void destroy_grid_button(void *arg)
{
	grid_button_t *grid_button = (grid_button_t *)arg;
	if (grid_button) {
		if (grid_button->button) {
			gtk_widget_destroy(grid_button->button);
			grid_button->button = NULL;
		}
		xfree(grid_button->node_name);
		xfree(grid_button);
	}
}

/* we don't set the call back for the button here because sometimes we
 * need to get a different call back based on what we are doing with
 * the button, an example of this would be in
 * add_extra_bluegene_buttons were the small block buttons do
 * something different than they do regularly
 * TODO - this may be simplified now that bluegene is gone.
 */

extern grid_button_t *create_grid_button_from_another(
	grid_button_t *grid_button, char *name, int color_inx)
{
	grid_button_t *send_grid_button = NULL;
	GdkColor color;
	uint16_t node_base_state;
	char *new_col = NULL;

	if (!grid_button || !name)
		return NULL;
	if (color_inx >= 0) {
		color_inx %= sview_colors_cnt;
		new_col = sview_colors[color_inx];
	} else if (color_inx == MAKE_BLACK)
		new_col = blank_color;
	else
		new_col = white_color;

	send_grid_button = xmalloc(sizeof(grid_button_t));
	memcpy(send_grid_button, grid_button, sizeof(grid_button_t));
	node_base_state = send_grid_button->state & NODE_STATE_BASE;
	send_grid_button->color_inx = color_inx;

	/* need to set the table to empty because we will want to fill
	   this into the new table later */
	send_grid_button->table = NULL;
	if (color_inx == MAKE_BLACK) {
		send_grid_button->button = gtk_button_new();
		//gtk_widget_set_sensitive (send_grid_button->button, false);
		gdk_color_parse(new_col, &color);
		send_grid_button->color = new_col;
		sview_widget_modify_bg(send_grid_button->button,
				       GTK_STATE_NORMAL, color);
/* 		sview_widget_modify_bg(send_grid_button->button,  */
/* 				       GTK_STATE_ACTIVE, color); */
	} else if ((color_inx >= 0) && node_base_state == NODE_STATE_DOWN) {
		GtkWidget *image = gtk_image_new_from_stock(
			GTK_STOCK_CANCEL,
			GTK_ICON_SIZE_SMALL_TOOLBAR);
		send_grid_button->button = gtk_event_box_new();
		gtk_event_box_set_above_child(
			GTK_EVENT_BOX(send_grid_button->button),
			false);
		gdk_color_parse("black", &color);
		sview_widget_modify_bg(send_grid_button->button,
				       GTK_STATE_NORMAL, color);
		//gdk_color_parse("white", &color);
/* 		sview_widget_modify_bg(send_grid_button->button,  */
/* 				     GTK_STATE_ACTIVE, color); */
		gtk_container_add(
			GTK_CONTAINER(send_grid_button->button),
			image);
	} else if ((color_inx >= 0)
		   && (send_grid_button->state & NODE_STATE_DRAIN)) {
		GtkWidget *image = gtk_image_new_from_stock(
			GTK_STOCK_DIALOG_ERROR,
			GTK_ICON_SIZE_SMALL_TOOLBAR);

		send_grid_button->button = gtk_event_box_new();
		gtk_event_box_set_above_child(
			GTK_EVENT_BOX(send_grid_button->button),
			false);
		gdk_color_parse("black", &color);
/* 		sview_widget_modify_bg(send_grid_button->button,  */
/* 				       GTK_STATE_NORMAL, color); */
		//gdk_color_parse("white", &color);
/* 		sview_widget_modify_bg(send_grid_button->button,  */
/* 				       GTK_STATE_ACTIVE, color); */
		gtk_container_add(
			GTK_CONTAINER(send_grid_button->button),
			image);
	} else {
		send_grid_button->button = gtk_button_new();
		send_grid_button->color = new_col;
		gdk_color_parse(new_col, &color);
		sview_widget_modify_bg(send_grid_button->button,
				       GTK_STATE_NORMAL, color);
/* 		sview_widget_modify_bg(send_grid_button->button,  */
/* 				       GTK_STATE_ACTIVE, color); */
	}
	gtk_widget_set_size_request(send_grid_button->button,
				    working_sview_config.button_size,
				    working_sview_config.button_size);

	send_grid_button->node_name = xstrdup(name);

	return send_grid_button;
}

/* start == -1 for all */
extern void change_grid_color(list_t *button_list, int start, int end,
			      int color_inx, bool only_change_unused,
			      enum node_states state_override)
{
	list_itr_t *itr = NULL;
	grid_button_t *grid_button = NULL;
	GdkColor color;
	char *new_col = NULL;

	if (!button_list)
		return;

	if (color_inx >= 0) {
		color_inx %= sview_colors_cnt;
		new_col = sview_colors[color_inx];
	} else if (color_inx == MAKE_BLACK) {
		new_col = blank_color;
	} else if (color_inx == MAKE_TOPO_1) {
		new_col = topo1_color;
	} else if (color_inx == MAKE_TOPO_2) {
		new_col = topo2_color;
	} else
		new_col = white_color;

	gdk_color_parse(new_col, &color);

	itr = list_iterator_create(button_list);
	while ((grid_button = list_next(itr))) {
		if ((start != -1) &&
		    ((grid_button->inx < start) || (grid_button->inx > end)))
			continue;
		_change_button_color(grid_button, color_inx, new_col,
				     color, only_change_unused, state_override);
	}
	list_iterator_destroy(itr);
}

/* This variation of change_grid_color() is faster when changing many
 * button colors at the same time since we can issue a single call to
 * _change_button_color() and eliminate a nested loop. */
extern void change_grid_color_array(list_t *button_list, int array_len,
				    int *color_inx, bool *color_set_flag,
				    bool only_change_unused,
				    enum node_states state_override)
{
	list_itr_t *itr = NULL;
	grid_button_t *grid_button = NULL;
	GdkColor color;
	char *new_col = NULL;

	if (!button_list)
		return;

	itr = list_iterator_create(button_list);
	while ((grid_button = list_next(itr))) {
		if ((grid_button->inx < 0) || (grid_button->inx >= array_len))
			continue;
		if (!color_set_flag[grid_button->inx])
			continue;

		if (color_inx[grid_button->inx] >= 0) {
			color_inx[grid_button->inx] %= sview_colors_cnt;
			new_col = sview_colors[color_inx[grid_button->inx]];
		} else if (color_inx[grid_button->inx] == MAKE_BLACK) {
			new_col = blank_color;
		} else if (color_inx[grid_button->inx] == MAKE_TOPO_1) {
			new_col = topo1_color;
		} else if (color_inx[grid_button->inx] == MAKE_TOPO_2) {
			new_col = topo2_color;
		} else
			new_col = white_color;
		gdk_color_parse(new_col, &color);

		_change_button_color(grid_button, color_inx[grid_button->inx],
				     new_col, color, only_change_unused,
				     state_override);
	}
	list_iterator_destroy(itr);
	return;
}

extern void highlight_grid(GtkTreeView *tree_view, int node_inx_id,
			   int color_inx_id, list_t *button_list)
{
	list_itr_t *itr = NULL;
	grid_button_t *grid_button = NULL;
	grid_foreach_t grid_foreach;

	if (!button_list || !tree_view)
		return;

	/*first clear all grid buttons*/
	itr = list_iterator_create(button_list);
	while ((grid_button = list_next(itr))) {
		/* clear everyone */
		if ((gtk_widget_get_state(grid_button->button)
		     != GTK_STATE_ACTIVE)) {
			gtk_widget_set_state(grid_button->button,
					     GTK_STATE_ACTIVE);
		}
	}
	list_iterator_destroy(itr);

	/* for each currently selected row,go back & ensure the
	 * corresponding grid button is highlighted */
	memset(&grid_foreach, 0, sizeof(grid_foreach_t));
	grid_foreach.node_inx_id = node_inx_id;
	grid_foreach.color_inx_id = color_inx_id;
	grid_foreach.button_list = button_list;
	if (grid_foreach.color_inx_id != (int)NO_VAL)
		gtk_tree_selection_selected_foreach(
			gtk_tree_view_get_selection(tree_view),
			_each_highlightd, &grid_foreach);
	else
		gtk_tree_selection_selected_foreach(
			gtk_tree_view_get_selection(tree_view),
			_each_highlight_selected, &grid_foreach);

	return;
}

/* start == -1 for all */
extern void highlight_grid_range(int start, int end, list_t *button_list)
{
	list_itr_t *itr = NULL;
	grid_button_t *grid_button = NULL;

	if (!button_list)
		return;

	itr = list_iterator_create(button_list);
	while ((grid_button = list_next(itr))) {
		if (start != -1)
			if ((grid_button->inx < start)
			    || (grid_button->inx > end)) {
				/* clear everyone else */
				if ((gtk_widget_get_state(grid_button->button)
				     != GTK_STATE_ACTIVE))
					gtk_widget_set_state(
						grid_button->button,
						GTK_STATE_ACTIVE);
				continue;
			}
		/* highlight this one, if it is already highlighted,
		 * put it back to normal */
		//g_print("highlighting %d\n", grid_button->inx);
		if ((gtk_widget_get_state(grid_button->button)
		     != GTK_STATE_NORMAL))
			gtk_widget_set_state(grid_button->button,
					     GTK_STATE_NORMAL);
	}
	list_iterator_destroy(itr);

	return;
}

extern void set_grid_used(list_t *button_list, int start, int end,
			  bool used, bool reset_highlight)
{
	list_itr_t *itr = NULL;
	grid_button_t *grid_button = NULL;

	if (!button_list)
		return;

	itr = list_iterator_create(button_list);
	while ((grid_button = list_next(itr))) {
		if (start != -1)
			if ((grid_button->inx < start)
			    || (grid_button->inx > end))
				continue;
		grid_button->used = used;
		if (reset_highlight)
			gtk_widget_set_state(grid_button->button,
					     GTK_STATE_NORMAL);

	}
	list_iterator_destroy(itr);

	return;
}

extern void get_button_list_from_main(list_t **button_list, int start, int end,
				      int color_inx)
{
	list_itr_t *itr = NULL;
	list_itr_t *button_itr = NULL;
	grid_button_t *grid_button = NULL;
	grid_button_t *send_grid_button = NULL;

	if (!*button_list)
		*button_list = list_create(destroy_grid_button);

	color_inx %= sview_colors_cnt;
	itr = list_iterator_create(grid_button_list);
	while ((grid_button = list_next(itr))) {
		if ((grid_button->inx < start)
		    ||  (grid_button->inx > end))
			continue;
		button_itr = list_iterator_create(*button_list);
		while ((send_grid_button = list_next(button_itr))) {
			if (send_grid_button->inx == grid_button->inx)
				break;
		}
		list_iterator_destroy(button_itr);
		if (send_grid_button)
			continue;

		send_grid_button = create_grid_button_from_another(
			grid_button, grid_button->node_name, color_inx);
		if (send_grid_button) {
			send_grid_button->button_list = *button_list;
			_add_button_signals(send_grid_button);
			list_append(*button_list, send_grid_button);
		}
	}
	list_iterator_destroy(itr);
	return;
}

extern list_t *copy_main_button_list(int initial_color)
{
	list_itr_t *itr = NULL;
	grid_button_t *grid_button = NULL;
	grid_button_t *send_grid_button = NULL;
	list_t *button_list = list_create(destroy_grid_button);

	itr = list_iterator_create(grid_button_list);
	while ((grid_button = list_next(itr))) {
		send_grid_button = create_grid_button_from_another(
			grid_button, grid_button->node_name, initial_color);
		if (send_grid_button) {
			send_grid_button->button_list = button_list;
			_add_button_signals(send_grid_button);
			send_grid_button->used = false;
			list_append(button_list, send_grid_button);
		}
	}
	list_iterator_destroy(itr);
	return button_list;
}

extern void put_buttons_in_table(GtkTable *table, list_t *button_list)
{
	int coord_x=0, coord_y=0;
	button_processor_t button_processor;
	grid_button_t *grid_button = NULL;
	list_itr_t *itr = NULL;
	list_sort(button_list, (ListCmpF) _sort_button_inx);

	if (!button_list) {
		g_print("put_buttons_in_table: no node_list given\n");
		return;
	}

	if (_init_button_processor(&button_processor, list_count(button_list))
	    != SLURM_SUCCESS)
		return;

	button_processor.table = table;
	button_processor.button_list = button_list;
	button_processor.coord_x = &coord_x;
	button_processor.coord_y = &coord_y;

	gtk_table_resize(table, button_processor.table_y,
			 working_sview_config.grid_x_width);

	itr = list_iterator_create(button_list);
	while ((grid_button = list_next(itr))) {
		grid_button->table = table;
		grid_button->table_x = coord_x;
		grid_button->table_y = coord_y;
		gtk_table_attach(table, grid_button->button,
				 coord_x, (coord_x+1),
				 coord_y, (coord_y+1),
				 GTK_SHRINK, GTK_SHRINK,
				 1, 1);
		coord_x++;
		if (coord_x == working_sview_config.grid_x_width) {
			coord_x = 0;
			coord_y++;
			if (!(coord_y % working_sview_config.grid_vert))
				gtk_table_set_row_spacing(
					table, coord_y-1,
					working_sview_config.gap_size);
		}

		if (coord_y == button_processor.table_y)
			break;

		if (coord_x
		    && !(coord_x % working_sview_config.grid_hori))
			gtk_table_set_col_spacing(table, coord_x-1, 5);
	}
	list_iterator_destroy(itr);

	gtk_widget_show_all(GTK_WIDGET(table));
}

extern int update_grid_table(GtkTable *table, list_t *button_list,
			     list_t *node_list)
{
	int rc = SLURM_SUCCESS;
	int coord_x=0, coord_y=0, inx=0;
	list_itr_t *itr = NULL, *itr2 = NULL;
	sview_node_info_t *sview_node_info_ptr = NULL;
	button_processor_t button_processor;

	if (!node_list) {
		g_print("update_grid_table: no node_list given\n");
		return SLURM_ERROR;
	}

	if (_init_button_processor(&button_processor, list_count(node_list))
	    != SLURM_SUCCESS)
		return SLURM_ERROR;

	button_processor.table = table;
	button_processor.button_list = button_list;
	button_processor.coord_x = &coord_x;
	button_processor.coord_y = &coord_y;
	button_processor.inx = &inx;

	gtk_table_resize(table, button_processor.table_y,
			 working_sview_config.grid_x_width);
	gtk_table_set_row_spacings(table, 0);
	gtk_table_set_col_spacings(table, 0);
	itr = list_iterator_create(node_list);
	itr2 = list_iterator_create(button_list);

	while ((sview_node_info_ptr = list_next(itr))) {
		int found = 0;
		/* if (!working_sview_config.show_hidden */
		/*     && !check_part_includes_node(inx)) { */
		/* 	inx++; */
		/* 	continue; */
		/* } */

//	again:
		while ((button_processor.grid_button = list_next(itr2))) {
			if (button_processor.grid_button->inx != inx) {
				continue;
			}
			found = 1;

			if ((rc = _add_button_to_list(
				     sview_node_info_ptr->node_ptr,
				     &button_processor)) != SLURM_SUCCESS)
				goto end_it;
			break;
		}
		if (!found) {
			//list_iterator_reset(itr2);
			//goto again;
			return RESET_GRID;
		}
		inx++;
	}
	rc = _add_button_to_list(NULL, &button_processor);

	/* This is needed to get the correct width of the grid window.
	 * If it is not given then we get a really narrow window. */
	gtk_table_set_row_spacing(table, coord_y?(coord_y-1):0, 1);

end_it:
	list_iterator_destroy(itr);
	list_iterator_destroy(itr2);
	return rc;
}

extern int get_system_stats(GtkTable *table)
{
	int rc = SLURM_SUCCESS;
	node_info_msg_t *node_info_ptr = NULL;
	list_t *node_list = NULL;

	if ((rc = get_new_info_node(&node_info_ptr, force_refresh))
	    == SLURM_NO_CHANGE_IN_DATA) {
	} else if (rc != SLURM_SUCCESS)
		return SLURM_ERROR;

	node_list = create_node_info_list(node_info_ptr, false);
	if (grid_button_list) {
		rc = update_grid_table(main_grid_table, grid_button_list,
				       node_list);
		if (rc == RESET_GRID) {
			FREE_NULL_LIST(grid_button_list);
			grid_button_list = list_create(destroy_grid_button);
			setup_grid_table(main_grid_table, grid_button_list,
					 node_list);
		}
	} else {
		grid_button_list = list_create(destroy_grid_button);
		setup_grid_table(main_grid_table, grid_button_list, node_list);
	}

	gtk_widget_show_all(GTK_WIDGET(main_grid_table));

	return SLURM_SUCCESS;
}

extern int setup_grid_table(GtkTable *table, list_t *button_list,
			    list_t *node_list)
{
	int rc = SLURM_SUCCESS;
	button_processor_t button_processor;
	int coord_x=0, coord_y=0;

	if (!node_list) {
		g_print("setup_grid_table: no node_list given\n");
		return SLURM_ERROR;
	}

	if (_init_button_processor(&button_processor, list_count(node_list))
	    != SLURM_SUCCESS)
		return SLURM_ERROR;

	button_processor.table = table;
	button_processor.button_list = button_list;
	button_processor.coord_x = &coord_x;
	button_processor.coord_y = &coord_y;

	gtk_table_resize(table, button_processor.table_y,
			 working_sview_config.grid_x_width);

	if (default_sview_config.grid_topological && g_topo_info_msg_ptr)
		rc = _grid_table_by_switch(&button_processor, node_list);
	else
		rc = _grid_table_by_list(&button_processor, node_list);

	list_sort(button_list, (ListCmpF) _sort_button_inx);

	return rc;
}

extern void sview_init_grid(bool reset_highlight)
{
	static node_info_msg_t *node_info_ptr = NULL;
	int rc = SLURM_SUCCESS;
	node_info_t *node_ptr = NULL;
	int i = 0;
	list_itr_t *itr = NULL;
	grid_button_t *grid_button = NULL;

	rc = get_new_info_node(&node_info_ptr, force_refresh);
	if (rc == SLURM_NO_CHANGE_IN_DATA) {
		/* need to clear out old data */
		set_grid_used(grid_button_list, -1, -1, false, reset_highlight);
		return;
	} else if (rc != SLURM_SUCCESS) {
		return;
	}

	if (!grid_button_list) {
		g_print("you need to run get_system_stats() first\n");
		exit(0);
	}

	itr = list_iterator_create(grid_button_list);
	for (i = 0; i < node_info_ptr->record_count; i++) {
		int tried_again = 0;
		node_ptr = &node_info_ptr->node_array[i];
	try_again:
		while ((grid_button = list_next(itr))) {
			if (grid_button->inx != i)
				continue;
			grid_button->state = node_ptr->node_state;
			gtk_widget_set_state(grid_button->button,
					     GTK_STATE_NORMAL);
			grid_button->used = false;
			break;
		}
		if (!grid_button && !tried_again) {
			/* the order should never change but just to
			 * make sure we don't miss it */
			list_iterator_reset(itr);
			tried_again = 1;
			goto try_again;
		}
	}
	list_iterator_destroy(itr);
}

/* make grid if it doesn't exist and set the buttons to unused */
extern void setup_popup_grid_list(popup_info_t *popup_win)
{
	int def_color = MAKE_BLACK;

	if (popup_win->grid_button_list) {
		set_grid_used(popup_win->grid_button_list,
			      -1, -1, false, false);
	} else {
		popup_win->grid_button_list =
			copy_main_button_list(def_color);
		put_buttons_in_table(popup_win->grid_table,
				     popup_win->grid_button_list);
		popup_win->full_grid = 1;
	}
}

/* clear extra buttons to N/A and if model then set those as white */
extern void post_setup_popup_grid_list(popup_info_t *popup_win)
{
	/* refresh the pointer */
	if (popup_win->model
	    && gtk_tree_store_iter_is_valid(GTK_TREE_STORE(popup_win->model),
					    &popup_win->iter)) {
		gtk_tree_model_get(popup_win->model, &popup_win->iter,
				   popup_win->node_inx_id,
				   &popup_win->node_inx, -1);
	} else {
		popup_win->node_inx = NULL;
	}

	if (popup_win->node_inx) {
		int j=0;
		while (popup_win->node_inx[j] >= 0) {
			change_grid_color(
				popup_win->grid_button_list,
				popup_win->node_inx[j],
				popup_win->node_inx[j+1], MAKE_WHITE, true, 0);
			j += 2;
		}
	}

	change_grid_color(popup_win->grid_button_list, -1, -1,
			  MAKE_BLACK, true, NODE_STATE_IDLE);
}
