/***********************************************************************
 *
 * TITLE:
 *	pline.c
 *
 * AUTHOR:
 *	Cassie Mulnix
 *
 * DESCRIPTION:
 *	This module is part of the OPPS editor, xopps.  It contains
 *	routines to handle precedence lines.
 *
 *                              CHANGE HISTORY
 *
 * $Log: pline.c,v $
 * Revision 1.20  1994/06/16  21:57:27  clm
 * updated to new dialog routines - extra parameter to DialogTextCreate
 *
 * Revision 1.19  1994/06/01  22:30:42  clm
 * changed color from structure to 3 arrays
 *
 * Revision 1.18  1994/05/20  23:31:43  clm
 * updated with HP, SGI changes
 *
 * Revision 1.17  1994/05/04  23:34:36  clm
 * ported to ANSI C
 *
 * Revision 1.16  1994/02/10  19:30:08  clm
 * added display lines to draw plines depending on placement on coordinates
 *
 * Revision 1.15  1994/02/09  20:57:39  clm
 * changed pline to not have jog in middle
 *
 * Revision 1.14  1993/05/27  20:51:01  clm
 * changed to attach to start date
 *
 * Revision 1.13  1993/05/18  20:58:30  clm
 * added new message.c function
 *
 * Revision 1.12  1993/02/26  17:36:21  clm
 * added  UTC_ONE_DAY/2 for centering symbols on date
 *
 * Revision 1.11  1993/02/08  16:14:56  clm
 * freed rlist->rects and rlist when removing a pline
 * check for NULL in add_pline, loc_pline
 * fixed get_object_coord
 *
 * Revision 1.11  1993/01/07  23:12:12  clm
 * freed rlist->rects and rlist when removing a pline
 *
 * Revision 1.10  1992/12/18  19:04:58  clm
 * changed expose call
 *
 * Revision 1.9  1992/12/17  18:22:04  clm
 *  fixed new_pline so it won't exit when pline array is filled
 *
 * Revision 1.8  1992/12/11  15:46:20  clm
 * made offset and spread of locate rectangle #defined
 *
 * Revision 1.6  1992/12/04  18:53:41  clm
 * added error checking for x in get_object_coord
 * added rubberbanding
 *
 * Revision 1.5  1992/11/24  16:30:17  clm
 * fixed locate function
 * added rubberbanding of lines as pline is added
 *
 * Revision 1.4  1992/11/12  18:58:08  clm
 * fixed rectangle size
 *
 * Revision 1.3  1992/11/09  21:50:52  clm
 * removed unused variables
 *
 * Revision 1.2  1992/11/09  20:52:43  clm
 * error checking for load_pline
 *
 * Revision 1.1  1992/11/09  16:57:17  clm
 * Initial revision
 *
 *
 ***********************************************************************
 *
 * WARNINGS:
 *
 * EXTERNAL CALLABLE COMPONENTS (PUBLIC):
 *
 * GLOBALS:
 *
 * WAIVERS:
 *
 * NOTES:
 *
 * MANPAGE:
 *
 ***********************************************************************/

#ifndef lint
static char rcsid[] =
    "$Id: pline.c,v 1.20 1994/06/16 21:57:27 clm OEL $";
#endif

/*
    pline.c - an xopps module containing routines for pline objects

    local functions:
        dsp_pline(i) - display pline object
        rem_pline(i) - remove pline object
        msg_pline(i) - display message on screen
*/

#include "xopps.h"

#define OFFSET 3			/* offset of x or y for rectangle */
#define SPREAD 6			/* width or height of rectangle */

 	/* local functions */
static int load_pline(char *);
static void display_lines(void);
static void draw_pline(Widget, XtPointer, XEvent *);    /* pline event handler */
static int check_object(int);

static int co;
static int x_start, y_start;		/* original coordinates */
static int x_last, y_last;		/* coordinates of last draw */

/***********************************************************************
 *
 * FUNCTION:
 *      init_pline()
 *
 * INPUTS:
 *
 * OUTPUTS:
 *
 * RETURNS:
 *
 * EXTERNALLY READ:
 *
 * EXTERNALLY MODIFIED:
 *
 * DESCRIPTION:
 *      sets the load character for the pline objects
 */

void 
init_pline(void)
{
    int i;

    register_io_obj('Q', load_pline);		/* register object */

    for (i = 0; i < MAX_PLN; i++) {
	plnary[i].obj1 = 0;
	plnary[i].obj2 = 0;
	plnary[i].rlist = newRectList(0);
    }
}

/***********************************************************************
 * FUNCTION:
 *	add_pline()
 *
 * INPUTS:
 *	i			(int) - index of object
 *	obj1, obj2		(int) - indices of pline objects
 *
 * OUTPUTS:
 *
 * RETURNS:
 *
 * EXTERNALLY READ:
 *
 * EXTERNALLY MODIFIED:
 *
 * DESCRIPTION:
 *	adds a precedence line
 */

void 
add_pline(int i, int obj1, int obj2)
{
    plnary[i].obj1 = obj1;
    plnary[i].obj2 = obj2;
    if (plnary[i].rlist == NULL) {
	plnary[i].rlist = newRectList(0);
    }
}

/***********************************************************************
 *
 * FUNCTION:
 *	dsp_pline()
 *
 * INPUTS:
 *	i	(int)
 *
 * OUTPUTS:
 *
 * RETURNS:
 *
 * EXTERNALLY READ:
 *
 * EXTERNALLY MODIFIED:
 *
 * DESCRIPTION:
 *	displays pline object i 
 */

void 
dsp_pline(int i)
{
    int co;
    int x1, y1, x2, y2;			/* x and y coordinates of pline */

    if (plnary[i].obj1 != 0) {
        co = get_object_coord(plnary[i].obj1, &x1, &y1);
	if (co != -1) {
            co = get_object_coord(plnary[i].obj2, &x2, &y2);
	    if (co != -1) {
        	gr_set_color(color_name[0], color_gscale[0]);
        	gr_set_line(GR_SHORT_DASH);
		if ((y1 == y2) || (x1 == x2)) {
		    gr_line(x1, y1, x2, y2);
        	} else if (x1 < x2) {
		    gr_line(x1, y1, x1, y2);
		    gr_line(x1, y2, x2, y2);
      	 	} else {
		    gr_line(x1, y1, x2, y1);
		    gr_line(x2, y1, x2, y2);
		}
       	        gr_set_line(GR_SOLID_LINE);
            }
	}
    }
}

/***********************************************************************
 *
 * FUNCTION:
 *	msg_pline()
 *
 * INPUTS:
 *	i	(int)
 *
 * OUTPUTS:
 *
 * RETURNS:
 *
 * EXTERNALLY READ:
 *
 * EXTERNALLY MODIFIED:
 *
 * DESCRIPTION:
 *	displays the pline message for pline i
 */

void 
msg_pline(int i, int dir)
{
    char buf[64];			/* temp buffer */

    (void)sprintf(buf,"Delete Pline for obj %d and %d", plnary[i].obj1,
	plnary[i].obj2);
    Message(buf);
}

/***********************************************************************
 *
 * FUNCTION:
 *      sav_pline()
 *
 * INPUTS:
 *	i		(int)
 *	fp		(FILE *)
 *
 * OUTPUTS:
 *
 * RETURNS:
 *
 * EXTERNALLY READ:
 *
 * EXTERNALLY MODIFIED:
 *
 * DESCRIPTION:
 *	This module saves pline i to file fp.
 *
 */

void 
sav_pline(int i, FILE *fp, int dir)
{
    char buf[256];

    buf[0] = 'Q';
    buf[1] = ' ';
    record_print(buf+2, "dd", plnary[i].obj1, plnary[i].obj2);
    fputs(buf, fp);
}

/***********************************************************************
 *
 * FUNCTION:
 *      load_pline()
 *
 * INPUTS:
 *      buf     (char *)
 *
 * OUTPUTS:
 *
 * RETURNS:
 *
 * EXTERNALLY READ:
 *
 * EXTERNALLY MODIFIED:
 *
 * DESCRIPTION:
 *      loads pline object record
 */

static int 
load_pline(char *buf)
{
    int obj1, obj2;			/* objects of precedence line */
    int i;
    int error = 0;

    if (record_scan(buf + 1, "dd", &obj1, &obj2) == 2) {
	if ((obj1 <= 0) || (obj1 > nobj)) {
	    Warning("Illegal Pline obj1 %d", obj1);
	    error = 1;
	    return -1;
	} else if ((obj2 <= 0) || (obj2 > nobj)) {
	    Warning("Illegal Pline obj2 %d", obj2);
	    error = 1;
	    return -1;
        } else {
	    for (i = 0; i < npln; i++) {
		 if (((plnary[i].obj1 == obj1) || (plnary[i].obj1 == obj2)) &&
	            ((plnary[i].obj2 == obj1) || (plnary[i].obj2 == obj2))) {
	            Warning("Line ignored - Pline %d to %d already exists", 
			obj1, obj2);
	            /* it exists so dont add pline */
	            error = 1;
	    	    return -1;
	            break;
	         }
	        /* 
	         * check to see that both objects are different 
	         */
	        if (obj1 == obj2) {
	            Warning("Line ignored - Pline %d to %d to itself", 
			obj1, obj2);
	            error = 1;
	    	    return -1;
	            break;
	        }
	    }
	}
	if (!error) {
	    if ((check_object(obj1) == 1) && 
		(check_object(obj2) == 1)) {
		i = new_pline();
		if (i != -1) {
	            add_pline(i, obj1, obj2);
                    if (objary[obj1].precptr == NULL) {
                        objary[obj1].precptr = new_dynarray();
                    }
                    append_dynarray(objary[obj1].precptr, i);
                    if (objary[obj2].precptr == NULL) {
                        objary[obj2].precptr = new_dynarray();
                    }
                    append_dynarray(objary[obj2].precptr, i);
	            return 0;
		} else {
		    return -1;
		}
	    } else {
		Warning("Illegal Pline object type");
		return -1;
	    }
	}
    } else {
	return -1;
    }
    return 0;
}

/***********************************************************************
 *
 * FUNCTION:
 *      rem_pline()
 *
 * INPUTS:
 *	i	(int)
 *
 * OUTPUTS:
 *
 * RETURNS:
 *
 * EXTERNALLY READ:
 *
 * EXTERNALLY MODIFIED:
 *
 * DESCRIPTION:
 *	This module removes pline i from the data base
 */

void 
rem_pline(int i, int dir)
{
    if ((i >= 0) && (plnary[i].obj1 != 0)) {
	/*
	 * remove the pline index from each of its objects
	 */
        delete_element(i, objary[plnary[i].obj1].precptr);
        delete_element(i, objary[plnary[i].obj2].precptr);
	/*
	 * remove the pline itself
  	 */
	plnary[i].obj1 = 0;
	plnary[i].obj2 = 0;
	freeRectList(plnary[i].rlist);
	plnary[i].rlist->rects = NULL;
	plnary[i].rlist = NULL;
    }
}

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

void 
loc_pline(int i, int dir)
{
    int x1, y1, x2, y2;			/* x and y coordinates of pline */
    XRectangle r1, r2, r3;		/* rectangles for object */
    int j;

    if (plnary[i].rlist == NULL) {
	return;
    }
    if ((plnary[i].obj1 != 0) && (plnary[i].obj1 < nobj)) {
	j = get_object_coord(plnary[i].obj1, &x1, &y1);
	if (j >= 0) {
	    j = get_object_coord(plnary[i].obj2, &x2, &y2);
	    if (j >= 0) {
		if (x1 == x2) {
		    /*
		     * rectangle for one vertical line
		     */
		    r1.x = x1 - OFFSET;
		    r1.width = SPREAD;
		    if (y1 < y2) {
			/*
			 * obj1 above obj2
			 */
	    	        r1.y = y1 - OFFSET;
	    	        r1.height = (y2 - y1) + SPREAD;
		    } else {
			/*
			 * obj1 below obj2
			 */
			r1.y = y2 - OFFSET;
			r1.height = (y1 - y2) + SPREAD;
		    }
	    	    setRectList(plnary[i].rlist, 1, &r1, RL_PRIMARY);
		} else if (y1 == y2) {
		    /*
		     * rectangle for one horizontal line
		     */
	    	    r1.y = y1 - OFFSET;
	    	    r1.height = SPREAD;
		    if (x1 < x2) {
		     /*
		      * obj1 to left of obj2
		      */
		        r1.x = x1 - OFFSET;
		        r1.width = (x2 - x1) + SPREAD;
		    } else {
		        /*
		         * obj1 to right of obj2
		         */
		        r1.x = x2 - OFFSET;
		        r1.width = (x1 - x2) + SPREAD;
		    }
	    	    setRectList(plnary[i].rlist, 1, &r1, RL_PRIMARY);
		} else {
		    /*
		     * rectangles for two lines
  		     */
		    r1.width = r2.height = r3.width = SPREAD;
		    if ((x1 < x2) && (y1 < y2)) {
			/*
		   	 * obj1 to left and above obj2
			 */
	   	        r1.x = x1 - OFFSET;
			r1.y = y1 - OFFSET;
			r1.height = (y2 - y1) + SPREAD;
	    	        r2.x = x1 - OFFSET;
			r2.y = y2 - OFFSET;
	    	        r2.width = (x2 - x1) + SPREAD;
		    } else if ((x1 > x2) && (y1 < y2)) {
			/*
		   	 * obj1 to right and above obj2
			 */
			r1.x = x2 - OFFSET;
			r1.y = y1 - OFFSET;
			r1.height = (y2 - y1) + SPREAD;
			r2.x = x2 - OFFSET;
			r2.y = y1 - OFFSET;
			r2.width = (x1 - x2) + SPREAD;
		    } else if ((x1 > x2) && (y1 > y2)) {
			/*
		   	 * obj1 to right and below obj2
			 */
			r1.x = x2 - OFFSET;
			r1.y = y2 - OFFSET;
			r1.height = (y1 - y2) + SPREAD;
			r2.x = x2 - OFFSET;
			r2.y = y1 - OFFSET;
			r2.width = (x1 - x2) + SPREAD;
		    } else if ((x1 < x2) && (y1 > y2)) {
			/*
		   	 * obj1 to left and below obj2
			 */
			r1.x = x1 - OFFSET;
			r1.y = y2 - OFFSET;
			r1.height = (y1 - y2) + SPREAD;
			r2.x = x1 - OFFSET;
			r2.y = y2 - OFFSET;
			r2.width = (x2 - x1) + SPREAD;
		    }
	    	    setRectList(plnary[i].rlist, 2, &r1, RL_PRIMARY, &r2, 
			RL_PRIMARY);
		}
	    } else {
		/* didn't find object 2 so set rlist to NULL */
	        setRectList(plnary[i].rlist, 0);
	        return;
	    }
	} else {
	    /* didn't find object 1 so set rlist to NULL */
	    setRectList(plnary[i].rlist, 0);
	    return;
	}
    } else {
	/*  no precedence line or no object so set to NULL */
	setRectList(plnary[i].rlist, 0);
	return;
    }
}

/***********************************************************************
 *
 * FUNCTION:
 *      begin_pline()
 *
 * INPUTS:
 *      w               (Widget)
 *      co_p            (int)
 *      x, y            (int)
 *
 * OUTPUTS:
 *
 * RETURNS:
 *
 * EXTERNALLY READ:
 *
 * EXTERNALLY MODIFIED:
 *
 * DESCRIPTION:
 *      called when the left mouse button is pressed on a dated object
 */

void 
begin_pline(Widget w, int co_p, int x, int y)
{
    co = co_p;
    /*
     * keep track of start and last location of cursor
     */
    x_start = x;
    y_start = y;
    x_last = x;
    y_last = y;
    XDrawLine(dw.display, dw.win, hilite_gc, x_start, y_start, 
	x_last, y_last);
    XtAddEventHandler(w, Button1MotionMask, FALSE, 
	(XtEventHandler)draw_pline, NULL);
}

/***********************************************************************
 *
 * FUNCTION:
 *      finish_pline()
 *
 * INPUTS:
 *      w       	(Widget)
 *	obj1, obj2	(int)
 *
 * OUTPUTS:
 *
 * RETURNS:
 *
 * EXTERNALLY READ:
 *
 * EXTERNALLY MODIFIED:
 *
 * DESCRIPTION:
 *      finishes the pline when the mouse button is released
 */

void 
finish_pline(Widget w, int co, int obj1, int obj2)
{
    int exist = 0;		/* error if line already exists */
    int i;			/* temp loop index */

    XtRemoveEventHandler(w, Button1MotionMask, FALSE, 
	(XtEventHandler)draw_pline, NULL);
    /* 
     * redraw the last precedence line drawn
     */
    display_lines();
    if ((check_object(obj1) == 1) && (check_object(obj2) == 1)) {
        /* 
         * check to see if pline already exists 
         */
	for (i = 0; i < npln; i++) {
            /* check to see if pline already exists */
    	    if (((plnary[i].obj1 == obj1) || (plnary[i].obj1 == obj2)) &&
	        ((plnary[i].obj2 == obj1) || (plnary[i].obj2 == obj2))) {
	        Warning("This pline already exists");
	        /* it exists so dont add pline */
	        exist = 1;
	        break;
	    }
	    /* 
	     * check to see that both objects are different 
	     */
	    if (obj1 == obj2) {
	        Message("Position: X = %3d, Y = %3d", x_start, y_start);
	        exist = 1;
	        break;
	    }
	}
	/* 
	 * set objects to pline and dsp_pline 
	 */
	if (!exist) {
	    Message("Adding pline");
	    add_pline(co, obj1, obj2);
	    plnary[co].obj1 = obj1;
	    plnary[co].obj2 = obj2;
	    if (objary[obj1].precptr != NULL) { 
	        append_dynarray(objary[obj1].precptr, co);
	    } else {
	        objary[obj1].precptr = new_dynarray();
	        append_dynarray(objary[obj1].precptr, co);
	    }
	    if (objary[obj2].precptr != NULL) {
	        append_dynarray(objary[obj2].precptr, co);
	    } else {
	        objary[obj2].precptr = new_dynarray();
	        append_dynarray(objary[obj2].precptr, co);
	    }
	    loc_pline(co, OBJECT);
	    dsp_pline(co);
	    modified = TRUE;
            issue_date();
    	}
	exposeRectList(0, plnary[co].rlist);
    } else {
	Warning("Object cannot have precedence lines");
    }
}

/***********************************************************************
 *
 * FUNCTION:
 *      get_object_coord()
 *
 * INPUTS:
 *	obj		(int) - object index
 *
 * OUTPUTS:
 *
 * RETURNS:
 *	x, y		(int) - objects coordinates
 *
 * EXTERNALLY READ:
 *
 * EXTERNALLY MODIFIED:
 *
 * DESCRIPTION:
 *      finds the coordinates of the object where the pline will attach
 */

int 
get_object_coord(int obj, int *x, int *y)
{
    int objindex;			/* index of current object */
    XRectangle *(*r)[];			/* rectangle for y coord */
    int ln_pos;				/* line position */
    int line;				/* line number of object */

    objindex = obj;
    switch (objary[objindex].type) {
    case OBJ_EVT:
	/*
	 * precedence line attaches to symbol
	 */
	if ((objary[objindex].z.evtptr->edate >= objary[0].z.chtptr->start_date)
	    && (objary[objindex].z.evtptr->edate <
	    objary[0].z.chtptr->end_date)) {
	      *x = utc_to_x(objary[objindex].z.evtptr->edate + UTC_ONE_DAY/2);
	} else if (objary[objindex].z.evtptr->edate == 
	    objary[0].z.chtptr->end_date) {
	    *x = x_left_margin;
	} else {
	    return -1;
	}
	line = objary[objindex].z.evtptr->line;
	if ((line >= page_begin) && (line <= page_end)) {
            ln_pos = hln_objary[objary[objindex].z.evtptr->line];
            r = getMoveRect(Hobjary[ln_pos].rlist);
            *y = (*r)[0]->y + y_gap/2;
	    return 0;
	} else {
	    return -1;
	}
        break;
    case OBJ_ACT:
	/*
	 * precedence line attaches to symbol of end date
	 */
	if ((objary[objindex].z.actptr->strtdate >= 
	    objary[0].z.chtptr->start_date) && 
	    (objary[objindex].z.actptr->strtdate < 
	    objary[0].z.chtptr->end_date)) {
	    *x = utc_to_x(objary[objindex].z.actptr->strtdate + UTC_ONE_DAY/2);
	} else if (objary[objindex].z.actptr->strtdate ==
	    objary[0].z.chtptr->end_date) {
	    *x = x_right_margin;
	} else {
	    return -1;
	}
	line = objary[objindex].z.actptr->line;
	if ((line >= page_begin) && (line <= page_end)) {
            ln_pos = hln_objary[objary[objindex].z.actptr->line];
            r = getMoveRect(Hobjary[ln_pos].rlist);
            *y = (*r)[0]->y + y_gap/2;
	    return 0;
	} else {
	    return -1;
	}
        break;
    case OBJ_SACT:
	/*
	 * precedence line attaches to symbol of end date
	 */
	if ((objary[objindex].z.sactptr->strtdate >= 
	    objary[0].z.chtptr->start_date) && 
	    (objary[objindex].z.sactptr->strtdate <
	    objary[0].z.chtptr->end_date)) {
            *x = utc_to_x(objary[objindex].z.sactptr->strtdate + UTC_ONE_DAY/2);
	} else if (objary[objindex].z.sactptr->strtdate == 
	    objary[0].z.chtptr->end_date) {
	    *x = x_right_margin;
	} else {
	    return -1;
	}
	line = objary[objindex].z.sactptr->line;
	if ((line >= page_begin) && (line <= page_end)) {
            ln_pos = hln_objary[objary[objindex].z.sactptr->line];
            r = getMoveRect(Hobjary[ln_pos].rlist);
            *y = (*r)[0]->y + y_gap/2;
	    return 0;
	} else {
	    return -1;
	}
        break;
    case OBJ_SEQ:
	/*
	 * precedence line attaches to symbol of end date
	 */
	if ((objary[objindex].z.seqptr->strtdate >= 
	    objary[0].z.chtptr->start_date) && 
	    (objary[objindex].z.seqptr->strtdate <
	    objary[0].z.chtptr->end_date)) {
            *x = utc_to_x(objary[objindex].z.seqptr->strtdate + UTC_ONE_DAY); 
	} else if (objary[objindex].z.seqptr->strtdate == 
	    objary[0].z.chtptr->end_date) {
	    *x = x_right_margin;
	} else {
	    return -1;
	}
	line = objary[objindex].z.seqptr->line;
	if ((line >= page_begin) && (line <= page_end)) {
            ln_pos = hln_objary[objary[objindex].z.seqptr->line];
            r = getMoveRect(Hobjary[ln_pos].rlist);
            *y = (*r)[0]->y + y_gap/2;
	    return 0;
	} else {
	    return -1;
	}
        break;
    case OBJ_SLP:
	/*
	 * precedence line attaches to symbol of end date
	 */
	if ((objary[objindex].z.slpptr->strtdate >= 
	    objary[0].z.chtptr->start_date) && 
	    (objary[objindex].z.slpptr->strtdate <
	    objary[0].z.chtptr->end_date)) {
            *x = utc_to_x(objary[objindex].z.slpptr->strtdate + UTC_ONE_DAY/2);
	} else if (objary[objindex].z.slpptr->strtdate == 
	    objary[0].z.chtptr->end_date) {
	    *x = x_right_margin;
	} else {
	    return -1;
	}
	line = objary[objindex].z.slpptr->line;
	if ((line >= page_begin) && (line <= page_end)) {
            ln_pos = hln_objary[objary[objindex].z.slpptr->line];
            r = getMoveRect(Hobjary[ln_pos].rlist);
            *y = (*r)[0]->y + y_gap/2;
	    return 0;
	} else {
	    return -1;
	}
        break;
    default:
	return 0;
        break;
    }
}

/***********************************************************************
 *
 * FUNCTION:
 *      draw_pline()
 *
 * INPUTS:
 *      w               (Widget)
 *      client_data     (XtPointer)
 *      event           (XEvent)
 *
 * OUTPUTS:
 *
 * RETURNS:
 *
 * EXTERNALLY READ:
 *
 * EXTERNALLY MODIFIED:
 *
 * DESCRIPTION:
 *      draws the pline while the left mouse button is depressed
 */

static void 
draw_pline(Widget w, XtPointer client_data, XEvent *event)
{
    /*
     * redraw last precedence line
     */
    display_lines();

    /*
     * update to new cursor location and draw precedence line
     */
    x_last = event->xmotion.x;
    y_last = event->xmotion.y;
    display_lines();
}

/***********************************************************************
 *
 * FUNCTION:
 *      display_lines()
 *
 * INPUTS:
 *	none
 *
 * OUTPUTS:
 *	none
 *
 * RETURNS:
 *	none
 *
 * EXTERNALLY READ:
 *	none
 *
 * EXTERNALLY MODIFIED:
 *	none
 *
 * DESCRIPTION:
 *      draws the pline while the left mouse button is depressed
 *	depending on the X and Y coordinates
 */

static void 
display_lines(void)
{
    if (x_start < x_last) {
	XDrawLine(dw.display, dw.win, hilite_gc, x_start, y_start, 
	    x_start, y_last);
	XDrawLine(dw.display, dw.win, hilite_gc, x_start, y_last, x_last,
	    y_last);
    } else if (x_start > x_last) {
	XDrawLine(dw.display, dw.win, hilite_gc, x_start, y_start, 
	    x_last, y_start);
	XDrawLine(dw.display, dw.win, hilite_gc, x_last, y_start, x_last,
	    y_last);
    }
}

/***********************************************************************
 *
 * FUNCTION:
 *      check_object()
 *
 * INPUTS:
 * 	obj	(int)
 *
 * OUTPUTS:
 *
 * RETURNS:
 *
 * EXTERNALLY READ:
 *
 * EXTERNALLY MODIFIED:
 *
 * DESCRIPTION:
 *      checks to make sure that the loaded object numbers are dated
 *	object types
 */

static int 
check_object(int obj)
{
    int type = 0;

    switch (objary[obj].type) {
    case OBJ_ACT:
    case OBJ_EVT:
    case OBJ_SACT:
    case OBJ_SEQ:
    case OBJ_SLP:
	type = 1;
 	break;
    default:
	type = 0;
    }
    return type;
}
