 /***********************************************************************
 *
 * TITLE:
 *	slip.c
 *
 * AUTHOR:
 *	Cassie Mulnix
 *
 * DESCRIPTION:	
 *	This module is part of the OPPS editor, xopps.  It contains
 *	routines to handle slip objects.
 *
 *                              CHANGE HISTORY
 *
 * $Log: slip.c,v $
 * Revision 1.47  1994/12/31  04:38:24  kevin
 * fixed memory allocation problem after DialogTextGet
 *
 * Revision 1.46  1994/08/10  22:05:48  cassie
 * removed call to DialogFlagSet in verify_fun since
 * it is already set in ok_button
 *
 * Revision 1.45  1994/07/20  19:06:35  clm
 * updated TRUE, ERROR etc in cancel & ok_button functions
 * to DIALOG_ constants
 *
 * Revision 1.44  1994/06/16  21:57:27  clm
 * updated to new dialog routines - extra parameter to DialogTextCreate
 *
 * Revision 1.43  1994/06/16  16:56:35  clm
 * updated to new gr_ routines using GR_ for font names
 *
 * Revision 1.42  1994/06/08  18:48:45  clm
 * removed Xm library includes since they are in dialog
 *
 * Revision 1.41  1994/06/07  16:49:30  clm
 * fixed locate of slip object
 *
 * Revision 1.40  1994/06/07  00:52:11  clm
 * fixed ok_button date values
 *
 * Revision 1.39  1994/06/01  22:27:07  clm
 * rewrote init functions to use dialog oellib functions
 * also don't initialize popups until object called
 *
 * Revision 1.38  1994/05/20  23:31:43  clm
 * updated with HP, SGI changes
 *
 * Revision 1.37  1994/05/04  23:34:36  clm
 * ported to ANSI C
 *
 * Revision 1.36  1994/02/09  19:16:21  clm
 * moved gr_set_color after gr_rect_clear so it is set correctly
 *
 * Revision 1.35  1993/11/11  18:12:10  clm
 * adjusted vertical position of text
 *
 * Revision 1.34  1993/10/11  15:46:40  clm
 * added clear rectangle around object so that it stands out from vertical lines
 *
 * Revision 1.33  1993/05/21  16:01:58  clm
 * fixed buffer size for sav function
 *
 * Revision 1.32  1993/05/18  22:39:41  clm
 * added meaningful error messages for check_num and check_day
 *
 * Revision 1.31  1993/05/18  20:58:30  clm
 * added new message.c function
 *
 * Revision 1.30  1993/02/20  00:04:14  clm
 * added Slip Precedence Objects to edit popup
 *
 * Revision 1.29  1993/02/08  16:28:12  clm
 * centered symbol on date
 *
 * Revision 1.28  1993/02/08  16:25:56  clm
 * fixed loc_function for y2
 * fixed clrary set
 * fixed dsp_marker size to match symbol object
 *
 * Revision 1.27  1992/12/15  20:39:51  clm
 * changed strlen to sizeof when assigning symbols
 *
 * Revision 1.26  1992/12/14  18:55:08  clm
 *  really fixed dsp and loc bug
 *
 * Revision 1.25  1992/12/11  22:47:55  clm
 * fixed dsp error checking of page bounds
 *
 * Revision 1.24  1992/12/11  22:11:27  clm
 * fixed loc and dsp for completely offpage objects
 *
 * Revision 1.23  1992/12/10  21:45:40  clm
 * fixed new_index so chart is always object 0
 *
 * Revision 1.22  1992/11/30  23:06:57  clm
 * fixed locate function
 *
 * Revision 1.21  1992/11/24  16:28:27  clm
 * fixed rem functions - setting of ip array
 *
 * Revision 1.20  1992/11/20  16:00:44  clm
 * fixed number of elements in load event
 *
 * Revision 1.19  1992/11/12  18:56:31  clm
 * added display date option
 *
 * Revision 1.18  1992/11/09  16:33:21  clm
 * added precedence lines
 *
 * Revision 1.17  1992/10/13  18:13:31  clm
 * fixed copy of text items
 *
 * Revision 1.16  1992/10/12  18:12:27  clm
 *  fixed move to only change y coordinate
 *
 * Revision 1.15  1992/10/09  21:17:43  clm
 * fixed move routine
 *
 * Revision 1.14  1992/10/02  20:41:54  clm
 * housekeeping
 *
 * Revision 1.13  1992/09/30  22:25:55  clm
 * fixed display of s_char and e_char
 * fixed rectangle for x position
 *
 * Revision 1.11  1992/09/29  21:42:20  clm
 * added id text and toggle
 *
 * Revision 1.10  1992/09/25  20:41:39  clm
 * error checking for end date < start date
 *
 * Revision 1.8  1992/09/16  17:33:05  clm
 * fixed load function char *text to char text[128]
 *
 * Revision 1.7  1992/09/15  15:59:03  clm
 * added text and text positioning to object
 *
 * Revision 1.6  1992/08/28  15:20:11  clm
 * fixed display of lines
 *
 * Revision 1.5  1992/08/27  20:15:15  clm
 * took loc out of load since pg_lines is also loaded
 *
 * Revision 1.4  1992/08/26  17:55:58  clm
 * fixed loc and dsp of slip so that if part of the object is on the
 * screen, it still shows
 *
 * Revision 1.3  1992/08/10  20:59:18  clm
 * added error checking to load routine
 *
 * Revision 1.2  1992/08/10  17:41:29  clm
 * fixed loc and dsp so that object appears when pages displayed changes
 *
 * Revision 1.1  1992/08/04  17:02:05  clm
 * Initial revision
 *
 *
 ***********************************************************************
 *
 * WARNINGS:
 *
 * EXTERNAL CALLABLE COMPONENTS (PUBLIC):
 *
 * GLOBALS:
 *
 * WAIVERS:
 *
 * NOTES:
 *
 * MANPAGE:
 *
 ***********************************************************************/

#ifndef lint
static char rcsid[] =
    "$Id: slip.c,v 1.47 1994/12/31 04:38:24 kevin OEL $";
#endif

/*
    slip.c - an xopps module for simple activity objects

    local functions:
        dsp_slip(i) - display slip object
        rem_slip(i) - remove slip object
        mov_slip(i) - move slip object
        edt_slip(i) - change contents of slip field
        msg_slip(i) - display message on screen
*/

#include "xopps.h"

static int font_values[] = {
    GR_COURIER, GR_COURIER_BOLD, GR_HELVETICA, GR_HELVETICA_BOLD, GR_TIMES, 
    GR_TIMES_BOLD
};

static int font_sizes[] = {
    8, 10, 12, 14, 18, 24
};

static int symbol_nums[MAX_MARKER];

	/* local functions */
static void create_dialog(void);
static void slip_ok_button(void);		/* Callback for ok button */
static void cancel_button(void);		/* Callback for cancel button */
static void change_drawlyr(Widget, XtPointer, XtPointer);
static void change_smark(Widget, XtPointer, XtPointer);
static void change_emark(Widget, XtPointer, XtPointer);
static void change_line(Widget, XtPointer, XtPointer);
static void change_color(Widget, XtPointer, XtPointer);
static void change_font(Widget, XtPointer, XtPointer);
static void change_point(Widget, XtPointer, XtPointer);
static void change_hpos(Widget, XtPointer, XtPointer);
static void change_vpos(Widget, XtPointer, XtPointer);
static void change_idhpos(Widget, XtPointer, XtPointer);
static void change_idvpos(Widget, XtPointer, XtPointer);
static void change_idtog(Widget, XtPointer, XtPointer);
static void change_disp(Widget, XtPointer, XtPointer);
static void change_pline(Widget, XtPointer, XtPointer);
static void set_pline(utc_val, utc_val);       /* Executes pline object slips */
static void dsp_slip(int);
static void edt_slip(int, int);
static void rem_slip(int, int);
static void lim_slip(int, int *, int *, int *, int *, int);
static void loc_slip(int, int);
static void mov_slip(int, int, int, int);
static void cpy_slip(struct obj *, struct obj *);
static void msg_slip(int, int);
static void sav_slip(int, FILE *, int);
static int load_slip(char *);
static void verify_fun(Widget, XtPointer, XtPointer);

static struct ops slp_ops = {
    dsp_slip, edt_slip, rem_slip, lim_slip, loc_slip, mov_slip,
    cpy_slip, msg_slip, sav_slip
};
                                              /* function pointer */

static DialogDate *sdate, *edate;
static DialogText *lpos;
static DialogOption *drawlyr, *smark, *emark;
static DialogText *schar, *echar;
static DialogOption *line, *color;
static DialogOption *font, *point;
static DialogText *text, *idtext;
static DialogOption *hpos, *vpos;
static DialogOption *idhpos, *idvpos;
static DialogOption *idtog, *disp, *plinew;

static Widget slip_dialog;			/* dialog shell for popup */
static Widget parent_shell;
static int nmarks;				/* number symbols */
static int new_smark;				/* new value for start symbol */
static int new_emark;				/* new value for end symbol */
static int new_drawlyr;				/* new value for layer */
static int new_line_type;			/* new value for line type */
static int new_color;				/* new value for color */
static int new_font;				/* new value for font */
static int new_point;				/* new value for point size */
static int new_hpos;				/* new horizontal position */
static int new_vpos;				/* new vertical position */
static int new_idhpos;				/* new id horizontal position */
static int new_idvpos;				/* new id vertical position */
static int new_idtog;				/* new id toggle button */
static int new_disp;				/* new date display */

static int pline_flag = FALSE;			/* slip plines flag */

/***********************************************************************
 *
 * FUNCTION:
 *	init_slip_object()
 *
 * INPUTS:
 *	parent	(Widget)
 *
 * OUTPUTS:
 *	none
 *
 * RETURNS:
 *	none
 *
 * EXTERNALLY READ:
 *	none
 *
 * EXTERNALLY MODIFIED:
 *	none
 *
 * DESCRIPTION:
 *	registers the slip object and sets the parent
 */

void 
init_slip_object(Widget parent)
{
    register_io_obj('S', load_slip);			/* register object */
    parent_shell = parent;
}

/***********************************************************************
 *
 * FUNCTION:
 *	create_dialog()
 *
 * INPUTS:
 *	none
 *
 * OUTPUTS:
 *	none
 *
 * RETURNS:
 *	none
 *
 * EXTERNALLY READ:
 *	none
 *
 * EXTERNALLY MODIFIED:
 *	none
 *
 * DESCRIPTION:
 *	sets up widgets for slip
 */

static void
create_dialog(void)
{
    Pixmap marks[16];                       /* symbol images */
    int n;

    static char *hpos_list[] = { "Left", "Center", "Right" };
    static char *vpos_list[] = { "Above", "Below", "Center" };
    static char *disps[] = { "None", "Display" };
    static char *fonts[] = { "Courier", "Courier Bold", "Helvetica",
        "Helvetica Bold", "Times", "Times Bold" };
    static char *points[] = { "8", "10", "12", "14", "18", "24" };
    static char *dates[] = { "None", "DOY", "Month/Day" };
    static char *drawlyrs[] = { "0", "1", "2", "3" };
    static char *lines[] = { "Center", "Lower & Upper", "Lower", "Upper" };
    static char *plines[] = { "No", "Yes" };

    get_markers(marks, &nmarks);
    for (n = 0; n < nmarks; n++) {
        symbol_nums[n] = n;
    }

    slip_dialog = DialogInit(parent_shell, "Slip Object", "slip", verify_fun,
	(XtPointer)DIALOG_CANCEL);

    DialogAddRow(2);
    sdate = DialogDateCreate("Start Date ");
    edate = DialogDateCreate("End Date ");

    lpos = DialogTextCreate("Line Position ", 2, 2);

    DialogAddRow(2);
    smark = DialogOptionCreate("Start Marker ", nmarks, 0, change_smark,
	DIALOG_OPT_PIX_ARY, marks, NULL);
    emark = DialogOptionCreate("End Marker ", nmarks, 0, change_emark,
	DIALOG_OPT_PIX_ARY, marks, NULL);

    DialogAddRow(2);
    schar = DialogTextCreate("Start Label Character ", 1, 1);
    echar = DialogTextCreate("End Label Character ", 1, 1);

    text = DialogTextCreate("Text ", 50, 100);

    DialogAddRow(2);
    hpos = DialogOptionCreate("Horiz. Text Position ", 3, 0, change_hpos,
	DIALOG_OPT_STR_ARY, hpos_list, NULL);
    vpos = DialogOptionCreate("Vert. Text Position ", 3, 0, change_vpos,
	DIALOG_OPT_STR_ARY, vpos_list, NULL);

    DialogAddRow(2);
    idtext = DialogTextCreate("Id ", 20, 100);
    idtog = DialogOptionCreate("Display Id ", 2, 0, change_idtog, 
	DIALOG_OPT_STR_ARY, disps, NULL);

    DialogAddRow(2);
    idhpos = DialogOptionCreate("Horizontal Id Position ", 3, 0, change_idhpos,
	DIALOG_OPT_STR_ARY, hpos_list, NULL);
    idvpos = DialogOptionCreate("Vertical Id Position ", 3, 0, change_idvpos,
	DIALOG_OPT_STR_ARY, vpos_list, NULL);

    DialogAddRow(2);
    font = DialogOptionCreate("Font ", 6, 5, change_font, DIALOG_OPT_STR_ARY,
	fonts, font_values);
    point = DialogOptionCreate("Point ", 6, 10, change_point, 
	DIALOG_OPT_STR_ARY, points, font_sizes);

    DialogAddRow(2);
    disp = DialogOptionCreate("Display Date", 3, 1, change_disp, 
	DIALOG_OPT_STR_ARY, dates, NULL);
    drawlyr = DialogOptionCreate("Draw Layer ", 4, 0, change_drawlyr, 
	DIALOG_OPT_STR_ARY, drawlyrs, NULL);

    DialogAddRow(2);
    line = DialogOptionCreate("Line Type ", 4, 0, change_line, 
	DIALOG_OPT_STR_ARY, lines, NULL);
    color = DialogOptionCreate("Color ", ncolor, 0, change_color,
	DIALOG_OPT_STR_ARY, color_name, color_index);

    plinew = DialogOptionCreate("Slip Precedence Objects ", 2, 0, change_pline,
	DIALOG_OPT_STR_ARY, plines, NULL);

    DialogStdButtons(verify_fun, (XtPointer)DIALOG_UPDATE, verify_fun,
        (XtPointer)DIALOG_CANCEL, (XtCallbackProc)ShowHelp, "slip");

}

/***********************************************************************
 *
 * FUNCTION:
 *	add_slip()
 *
 * INPUTS:
 *	st_date, e_date				(utc_val)
 *	s_char, e_char, text			(char *)
 *	line, strtsym, endsym, layer 		(int)
 *	font, point, hpos, vpos			(int)
 *
 * OUTPUTS:
 *	none
 *
 * RETURNS:
 *	none
 *
 * EXTERNALLY READ:
 *	none
 *
 * EXTERNALLY MODIFIED:
 *	none
 *
 * DESCRIPTION:
 *	adds an slip object
 */

int 
add_slip(utc_val st_date, utc_val e_date, int line, int strtsym, int endsym, char *s_char, char *e_char, enum slin_typ line_type, int color, int font, int point, char *text, int hpos, int vpos, int layer, enum tds disp, char *idtext, int idtog, int idhpos, int idvpos)
{
    int i;              /* index */

    i = new_index(FALSE);
    objary[i].z.slpptr = (struct slp *)XtMalloc(sizeof(struct slp));
    objary[i].z.slpptr->strtdate = st_date;
    objary[i].z.slpptr->endate = e_date;
    objary[i].z.slpptr->line = line;
    objary[i].z.slpptr->strtsym = strtsym;
    objary[i].z.slpptr->endsym = endsym;
    objary[i].z.slpptr->s_char = XtNewString(s_char);
    objary[i].z.slpptr->e_char = XtNewString(e_char);
    objary[i].z.slpptr->line_type = line_type;
    objary[i].z.slpptr->color = color;
    objary[i].z.slpptr->font = font;
    objary[i].z.slpptr->point = point;
    objary[i].z.slpptr->hpos = hpos;
    objary[i].z.slpptr->vpos = vpos;
    objary[i].z.slpptr->disp = disp;
    objary[i].z.slpptr->text = XtNewString(text);
    objary[i].z.slpptr->idhpos = idhpos;
    objary[i].z.slpptr->idvpos = idvpos;
    objary[i].z.slpptr->idtog = idtog;
    objary[i].z.slpptr->idtext = XtNewString(idtext);
    objary[i].type = OBJ_SLP;
    objary[i].layer = layer;
    objary[i].opsptr = &slp_ops;
    return i;
}

/***********************************************************************
 *
 * FUNCTION:
 *      change_disp()
 *
 * INPUTS:
 *      button          (Widget)
 *      option          (XtPointer)
 *      anydata         (XtPointer)
 *
 * OUTPUTS:
 *	none
 *
 * RETURNS:
 *	none
 *
 * EXTERNALLY READ:
 *	none
 *
 * EXTERNALLY MODIFIED:
 *	none
 *
 * DESCRIPTION:
 *      changes display date to the input value
 */

static void 
change_disp(Widget button, XtPointer option, XtPointer any_data)
{
    new_disp = (int)option;
}

/***********************************************************************
 *
 * FUNCTION:
 *	change_drawlyr()
 *
 * INPUTS:
 *	button			(Widget)
 *	option, any_data	(XtPointer)
 *
 * OUTPUTS:
 *	none
 *
 * RETURNS:
 *	none
 *
 * EXTERNALLY READ:
 *	none
 *
 * EXTERNALLY MODIFIED:
 *	none
 *
 * DESCRIPTION:	
 *	changes the draw layer of the slip object
 */

static void 
change_drawlyr(Widget button, XtPointer option, XtPointer any_data)
{
    new_drawlyr = (int)option;
}

/***********************************************************************
 *
 * FUNCTION:
 *      change_smark()
 *
 * INPUTS:
 *      button          - (Widget)
 *      option          - (XtPointer)
 *      any_data        - (XtPointer)
 *
 * OUTPUTS:
 *	none
 *
 * RETURNS:
 *	none
 *
 * EXTERNALLY READ:
 *	none
 *
 * EXTERNALLY MODIFIED:
 *	none
 *
 * DESCRIPTION:	
 *	changes the smark of the slip object
 *
 */

static void 
change_smark(Widget button, XtPointer option, XtPointer any_data)
{
    new_smark = (int)option;
}

/***********************************************************************
 *
 * FUNCTION:
 *      change_emark()
 *
 * INPUTS:
 *      button          - (Widget)
 *      option          - (XtPointer)
 *      any_data        - (XtPointer)
 *
 * OUTPUTS:
 *	none
 *
 * RETURNS:
 *	none
 *
 * EXTERNALLY READ:
 *	none
 *
 * EXTERNALLY MODIFIED:
 *	none
 *
 * DESCRIPTION:	
 *	changes the emark of the slip object
 *
 */

static void 
change_emark(Widget button, XtPointer option, XtPointer any_data)
{
    new_emark = (int)option;
}

/***********************************************************************
 *
 * FUNCTION:
 *      change_line()
 *
 * INPUTS:
 *      button          - (Widget)
 *      option          - (XtPointer)
 *      any_data        - (XtPointer)
 *
 * OUTPUTS:
 *	none
 *
 * RETURNS:
 *	none
 *
 * EXTERNALLY READ:
 *	none
 *
 * EXTERNALLY MODIFIED:
 *	none
 *
 * DESCRIPTION:
 *      changes the line_type of the slip object
 *
 */

static void 
change_line(Widget button, XtPointer option, XtPointer any_data)
{
    new_line_type = (int)option;
}

/***********************************************************************
 *
 * FUNCTION:
 *      change_color()
 *
 * INPUTS:
 *      button          - (Widget)
 *      option          - (XtPointer)
 *      any_data        - (XtPointer)
 *
 * OUTPUTS:
 *	none
 *
 * RETURNS:
 *	none
 *
 * EXTERNALLY READ:
 *	none
 *
 * EXTERNALLY MODIFIED:
 *	none
 *
 * DESCRIPTION:
 *      changes the color of the slip object
 *
 */

static void 
change_color(Widget button, XtPointer option, XtPointer any_data)
{
    new_color = (int)option;
}

/***********************************************************************
 *
 * FUNCTION:
 *      change_point()
 *
 * INPUTS:
 *      button          - (Widget)
 *      option          - (XtPointer)
 *      any_data        - (XtPointer)
 *
 * OUTPUTS:
 *	none
 *
 * RETURNS:
 *	none
 *
 * EXTERNALLY READ:
 *	none
 *
 * EXTERNALLY MODIFIED:
 *	none
 *
 * DESCRIPTION:
 *      This module sets the selected font point size.
 */

/* ARGSUSED */
static void 
change_point(Widget button, XtPointer option, XtPointer any_data)
{
    new_point = (int)option;
}

/***********************************************************************
 *
 * FUNCTION:
 *      change_font()
 *
 * INPUTS:
 *      button          - (Widget)
 *      option          - (XtPointer)
 *      any_data        - (XtPointer)
 *
 * OUTPUTS:
 *	none
 *
 * RETURNS:
 *	none
 *
 * EXTERNALLY READ:
 *	none
 *
 * EXTERNALLY MODIFIED:
 *	none
 *
 * DESCRIPTION:
 *      This module changes the selected font.
 */

/* ARGSUSED */
static void 
change_font(Widget button, XtPointer option, XtPointer any_data)
{
    new_font = (int)option;
}

/***********************************************************************
 *
 * FUNCTION:
 *      change_hpos()
 *
 * INPUTS:
 *      button                  (Widget)
 *      option, any_data        (XtPointer)
 *
 * OUTPUTS:
 *	none
 *
 * RETURNS:
 *	none
 *
 * EXTERNALLY READ:
 *	none
 *
 * EXTERNALLY MODIFIED:
 *	none
 *
 * DESCRIPTION:
 *      changes the hpos position of the slip object
 */

static void 
change_hpos(Widget button, XtPointer option, XtPointer any_data)
{
    new_hpos = (int)option;
}

/***********************************************************************
 *
 * FUNCTION:
 *      change_vpos()
 *
 * INPUTS:
 *      button                  (Widget)
 *      option, any_data        (XtPointer)
 *
 * OUTPUTS:
 *	none
 *
 * RETURNS:
 *	none
 *
 * EXTERNALLY READ:
 *	none
 *
 * EXTERNALLY MODIFIED:
 *	none
 *
 * DESCRIPTION:
 *      changes the vpos position of the slip object
 */

static void 
change_vpos(Widget button, XtPointer option, XtPointer any_data)
{
    new_vpos = (int)option;
}

/***********************************************************************
 *
 * FUNCTION:
 *      change_idhpos()
 *
 * INPUTS:
 *      button                  (Widget)
 *      option, any_data        (XtPointer)
 *
 * OUTPUTS:
 *	none
 *
 * RETURNS:
 *	none
 *
 * EXTERNALLY READ:
 *	none
 *
 * EXTERNALLY MODIFIED:
 *	none
 *
 * DESCRIPTION:
 *      changes the id hpos position of the slip object
 */

static void 
change_idhpos(Widget button, XtPointer option, XtPointer any_data)
{
    new_idhpos = (int)option;
}

/***********************************************************************
 *
 * FUNCTION:
 *      change_idvpos()
 *
 * INPUTS:
 *      button                  (Widget)
 *      option, any_data        (XtPointer)
 *
 * OUTPUTS:
 *	none
 *
 * RETURNS:
 *	none
 *
 * EXTERNALLY READ:
 *	none
 *
 * EXTERNALLY MODIFIED:
 *	none
 *
 * DESCRIPTION:
 *      changes the idvpos position of the slip object
 */

static void 
change_idvpos(Widget button, XtPointer option, XtPointer any_data)
{
    new_idvpos = (int)option;
}

/***********************************************************************
 *
 * FUNCTION:
 *      change_idtog()
 *
 * INPUTS:
 *      button                  (Widget)
 *      option, any_data        (XtPointer)
 *
 * OUTPUTS:
 *	none
 *
 * RETURNS:
 *	none
 *
 * EXTERNALLY READ:
 *	none
 *
 * EXTERNALLY MODIFIED:
 *	none
 *
 * DESCRIPTION:
 *      changes the idtog value of the slip object
 */

static void 
change_idtog(Widget button, XtPointer option, XtPointer any_data)
{
    new_idtog = (int)option;
}

/***********************************************************************
 *
 * FUNCTION:
 *      change_pline()
 *
 * INPUTS:
 *      button          - (Widget)
 *      option          - (XtPointer)
 *
 * OUTPUTS:
 *	none
 *
 * RETURNS:
 *	none
 *
 * EXTERNALLY READ:
 *	none
 *
 * EXTERNALLY MODIFIED:
 *	none
 *
 * DESCRIPTION:
 *      This module sets the pline object slip value for activities
 *
 */

static void 
change_pline(Widget button, XtPointer option, XtPointer any_data)
{
    pline_flag = (int)option;
}

/***********************************************************************
 *
 * FUNCTION:
 *	dsp_slip()
 *
 * INPUTS:
 *	i  (int)
 *
 * OUTPUTS:
 *	none
 *
 * RETURNS:
 *	none
 *
 * EXTERNALLY READ:
 *	none
 *
 * EXTERNALLY MODIFIED:
 *	none
 *
 * DESCRIPTION: 
 *	pops up a edit box for the slip i
 */

static void 
dsp_slip(int i)
{
    struct slp *slpptr;       		/* local pointer */
    XRectangle *(*line_rect)[];		/* rectangle for horiz. line */
    int y;				/* temp variable for y */
    int xs, xe;				/* start and end times */
    enum tog s_flag, e_flag;		/* flag to draw symbol */
    int height;				/* height of slip object */
    int txheight, width;		/* width and height of text */
    int text_x, text_y;			/* positioning of text */
    int idtext_x, idtext_y;		/* positioning of id text */
    int sym_x, sym_y;			/* positioning of symbol chars */
    enum tog mask;			/* mask for white background */
    char lbuf[6], rbuf[6];		/* temp buffer for date display */
    int dxltime, dxrtime;		/* width of date buffer */
    int mo, da, yr;			/* parsed date */
    int utc_date;			/* utc doy of date */
    int txwidth;			/* width of font character */

    slpptr = objary[i].z.slpptr;
    height = y_gap - 1;
    xs = utc_to_x(objary[i].z.slpptr->strtdate + UTC_ONE_DAY/2);
    xe = utc_to_x(objary[i].z.slpptr->endate + UTC_ONE_DAY/2);
    s_flag = TOG_ON;
    e_flag = TOG_ON;
    if (xs == XVAL_EARLY) {
	s_flag = TOG_OFF;
	xs = x_time_offset;
    }
    if (xe == XVAL_LATE) {
	e_flag = TOG_OFF;
	xe = x_right_margin;
    }
    /* add one day for correct centering */
    xs++;
    xe++;
    if (xs > xe) {
	xe = xs + 2;
    }
    txwidth = gr_txwidth(slpptr->font|slpptr->point);
    if (slpptr->disp == TDS_DOY) {
	utc_date = get_doy(slpptr->strtdate);
	(void)sprintf(lbuf, "%03d", utc_date);
	utc_date = get_doy(slpptr->endate);
	(void)sprintf(rbuf, "%03d", utc_date);
	dxltime = (strlen(lbuf) + 1) * txwidth;
	dxrtime = (strlen(rbuf) + 1) * txwidth;
    } else if (slpptr->disp == TDS_DATE) {
	get_mdy(&mo, &da, &yr, slpptr->strtdate);
	(void)sprintf(lbuf, "%d/%d", mo, da);
	get_mdy(&mo, &da, &yr, slpptr->endate);
	(void)sprintf(rbuf, "%d/%d", mo, da);
	dxltime = (strlen(lbuf) + 1) * txwidth;
	dxrtime = (strlen(rbuf) + 1) * txwidth;
    } else {
	(void)sprintf(lbuf, "%s", "");
	(void)sprintf(rbuf, "%s", "");
	dxltime = 0;
	dxrtime = 0;
    }
    if (((slpptr->line >= page_begin) && (slpptr->line <= page_end)) &&
	((slpptr->strtdate <= objary[0].z.chtptr->end_date) && 
	(slpptr->endate >= objary[0].z.chtptr->start_date))) {
	 line_rect = getMoveRect(Hobjary[hln_objary[slpptr->line]].rlist);
   	 y = (*line_rect)[0]->y + y_gap;
	 switch(slpptr->line_type) {
	 case S_CENTER:
	    gr_rect_clear(xs - 2, y - height, xe - xs + 2, height);
	    gr_set_line(GR_SHORT_DASH);
    	    gr_set_color(color_name[slpptr->color],color_gscale[slpptr->color]);
	    gr_line(xs, y - y_gap/2, xe, y - y_gap/2);
	    gr_set_line(GR_SOLID_LINE);
	    break;
        case S_LOWER_UPPER:
	    gr_rect_clear(xs - 2, y - height, xe - xs + 2, height);
    	    gr_set_line(GR_SHORT_DASH);
    	    gr_set_color(color_name[slpptr->color], 
		color_gscale[slpptr->color]);
	    gr_line(xs, y - 4, xe, y - 4);
	    gr_line(xs, y - height + 3, xe, y - height + 3);
	    gr_set_line(GR_SOLID_LINE);
	    break;
        case S_LOWER:
	    gr_rect_clear(xs - 2, y - height, xe - xs + 2, height);
	    gr_set_line(GR_SHORT_DASH);
    	    gr_set_color(color_name[slpptr->color], 
		color_gscale[slpptr->color]);
	    gr_line(xs, y-4, xe, y-4);
	    gr_set_line(GR_SOLID_LINE);
	    break;
        case S_UPPER:
	    gr_rect_clear(xs - 2, y - height, xe - xs + 2, height);
	    gr_set_line(GR_SHORT_DASH);
    	    gr_set_color(color_name[slpptr->color], 
		color_gscale[slpptr->color]);
	    gr_line(xs, y - height + 3, xe, y - height + 3);
	    gr_set_line(GR_SOLID_LINE);
	    break;
 	}
 	txheight = gr_txheight(slpptr->font|slpptr->point);
        if (s_flag == TOG_ON) {
    	    dsp_marker(slpptr->strtsym, xs - y_gap/2, (*line_rect)[0]->y + 3,
		y_gap - 5, 0);
	    if (slpptr->s_char != "") {
                if (slpptr->strtsym == 0) {
                    sym_x = xs - 4;
                    sym_y = y - y_gap/2 + txheight/2;
                } else if (slpptr->strtsym == 2) {
                    sym_x = xs - 4;
                    sym_y = y - y_gap/2 + txheight/2 + 1;
                } else if (slpptr->strtsym == 4) {
                    sym_x = xs - 4;
                    sym_y = y - y_gap/2 + txheight/2 - 2;
                } else if (slpptr->strtsym == 10) {
                    sym_x = xs - 4;
                    sym_y = y - y_gap/2 + txheight/2 - 1;
                } else {
		    sym_x = xs - 4;
		    sym_y = y - y_gap/2 + txheight/2;
                }
                gr_text(sym_x, sym_y, slpptr->s_char, GR_LEFT,
                    (slpptr->font|slpptr->point), 0);
	    }
        } 
        if (e_flag == TOG_ON) {
	    dsp_marker(slpptr->endsym, xe - y_gap/2, (*line_rect)[0]->y + 3, 
	        y_gap - 5, 0);
	    if (slpptr->e_char != "") {
                if (slpptr->endsym == 0) {
                    sym_x = xe - 4;
                    sym_y = y - y_gap/2 + txheight/2;
                } else if (slpptr->endsym == 2) {
                    sym_x = xe - 4;
                    sym_y = y - y_gap/2 + txheight/2 + 1;
                } else if (slpptr->endsym == 4) {
                    sym_x = xe - 4;
                    sym_y = y - y_gap/2 + txheight/2 - 2;
                } else if (slpptr->endsym == 10) {
                    sym_x = xe - 4;
                    sym_y = y - y_gap/2 + txheight/2 - 1;
                } else {
		    sym_x = xe - 4;
		    sym_y = y - y_gap/2 + txheight/2;
		}
                gr_text(sym_x, sym_y, slpptr->e_char, GR_LEFT,
                    (slpptr->font|slpptr->point), 0);
	    }
        }
	
 	if (objary[i].layer == 0) {
	    mask = TOG_OFF;
	} else {
	    mask = TOG_ON;
	}

	width = gr_strwidth(slpptr->text, slpptr->font|slpptr->point);
	switch(slpptr->hpos) {
	case GR_LEFT:
	    if (s_flag == TOG_ON) {
		text_x = xs - y_gap/2 - width - 1;
	    } else {
		text_x = xs - width - 2;
	    }
	    if (slpptr->disp != TDS_NONE) {
		text_x -= y_gap;
	    }
	    break;
 	case GR_RIGHT:
	    if (e_flag == TOG_ON) {
		text_x = xe + y_gap/2 + 1;
	    } else {
	        text_x = xe + 1;
	    }
	    if (slpptr->disp != TDS_NONE) {
		text_x += y_gap;
	    }
	    break;
	default:
	    text_x = xs - width/2 + (xe - xs)/2;
	    break;
	}
	switch (slpptr->vpos) {
	case TX_ABOVE:
	    text_y = (*line_rect)[0]->y;
	    break;
        case TX_BELOW:
   	    text_y = (*line_rect)[0]->y + y_gap + txheight + 2;
	    break;
	default:
	    text_y = (*line_rect)[0]->y + 1 + txheight/2 + y_gap/2;
	    break;
	}
	if (slpptr->idtog == TOG_ON) {
            width = gr_strwidth(slpptr->idtext, slpptr->font|slpptr->point);
            switch (slpptr->idhpos) {
            case GR_LEFT:
                idtext_x = xs - y_gap/2 - width - 1;
		if (slpptr->disp != TDS_NONE) {
		    idtext_x -= y_gap;
	 	}
                break;
            case GR_RIGHT:
                idtext_x = xe + y_gap/2 + 1;
		if (slpptr->disp != TDS_NONE) {
		    idtext_x += y_gap;
	 	}
                break;
            default:
                idtext_x = xs - width/2 + (xe - xs)/2;
                break;
            }
	    switch (slpptr->idvpos) {
	    case TX_ABOVE:
	        idtext_y = (*line_rect)[0]->y;
	        break;
            case TX_BELOW:
    	        idtext_y = (*line_rect)[0]->y + txheight + y_gap + 2;
	        break;
	    default:
	        idtext_y = (*line_rect)[0]->y + 1 + txheight/2 + y_gap/2;
	        break;
	    }
	}
 	gr_text(xs - y_gap - 6, (*line_rect)[0]->y + 1 + txheight/2 + y_gap/2,
	    lbuf, GR_LEFT, (slpptr->font|slpptr->point), (int)mask);
	gr_text(xe + y_gap/2 + 1, (*line_rect)[0]->y + 1 + txheight/2 + y_gap/2,
	    rbuf, GR_LEFT, (slpptr->font|slpptr->point), (int)mask);
	gr_text(text_x, text_y, slpptr->text, GR_LEFT, 
	    (slpptr->font|slpptr->point), (int)mask);
	if (slpptr->idtog == TOG_ON) {
	    gr_text(idtext_x, idtext_y, slpptr->idtext, GR_LEFT,
		(slpptr->font|slpptr->point), (int)mask);
	}
    }
}

/***********************************************************************
 *
 * FUNCTION:
 *	loc_slip()
 *
 * INPUTS:
 *	i  (int)
 *
 * OUTPUTS:
 *	none
 *
 * RETURNS:
 *	none
 *
 * EXTERNALLY READ:
 *	none
 *
 * EXTERNALLY MODIFIED:
 *	none
 *
 * DESCRIPTION: 
 *	This module locates the position of slip object i
 */

static void 
loc_slip(int i, int dir)
{
    XRectangle r;			/* rectangle */
    XRectangle *(*line_rect)[];		/* Horiz. line rectangle */
    struct slp *slpptr;			/* local object pointer */
    int co;				/* temp variable */
    int xs, xe;				/* start/end position of slip object */
    enum tog s_flag;			/* flag to draw symbol */
    int txheight, width;		/* height and width of text */
    int txwidth;			/* width of font character */
    int utc_date;			/* utc doy of date */
    int mo, da, yr;			/* parsed date */
    char lbuf[6], rbuf[6];		/* buffers for date display */
    int dxltime, dxrtime;		/* length of date buffers */

    slpptr= objary[i].z.slpptr;
    if (((slpptr->line < page_begin) || (slpptr->line > page_end)) ||
	((slpptr->strtdate < objary[0].z.chtptr->start_date) &&
	(slpptr->endate < objary[0].z.chtptr->start_date)) ||
	((slpptr->strtdate > objary[0].z.chtptr->end_date) &&
	(slpptr->endate > objary[0].z.chtptr->end_date))) {
	    setRectList(objary[i].rlist,0);
  	    return;
    }
    xs = utc_to_x(slpptr->strtdate + UTC_ONE_DAY/2);
    xe = utc_to_x(slpptr->endate + UTC_ONE_DAY/2);
    s_flag = TOG_ON;
    if (xs == XVAL_EARLY) {
	s_flag = TOG_OFF;
	xs = x_time_offset;
    }
    if (xe == XVAL_LATE) {
        xe = x_right_margin;
    }
    /* add one for correct centering */
    xs++;
    xe++;
    if (xs > xe) {
	xe = xs + 2;
    }
    co = hln_objary[slpptr->line];
    line_rect = getMoveRect(Hobjary[co].rlist);
    txwidth = gr_txwidth(slpptr->font|slpptr->point);
    if (slpptr->disp == TDS_DOY) {
	utc_date = get_doy(slpptr->strtdate);
	(void)sprintf(lbuf, "%03d", utc_date);
	utc_date = get_doy(slpptr->endate);
	(void)sprintf(rbuf, "%03d", utc_date);
	dxltime = (strlen(lbuf) + 1) * txwidth;
	dxrtime = (strlen(rbuf) + 1) * txwidth;
    } else if (slpptr->disp == TDS_DATE) {
	get_mdy(&mo, &da, &yr, slpptr->strtdate);
	(void)sprintf(lbuf, "%d%d", mo, da);
	get_mdy(&mo, &da, &yr, slpptr->endate);
	(void)sprintf(rbuf, "%d/%d", mo, da);
	dxltime = (strlen(lbuf) + 1) * txwidth;
	dxrtime = (strlen(rbuf) + 1) * txwidth;
    } else {
	(void)sprintf(lbuf, "%s", "");
        (void)sprintf(rbuf, "%s", "");
        dxltime = 0;
        dxrtime = 0;
    }
    if (s_flag == TOG_ON) {
	r.x = xs - y_gap/2 - dxltime - 7;
    } else {
	r.x = xs - 7 - dxltime;
    }
    r.y = (*line_rect)[0]->y + 1;
    r.width = xe - xs + 2 + y_gap + dxltime + dxrtime;
    r.height = y_gap + 2;
    width = gr_strwidth(slpptr->text, slpptr->font|slpptr->point);
    if (gr_strwidth(slpptr->idtext, slpptr->font|slpptr->point) > width) {
	width = gr_strwidth(slpptr->idtext, slpptr->font|slpptr->point);
    }
    if (((slpptr->hpos == GR_LEFT) && (strcmp(slpptr->text, "") != 0)) || 
	((slpptr->idhpos == GR_LEFT) && (strcmp(slpptr->idtext, "") != 0))) {
	r.x = r.x - width;
	r.width = r.width + width + 5;
    }
    if (((slpptr->hpos == GR_RIGHT) && (strcmp(slpptr->text, "") != 0)) || 
	((slpptr->idhpos == GR_RIGHT) && (strcmp(slpptr->idtext, "") != 0))) {
	r.width = r.width + width + 5;
    }
    if (((slpptr->hpos == GR_CENTER) && (strcmp(slpptr->text, "") != 0)) ||
        ((slpptr->idhpos == GR_CENTER) && (strcmp(slpptr->idtext, "") != 0))) {
	r.x = r.x - width/4;
        r.width = r.width + width/2 + 5;
    }
    txheight = gr_txheight(slpptr->font|slpptr->point);
    if (((slpptr->vpos == TX_ABOVE) && (strcmp(slpptr->text, "") != 0)) || 
	((slpptr->idvpos == TX_ABOVE) && (strcmp(slpptr->idtext, "") != 0))) {
	r.y = r.y - 1 - txheight;
	r.height = r.height + txheight + 1;
    }
    if (((slpptr->vpos == TX_BELOW) && (strcmp(slpptr->text, "") != 0)) || 
	((slpptr->idvpos == TX_BELOW) && (strcmp(slpptr->idtext, "") != 0))) {
	r.height = r.height + txheight + 1;
    }
    setRectList(objary[i].rlist, 1, &r, RL_PRIMARY);
}

/***********************************************************************
 *
 * FUNCTION:
 *	edit_slip()
 *
 * INPUTS:
 *	i, new	(int)
 *
 * OUTPUTS:
 *	none
 *
 * RETURNS:
 *	none
 *
 * EXTERNALLY READ:
 *	none
 *
 * EXTERNALLY MODIFIED:
 *	none
 *
 * DESCRIPTION:
 *	pops up a edit box for the slip i
 */

static void 
edt_slip(int i, int new)
{
    char buf[4];

    if (slip_dialog == NULL) {
	create_dialog();
    }

    (*(objary[i].opsptr->cpy))(&objtmp, &objary[i]);
    new_smark = objtmp.z.slpptr->strtsym;
    new_emark = objtmp.z.slpptr->endsym;
    new_font = objtmp.z.slpptr->font;
    new_point = objtmp.z.slpptr->point;
    new_hpos = objtmp.z.slpptr->hpos;
    new_vpos = objtmp.z.slpptr->vpos;
    new_drawlyr = objtmp.layer;
    new_idhpos = objtmp.z.slpptr->idhpos;
    new_idvpos = objtmp.z.slpptr->idvpos;
    new_idtog = objtmp.z.slpptr->idtog;
    new_disp = objtmp.z.slpptr->disp;
    new_color = objtmp.z.slpptr->color;
    pline_flag = FALSE;
    if (new) {
    /*
     * only need rem when undo option is added
     */
 	(*(objary[i].opsptr->rem))(i, OBJECT);
	i = -1;
    }

    DialogDateSet(sdate, objtmp.z.slpptr->strtdate);
    DialogDateSet(edate, objtmp.z.slpptr->endate);

    sprintf(buf, "%d", objtmp.z.slpptr->line);
    DialogTextSet(lpos, buf);

    DialogOptionSet(smark, (int)new_smark);
    DialogOptionSet(emark, (int)new_emark);

    DialogTextSet(schar, objtmp.z.slpptr->s_char);
    DialogTextSet(echar, objtmp.z.slpptr->e_char);

    DialogOptionSet(line, (int)new_line_type);
    DialogOptionSet(color, (int)new_color);
    DialogOptionSet(drawlyr, (int)new_drawlyr);
    DialogOptionSet(font, (int)new_font);
    DialogOptionSet(point, (int)new_point);
    DialogOptionSet(hpos, (int)new_hpos);
    DialogOptionSet(vpos, (int)new_vpos);
    DialogOptionSet(disp, (int)new_disp);
    DialogOptionSet(idhpos, (int)new_idhpos);
    DialogOptionSet(idvpos, (int)new_idvpos);
    DialogOptionSet(idtog, (int)new_idtog);

    DialogTextSet(text, objtmp.z.slpptr->text);

    if ((objtmp.precptr == NULL) || (new)) {
	XtSetSensitive(plinew->parent, FALSE);
    } else {
	XtSetSensitive(plinew->parent, TRUE);
    }

    DialogOptionSet(plinew, pline_flag);

    DialogTextSet(idtext, objtmp.z.slpptr->idtext);
    EditObject(i, slip_dialog);
}

/***********************************************************************
 *
 * FUNCTION:
 *	rem_slip()
 *
 * INPUTS:
 *	i  (int)
 *
 * OUTPUTS:
 *	none
 *
 * RETURNS:
 *	none
 *
 * EXTERNALLY READ:
 *	none
 *
 * EXTERNALLY MODIFIED:
 *	none
 *
 * DESCRIPTION:
 *	This module removes slip object i from the data base
 */

static void 
rem_slip(int i, int dir)
{
    struct obj *objptr;				/* temp object pointer */
    int (*ip)[];                                /* array of pline indices */
    int nip;                                    /* number of indices */
    int j;                                      /* temp loop index */
    int prec = 0;

    switch (i) {
    case BACK:
	objptr = &objbck;
 	break;
    case TEMP:
	objptr = &objtmp;
	prec = 1;
	break;
    default: 
	objptr = &(objary[i]);
	break;
    }
    /*
     * do not remove precedence lines in cancel button was pressed
     */
    if (!prec) {
        if (objptr->precptr != NULL) {
            if (objptr->precptr->nelems > 0) {
                nip = objptr->precptr->nelems;
                ip = (int(*)[])XtMalloc((Cardinal)(sizeof(int) * nip));
	        for (j = 0; j < nip; j++) {
                    (*ip)[j] = elemof_dynarray(objptr->precptr, j);
	        }
                for (j = 0; j < nip; j++) {
                    rem_pline((*ip)[j], OBJECT);
                }
                XtFree((char *)ip);
                delete_dynarray(objptr->precptr);
            }
        }
    }

    freeRectList(objptr->rlist);
    XtFree((char *)objptr->z.slpptr);
    rem_object(objptr);
}

/***********************************************************************
 *
 * FUNCTION:   
 *	lim_slip()
 *
 * INPUTS:
 *	i  		(int)
 *	x1, y1, x2, y2	(int *)
 *
 * OUTPUTS:
 *	none
 *
 * RETURNS:
 *	none
 *
 * EXTERNALLY READ:
 *	none
 *
 * EXTERNALLY MODIFIED:
 *	none
 *
 * DESCRIPTION:
 *	This module limits the range of motion of the slip object i
 */

static void 
lim_slip(int i, int *x1, int *y1, int *x2, int *y2, int dir)
{
    XRectangle *(*r)[];				/* rectangle */

    r = getMoveRect(objary[i].rlist);
    *x1 = (*r)[0]->x;
    *y1 = y_act_bottom;
    *x2 = (*r)[0]->x;
    *y2 = y_lines_end - y_gap;
}

/***********************************************************************
 *
 * FUNCTION:
 *	mov_slip()
 *
 * INPUTS:
 *	i, x, y  	(int)
 *
 * OUTPUTS:
 *	none
 *
 * RETURNS:
 *	none
 *
 * EXTERNALLY READ:
 *	none
 *
 * EXTERNALLY MODIFIED:
 *	none
 *
 * DESCRIPTION:
 *	This module moves the slip object when the middle mouse
 *	button is pressed
 */

static void 
mov_slip(int i, int x, int y, int dir)
{
    XRectangle *(*r)[];				/* rectangle */

    r = getMoveRect(objary[i].rlist);
    objary[i].z.slpptr->line = (((*r)[0]->y + y +1 - y_act_bottom)/y_gap) + 
	page_begin;
}

/***********************************************************************
 *
 * FUNCTION:
 *	cpy_slip()
 *
 * INPUTS:
 *	to, from	(struct obj *) 
 *
 * OUTPUTS:
 *	none
 *
 * RETURNS:
 *	none
 *
 * EXTERNALLY READ:
 *	none
 *
 * EXTERNALLY MODIFIED:
 *	none
 *
 * DESCRIPTION:
 *	This module copies slip from to slip to
 */

static void 
cpy_slip(struct obj *to, struct obj *from)
{
    if (from->type == OBJ_NUL) {
	return;
    }
    to->z.slpptr = (struct slp *)XtMalloc(sizeof(struct slp));
    to->z.slpptr->strtdate = from->z.slpptr->strtdate;
    to->z.slpptr->endate = from->z.slpptr->endate;
    to->z.slpptr->line = from->z.slpptr->line;
    to->z.slpptr->strtsym = from->z.slpptr->strtsym;
    to->z.slpptr->endsym = from->z.slpptr->endsym;
    to->z.slpptr->s_char = from->z.slpptr->s_char;
    to->z.slpptr->e_char = from->z.slpptr->e_char;
    to->z.slpptr->line_type = from->z.slpptr->line_type;
    to->z.slpptr->color = from->z.slpptr->color;
    to->z.slpptr->font = from->z.slpptr->font;
    to->z.slpptr->point = from->z.slpptr->point;
    to->z.slpptr->hpos = from->z.slpptr->hpos;
    to->z.slpptr->vpos = from->z.slpptr->vpos;
    to->z.slpptr->disp = from->z.slpptr->disp;
    to->z.slpptr->idtog = from->z.slpptr->idtog;
    to->z.slpptr->idhpos = from->z.slpptr->idhpos;
    to->z.slpptr->idvpos = from->z.slpptr->idvpos;
    to->z.slpptr->text = XtNewString(from->z.slpptr->text);
    to->z.slpptr->idtext = XtNewString(from->z.slpptr->idtext);
    to->type = OBJ_SLP;
    to->opsptr = &slp_ops;
    to->layer = from->layer;
    to->precptr = from->precptr;
    to->rlist = copyRectList(from->rlist);
}

/***********************************************************************
 *
 * FUNCTION:
 *	msg_slip()
 *
 * INPUTS:
 *	i  (int)
 *
 * OUTPUTS:
 *	none
 *
 * RETURNS:
 *	none
 *
 * EXTERNALLY READ:
 *	none
 *
 * EXTERNALLY MODIFIED:
 *	none
 *
 * DESCRIPTION:
 *	displays the slip message for object i
 */

static void 
msg_slip(int i, int dir)
{
    char buf[64];				/* temp buffer */
    int mo, da, yr, mo2, da2, yr2;		/* temp date values */

    get_mdy(&mo, &da, &yr, objary[i].z. slpptr->strtdate);
    get_mdy(&mo2, &da2, &yr2, objary[i].z.slpptr->endate);
    (void)sprintf(buf, "Slip: %d/%d/%d - %d/%d/%d", mo, da, yr, mo2, da2, yr2);
    Message(buf);
}

/***********************************************************************
 *
 * FUNCTION:
 *	sav_slip()
 *
 * INPUTS:
 *	i  	(int)
 *	fp	(FILE *)
 *
 * OUTPUTS:
 *	none
 *
 * RETURNS:
 *	none
 *
 * EXTERNALLY READ:
 *	none
 *
 * EXTERNALLY MODIFIED:
 *	none
 *
 * DESCRIPTION:
 *	saves the slip object i to fp
 */

static void 
sav_slip(int i, FILE *fp, int dir)
{ 
    struct slp *slpptr;				/*temp object pointer */
    char buf[1024];				/* temp buffer */

    slpptr = objary[i].z.slpptr;
    buf[0] = 'S';
    buf[1] = ' ';
    record_print(buf+2, "ttdddqqddddqddddqddd",slpptr->strtdate,slpptr->endate, 
	slpptr->line, slpptr->strtsym, slpptr->endsym, slpptr->s_char,
	slpptr->e_char, slpptr->line_type, slpptr->color, slpptr->font,
	slpptr->point, slpptr->text, slpptr->hpos, slpptr->vpos,
	objary[i].layer, slpptr->disp, slpptr->idtext, slpptr->idtog, 
	slpptr->idhpos, slpptr->idvpos);
    fputs(buf, fp);
}

/***********************************************************************
 *
 * FUNCTION:
 *      load_slip()
 *
 * INPUTS:
 *      buf     (char *)
 *
 * OUTPUTS:
 *	none
 *
 * RETURNS:
 *	none
 *
 * EXTERNALLY READ:
 *	none
 *
 * EXTERNALLY MODIFIED:
 *	none
 *
 * DESCRIPTION:
 *      loads slip object record
 */

static int 
load_slip(char *buf)
{
    utc_val st_date, e_date;          /* start and end date */
    int line;                         /* index to hline object */
    int strtsym, endsym;              /* pointer to starting symbol type */
    char s_char[2], e_char[2];	      /* start and end chars in symbols */
    enum slin_typ line_type;	      /* line type */
    int color;			      /* color of object */
    int font, point;		      /* font and point of object text */
    char text[128];	  	      /* text for object */
    int hpos, vpos;		      /* positioning of text */
    int layer;                        /* drawing layer */
    enum tds disp;		      /* date display */
    int i;			      /* temp index */
    int idhpos, idvpos;		      /* positioning of id text */
    char idtext[128];	  	      /* id text for object */
    int idtog;			      /* id toggle value */

    if (record_scan(buf + 1, "ttdddqqddddqddddqddd", &st_date, &e_date, &line,
	&strtsym, &endsym, s_char, e_char, &line_type, &color, &font,
	&point, text, &hpos, &vpos, &layer, &disp, idtext, &idtog, &idhpos, 
	&idvpos) == 20) {
	if ((line < 0) || (line > num_pages * pg_lines)) {
	    Warning("Illegal Slip line %d", line);
	} else if ((strtsym < 0) || (strtsym > 14)) {
	    Warning("Illegal Slip start symbol %d", strtsym);
	} else if ((endsym < 0) || (endsym > 14)) {
	    Warning("Illegal Slip end symbol %d", endsym);
	} else if (((int)line_type < 0) || ((int)line_type > 3)) {
	    Warning("Illegal Slip line type %d", line_type);
	} else if ((color < 0) || (color > ncolor)) {
	    Warning("Illegal Slip color %d", color);
	} else if ((layer < 0) || (layer > 3)) {
	    Warning("Illegal Slip layer %d", layer);
 	} else if (((int)disp < TDS_NONE) || ((int)disp > TDS_DATE)) {
	    Warning("Illegal Slip display %d", disp);
	} else if ((font != GR_COURIER) && (font != GR_COURIER_BOLD) &&
	    (font != GR_HELVETICA) && (font != GR_HELVETICA_BOLD) && 
	    (font != GR_TIMES) && (font != GR_TIMES_BOLD)) {
	    Warning("Illegal Slip font %d", font);
	} else if ((point != 8) && (point != 10) && (point != 12) &&
	    (point != 14) && (point != 18) && (point != 24)) {
	    Warning("Illegal Slip point size %d", point);
	} else if ((hpos < 0) || (hpos > 2)) {
	    Warning("Illegal Slip Horizontal Position %d", hpos);
	} else if ((vpos < 0) || (vpos > 2)) {
	    Warning("Illegal Slip Vertical Position %d", vpos);
	} else if ((idhpos < 0) || (idhpos > 2)) {
	    Warning("Illegal Slip ID Horizontal Position %d", idhpos);
	} else if ((idvpos < 0) || (idvpos > 2)) {
	    Warning("Illegal Slip ID Vertical Position %d", idvpos);
	} else if ((idtog < 0) || (idtog > 2)) {
	    Warning("Illegal Slip ID Display Toggle %d", idtog);
	} else {
            i = add_slip(st_date, e_date, line, strtsym, endsym, s_char,
	        e_char, line_type, color, font, point, text, hpos, vpos, layer,
		disp, idtext, idtog, idhpos, idvpos);
            return 0;
	}
	return -1;
    } else {
	return -1;
    }
}

/***********************************************************************
 *
 * FUNCTION:
 *	slip_ok_button() 
 *
 * INPUTS:    
 *
 * OUTPUTS:
 *	none
 *
 * RETURNS:
 *	none
 *
 * EXTERNALLY READ:
 *	none
 *
 * EXTERNALLY MODIFIED:
 *	none
 *
 * DESCRIPTION:
 *	this module checks input after the ok button is pressed
 */

static void 
slip_ok_button(void)
{
    int change = DIALOG_NO_CHANGE;		/* temp boolean */
    utc_val sdate_diff, edate_diff;		/* slip in dates */
    utc_val temp_date;
    char *buf;
    int val;					/* temporary integer */

    temp_date = DialogDateGet(sdate);
    if (temp_date == UTC_INVALID) {
	Warning("Improper Start Date");
	change |= DIALOG_ERROR;
    } else if (temp_date != objtmp.z.slpptr->strtdate) {
	change |= DIALOG_UPDATE;
    }
    sdate_diff = temp_date - objtmp.z.slpptr->strtdate;

    temp_date = DialogDateGet(edate);
    if (temp_date == UTC_INVALID) {
	Warning("Improper End Date");
	change |= DIALOG_ERROR;
    } else if (temp_date != objtmp.z.slpptr->endate) {
	change |= DIALOG_UPDATE;
    }
    edate_diff = temp_date - objtmp.z.slpptr->endate;

    /*
     * slip objects associated by precedence lines
     */
    set_pline(sdate_diff, edate_diff);
    objtmp.z.slpptr->strtdate = objtmp.z.slpptr->strtdate + sdate_diff;
    objtmp.z.slpptr->endate = objtmp.z.slpptr->endate + edate_diff;

    if (objtmp.z.slpptr->endate < objtmp.z.slpptr->strtdate) {
	Warning("Slip Start date must precede End date");
	change |= DIALOG_ERROR;
    }

    val = DialogTextGetInt(lpos);
    if ((val < 1) || (val > MAX_LINE)) {
	Warning("Improper Line Position");
    } else if (val != objtmp.z.slpptr->line) {
	change |= DIALOG_UPDATE;
	objtmp.z.slpptr->line = val;
    }

    if (new_smark != objtmp.z.slpptr->strtsym) {
	change |= DIALOG_UPDATE;
    }
    objtmp.z.slpptr->strtsym = DialogOptionGet(smark);

    if (new_emark != objtmp.z.slpptr->endsym) {
	change |= DIALOG_UPDATE;
    }
    objtmp.z.slpptr->endsym = DialogOptionGet(emark);

    buf = DialogTextGet(schar);
    if (strcmp(buf, objtmp.z.slpptr->s_char)) {
	change |= DIALOG_UPDATE;
	XtFree(objtmp.z.slpptr->s_char);
	objtmp.z.slpptr->s_char = buf;
    } else {
	XtFree(buf);
    }

    buf = DialogTextGet(echar);
    if (strcmp(buf, objtmp.z.slpptr->e_char)) {
	change |= DIALOG_UPDATE;
	XtFree(objtmp.z.slpptr->e_char);
	objtmp.z.slpptr->e_char = buf;
    } else {
	XtFree(buf);
    }

    if (new_line_type != objtmp.z.slpptr->line_type) {
	change |= DIALOG_UPDATE;
    }
    objtmp.z.slpptr->line_type = DialogOptionGet(line);

    if (new_color != objtmp.z.slpptr->color) {
	change |= DIALOG_UPDATE;
    }
    objtmp.z.slpptr->color = DialogOptionGet(color);

    if (new_font != objtmp.z.slpptr->font) {
	change |= DIALOG_UPDATE;
    }
    objtmp.z.slpptr->font = DialogOptionGet(font);

    if (new_point != objtmp.z.slpptr->point) {
	change |= DIALOG_UPDATE;
    }
    objtmp.z.slpptr->point = DialogOptionGet(point);

    if (new_hpos != objtmp.z.slpptr->hpos) {
	change |= DIALOG_UPDATE;
    }
    objtmp.z.slpptr->hpos = DialogOptionGet(hpos);

    if (new_vpos != objtmp.z.slpptr->vpos) {
	change |= DIALOG_UPDATE;
    }
    objtmp.z.slpptr->vpos = DialogOptionGet(vpos);

    if (new_idtog != objtmp.z.slpptr->idtog) {
	change |= DIALOG_UPDATE;
    }
    objtmp.z.slpptr->idtog = DialogOptionGet(idtog);

    if (new_idhpos != objtmp.z.slpptr->idhpos) {
	change |= DIALOG_UPDATE;
    }
    objtmp.z.slpptr->idhpos = DialogOptionGet(idhpos);

    if (new_idvpos != objtmp.z.slpptr->idvpos) {
	change |= DIALOG_UPDATE;
    }
    objtmp.z.slpptr->idvpos = DialogOptionGet(idvpos);

    if (new_drawlyr != objtmp.layer) {
	change |= DIALOG_UPDATE;
    }
    objtmp.layer = DialogOptionGet(drawlyr);

    if (new_disp != objtmp.z.slpptr->disp) {
	change |= DIALOG_UPDATE;
    }
    objtmp.z.slpptr->disp = DialogOptionGet(disp);

    buf = DialogTextGet(text);
    if (strcmp(buf, objtmp.z.slpptr->text)) {
	change |= DIALOG_UPDATE;
	XtFree(objtmp.z.slpptr->text);
	objtmp.z.slpptr->text = buf;
    } else {
	XtFree(buf);
    }

    buf = DialogTextGet(idtext);
    if (strcmp(buf, objtmp.z.slpptr->idtext)) {
	change |= DIALOG_UPDATE;
	XtFree(objtmp.z.slpptr->idtext);
	objtmp.z.slpptr->idtext = buf;
    } else {
	XtFree(buf);
    }

    object_change = change;
    DialogFlagSet(change);
}

/***********************************************************************
 *
 * FUNCTION:
 *	cancel_button()
 *
 * INPUTS:
 *	none
 *
 * OUTPUTS:
 *	none
 *
 * RETURNS:
 *	none
 *
 * EXTERNALLY READ:
 *	none
 *
 * EXTERNALLY MODIFIED:
 *	none
 *
 * DESCRIPTION:
 *	discards any edits and closes edit window
 */

static void 
cancel_button(void)
{
    object_change = DIALOG_CANCEL;
    DialogFlagSet(DIALOG_CANCEL);
}

/***********************************************************************
 *
 * FUNCTION:
 *      set_pline()
 *
 * INPUTS:
 *      sdate_diff, edate_diff       (int)
 *
 * OUTPUTS:
 *	none
 *
 * RETURNS:
 *	none
 *
 * EXTERNALLY READ:
 *	none
 *
 * EXTERNALLY MODIFIED:
 *	none
 *
 * DESCRIPTION:
 *      This module adjusts the dates of the objects associated by
 *      precedence lines by the slip amount of the slip dates
 */

static void 
set_pline(utc_val sdate_diff, utc_val edate_diff)
{
int i, co;                      /* temp indices */

    if ((pline_flag) && (objtmp.precptr != NULL)) {
        for (i = 0; i < sizeof_dynarray(objtmp.precptr); i++) {
            co = elemof_dynarray(objtmp.precptr, i);
            if ((objary[plnary[co].obj1].z.slpptr->strtdate !=
                objtmp.z.slpptr->strtdate) || 
		(objary[plnary[co].obj1].z.slpptr->endate != 
		objtmp.z.slpptr->endate)) {
                switch (objary[plnary[co].obj1].type) {
                case OBJ_EVT:
                    objary[plnary[co].obj1].z.evtptr->edate += sdate_diff;
                    (*(objary[plnary[co].obj1].opsptr->loc))(plnary[co].obj1,
			OBJECT);
                    break;
                case OBJ_ACT:
                    objary[plnary[co].obj1].z.actptr->strtdate += sdate_diff;
                    objary[plnary[co].obj1].z.actptr->endate += edate_diff;
                    (*(objary[plnary[co].obj1].opsptr->loc))(plnary[co].obj1,
			OBJECT);
                    break;
                case OBJ_SACT:
                    objary[plnary[co].obj1].z.sactptr->strtdate += sdate_diff;
                    objary[plnary[co].obj1].z.sactptr->endate += edate_diff;
                    (*(objary[plnary[co].obj1].opsptr->loc))(plnary[co].obj1,
			OBJECT);
                    break;
                case OBJ_SLP:
                    objary[plnary[co].obj1].z.slpptr->strtdate += sdate_diff;
                    objary[plnary[co].obj1].z.slpptr->endate += edate_diff;
                    (*(objary[plnary[co].obj1].opsptr->loc))(plnary[co].obj1,
			OBJECT);
                    break;
                case OBJ_SEQ:
                    objary[plnary[co].obj1].z.seqptr->strtdate += sdate_diff;
                    objary[plnary[co].obj1].z.seqptr->endate += edate_diff;
                    (*(objary[plnary[co].obj1].opsptr->loc))(plnary[co].obj1,
			OBJECT);
                    break;
                default:
                    break;
                }
            }
            if ((objary[plnary[co].obj2].z.slpptr->strtdate !=
                objtmp.z.slpptr->strtdate) || 
		(objary[plnary[co].obj2].z.slpptr->endate != 
		objtmp.z.slpptr->endate)) {
                switch (objary[plnary[co].obj2].type) {
                case OBJ_EVT:
                    objary[plnary[co].obj2].z.evtptr->edate += sdate_diff;
                    (*(objary[plnary[co].obj2].opsptr->loc))(plnary[co].obj2,
			OBJECT);
                    break;
                case OBJ_ACT:
                    objary[plnary[co].obj2].z.actptr->strtdate += sdate_diff;
                    objary[plnary[co].obj2].z.actptr->endate += edate_diff;
                    (*(objary[plnary[co].obj2].opsptr->loc))(plnary[co].obj2,
			OBJECT);
                    break;
                case OBJ_SACT:
                    objary[plnary[co].obj2].z.sactptr->strtdate += sdate_diff;
                    objary[plnary[co].obj2].z.sactptr->endate += edate_diff;
                    (*(objary[plnary[co].obj2].opsptr->loc))(plnary[co].obj2,
			OBJECT);
                    break;
                case OBJ_SLP:
                    objary[plnary[co].obj2].z.slpptr->strtdate += sdate_diff;
                    objary[plnary[co].obj2].z.slpptr->endate += edate_diff;
                    (*(objary[plnary[co].obj2].opsptr->loc))(plnary[co].obj2,
			OBJECT);
                    break;
                case OBJ_SEQ:
                    objary[plnary[co].obj2].z.seqptr->strtdate += sdate_diff;
                    objary[plnary[co].obj2].z.seqptr->endate += edate_diff;
                    (*(objary[plnary[co].obj2].opsptr->loc))(plnary[co].obj2,
			OBJECT);
                    break;
                default:
                    break;
                }
            }
        }
    }
}

/***********************************************************************
 *
 * FUNCTION:
 *      verify_fun()
 *
 * INPUTS:
 *      w       (Widget)
 *      x, y    (XtPointer)
 *
 * OUTPUTS:
 *      none
 *
 * RETURNS:
 *      none
 *
 * EXTERNALLY READ:
 *      none
 *
 * EXTERNALLY MODIFIED:
 *      none
 *
 * DESCRIPTION:
 *      validates that the popup dialog can be closed
 */

static void
verify_fun(Widget w, XtPointer x, XtPointer y)
{
    if ((int)x == DIALOG_CANCEL) {
        if (!ShellValidateClose(w)) return;
        cancel_button();
    } else if ((int)x == DIALOG_UPDATE) {
        slip_ok_button();
    }
}

