/***************************************************************************/
/***************************************************************************/
/*                                                                         */
/*   (c) 1995-1999.  The Regents of the University of California.  All     */
/*   rights reserved.                                                      */
/*                                                                         */
/*   This work was produced at the University of California, Lawrence      */
/*   Livermore National Laboratory (UC LLNL) under contract no.            */
/*   W-7405-ENG-48 (Contract 48) between the U.S. Department of Energy     */
/*   (DOE) and The Regents of the University of California (University)    */
/*   for the operation of UC LLNL.  Copyright is reserved to the           */
/*   University for purposes of controlled dissemination,                  */
/*   commercialization through formal licensing, or other disposition      */
/*   under terms of Contract 48; DOE policies, regulations and orders;     */
/*   and U.S. statutes.  The rights of the Federal Government are          */
/*   reserved under Contract 48 subject to the restrictions agreed upon    */
/*   by the DOE and University.                                            */
/*                                                                         */
/*                                                                         */
/*                              DISCLAIMER                                 */
/*                                                                         */
/*   This software was prepared as an account of work sponsored by an      */
/*   agency of the United States Government.  Neither the United States    */
/*   Government nor the University of California nor any of their          */
/*   employees, makes any warranty, express or implied, or assumes any     */
/*   liability or responsibility for the accuracy, completeness, or        */
/*   usefulness of any information, apparatus, product, or process         */
/*   disclosed, or represents that its specific commercial products,       */
/*   process, or service by trade name, trademark, manufacturer, or        */
/*   otherwise, does not necessarily constitute or imply its               */
/*   endorsement, recommendation, or favoring by the United States         */
/*   Government or the University of California. The views and opinions    */
/*   of the authors expressed herein do not necessarily state or reflect   */
/*   those of the United States Government or the University of            */
/*   California, and shall not be used for advertising or product          */
/*   endorsement purposes.                                                 */
/*                                                                         */
/*   Permission to use, copy, modify and distribute this software and its  */
/*   documentation for any non-commercial purpose, without fee, is         */
/*   hereby granted, provided that the above copyright notice and this     */
/*   permission notice appear in all copies of the software and            */
/*   supporting documentation, and that all UC LLNL identification in      */
/*   the user interface remain unchanged.  The title to copyright LLNL     */
/*   XDIR shall at all times remain with The Regents of the University     */
/*   of California and users agree to preserve same. Users seeking the     */
/*   right to make derivative works with LLNL XDIR for commercial          */
/*   purposes may obtain a license from the Lawrence Livermore National    */
/*   Laboratory's Technology Transfer Office, P.O. Box 808, L-795,         */
/*   Livermore, CA 94550.                                                  */
/*                                                                         */
/***************************************************************************/
/***************************************************************************/

#include <Xm/DrawnB.h>
#include "xdir.h"
#include "buttons.h"

struct button_st {
	char *name;
	int first_time;
	unsigned char *bits;
	int width;
	int height;
	void (*cb_expose)();
	int id;
	Pixmap normal_pixmap;
	Pixmap normal_grey_pixmap;
	Pixmap inverse_pixmap;
	Pixmap inverse_grey_pixmap;
	Pixmap armed_pixmap;
};

void cb_layout_button_expose();
void cb_normal_button_expose();
void cb_tunneling_button_expose();
void cb_dotfiles_button_expose();
void cb_cache_button_expose();
void cb_button_arm();
void draw_button();

static struct button_st button_info[] = {

	{ "closeButton", True, skull_bits, skull_width, skull_height,
	  cb_normal_button_expose, 0 },

	{ "deleteButton", True, trash_bits, trash_width, trash_height,
	  cb_normal_button_expose, 0 },

	{ "dotFilesButton", True, dot_files_bits, dot_files_width, dot_files_height,
	  cb_dotfiles_button_expose, 0 },

	{ "cacheButton", True, cache_bits, cache_width, cache_height,
	  cb_cache_button_expose, 0 },
	
	{ "fullInfoButton", True, full_info_bits, full_info_width,
	  full_info_height, cb_layout_button_expose, FULL_INFO },

	{ "homeButton", True, home_bits, home_width, home_height,
	  cb_normal_button_expose, 0 },

	{ "mkdirButton", True, folder_bits, folder_width, folder_height,
	  cb_normal_button_expose, 0 },

	{ "refreshDirButton", True, refresh_bits, refresh_width, refresh_height,
	  cb_normal_button_expose, 0 },

	{ "tabularButton", True, tabular_bits, tabular_width, tabular_height,
	  cb_layout_button_expose, TABULAR },

	{ "iconicButton", True, iconic_bits, iconic_width,
	  iconic_height, cb_layout_button_expose, ICONIC },

	{ "treeButton", True, tree_bits, tree_width, tree_height,
	  cb_layout_button_expose, TREE },

	{ "tunnelingButton", True, tunnel_bits, tunnel_width, tunnel_height,
	  cb_tunneling_button_expose, 0 },

	{ "upArrowButton", True, arrow_bits, arrow_width, arrow_height,
	  cb_normal_button_expose, 0 },

	{ "viewButton", True, view_bits, view_width, view_height,
	  cb_normal_button_expose, 0 }
};

static int nbuttons = XtNumber(button_info);

extern Display *display;


/*
 * update_layout_mode_buttons - Update the layout mode buttons to
 *                              correspond to the current layout mode
 *                              value.
 */
void
update_layout_mode_buttons(dirwin)
struct dirwin_st *dirwin;
{
	int tabular_indx = button_index("tabularButton");
	int iconic_indx = button_index("iconicButton");
	int tree_indx = button_index("treeButton");
	int full_info_indx = button_index("fullInfoButton");

	/* First turn them all off */
	if (XtIsSensitive(dirwin->w_tabularButton))
		draw_button(dirwin->w_tabularButton,
			button_info[tabular_indx].normal_pixmap);
	else
		draw_button(dirwin->w_tabularButton,
			button_info[tabular_indx].normal_grey_pixmap);
	if (XtIsSensitive(dirwin->w_iconicButton))
		draw_button(dirwin->w_iconicButton,
			button_info[iconic_indx].normal_pixmap);
	else
		draw_button(dirwin->w_iconicButton,
			button_info[iconic_indx].normal_grey_pixmap);
	if (XtIsSensitive(dirwin->w_treeButton))
		draw_button(dirwin->w_treeButton,
			button_info[tree_indx].normal_pixmap);
	else
		draw_button(dirwin->w_treeButton,
			button_info[tree_indx].normal_grey_pixmap);
	if (XtIsSensitive(dirwin->w_fullInfoButton))
		draw_button(dirwin->w_fullInfoButton,
			button_info[full_info_indx].normal_pixmap);
	else
		draw_button(dirwin->w_fullInfoButton,
			button_info[full_info_indx].normal_grey_pixmap);


	/* Now turn the appropriate one on */
	switch (dirwin->layout) {
	case TABULAR:
		if (XtIsSensitive(dirwin->w_tabularButton))
			draw_button(dirwin->w_tabularButton,
				button_info[tabular_indx].inverse_pixmap);
		else
			draw_button(dirwin->w_tabularButton,
				button_info[tabular_indx].inverse_grey_pixmap);
		break;
	case ICONIC:
		if (XtIsSensitive(dirwin->w_iconicButton))
			draw_button(dirwin->w_iconicButton,
				button_info[iconic_indx].inverse_pixmap);
		else
			draw_button(dirwin->w_iconicButton,
				button_info[iconic_indx].inverse_grey_pixmap);
		break;
	case TREE:
		if (XtIsSensitive(dirwin->w_treeButton))
			draw_button(dirwin->w_treeButton,
				button_info[tree_indx].inverse_pixmap);
		else
			draw_button(dirwin->w_treeButton,
				button_info[tree_indx].inverse_grey_pixmap);
		break;
	case FULL_INFO:
		if (XtIsSensitive(dirwin->w_fullInfoButton))
			draw_button(dirwin->w_fullInfoButton,
				button_info[full_info_indx].inverse_pixmap);
		else
			draw_button(dirwin->w_fullInfoButton,
				button_info[full_info_indx].inverse_grey_pixmap);
		break;
	}
}


/*
 * draw_button - Copy the picture from the specified "pixmap" onto the
 *               specified drawn button "widget".
 */
void
draw_button(widget, pixmap)
Widget widget;
Pixmap pixmap;
{
	Dimension st;
	Dimension ht;
	Dimension h;
	Dimension w;

	XtVaGetValues(
		widget,
		XmNhighlightThickness,	&ht,
		XmNshadowThickness,		&st,
		XmNwidth,				&w,
		XmNheight,				&h,
		NULL
	);

	XCopyArea(display, pixmap, XtWindow(widget),
		XDefaultGCOfScreen(XtScreen(widget)), 0, 0, w-2*(ht+st), h-2*(ht+st),
		ht+st, ht+st);
}


/*
 * create_button - Create a drawn button and set up its associated pixmaps
 *                 and callbacks.  "dirwin" is the directory window that
 *                 will hold the button.  "name" is the name of the button
 *                 (which must correspond to a name in the "button_info"
 *                 table.  "w_parent" is the parent of the button.  Returns
 *                 widget id of drawn button.
 */
Widget
create_button(name, dirwin, w_parent)
char *name;
struct dirwin_st *dirwin;
Widget w_parent;
{
	int indx;
	Widget widget;
	Dimension st;
	Dimension ht;

	/* First find the name in the button information table */
	for (indx=0; indx<nbuttons; indx++)
		if (!strcmp(name, button_info[indx].name))
			break;
	if (indx == nbuttons)    /* Sanity check */
		fatal_error("Programming bug in create_button()");

	widget = XtVaCreateManagedWidget(
		button_info[indx].name,
		xmDrawnButtonWidgetClass,
		w_parent,
		XmNpushButtonEnabled,	True,
		NULL
	);
	XtAddCallback(widget, XmNactivateCallback, button_info[indx].cb_expose,
		(XtPointer)dirwin);
	XtAddCallback(widget, XmNexposeCallback, button_info[indx].cb_expose,
		(XtPointer)dirwin);
	XtAddCallback(widget, XmNarmCallback, cb_button_arm, (XtPointer)dirwin);
	XtAddCallback(widget, XmNdisarmCallback, button_info[indx].cb_expose,
		(XtPointer)dirwin);
	if (button_info[indx].first_time) {
		create_button_pixmaps(
			widget,
			button_info[indx].bits,
			button_info[indx].width,
			button_info[indx].height,
			&button_info[indx].normal_pixmap,
			&button_info[indx].normal_grey_pixmap,
			&button_info[indx].inverse_pixmap,
			&button_info[indx].inverse_grey_pixmap,
			&button_info[indx].armed_pixmap
		);
		button_info[indx].first_time = False;
	}
	XtVaGetValues(widget,
		XmNhighlightThickness,	&ht,
		XmNshadowThickness,		&st,
		NULL
	);
	XtVaSetValues(widget,
		XmNwidth,		2*(ht+st)+button_info[indx].width,
		XmNheight,		2*(ht+st)+button_info[indx].height,
		XmNuserData,	(XtPointer)indx,
		NULL
	);

	return widget;
}


/*
 * cb_layout_button_expose - Callback for drawing layout buttons.
 */
void
cb_layout_button_expose(widget, client_data, call_data)
Widget widget;
XtPointer client_data;
XtPointer call_data;
{
	struct dirwin_st *dirwin = (struct dirwin_st *)client_data;
	int indx;

	/* Get index into button information table */
	XtVaGetValues(widget, XmNuserData, &indx, NULL);

	if (dirwin->layout == button_info[indx].id) {
		if (XtIsSensitive(widget))
			draw_button(widget, button_info[indx].inverse_pixmap);
		else
			draw_button(widget, button_info[indx].inverse_grey_pixmap);
	} else {
		if (XtIsSensitive(widget))
			draw_button(widget, button_info[indx].normal_pixmap);
		else
			draw_button(widget, button_info[indx].normal_grey_pixmap);
	}
}


/*
 * button_index - Returns the index into the button information table where
 *                an entry with "name" resides.
 */
button_index(name)
char *name;
{
	int i;

	for (i=0; i<nbuttons; i++)
		if (!strcmp(name, button_info[i].name))
			break;

	/* Sanity check */
	if (i == nbuttons)
		fatal_error("Programming bug in button_index()");

	return i;
}


/*
 * cb_button_arm - Callback for drawing armed button.
 */
void
cb_button_arm(widget, client_data, call_data)
Widget widget;
XtPointer client_data;
XtPointer call_data;
{
	int indx;

	/* Get index into button information table */
	XtVaGetValues(widget, XmNuserData, &indx, NULL);

	draw_button(widget, button_info[indx].armed_pixmap);
}


/*
 * cb_normal_button_expose - Callback for normal buttons.
 */
void
cb_normal_button_expose(widget, client_data, call_data)
Widget widget;
XtPointer client_data;
XtPointer call_data;
{
	int indx;

	/* Get index into button information table */
	XtVaGetValues(widget, XmNuserData, &indx, NULL);

	if (XtIsSensitive(widget))
		draw_button(widget, button_info[indx].normal_pixmap);
	else
		draw_button(widget, button_info[indx].normal_grey_pixmap);
}


/*
 * cb_tunneling_button_expose - Callback for drawing tunneling button.
 */
void
cb_tunneling_button_expose(widget, client_data, call_data)
Widget widget;
XtPointer client_data;
XtPointer call_data;
{
	struct dirwin_st *dirwin = (struct dirwin_st *)client_data;
	int indx;

	/* Get index into button information table */
	XtVaGetValues(widget, XmNuserData, &indx, NULL);

	if (dirwin->tunneling_mode) {
		if (XtIsSensitive(widget))
			draw_button(widget, button_info[indx].inverse_pixmap);
		else
			draw_button(widget, button_info[indx].inverse_grey_pixmap);
	} else {
		if (XtIsSensitive(widget))
			draw_button(widget, button_info[indx].normal_pixmap);
		else
			draw_button(widget, button_info[indx].normal_grey_pixmap);
	}
}


/*
 * cb_cache_button_expose - Callback for drawing cache button.
 */
void
cb_cache_button_expose(widget, client_data, call_data)
Widget widget;
XtPointer client_data;
XtPointer call_data;
{
	struct dirwin_st *dirwin = (struct dirwin_st *)client_data;
	int indx;

	/* Get index into button information table */
	XtVaGetValues(widget, XmNuserData, &indx, NULL);

	if (dirwin->cache_mode) {
		if (XtIsSensitive(widget))
			draw_button(widget, button_info[indx].inverse_pixmap);
		else
			draw_button(widget, button_info[indx].inverse_grey_pixmap);
	} else {
		if (XtIsSensitive(widget))
			draw_button(widget, button_info[indx].normal_pixmap);
		else
			draw_button(widget, button_info[indx].normal_grey_pixmap);
	}
}


/*
 * cb_dotfiles_button_expose - Callback for drawing dot files button.
 */
void
cb_dotfiles_button_expose(widget, client_data, call_data)
Widget widget;
XtPointer client_data;
XtPointer call_data;
{
	struct dirwin_st *dirwin = (struct dirwin_st *)client_data;
	int indx;

	/* Get index into button information table */
	XtVaGetValues(widget, XmNuserData, &indx, NULL);

	if (dirwin->dotfiles_mode) {
		if (XtIsSensitive(widget))
			draw_button(widget, button_info[indx].inverse_pixmap);
		else
			draw_button(widget, button_info[indx].inverse_grey_pixmap);
	} else {
		if (XtIsSensitive(widget))
			draw_button(widget, button_info[indx].normal_pixmap);
		else
			draw_button(widget, button_info[indx].normal_grey_pixmap);
	}
}



syntax highlighted by Code2HTML, v. 0.9.1