/* handle the history feature of skyview */

#include <stdio.h>
#if defined(__STDC__)
#include <stdlib.h>
#endif
#include <Xm/Xm.h>
#include <Xm/Label.h>
#include <Xm/RowColumn.h>
#include <Xm/Separator.h>
#include <Xm/PushB.h>
#include <Xm/ToggleB.h>
#include <Xm/CascadeB.h>

#include "P_.h"
#include "astro.h"
#include "circum.h"
#include "preferences.h"
#include "skyhist.h"

extern Widget toplevel_w;

extern void query P_((Widget tw, char *msg, char *label1, char *label2,
    char *label3, void (*func1)(), void (*func2)(), void (*func3)()));
extern void set_xmstring P_((Widget w, char *resource, char *txtp));
extern void xe_msg P_((char *msg, int app_modal));
extern void watch_cursor P_((int want));

/* N.B. if over ten, will need a different mnemonic system */
#define	MAXHIST	10	/* max history items */

/* a collection of PB widgets and the histories they represent.
 * the first nhist entries of hist[] are in use.
 */
typedef struct {
    Widget w;
    SvHistory h;
} Hist;
static Hist hist[MAXHIST];
static int nhist;

static void svh_add_cb P_((Widget w, XtPointer client, XtPointer call));
static void svh_delall_cb P_((Widget w, XtPointer client, XtPointer call));
static void svh_goback_cb P_((Widget w, XtPointer client, XtPointer call));
static void delete_all_confirmed P_((void));
static void setup_pb P_((Hist *hp));

/* called to create the history cascade and pulldown off the given menubar */
void
svh_create (mb_w)
Widget mb_w;
{
	Widget cb_w, pd_w;
	Widget w;
	Arg args[20];
	int i;
	int n;

	n = 0;
	pd_w = XmCreatePulldownMenu (mb_w, "HPD", args, n);

	n = 0;
	XtSetArg (args[n], XmNsubMenuId, pd_w); n++;
	XtSetArg (args[n], XmNmnemonic, 'H'); n++;
	cb_w = XmCreateCascadeButton (mb_w, "History", args, n);
	XtManageChild (cb_w);

	/* create the Add and Delete PBs.
	 * tried give Add an acc of Alt-h but it interfered with cascade's H
	 * in motif 1.2 -- 2.0 knew to ignore it for the cascade though.
	 */

	n = 0;
	w = XmCreatePushButton (pd_w, "Add", args, n);
	XtAddCallback (w, XmNactivateCallback, svh_add_cb, NULL);
	XtManageChild (w);

	n = 0;
	w = XmCreatePushButton (pd_w, "DelAll", args, n);
	XtAddCallback (w, XmNactivateCallback, svh_delall_cb, NULL);
	set_xmstring (w, XmNlabelString, "Delete All");
	XtManageChild (w);

	n = 0;
	w = XmCreateSeparator (pd_w, "HSep", args, n);
	XtManageChild (w);

	/* create the activation PBs. not managed until defined */

	for (i = 0; i < MAXHIST; i++) {
	    XmString acct;
	    char acc[64];

	    (void) sprintf (acc, "Alt-%d", i+1);
	    acct = XmStringCreateSimple (acc);
	    (void) sprintf (acc, "Alt<Key>%c", i+'1');

	    n = 0;
	    XtSetArg (args[n], XmNaccelerator, acc); n++;
	    XtSetArg (args[n], XmNacceleratorText, acct); n++;
	    w = XmCreatePushButton (pd_w, "H", args, n);
	    XtAddCallback (w, XmNactivateCallback, svh_goback_cb, (XtPointer)i);
	    hist[i].w = w;
	    XmStringFree (acct);
	}

}

/* called when the Add button is hit in the history pulldown */
/* ARGSUSED */
static void
svh_add_cb (w, client, call)
Widget w;
XtPointer client;
XtPointer call;
{
	if (nhist == MAXHIST) {
	    char msg[128];

	    (void) sprintf (msg, "No room for additional history -- max is %d",
								    MAXHIST);
	    xe_msg (msg, 1);
	    return;
	}

	svh_get (&hist[nhist].h);
	setup_pb (&hist[nhist]);
	nhist++;
}

/* called when the Delete all button is hit in the history pulldown */
/* ARGSUSED */
static void
svh_delall_cb (w, client, call)
Widget w;
XtPointer client;
XtPointer call;
{
	if (nhist > 0)
	    query (toplevel_w, "Delete all Sky view history entries?",
				"Yes -- delete all", "No -- delete none", NULL,
					    delete_all_confirmed, NULL, NULL);
	else
	    xe_msg ("No history entries to delete", 1);
}

/* called when a history entry is activated.
 * client is an index into hist[].
 */
/* ARGSUSED */
static void
svh_goback_cb (w, client, call)
Widget w;
XtPointer client;
XtPointer call;
{
	int n = (int)client;

	if (n < 0 || n >= nhist) {
	    printf ("Bad history number: %d\n", n);
	    return;
	}

	watch_cursor (1);

	svh_goto (&hist[n].h);

	watch_cursor (0);
}

/* delete all history entries */
static void
delete_all_confirmed()
{
	int i;

	for (i = 0; i < nhist; i++)
	    XtUnmanageChild (hist[i].w);
	
	nhist = 0;
}

/* setup the widget for the given hist entry */
static void
setup_pb (hp)
Hist *hp;
{
	char buf[128];
	SvHistory *shp = &hp->h;

	if (shp->aa_mode)
	    (void) sprintf (buf, "Alt/Az %5.1f %5.1f %5.1f",
	    	raddeg(shp->altdec), raddeg(shp->azra), raddeg(shp->fov));
	else
	    (void) sprintf (buf, "RA/Dec %5.2f %5.1f %5.1f",
	    	raddeg(shp->azra), raddeg(shp->altdec), raddeg(shp->fov));

	set_xmstring (hp->w, XmNlabelString, buf);
	XtManageChild (hp->w);
}
