/*********************************************************************
 *
 *            EZFM---EZWGL based file manager for X11
 *
 *             Copyright (C) 1998  Maorong Zou
 *
 *
 *  This file is part of EZFM.
 *
 *  EZFM 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, or (at your option)
 * any later version.
 *
 * EZFM 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 EZFM; see the file COPYING.  If not, write to
 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
 *
 *************************************************************************/

#define _MBTN_OPTION_C_
#include "ezfm.h"

/**********************************************************************************/
void setupMBtnOption      MY_ANSIARGS((void *btn, void *data));
int  searchWord           MY_ANSIARGS((char *buf, char *word, int *pos_ret));
/**********************************************************************************/
static void updateOptionMenu   MY_ANSIARGS((void *widget, void *data));
static void showHidden         MY_ANSIARGS((void *widget, void *data));
static void autoUpdate         MY_ANSIARGS((void *widget, void *data));
static void setOptions         MY_ANSIARGS((void *widget, void *data));
static void editConfigFile     MY_ANSIARGS((void *widget, void *data));
static void reassignButtons    MY_ANSIARGS((void *widget, void *data));
static void actionDialogueCb   MY_ANSIARGS((void *widget, void *data));
static void dndDialogueCb      MY_ANSIARGS((void *widget, void *data));
static void toolDialogueCb     MY_ANSIARGS((void *widget, void *data));
static void errorDialogueCb    MY_ANSIARGS((void *widget, void *data));
static void shAuRbCb           MY_ANSIARGS((void *widget, void *data));
static void srbtnCb            MY_ANSIARGS((void *widget, void *data));
/**********************************************************************************
 *
 * setup MenuButton 'File'
 */
#define O_AUTO_UPDATE   0
#define O_SHOW_HIDDEN   1
#define O_RUBBER_BAND   2
#define O_LIST_BOX      3

void setupMBtnOption(mbar, data)
     EZ_Widget *mbar; void *data;
{
  Toplevel  *toplevel = (Toplevel *)data;
  EZ_Widget *menu, *tmp, *mitem, *tmp1, *smenu;
  
  menu =     EZ_CreateWidgetXrm(EZ_WIDGET_MENU,      NULL,
				"ConfigureMenu",    "configureMenu",
				EZ_MENU_TEAR_OFF,    1,
				NULL);

  EZ_SetMenuSetupProcedure(menu, updateOptionMenu, data);

  tmp  =     EZ_CreateWidget(EZ_WIDGET_MENU_NORMAL_BUTTON, menu,
			     EZ_LABEL_STRING,              "Edit Config File...",
			     EZ_UNDERLINE,                  0,
			     EZ_CALLBACK,                   editConfigFile, NULL,
			     NULL);  
  
  tmp  =     EZ_CreateWidget(EZ_WIDGET_MENU_NORMAL_BUTTON,  menu,
			     EZ_LABEL_STRING,              "Set Display Options...",
			     EZ_UNDERLINE,                  0,
			     EZ_CALLBACK,                   setOptions, data,
			     NULL);
  tmp  =     EZ_CreateWidget(EZ_WIDGET_MENU_SEPARATOR,      menu,
			     NULL);

  tmp  =     EZ_CreateWidget(EZ_WIDGET_MENU_NORMAL_BUTTON,  menu,
			     EZ_LABEL_STRING,              "Reassign Mouse Buttons...",
			     EZ_UNDERLINE,                  0,
			     EZ_CALLBACK,                   reassignButtons, NULL,
			     NULL);
  tmp  =     EZ_CreateWidget(EZ_WIDGET_MENU_NORMAL_BUTTON,  menu,
			     EZ_LABEL_STRING,              "Transparency Dialogue...",
			     EZ_UNDERLINE,                  0,
			     EZ_CALLBACK,                   doTransparencyDialogue, NULL,
			     NULL);
  /*if(transparent == 0) EZ_DisableWidget(tmp);*/

  tmp  =     EZ_CreateWidget(EZ_WIDGET_MENU_SEPARATOR,      menu,
			     NULL);

  tmp  =     EZ_CreateWidget(EZ_WIDGET_MENU_CHECK_BUTTON,  menu,
			     EZ_LABEL_STRING,              "Confirm 'Double Click'",
			     EZ_UNDERLINE,                  9,
			     EZ_CHECK_BUTTON_ON_OFF,       (ezfmFlags & DONT_CONFIRM_ACT_BIT)==0,
			     EZ_CALLBACK,                   actionDialogueCb, NULL,
			     EZ_INDICATOR_SIZE_ADJUST,      0,
			     NULL);
  tmp  =     EZ_CreateWidget(EZ_WIDGET_MENU_CHECK_BUTTON,  menu,
			     EZ_LABEL_STRING,              "Confirm Drag 'n Drop",
			     EZ_UNDERLINE,                  2,
			     EZ_CHECK_BUTTON_ON_OFF,       (ezfmFlags & DONT_CONFIRM_DND_BIT)==0,
			     EZ_CALLBACK,                   dndDialogueCb, NULL,
			     EZ_INDICATOR_SIZE_ADJUST,      0,
			     NULL);

  tmp  =     EZ_CreateWidget(EZ_WIDGET_MENU_CHECK_BUTTON,  menu,
			     EZ_LABEL_STRING,              "Confirm 'Tool Execution'",
			     EZ_UNDERLINE,                  9,
			     EZ_CHECK_BUTTON_ON_OFF,       (ezfmFlags & DONT_CONFIRM_TOOL_BIT)==0,
			     EZ_CALLBACK,                   toolDialogueCb, NULL,
			     EZ_INDICATOR_SIZE_ADJUST,      0,
			     NULL);
  tmp  =     EZ_CreateWidget(EZ_WIDGET_MENU_SEPARATOR,      menu,
			     NULL);
  tmp  =     EZ_CreateWidget(EZ_WIDGET_MENU_CHECK_BUTTON,  menu,
			     EZ_LABEL_STRING,              "Show Exec Error",
			     EZ_UNDERLINE,                  5,
			     EZ_CHECK_BUTTON_ON_OFF,       (ezfmFlags & IGNORE_EXEC_ERROR_BIT)==0,
			     EZ_CALLBACK,                   errorDialogueCb, NULL,
			     EZ_INDICATOR_SIZE_ADJUST,      0,
			     NULL);
  tmp  =     EZ_CreateWidget(EZ_WIDGET_MENU_SEPARATOR,      menu,
			     NULL);

  tmp  =     EZ_CreateWidget(EZ_WIDGET_MENU_CHECK_BUTTON,  menu,
			     EZ_LABEL_STRING,              "Show Hidden Files",
			     EZ_UNDERLINE,                  5,
			     EZ_CHECK_BUTTON_ON_OFF,        0,
                             EZ_CLIENT_INT_DATA,            SHOW_HIDDEN_BIT,
			     EZ_CALLBACK,                   shAuRbCb, data,
			     EZ_INDICATOR_SIZE_ADJUST,      0,
			     NULL);
  EZ_SetWidgetPtrData(menu,tmp);

  tmp1 =     EZ_CreateWidget(EZ_WIDGET_MENU_CHECK_BUTTON,  menu,
			     EZ_LABEL_STRING,              "Auto Updates",
			     EZ_UNDERLINE,                  0,
			     EZ_CHECK_BUTTON_ON_OFF,        1,
                             EZ_CLIENT_INT_DATA,            AUTO_UPDATE_BIT,
			     EZ_CALLBACK,                   shAuRbCb, data,
			     EZ_INDICATOR_SIZE_ADJUST,      0,
			     NULL);
  EZ_SetWidgetPtrData(tmp,tmp1);
  tmp  =     EZ_CreateWidget(EZ_WIDGET_MENU_CHECK_BUTTON,  menu,
			     EZ_LABEL_STRING,              "Rubber Band",
			     EZ_UNDERLINE,                  7,
			     EZ_CHECK_BUTTON_ON_OFF,        1,
                             EZ_CLIENT_INT_DATA,            RUBBER_BAND_BIT,
			     EZ_CALLBACK,                   shAuRbCb, data,
			     EZ_INDICATOR_SIZE_ADJUST,      0,
			     NULL);
  EZ_SetWidgetPtrData(tmp1,tmp);
  tmp1  =     EZ_CreateWidget(EZ_WIDGET_MENU_SEPARATOR,      menu,
                              NULL);
  tmp1  =    EZ_CreateWidget(EZ_WIDGET_MENU_RADIO_BUTTON,    menu,
                             EZ_LABEL_STRING,               "Sort by Name",
                             EZ_UNDERLINE,                   8,
                             EZ_RADIO_BUTTON_VALUE,          0,
                             EZ_CALLBACK,                    srbtnCb, data,
                             EZ_RADIO_BUTTON_GROUP,          ezfmRbtnCounter,
                             EZ_INDICATOR_COLOR,             "green2",
			     NULL);
  EZ_SetWidgetPtrData(tmp,tmp1);
  tmp1  =    EZ_CreateWidget(EZ_WIDGET_MENU_RADIO_BUTTON,    menu,
                             EZ_LABEL_STRING,               "Sort by Size",
                             EZ_UNDERLINE,                   10,
                             EZ_RADIO_BUTTON_VALUE,          SORT_BY_SIZE,
                             EZ_CALLBACK,                    srbtnCb, data,
                             EZ_RADIO_BUTTON_GROUP,          ezfmRbtnCounter,
                             EZ_INDICATOR_COLOR,             "green2",
			     NULL);
  tmp1  =    EZ_CreateWidget(EZ_WIDGET_MENU_RADIO_BUTTON,    menu,
                             EZ_LABEL_STRING,               "Sort by Date",
                             EZ_UNDERLINE,                   8,
                             EZ_RADIO_BUTTON_VALUE,           SORT_BY_TIME,
                             EZ_CALLBACK,                    srbtnCb, data,
                             EZ_RADIO_BUTTON_GROUP,          ezfmRbtnCounter,
                             EZ_INDICATOR_COLOR,             "green2",
			     NULL);
  ezfmRbtnCounter++;
  mitem = EZ_MenuBarAddItemAndMenu(mbar, "Configure", 0, menu);
  EZ_AddWidgetCallBack(mitem, EZ_DESTROY_CALLBACK, mBarItemDestroyCB, menu, 0);
}
/*************************************************************************************/
static void srbtnCb(rbtn, data) EZ_Widget *rbtn; void *data;
{
  int ret = EZ_GetRadioButtonGroupVariableValue(rbtn);
  if(ret >= 0)
    {
      Toplevel *tp = (Toplevel *)data;
      int ss = tp->flags;      
      tp->flags = (ss & ~SORT_BY_BITS) | ret;
      ezfmSetFolderSorter(tp->folder[0], ret);
      ezfmSetFolderSorter(tp->folder[1], ret);
    }
}
/*************************************************************************************
 *
 * For now, there are only three global options ...
 */
static void hideCb(w,d) EZ_Widget *w; void *d; {EZ_DestroyWidget((EZ_Widget *)d);}

static ckbtnCb(w,d) EZ_Widget *w; void *d;
{
  EZ_Widget *gotoplevel = (EZ_Widget *)d;
  int jnk, state = EZ_GetCheckButtonState(w, &jnk);
  int n = EZ_GetWidgetIntData(w);
  int ss = EZ_GetWidgetIntData(gotoplevel);
  if(state) ss |= n;
  else      ss &= ~n;
  EZ_SetWidgetIntData(gotoplevel, ss);
}

static lboxMCb(w,d) EZ_Widget *w; void *d; /* motion cb */
{
  EZ_Widget *gotoplevel = (EZ_Widget *)d;
  char *sel = EZ_GetListBoxSelection(w);
  char *tmp = (char *)EZ_GetWidgetPtrData(w);
  if(sel)
    {
      EZ_LabelPixmap *pxm = EZ_CreateLabelPixmapFromImageFile(sel);
      strcpy(tmp, sel);
    }
  else strcpy(tmp, "None");
}
static lboxCb(w,d) EZ_Widget *w; void *d; /* motion cb */
{
  EZ_Widget *gotoplevel = (EZ_Widget *)d;
  char *sel = EZ_GetListBoxSelection(w);
  char *tmp = (char *)EZ_GetWidgetPtrData(w);
  if(sel)
    {
      EZ_LabelPixmap *pxm = EZ_CreateLabelPixmapFromImageFile(sel);
      strcpy(tmp, sel);
      EZ_ConfigureWidget(w, EZ_LABEL_PIXMAP, pxm, 0);
    }
  else strcpy(tmp, "None");
}
static lboxDestroyCb(w,d) EZ_Widget *w; void *d;
{  (void)free((char *)d); }

static sglobalCB(w,d) EZ_Widget *w; void *d;
{
  EZ_Widget *gotoplevel = (EZ_Widget *)d;
  int ss = EZ_GetWidgetIntData(gotoplevel);
  EZ_UnknownDataType dd;
  EZ_Widget *lbox;
  char *bname;

  EZ_GetWidgetUnknownData(gotoplevel, O_LIST_BOX, &dd);
  lbox = (EZ_Widget *)dd.p;
  ezfmFlags = ss;
  strcpy(ezfmFolderBgPixmap, (char *)EZ_GetWidgetPtrData(lbox));
  modifyDpyOptionAllFolders(ss, ezfmFolderBgPixmap);
}

static slocalCB(widget,data) EZ_Widget *widget; void *data;
{
  EZ_Widget *gotoplevel = (EZ_Widget *)data;
  Toplevel *tp = (Toplevel *)EZ_GetWidgetPtrData(gotoplevel);
  EZ_UnknownDataType dd;
  EZ_Widget *lbox;
  char *bname;
  int ss = EZ_GetWidgetIntData(gotoplevel);
  
  EZ_GetWidgetUnknownData(gotoplevel, O_LIST_BOX, &dd);
  lbox = (EZ_Widget *)dd.p;
  bname = (char *)EZ_GetWidgetPtrData(lbox);
  
  modifyDpyOptionOneFolder(tp->folder[0], ss, bname, 1);  
  modifyDpyOptionOneFolder(tp->folder[1], ss, bname, 1);  
}
/*************************************************************************************/
static void setOptions(widget, data)
     EZ_Widget *widget; void *data;
{ 
  EZ_UnknownDataType dd;
  EZ_Widget *au, *sh, *rubber, *lbox; /* 0 1 2 3 */
  EZ_Widget *gotoplevel;
  Toplevel *tp = (Toplevel *)data;
  int state, flags = tp->flags;

  if(1)
    {
      EZ_Widget  *frame, *frame1, *frame2, *frame3, *bframe, *hide, *sglobal, *slocal;
      char       **dirlist, *lboxStorage;
      int        i, n;
      
      gotoplevel = EZ_CreateWidget(EZ_WIDGET_FRAME, NULL,
				   EZ_TRANSIENT,    True,
				   EZ_FILL_MODE,    EZ_FILL_BOTH,
				   EZ_SIZE,         600, 400,
				   EZ_ORIENTATION,  EZ_VERTICAL,
				   0);
      EZ_SetWidgetPtrData(gotoplevel, data);
      EZ_SetWidgetIntData(gotoplevel, flags);

     
      frame3 =      EZ_CreateWidget(EZ_WIDGET_FRAME, gotoplevel,
				    EZ_FILL_MODE,    EZ_FILL_BOTH,
				    EZ_LABEL_STRING, "Background Pattern",
				    EZ_FOREGROUND,   "red",
				    0);
      
      frame1 =     EZ_CreateWidget(EZ_WIDGET_FRAME, gotoplevel,
				   EZ_FILL_MODE,    EZ_FILL_BOTH,
				   EZ_LABEL_STRING, "Miscellaneous",
				   EZ_FOREGROUND,   "red",
				   EZ_HEIGHT,        0,
				   0);

      lboxStorage = (char *)malloc(256*sizeof(char)); lboxStorage[0] = '\0';
      lbox =       EZ_CreateWidget(EZ_WIDGET_LIST_BOX,  frame3,
				   EZ_BORDER_WIDTH,     1,
				   EZ_MOTION_CALLBACK,  lboxMCb, gotoplevel,
				   EZ_CALLBACK,         lboxCb, gotoplevel,
				   EZ_CLIENT_PTR_DATA,  lboxStorage,
				   EZ_TEXT_BACKGROUND,  "white",
				   EZ_DESTROY_CALLBACK, lboxDestroyCb, lboxStorage,
				   NULL);
      if( (dirlist = listBgPatterns(&n)) != NULL)
	{
	  if(n > 0) 
	    {
	      EZ_SetListBoxItems(lbox, dirlist, n);
	      for(i = 0; i < n; i++) EZ_Free(dirlist[i]);
	    }
	  EZ_Free(dirlist);
	}
      EZ_AppendListBoxItem(lbox, "None");
      
      au =          EZ_CreateWidget(EZ_WIDGET_CHECK_BUTTON,   frame1,
				    EZ_LABEL_STRING,          "Auto Update",
				    EZ_CLIENT_INT_DATA,       AUTO_UPDATE_BIT,
				    EZ_UNDERLINE,             0,
				    EZ_CHECK_BUTTON_ON_VALUE, 1,
				    EZ_CHECK_BUTTON_OFF_VALUE,0,
				    EZ_SIZE,                  0, 0,
				    EZ_INDICATOR_TYPE,        EZ_RECTANGLE_INDICATOR,
				    EZ_INDICATOR_COLOR,       "yellow",
				    EZ_BORDER_TYPE,           EZ_BORDER_UP,
				    EZ_BORDER_WIDTH,          1,
				    EZ_CALLBACK,              ckbtnCb, gotoplevel,
				    0);

      sh =          EZ_CreateWidget(EZ_WIDGET_CHECK_BUTTON,   frame1,
				    EZ_LABEL_STRING,          "Show Hidden Files",
				    EZ_UNDERLINE,             0,
				    EZ_CLIENT_INT_DATA,       SHOW_HIDDEN_BIT,
				    EZ_CHECK_BUTTON_ON_VALUE, 1,
				    EZ_CHECK_BUTTON_OFF_VALUE,0,
				    EZ_SIZE,                  0, 0,
				    EZ_INDICATOR_TYPE,        EZ_RECTANGLE_INDICATOR,
				    EZ_INDICATOR_COLOR,       "yellow",
				    EZ_BORDER_TYPE,           EZ_BORDER_UP,
				    EZ_BORDER_WIDTH,          1,
				    EZ_CALLBACK,              ckbtnCb, gotoplevel,
				    0);

      rubber =      EZ_CreateWidget(EZ_WIDGET_CHECK_BUTTON,   frame1,
				    EZ_LABEL_STRING,          "Rubber band",
				    EZ_UNDERLINE,             0,
				    EZ_CLIENT_INT_DATA,       RUBBER_BAND_BIT,
				    EZ_CHECK_BUTTON_ON_VALUE, 1,
				    EZ_CHECK_BUTTON_OFF_VALUE,0,
				    EZ_SIZE,                  0, 0,
				    EZ_INDICATOR_TYPE,        EZ_RECTANGLE_INDICATOR,
				    EZ_INDICATOR_COLOR,       "yellow",
				    EZ_BORDER_TYPE,           EZ_BORDER_UP,
				    EZ_BORDER_WIDTH,          1,
				    EZ_CALLBACK,              ckbtnCb, gotoplevel,
				    0);
      /* EZ_DisableWidget(rubber);*/

      bframe =     EZ_CreateWidget(EZ_WIDGET_FRAME, gotoplevel,
				   EZ_LABEL_STRING, " ",
				   EZ_HEIGHT,        0,
				   0);

      sglobal =    EZ_CreateWidget(EZ_WIDGET_NORMAL_BUTTON,   bframe,
				   EZ_LABEL_STRING,          "Apply to All",
				   EZ_UNDERLINE,              1,
				   EZ_SIZE,                   0, 0,
				   EZ_CALLBACK,              sglobalCB, gotoplevel,
				   EZ_BORDER_WIDTH,          1,
				   0);

      slocal =     EZ_CreateWidget(EZ_WIDGET_NORMAL_BUTTON,   bframe,
				   EZ_LABEL_STRING,          "Apply",
				   EZ_UNDERLINE,              0,
				   EZ_SIZE,                  0, 0,
				   EZ_CALLBACK,              slocalCB, gotoplevel,
				   EZ_BORDER_WIDTH,          1,
				   0);
      
      hide =        EZ_CreateWidget(EZ_WIDGET_NORMAL_BUTTON,   bframe,
				    EZ_LABEL_STRING,          "Close",
				    EZ_UNDERLINE,              0,
				    EZ_SIZE,                  0, 0,
				    EZ_CALLBACK,              hideCb, gotoplevel,
				    EZ_BORDER_WIDTH,          1,
				    0);
      dd.p = au;
      EZ_SetWidgetUnknownData(gotoplevel, 0, dd);
      dd.p = sh;
      EZ_SetWidgetUnknownData(gotoplevel, 1, dd);
      dd.p = rubber;
      EZ_SetWidgetUnknownData(gotoplevel, 2, dd);
      dd.p = lbox;
      EZ_SetWidgetUnknownData(gotoplevel, 3, dd);

      /* set up */
      /* show hidden btn */
      state = flags & SHOW_HIDDEN_BIT;
      if(state) EZ_SetCheckButtonState(sh, 1);
      else   EZ_SetCheckButtonState(sh, 0);

	/* auto-update btn */
      state = flags & AUTO_UPDATE_BIT;
      if(state) EZ_SetCheckButtonState(au, 1);
      else   EZ_SetCheckButtonState(au, 0);

      /* rubber band btn */
      state = flags & RUBBER_BAND_BIT;
      if(state) EZ_SetCheckButtonState(rubber, 1);
      else   EZ_SetCheckButtonState(rubber, 0);

      {
	EZ_ListBoxEntry *lbe;
	int  i,  count = 0;
	char *background;
	Folder *folder = tp->activeFolder;
	if(folder == NULL) folder = tp->folder[0];
	background = folder->bgpixmap;
	if(background)
	  {
	    EZ_GetListBoxData(lbox, &lbe, &count);
	    for(i = 0; i < count; i++)
	      {
		if(searchWord(lbe[i].data, background, NULL))
		  {
		    EZ_ListBoxSelectItemUsingIdx(lbox, i);
		    break;
		  }
	      }
	  }
	EZ_ConfigureWidget(lbox, EZ_IMAGE_FILE, background, 0);
	lboxMCb(lbox,gotoplevel); /* !! */
      }
    }
  
  EZ_DisplayWidget(gotoplevel);
  EZ_SetGrab(gotoplevel);
}
/*************************************************************************************/
#define  _ACT_BTN_     231
#define  _MENU_BTN_    232
#define  _DND_BTN_     233

static EZ_Widget *dtplevel, *radioButtons[3][3];

static void doReassignBtnsCb(widget, data) EZ_Widget *widget; void *data;
{
  int  i, ok = 1;
  int  btns[3];

  for(i = 0; i < 3; i++) 
    {
      EZ_Widget *tmp = radioButtons[i][0];
      btns[i] = EZ_GetRadioButtonGroupVariableValue(tmp);
      if(btns[i] < 0) { ok = 0; break;}
    }
  if(!ok)
    {
      ezfmExecutionErrorI("One or more button(s)", "is not assigned",
			  "You need to assign",  "all three buttons");
    }
  else
    {
      EZ_Btn1 = btns[0]; EZ_Btn2 = btns[1]; EZ_Btn3 = btns[2];
      EZ_HideWidget(dtplevel);
    }
}
static void cancelReassignBtnsCb(widget, data) EZ_Widget *widget; void *data;
{ EZ_HideWidget(dtplevel); }

static void rbtnCb(widget, data) EZ_Widget *widget; void *data;
{
  int i, j, col = EZ_GetWidgetIntData(widget);
  int val = EZ_GetRadioButtonGroupVariableValue(widget);

  EZ_FreezeWidget( (EZ_Widget *)data);
  for(i = 0; i < 3; i++) 
    for(j = 0; j < 3; j++) 
      EZ_EnableWidget(radioButtons[i][j]);
  for(i = 0; i < 3; i++) 
    {
      EZ_Widget *tmp = radioButtons[i][col];
      if(tmp != widget)
	{
	  int v = EZ_GetRadioButtonGroupVariableValue(tmp);
	  if(v == val) EZ_SetRadioButtonGroupVariableValue(tmp, -1);
	  EZ_DisableWidget(tmp);
	}
    }
  EZ_UnFreezeWidget((EZ_Widget *)data);
}

static void assignBtnRow(tframe, str, idx)
     EZ_Widget *tframe; char *str; int idx;
{
  EZ_Widget *label;

  label =      EZ_CreateWidget(EZ_WIDGET_LABEL,       tframe,
			       EZ_LABEL_STRING,       str,
			       EZ_GRID_CELL_GEOMETRY,  0, idx , 1, 1, 
			       EZ_GRID_CELL_PLACEMENT, EZ_FILL_HORIZONTALLY, EZ_RIGHT,
			       EZ_LABEL_POSITION,     EZ_RIGHT,
			       NULL);
  radioButtons[idx][0] = EZ_CreateWidget(EZ_WIDGET_RADIO_BUTTON, tframe,
					 EZ_LABEL_STRING,        "Left",
					 EZ_PADX,                 0,
					 EZ_PADY,                 0,
					 EZ_FONT_ID,              ezfmFontId[LABEL_MEDIUM_FONT],
					 EZ_GRID_CELL_GEOMETRY,  1, idx , 1, 1,
					 EZ_RADIO_BUTTON_GROUP,  idx+231,
					 EZ_RADIO_BUTTON_VALUE,  Button1,
					 EZ_CLIENT_INT_DATA,     0,
					 EZ_CALLBACK,            rbtnCb, tframe,
					 NULL);
  radioButtons[idx][1] = EZ_CreateWidget(EZ_WIDGET_RADIO_BUTTON, tframe,
					 EZ_LABEL_STRING,        "Middle",
					 EZ_PADX,                 0,
					 EZ_PADY,                 0,
					 EZ_FONT_ID,              ezfmFontId[LABEL_MEDIUM_FONT],
					 EZ_RADIO_BUTTON_GROUP,  idx+231,
					 EZ_RADIO_BUTTON_VALUE,  Button2,
					 EZ_GRID_CELL_GEOMETRY,  2, idx , 1, 1, 
					 EZ_CLIENT_INT_DATA,     1,
					 EZ_CALLBACK,            rbtnCb, tframe,
					 NULL);
  radioButtons[idx][2] = EZ_CreateWidget(EZ_WIDGET_RADIO_BUTTON, tframe,
					 EZ_LABEL_STRING,        "Right",
					 EZ_PADX,                 0,
					 EZ_PADY,                 0,
					 EZ_FONT_ID,              ezfmFontId[LABEL_MEDIUM_FONT],
					 EZ_RADIO_BUTTON_GROUP,  idx+231,
					 EZ_RADIO_BUTTON_VALUE,  Button3,
					 EZ_GRID_CELL_GEOMETRY,  3, idx , 1, 1,
					 EZ_CLIENT_INT_DATA,     2,
					 EZ_CALLBACK,            rbtnCb, tframe,
					 NULL);
}


static void reassignButtons(widget, data) EZ_Widget *widget; void *data;
{
  if(!EZ_WidgetExist(dtplevel))
    {
      EZ_Widget *frame, *ok, *cancel;
      dtplevel = EZ_CreateWidget(EZ_WIDGET_FRAME,     NULL,
				 EZ_FILL_MODE,        EZ_FILL_BOTH,
				 EZ_ORIENTATION,      EZ_VERTICAL,
				 EZ_TRANSIENT,        True,  
				 NULL);

      frame =    EZ_CreateWidget(EZ_WIDGET_FRAME,     dtplevel,
				 EZ_FILL_MODE,        EZ_FILL_BOTH,
				 EZ_ORIENTATION,      EZ_VERTICAL,
				 EZ_IPADY,            0,
				 EZ_TRANSIENT,        True,  
				 EZ_FONT_ID,          ezfmFontId[LABEL_LARGE_FONT],
				 EZ_FOREGROUND,       "red",
				 EZ_LABEL_STRING,     "Reassign Mouse Buttons",
				 EZ_HEIGHT,           0,
				 NULL);
      assignBtnRow(frame, "Activation Button:", 0);
      assignBtnRow(frame, "Menu Button:", 1);
      assignBtnRow(frame, "DnD Button:", 2);

      frame = EZ_CreateWidget(EZ_WIDGET_FRAME,       dtplevel, 
			      EZ_LABEL_STRING,       " ",
			      EZ_HEIGHT,              0,
			      0);
      ok  = EZ_CreateWidget(EZ_WIDGET_NORMAL_BUTTON, frame,
			    EZ_LABEL_STRING,         "Apply",
			    EZ_UNDERLINE,            0,
			    EZ_CALLBACK,             doReassignBtnsCb, NULL,
			    0);
      cancel= EZ_CreateWidget(EZ_WIDGET_NORMAL_BUTTON, frame,
			      EZ_LABEL_STRING,         "Cancel",
			      EZ_UNDERLINE,            0,
			      EZ_CALLBACK,             cancelReassignBtnsCb, NULL,
			      0);
    }
  /* set up */
  {
    EZ_FreezeWidget(dtplevel);
    EZ_SetRadioButtonGroupVariableValue(radioButtons[0][0], EZ_Btn1);
    EZ_SetRadioButtonGroupVariableValue(radioButtons[1][0], EZ_Btn2);
    EZ_SetRadioButtonGroupVariableValue(radioButtons[2][0], EZ_Btn3);
    EZ_UnFreezeWidget(dtplevel);
    EZ_DisplayWidget(dtplevel);
  }
}

#undef  _ACT_BTN_
#undef  _MENU_BTN_
#undef  _DND_BTN_

/******************************************************************************************
 *
 *  edit configuration file
 */
static char *saveConfigMsg = "Changes will take effect the next time you start ezfm";

static void  instCB(widget, data) EZ_Widget *widget; void *data;
{
  char *fname = (char *)data;
  char tfname[1024], cmd[2048];
  char *home = getenv("HOME");
  sprintf(tfname,  "%s/.ezfmrc", home);
  sprintf(cmd, COPY_CMD,  fname, tfname);
  executeShCmd(cmd, NULL, 0, NULL);
  ezfmEditTextFile(tfname, 1, saveConfigMsg);
  free(fname);
  EZ_DestroyWidget((EZ_Widget *)EZ_GetWidgetPtrData(widget));
}

static void  viewCB(widget, data) EZ_Widget *widget; void *data;
{
  char *fname = (char *)data;
  ezfmEditTextFile(fname, 0, NULL);
  free(fname);
  EZ_DestroyWidget((EZ_Widget *)EZ_GetWidgetPtrData(widget));
}
static void  cancelCB(widget, data) EZ_Widget *widget; void *data;
{ EZ_DestroyWidget((EZ_Widget *)data); }

/*---------------*/
static void editConfigFile(widget, data)
     EZ_Widget *widget; void *data;
{
  char fname[1024];
  fname[0] = '\0';
  ProcessRCFile(ezfmRc, fname);
  if(fname[0])
    {
      if(access(fname, W_OK) != 0)
	{
	  EZ_Widget *frame, *bframe, *label, *inst, *view, *canc;
	  char tstr[1024], *sfname;
	  int len = strlen(fname);
	  sfname = (char *)malloc((len+1)*sizeof(char));
	  strcpy(sfname, fname);

	  frame = EZ_CreateWidget(EZ_WIDGET_FRAME,    NULL, 
				  EZ_LABEL_STRING,    "Warning",
				  EZ_FOREGROUND,      "red",
				  EZ_ORIENTATION,     EZ_VERTICAL,
				  EZ_FILL_MODE,       EZ_FILL_BOTH,
				  EZ_TRANSIENT,       1,
				  NULL);
	  sprintf(tstr, "You don't have write permission on '%s'\n You need to install a copy of this file in your home directory", fname);
	  label = EZ_CreateWidget(EZ_WIDGET_LABEL,    frame,
				  EZ_LABEL_STRING,    tstr,
				  EZ_TEXT_LINE_LENGTH, 128,
				  NULL);

	  bframe = EZ_CreateWidget(EZ_WIDGET_FRAME,   frame,
				  EZ_LABEL_STRING,    " ",
				   EZ_HEIGHT,         0,
				   NULL);
	  inst   = EZ_CreateWidget(EZ_WIDGET_NORMAL_BUTTON, bframe,
				   EZ_LABEL_STRING,         "Install & Edit",
				   EZ_UNDERLINE,             0,
				   EZ_CALLBACK,              instCB, sfname,
				   EZ_CLIENT_PTR_DATA,       frame,
				   NULL);
	  view  =  EZ_CreateWidget(EZ_WIDGET_NORMAL_BUTTON, bframe,
				   EZ_LABEL_STRING,         "View Only",
				   EZ_UNDERLINE,             0,
				   EZ_CALLBACK,              viewCB, sfname,
				   EZ_CLIENT_PTR_DATA,       frame,
				   NULL);
	  canc =  EZ_CreateWidget(EZ_WIDGET_NORMAL_BUTTON, bframe,
				  EZ_LABEL_STRING,         "Cancel",
				  EZ_UNDERLINE,             0,
				  EZ_CALLBACK,              cancelCB, frame,
				  NULL);
	  EZ_DisplayWidget(frame);
	}
      else ezfmEditTextFile(fname, 1, saveConfigMsg);
    }
}
/************************************************************************
 *
 * search for word in buf. Return 1 if found.
 * if pos_ret is not NULL, it returns the starting
 * location of the match.
 */
int searchWord(buf, word, pos_ret) 
     char *buf; char *word; int *pos_ret;
{
  int blen, wlen;
  int pfxS[256], *pfx = pfxS;

  if(buf == NULL || word == NULL) return(0);
  blen = strlen(buf);
  wlen = strlen(word);
  if(blen < wlen) return(0);
  if(wlen > 250)  pfx = (int *) malloc( (wlen + 4) * sizeof(int));

  /* compute the prefix function */
  {
    int m = wlen;
    int i,j;
    pfx[0] = -2;
    pfx[1] = -1;
    for(i = 2; i < m; i++)
      {
	j = pfx[i-1] + 1;
	while(word[i-1] != word[j] && j >= 0) j = pfx[j]+1;
	pfx[i] = j;
      }
  }

  /* match */
  {
    int n = blen;
    int m = wlen;
    int i=0, j=0;

    while(i < n)
      {
	if(word[j] == buf[i]) {j++; i++;}
	else 
	  {
	    j = pfx[j] + 1;
	    if(j < 0) {j = 0; i++;}
	  }
	if(j == m)
	  {
	    if(pos_ret) *pos_ret = i-m;
	    if(pfx != pfxS) free(pfx);
	    return(1);
	  }
      }
  }
  if(pfx != pfxS) free(pfx);
  return(0);
}
/******************************************************************************************/
static void actionDialogueCb(widget, data)
     EZ_Widget *widget; void *data;
{
  int jnk, state = EZ_GetCheckButtonState(widget, &jnk);
  if(state) ezfmFlags &=  ~DONT_CONFIRM_ACT_BIT;  /* turn off */
  else ezfmFlags |=  DONT_CONFIRM_ACT_BIT;
}
static void dndDialogueCb(widget, data)
     EZ_Widget *widget; void *data;
{
  int jnk, state = EZ_GetCheckButtonState(widget, &jnk);
  if(state) ezfmFlags &=  ~DONT_CONFIRM_DND_BIT;  /* turn off */
  else ezfmFlags |= DONT_CONFIRM_DND_BIT;
}
static void toolDialogueCb(widget, data)
     EZ_Widget *widget; void *data;
{
  int jnk, state = EZ_GetCheckButtonState(widget, &jnk);
  if(state) ezfmFlags &=  ~DONT_CONFIRM_TOOL_BIT;  /* turn off */
  else ezfmFlags |= DONT_CONFIRM_TOOL_BIT;
}

static void errorDialogueCb(widget, data)
     EZ_Widget *widget; void *data;
{
  int jnk, state = EZ_GetCheckButtonState(widget, &jnk);
  if(state) ezfmFlags &=  ~IGNORE_EXEC_ERROR_BIT;  /* turn off */
  else ezfmFlags |= IGNORE_EXEC_ERROR_BIT;
}
/*****************************************************************************************
 *
 * Invoked before the option menu is posted. Update the state of the check buttons.
 */
static void updateOptionMenu(menu, data)
     EZ_Widget *menu; void *data;
{
  Toplevel *tp = (Toplevel *)data;
  EZ_Widget *sh = EZ_GetWidgetPtrData(menu);
  EZ_Widget *au =  EZ_GetWidgetPtrData(sh);
  EZ_Widget *rb =  EZ_GetWidgetPtrData(au);
  EZ_Widget *st =  EZ_GetWidgetPtrData(rb);
  int flags = tp->flags;
  
  if(flags & SHOW_HIDDEN_BIT) EZ_SetCheckButtonState(sh, 1);
  else   EZ_SetCheckButtonState(sh, 0); 
  
  if(flags & AUTO_UPDATE_BIT) EZ_SetCheckButtonState(au, 1);
  else   EZ_SetCheckButtonState(au, 0);  
  
  if(flags & RUBBER_BAND_BIT) EZ_SetCheckButtonState(rb, 1);
  else   EZ_SetCheckButtonState(rb, 0);

  EZ_SetRadioButtonGroupVariableValue(st, flags & SORT_BY_BITS);
}

/*****************************************************************************************
 *
 * ShowHidden, AutoUpdate and RubberBand check button callback
 */

static void shAuRbCb(widget, data)
     EZ_Widget *widget; void *data;
{
  Toplevel *tp = (Toplevel *)data;
  int jnk, state = EZ_GetCheckButtonState(widget, &jnk);
  int n = EZ_GetWidgetIntData(widget);
  int ss = tp->flags;
  if(state) ss |= n;
  else      ss &= ~n;
  modifyDpyOptionOneFolder(tp->folder[0], ss, NULL, 0);  
  modifyDpyOptionOneFolder(tp->folder[1], ss, NULL, 0);    
}
/******************************************************************************************/
#undef _MBTN_OPTION_C_
