/*
 *      Offset.c
 *
 *      Plotter demo program using motif
 *      klin, Thu Aug 20 13:40:10 1992
 */

#include <stdio.h>
#include <Xm/XmP.h>
#include <X11/Shell.h>
#include <Xm/Form.h>
#include <Xm/Label.h>
#include <Xm/PushB.h>
#include <Xm/Scale.h>
#include <Xm/Form.h>
#include <Xm/Frame.h>

#include <X11/At/XYLinePlot.h>

#ifndef XtPointer
# define XtPointer caddr_t
#endif

#define SCALE_DEC 3

extern Widget mainwindow;
extern Widget sline, zsline;

static Widget xscale = NULL;
static Widget yscale = NULL;

static Widget scale_dialog = NULL;
static Widget ok_button = NULL;
static Widget reset_button = NULL;
static Widget cancel_button = NULL;

static Boolean in_scale_dialog = False;
static int xoffset, yoffset, factor;
static int xdefault, ydefault;

static void ok_callback(), cancel_callback();
static void reset_callback();
static void xvalue_callback();
static void yvalue_callback();

void Popup_offset(min, max)
  int min, max;
{
  Arg args[12];
  Cardinal n;
  XmString xms[1];
  Widget scale_label = NULL;
  Widget scale_form = NULL;
  Widget xscale_frame = NULL;
  Widget yscale_frame = NULL;
  double x, y;

  if(scale_dialog == NULL) {

    /* Create the scale dialog */

    n = 0;
    XtSetArg(args[n], XmNunitType, XmPIXELS); n++;
    XtSetArg(args[n], XmNx, (Position) 400); n++;
    XtSetArg(args[n], XmNy, (Position) 400); n++;
    XtSetArg(args[n], XmNwidth, (Dimension) 250); n++;
    XtSetArg(args[n], XmNresizePolicy, XmRESIZE_NONE); n++;
    XtSetArg(args[n], XmNdefaultPosition, False); n++;
    XtSetArg(args[n], XmNautoUnmanage, False); n++;
    xms[0] = (XmString) XmStringCreateLtoR("Plotter Demo Offset Dialog", XmSTRING_DEFAULT_CHARSET);
    XtSetArg(args[n], XmNdialogTitle, xms[0]); n++;
    scale_dialog = XmCreateFormDialog(mainwindow, "scale_dialog", args, n);
    XmStringFree(xms[0]);

    /* Create the scale label */

    n = 0;
    xms[0] = (XmString) XmStringCreateLtoR("Set X/Y offsets", XmSTRING_DEFAULT_CHARSET);
    XtSetArg(args[n], XmNlabelString, xms[0]); n++;
    XtSetArg(args[n], XmNx, (Position) 0); n++;
    XtSetArg(args[n], XmNy, (Position) 0); n++;
    scale_label = XmCreateLabel(scale_dialog, "scale_label", args, n);
    XtManageChild(scale_label);
    XmStringFree(xms[0]);

    /* Create the X, Y offset scales */
    n = 0;
    XtSetArg(args[n], XmNresizePolicy, XmRESIZE_NONE); n++;
    scale_form = XmCreateForm(scale_dialog, "scale_form", args, n);
    XtManageChild(scale_form);

    n = 0;
    XtSetArg(args[n], XmNshadowType, XmSHADOW_OUT); n++;
    XtSetArg(args[n], XmNshadowThickness, (Dimension) 4); n++;
    xscale_frame = XmCreateFrame(scale_form, "scale_frame", args, n);
    XtManageChild(xscale_frame);

    n = 0;
    XtSetArg(args[n], XmNshadowType, XmSHADOW_OUT); n++;
    XtSetArg(args[n], XmNshadowThickness, (Dimension) 4); n++;
    yscale_frame = XmCreateFrame(scale_form, "scale_frame", args, n);
    XtManageChild(yscale_frame);

    n = 0;
    XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
    XtSetArg(args[n], XmNbottomPosition, 50); n++;
    XtSetArg(args[n], XmNbottomAttachment, XmATTACH_POSITION); n++;
    XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
    XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++;
    XtSetValues(xscale_frame, args, n);

    n = 0;
    XtSetArg(args[n], XmNtopPosition, 50); n++;
    XtSetArg(args[n], XmNtopAttachment, XmATTACH_POSITION); n++;
    XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
    XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
    XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++;
    XtSetValues(yscale_frame, args, n);

    n = 0;
    XtSetArg(args[n], XmNshowValue, True); n++;
    XtSetArg(args[n], XmNorientation, XmHORIZONTAL); n++;
    XtSetArg(args[n], XmNdecimalPoints, SCALE_DEC); n++;
    xms[0] = (XmString) XmStringCreateLtoR("X Offset", XmSTRING_DEFAULT_CHARSET);
    XtSetArg(args[n], XmNtitleString, xms[0]); n++;
    xscale = XmCreateScale(xscale_frame, "xscale", args, n);
    XtAddCallback(xscale, XmNvalueChangedCallback, xvalue_callback, (XtPointer) NULL);
    XtAddCallback(xscale, XmNdragCallback, xvalue_callback, (XtPointer) NULL);
    XtManageChild(xscale);
    XmStringFree(xms[0]);

    n = 0;
    XtSetArg(args[n], XmNshowValue, True); n++;
    XtSetArg(args[n], XmNorientation, XmHORIZONTAL); n++;
    XtSetArg(args[n], XmNdecimalPoints, SCALE_DEC); n++;
    xms[0] = (XmString) XmStringCreateLtoR("Y Offset", XmSTRING_DEFAULT_CHARSET);
    XtSetArg(args[n], XmNtitleString, xms[0]); n++;
    yscale = XmCreateScale(yscale_frame, "yscale", args, n);
    XtAddCallback(yscale, XmNvalueChangedCallback, yvalue_callback, (XtPointer) NULL);
    XtAddCallback(yscale, XmNdragCallback, yvalue_callback, (XtPointer) NULL);
    XtManageChild(yscale);
    XmStringFree(xms[0]);

    n = 0;
    XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
    XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
    XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
    XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++;
    XtSetValues(xscale, args, n);

    n = 0;
    XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
    XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
    XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
    XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++;
    XtSetValues(yscale, args, n);

    /* Create the scale buttons */

    n = 0;
    xms[0] = (XmString) XmStringCreateLtoR("OK", XmSTRING_DEFAULT_CHARSET);
    XtSetArg(args[n], XmNlabelString, xms[0]); n++;
    ok_button = XmCreatePushButton(scale_dialog, "button", args, n);
    XtAddCallback(ok_button, XmNactivateCallback, ok_callback, (XtPointer) NULL);
    XtManageChild(ok_button);
    XmStringFree(xms[0]);

    n = 0;
    xms[0] = (XmString) XmStringCreateLtoR("Reset", XmSTRING_DEFAULT_CHARSET);
    XtSetArg(args[n], XmNlabelString, xms[0]); n++;
    reset_button = XmCreatePushButton(scale_dialog, "button", args, n);
    XtAddCallback(reset_button, XmNactivateCallback, reset_callback, (XtPointer) NULL);
    XtManageChild(reset_button);
    XmStringFree(xms[0]);

    n = 0;
    xms[0] = (XmString) XmStringCreateLtoR("Cancel", XmSTRING_DEFAULT_CHARSET);
    XtSetArg(args[n], XmNlabelString, xms[0]); n++;
    cancel_button = XmCreatePushButton(scale_dialog, "button", args, n);
    XtAddCallback(cancel_button, XmNactivateCallback, cancel_callback, (XtPointer) NULL);
    XtManageChild(cancel_button);
    XmStringFree(xms[0]);

    n = 0;
    XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++;
    XtSetArg(args[n], XmNbottomAttachment, XmATTACH_NONE); n++;
    XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
    XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++;
    XtSetValues(scale_label, args, n);

    n = 0;
    XtSetArg(args[n], XmNtopWidget, scale_label); n++;
    XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
    XtSetArg(args[n], XmNbottomWidget, ok_button); n++;
    XtSetArg(args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++;
    XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
    XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++;
    XtSetValues(scale_form, args, n);

    n = 0;
    XtSetArg(args[n], XmNtopAttachment, XmATTACH_NONE); n++;
    XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
    XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++;
    XtSetArg(args[n], XmNrightPosition, 30); n++;
    XtSetArg(args[n], XmNrightAttachment, XmATTACH_POSITION); n++;
    XtSetValues(ok_button, args, n);

    n = 0;
    XtSetArg(args[n], XmNtopAttachment, XmATTACH_NONE); n++;
    XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
    XtSetArg(args[n], XmNleftPosition, 33); n++;
    XtSetArg(args[n], XmNleftAttachment, XmATTACH_POSITION); n++;
    XtSetArg(args[n], XmNrightPosition, 67); n++;
    XtSetArg(args[n], XmNrightAttachment, XmATTACH_POSITION); n++;
    XtSetValues(reset_button, args, n);

    n = 0;
    XtSetArg(args[n], XmNtopAttachment, XmATTACH_NONE); n++;
    XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
    XtSetArg(args[n], XmNleftPosition, 67); n++;
    XtSetArg(args[n], XmNleftAttachment, XmATTACH_POSITION); n++;
    XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++;
    XtSetValues(cancel_button, args, n);

    n = 0;
    XtSetArg(args[n], XmNdefaultButton, reset_button); n++;
    XtSetValues(scale_dialog, args, n);
  }

  XtVaGetValues(sline, XtNxOffset, &x, NULL);
  XtVaGetValues(sline, XtNyOffset, &y, NULL);
  factor = max - min;
  xoffset = xdefault = (int) (x * (double) factor);
  yoffset = xdefault = (int) (y * (double) factor);
  XtVaSetValues(xscale, XmNvalue, xoffset, XmNminimum, min, XmNmaximum, max, NULL);
  XtVaSetValues(yscale, XmNvalue, yoffset, XmNminimum, min, XmNmaximum, max, NULL);

  XtManageChild(scale_dialog);
  in_scale_dialog = True;
  XtSetValues(XtParent(scale_dialog), XmNshellUnitType, XmPIXELS, NULL);
}

void Popdown_offset()
{
  if(in_scale_dialog || (scale_dialog && XtIsManaged(scale_dialog))) {
    XtUnmanageChild(scale_dialog);
    in_scale_dialog = False;
  }
}

static void ok_callback()
{
  double x, y;

  x = xoffset / (double) factor;
  y = yoffset / (double) factor;
  XtVaSetValues(sline,  XtNxOffset, &x, XtNyOffset, &y, NULL);
  XtVaSetValues(zsline, XtNxOffset, &x, XtNyOffset, &y, NULL);
  Popdown_offset();
}

static void cancel_callback()
{
  double x, y;

  x = xdefault / (double) factor;
  y = ydefault / (double) factor;
  XtVaSetValues(sline,  XtNxOffset, &x, XtNyOffset, &y, NULL);
  XtVaSetValues(zsline, XtNxOffset, &x, XtNyOffset, &y, NULL);
  Popdown_offset();
}

static void xvalue_callback(widget, client_data, call_data)
  Widget widget;
  XtPointer client_data;
  XmScaleCallbackStruct *call_data;
{
  double x;

  xoffset = call_data->value;
  x = xoffset / (double) factor;
  XtVaSetValues(sline,  XtNxOffset, &x, NULL);
  XtVaSetValues(zsline, XtNxOffset, &x, NULL);
}

static void yvalue_callback(widget, client_data, call_data)
  Widget widget;
  XtPointer client_data;
  XmScaleCallbackStruct *call_data;
{
  double y;

  yoffset = call_data->value;
  y = yoffset / (double) factor;
  XtVaSetValues(sline,  XtNyOffset, &y, NULL);
  XtVaSetValues(zsline, XtNyOffset, &y, NULL);
}

static void reset_callback()
{
  double x, y;

  xoffset = yoffset = 0;
  x = y = 0.0;
  XtVaSetValues(sline,  XtNxOffset, &x, XtNyOffset, &y, NULL);
  XtVaSetValues(zsline, XtNxOffset, &x, XtNyOffset, &y, NULL);
  XtVaSetValues(xscale, XmNvalue, xoffset, NULL);
  XtVaSetValues(yscale, XmNvalue, yoffset, NULL);
}
