/*******************************************************************************
*                                                                              *
*                                   Viewmol                                    *
*                                                                              *
*                               M O F O R M . C                                *
*                                                                              *
*                 Copyright (c) Joerg-R. Hill, October 2003                    *
*                                                                              *
********************************************************************************
*
* $Id: moform.c,v 1.6 2003/11/07 11:07:31 jrh Exp $
* $Log: moform.c,v $
* Revision 1.6  2003/11/07 11:07:31  jrh
* Release 2.4
*
* Revision 1.5  2000/12/10 15:12:37  jrh
* Release 2.3
*
* Revision 1.4  1999/05/24 01:26:42  jrh
* Release 2.2.1
*
* Revision 1.3  1999/02/07 21:53:23  jrh
* Release 2.2
*
* Revision 1.2  1998/01/26 00:48:47  jrh
* Release 2.1
*
* Revision 1.1  1996/12/10  18:42:23  jrh
* Initial revision
*
*/
#include<math.h>
#include<X11/Intrinsic.h>
#include<Xm/Xm.h>
#include<Xm/BulletinB.h>
#include<Xm/FileSB.h>
#include<Xm/Form.h>
#include<Xm/Label.h>
#include<Xm/LabelG.h>
#include<Xm/MessageB.h>
#include<Xm/PanedW.h>
#include<Xm/PushB.h>
#include<Xm/PushBG.h>
#include<Xm/RowColumn.h>
#include<Xm/Scale.h>
#include<Xm/Separator.h>
#include<Xm/Text.h>
#include<Xm/ToggleB.h>
#include "viewmol.h"
#include "dialog.h"

static Widget dialog;
static double denres_save;
static int unit_save;

extern struct WINDOW windows[];
extern Widget topShell;
extern int unit;
extern double denres;

void setupEnergyUnits(struct TOGGLE *);
void GetUnit(Widget, struct TOGGLE *, XmToggleButtonCallbackStruct *);
void GetSlider(Widget, struct SLIDER *, XmScrollBarCallbackStruct *);
void MODiagramDialogExit(Widget, caddr_t, XmPushButtonCallbackStruct *);

extern void drawMODiagram(Widget, caddr_t, XmAnyCallbackStruct *);
extern void MapBox(Widget, caddr_t, XmAnyCallbackStruct *);
extern Widget CreateToggleBox(Widget, struct PushButtonRow *, int, int,
                                int, int, int);
extern void CreatePushButtonRow(Widget, struct PushButtonRow *, int);
extern void setMenuItem(int, int);
extern Widget initShell(Widget, char *, Widget *, Widget *);

void MODiagramDialog(Widget widget, caddr_t dummy, XmAnyCallbackStruct *data)
{
  Widget form, board, form1, form2, radiobox, label, slider;
  Widget sep1, sep2;
  static struct TOGGLE toggle[4];
  static struct PushButtonRow buttons[] = {
    { "ok", MODiagramDialogExit, (XtPointer)TRUE, NULL },
    { "cancel", MODiagramDialogExit, (XtPointer)FALSE, NULL }
  };
  static struct PushButtonRow radiobox_buttons[] = {
    { "hartrees", GetUnit, (XtPointer)&toggle[0], NULL },
    { "kj_mol", GetUnit, (XtPointer)&toggle[1], NULL },
    { "ev", GetUnit, (XtPointer)&toggle[2], NULL },
    { "cm", GetUnit, (XtPointer)&toggle[3], NULL }
  };
  static struct SLIDER resolution;
  short decimals;

  /* This function creates the dialog for the MO diagram window */

  setMenuItem(MO_SETTINGS, False);

  unit_save=unit;
  denres_save=denres;

  dialog=initShell(windows[MO].widget, "MODiagramForm", &board,
			 &form);

  form1=XtVaCreateWidget("controlarea", xmFormWidgetClass, form, NULL);
  sep1=XtVaCreateManagedWidget("sep1", xmSeparatorWidgetClass, form, NULL);
  form2=XtVaCreateWidget("sliderarea", xmFormWidgetClass, form, NULL);
  sep2=XtVaCreateManagedWidget("sep2", xmSeparatorWidgetClass, form, NULL);

  setupEnergyUnits(toggle);
  radiobox=CreateToggleBox(form1, radiobox_buttons, XtNumber(radiobox_buttons),
                           XmVERTICAL, 1, True, unit-1);
  XtVaSetValues(radiobox, XmNleftAttachment, XmATTACH_FORM,
                          XmNtopAttachment, XmATTACH_FORM,
                          NULL);
  XtManageChild(form1);

  label=XtVaCreateManagedWidget("resolutionlabel", xmLabelWidgetClass, form2,
                                XmNleftAttachment, XmATTACH_FORM,
                                XmNrightAttachment, XmATTACH_FORM,
                                XmNtopAttachment, XmATTACH_FORM,
                                NULL);
  slider=XtVaCreateManagedWidget("resolution", xmScaleWidgetClass, form2,
                                  XmNorientation, XmHORIZONTAL,
                                  XmNshowValue, True,
                                  XmNsensitive, True,
                                  XmNleftAttachment, XmATTACH_FORM,
                                  XmNrightAttachment, XmATTACH_FORM,
                                  XmNtopAttachment, XmATTACH_WIDGET,
                                  XmNtopWidget, label,
                                  XmNbottomAttachment, XmATTACH_FORM,
                                  NULL);
  XtVaGetValues(slider, XmNdecimalPoints, &decimals, NULL);
  if (denres > 0.0)
    XtVaSetValues(slider, XmNvalue, (int)(denres*pow((double)10., (double)(decimals))), NULL);
  resolution.number=&denres;
  resolution.decimals=(int)decimals;
  resolution.draw=(void (*)())drawMODiagram;
  XtAddCallback(slider, XmNvalueChangedCallback, (XtCallbackProc)GetSlider, &resolution);
  XtManageChild(form2);

  CreatePushButtonRow(form, buttons, XtNumber(buttons));
  XtAddCallback(dialog, XmNpopupCallback, (XtCallbackProc)MapBox, (caddr_t)NULL);
  XtManageChild(form);
  XtManageChild(board);
}

void setupEnergyUnits(struct TOGGLE *toggle)
{
  register int i;

  for (i=0; i<4; i++)
  {
    toggle[i].var=&unit;
    toggle[i].draw=drawMODiagram;
  }
  toggle[0].value=HARTREE;
  toggle[1].value=KJ_MOL;
  toggle[2].value=EV;
  toggle[3].value=CM;
}

void GetUnit(Widget widget, struct TOGGLE *which, XmToggleButtonCallbackStruct *data)
{
  if (data->set) *(which->var)=which->value;
  if (*(which->draw) != NULL) (*(which->draw))((Widget)0, (caddr_t)0, (caddr_t)0);
}

void GetSlider(Widget widget, struct SLIDER *slider, XmScrollBarCallbackStruct *data)
{
  *(slider->number)=(double)(data->value)/pow((double)10.0, (double)slider->decimals);
  if (*(slider->draw) != NULL) (*(slider->draw))((Widget)0, (caddr_t)0, (caddr_t)0);
}

void MODiagramDialogExit(Widget widget, caddr_t which, XmPushButtonCallbackStruct *data)
{
  if (!(int)which)
  {
    unit=unit_save;
    denres=denres_save;
  }
  XtDestroyWidget(dialog);
  setMenuItem(MO_SETTINGS, True);
  drawMODiagram((Widget)0, (caddr_t)0, (XmAnyCallbackStruct *)0);
}
