 /*
  * Khoros: $Id: view.c,v 1.1 1991/05/10 15:59:17 khoros Exp $
  */

#if !defined(lint) && !defined(SABER)
static char rcsid[] = "Khoros: $Id: view.c,v 1.1 1991/05/10 15:59:17 khoros Exp $";
#endif

 /*
  * $Log: view.c,v $
 * Revision 1.1  1991/05/10  15:59:17  khoros
 * Initial revision
 *
  */ 

/*
 *----------------------------------------------------------------------
 *
 *            Copyright 1990 University of New Mexico
 *
 *  Permission to use, copy, modify, distribute, and sell this
 *  software and its documentation for any purpose is hereby
 *  granted without fee, provided that the above copyright
 *  notice appear in all copies and that both that copyright
 *  notice and this permission notice appear in supporting docu-
 *  mentation, and that the name of UNM not be used in advertis-
 *  ing or publicity pertaining to distribution of the software
 *  without specific, written prior permission.  UNM makes no
 *  representations about the suitability of this software for
 *  any purpose.  It is provided "as is" without express or
 *  implied warranty.
 *
 *  UNM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 *  INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FIT-
 *  NESS, IN NO EVENT SHALL UNM BE LIABLE FOR ANY SPECIAL,
 *  INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
 *  RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
 *  ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
 *  OF THIS SOFTWARE.
 *
 *----------------------------------------------------------------------
 */
#include "unmcopyright.h"
#include "warpimage.h"
#include <X11/Xaw/Box.h>

/* >>>>>>>>>>>>>>>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
   >>>>                                                       <<<<
   >>>>			View Routines  		              <<<<
   >>>>                                                       <<<<
   >>>>			create_view_workspace()		      <<<<
   >>>>			add_tiepoint_label()		      <<<<
   >>>>			close_view_cb()			      <<<<
   >>>>			return_live_tiepts()		      <<<<
   >>>>			get_new_tiept_coord()		      <<<<
   >>>>                                                       <<<<
   >>>>>>>>>>>>>>>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<  */

/************************************************************
*
*  MODULE NAME: create_view_workspace()
*
*      PURPOSE: create_view_workspace is the routine that will initially
*		create the View workspace, on which the tiepoints and
*		their values will be listed.
*
*        INPUT: title - the title of the workspace
*
*       OUTPUT: none
*
*   WRITTEN BY: Danielle Argiro & Tom Sauer
*
**************************************************************/

static wksp_count = 0;

Widget create_view_workspace(title)
char *title;
{
   Widget toplevel;     /* toplevel widget for workspace */
   Widget back;         /* backplane for scroll bars */
   Widget label;        /* label describing type of message */
   Widget col_header;   /* column header for tiepoints' id, src, dest*/
   Widget close;        /* button to get rid of workspace */
   Widget viewport;     /* viewport with scrollbars */
   int i;
   Arg arg[MaxArgs];
   char *top_name, *cap_top_name, *id, *src_contents, *dest_contents;
   char name[MaxLength], temp[MaxLength];
   void close_view_cb();
   TiePointNode *tiept;
   Widget add_tiepoint_label();

   
   /*
    * create identifying widget name
    */
   sprintf(name,"View_Tiepoints_%d",wksp_count);
   wksp_count++;
   top_name = xvf_strcpy(name);
   cap_top_name = xvf_cap_first_letter(top_name);
   
   /*
    * create the form's toplevel widget
    */
   i = 0;
   XtSetArg(arg[i], XtNscreen, DefaultScreenOfDisplay(display));  i++;
   XtSetArg(arg[i], XtNargc, ac);                                 i++;
   XtSetArg(arg[i], XtNargv, av);                                 i++;
   toplevel = XtAppCreateShell(top_name,cap_top_name,
                               applicationShellWidgetClass, 
			       display, arg, i);

   /*
    * create the backplane widget
    */
   i = 0;
   XtSetArg(arg[i],XtNmappedWhenManaged,True);          i++;
   XtSetArg(arg[i],XtNborderWidth,1);                   i++;
   back = XtCreateManagedWidget("wksp_back",formWidgetClass,
                                      toplevel,arg,i);

   /*
    * create the label widget
    */
    i = 0;
    XtSetArg(arg[i],XtNborderWidth,0);   		  	i++;
    XtSetArg(arg[i],XtNhorizDistance,2*xvf_font_width);  	i++;
    XtSetArg(arg[i],XtNlabel,xvf_strcpy(title));    		i++;
    if (xvf_font != NULL)
    {
        XtSetArg(arg[i],XtNfont,xvf_font);                      i++;
    }
    label = XtCreateManagedWidget("label",labelWidgetClass, back,arg,i);

   /*
    * create the column header widget
    */
    i = 0;
    XtSetArg(arg[i],XtNborderWidth,0);   		  	i++;
    XtSetArg(arg[i],XtNhorizDistance,2*xvf_font_width);  	i++;
    XtSetArg(arg[i],XtNfromVert,label);  		i++;
    XtSetArg(arg[i],XtNlabel,"No.     Source    Destination"); 	i++;
    if (xvf_font != NULL)
    {
        XtSetArg(arg[i],XtNfont,xvf_font);                      i++;
    }
    col_header = XtCreateManagedWidget("col_header",
					labelWidgetClass, back,arg,i);

   /*
    * create close button
    */
   i = 0;
   XtSetArg(arg[i],XtNfromHoriz,label);      		  i++;
   XtSetArg(arg[i],XtNhorizDistance,50);   		  i++;
   XtSetArg(arg[i],XtNfromVert,NULL);                     i++;
   XtSetArg(arg[i],XtNlabel,"Close");                     i++;
   if (xvf_font != NULL)
   {
      XtSetArg(arg[i],XtNfont,xvf_font);                  i++;
   }
   close = XtCreateManagedWidget("close", commandWidgetClass,back,arg,i);
   XtAddCallback(close,XtNcallback,close_view_cb,toplevel);

   /*
    * create the viewport widget which will
    * provide backplane with scroll bar
    */

   i = 0;
   XtSetArg(arg[i], XtNallowVert, True);                        i++;
   XtSetArg(arg[i], XtNfromVert, col_header);  		        i++;
   XtSetArg(arg[i], XtNforceBars, True);  		        i++;
   XtSetArg(arg[i], XtNwidth, xvf_font_width * 30); i++;
   XtSetArg(arg[i], XtNheight, xvf_font_height * 20); i++;
   viewport = XtCreateManagedWidget("view_back",viewportWidgetClass,
                                     back,arg,i);
   i = 0;
   XtSetArg(arg[i],XtNmappedWhenManaged,True);  i++;
   XtSetArg(arg[i],XtNborderWidth,1);           i++;
   XtSetArg(arg[i],XtNdefaultDistance,4);       i++;
   XtSetArg(arg[i], XtNwidth, xvf_font_width * 30); i++;
   XtSetArg(arg[i], XtNheight, xvf_font_height * 20); i++;
   viewback = XtCreateManagedWidget("view_back",boxWidgetClass,
                                      viewport,arg,i); /* note viewback global*/

   /*
    *  add in the tiepoint labels - one for each node in the tiepoints list
    */
   tiept = tiepoints;

   tiept_label_offset = NULL;
   while (tiept != NULL)
   {
      sprintf(temp, "%d", tiept->id);
      id = xvf_strcpy(temp);
      sprintf(temp, "%d,%d", tiept->src_x, tiept->src_y);
      src_contents = xvf_strcpy(temp);
      sprintf(temp, "%d,%d", tiept->dest_x, tiept->dest_y);
      dest_contents = xvf_strcpy(temp);
      tiept->offset = tiept_label_offset;
      tiept_label_offset =  add_tiepoint_label(viewback, id, src_contents, 
				   dest_contents, tiept_label_offset, 
				   &tiept->src, &tiept->dest);
      tiept->tiept_label = tiept_label_offset;
      tiept = tiept->next;
   }

   /*
    *  map the workspace widget to the screen
    */
   xvf_place_widget(toplevel, NULL);
   return(toplevel);

}



/************************************************************
*
*  MODULE NAME: add_tiepoint_label()
*
*      PURPOSE: add_tiepoint_label is the routine that will add
*		a blank tiepoint label to the View workspace. It
*		will have its (x,y) values filled in when the user adds 
*		a tiepoint marker to the source image, or when the 
*		user fills in its (x,y) values by hand.
*
*        INPUT: parent -
*		title - 
*		src_contents - the source tiepoint coordinates
*		dest_contents - the destination tiepoint coordinates
*		vert_offset - the widget offset from the last widget
*		src_wid - 
*		dest_wid -
*
*       OUTPUT: the green source tiepoint appears on the source image
*
*   WRITTEN BY: Danielle Argiro & Tom Sauer
*
***********************************************************/

Widget add_tiepoint_label(parent, title, src_contents, dest_contents,
			  vert_offset, src_wid, dest_wid)
Widget parent;
char   *title;
char   *src_contents;
char   *dest_contents;
Widget vert_offset;
Widget *src_wid, *dest_wid;
{

    int i;
    Arg arg[MaxArgs];
    Widget back, label, pixmap;
    Widget xvf_create_cr_pixmap_widget();

    i = 0;
    XtSetArg(arg[i], XtNfromVert, vert_offset);                     	i++;
    XtSetArg(arg[i], XtNmappedWhenManaged,True);                        i++;
    XtSetArg(arg[i], XtNborderWidth,0);                   		i++;
    XtSetArg(arg[i], XtNwidth,(Dimension) 9*xvf_font_width);           	i++;
    XtSetArg(arg[i], XtNheight,(Dimension) xvf_font_height+5);         	i++;
    XtSetArg(arg[i], XtNresizable,True);       				i++;
    back = XtCreateManagedWidget("back", formWidgetClass,parent,arg,i);


    i = 0;
    XtSetArg(arg[i],XtNlabel,  xvf_strcpy(title));              i++;
    XtSetArg(arg[i],XtNborderWidth,0);                   	i++;
    if (xvf_font != NULL)
    {
          XtSetArg(arg[i],XtNfont,xvf_font);                    i++;
    }
    label =  XtCreateManagedWidget("label", labelWidgetClass,
                                   back,arg,i);

    i = 0;
    XtSetArg(arg[i],XtNeditType,XawtextEdit);               		i++;
    XtSetArg(arg[i],XtNtype,XawAsciiString);                		i++;
    XtSetArg(arg[i],XtNstring,src_contents);		     		i++;
    XtSetArg(arg[i],XtNinsertPosition, xvf_strlen(src_contents));      	i++;
    XtSetArg(arg[i],XtNwidth,(Dimension) 9*xvf_font_width);            	i++;
    XtSetArg(arg[i],XtNheight,(Dimension) xvf_font_height+5);          	i++;
    XtSetArg(arg[i],XtNresizable,False);       			   	i++;
    XtSetArg(arg[i],XtNfromHoriz,label);      				i++;
    if (xvf_font != NULL)
    {
         XtSetArg(arg[i],XtNfont,xvf_font);         	               	i++;
    }
    *src_wid = XtCreateManagedWidget("src_wid", asciiTextWidgetClass,
                                 back, arg, i);
    XtOverrideTranslations(*src_wid, live_tiepts_trans);


   
    if (tiepoint_mode == SourceAndDest)
    {
        i = 0;
        XtSetArg(arg[i],XtNeditType,XawtextEdit);              		i++;
        XtSetArg(arg[i],XtNtype,XawAsciiString);               		i++;
        XtSetArg(arg[i],XtNstring,dest_contents);	     		i++;
        XtSetArg(arg[i],XtNinsertPosition, xvf_strlen(dest_contents));  i++;
        XtSetArg(arg[i],XtNwidth,(Dimension) 9*xvf_font_width);         i++;
        XtSetArg(arg[i],XtNheight,(Dimension) xvf_font_height+5);   	i++; 
        XtSetArg(arg[i],XtNresizable,False);       			i++;
        XtSetArg(arg[i],XtNfromHoriz,*src_wid);     			i++;
        if (xvf_font != NULL)
        {
             XtSetArg(arg[i],XtNfont,xvf_font);         	        i++;
        }
        *dest_wid = XtCreateManagedWidget("dest_wid", asciiTextWidgetClass,
                                          back, arg, i);
        XtOverrideTranslations(*dest_wid, live_tiepts_trans);

        pixmap = xvf_create_cr_pixmap_widget(back, *dest_wid);
    }
    else
       pixmap = xvf_create_cr_pixmap_widget(back, *src_wid);

    return(back);
}

/************************************************************
*
*  MODULE NAME: close_view_cb()
*
*      PURPOSE: close_view_cb is the callback for the "Close"
*		button on the "View Tiepoints" widget.  It 
*		deletes the widget.
*
*        INPUT: 
*
*       OUTPUT: the green source tiepoint appears on the source image
*
*   WRITTEN BY: Danielle Argiro & Tom Sauer
*
***************************************************************/

void close_view_cb(widget, clientData, callData)
Widget widget;
caddr_t clientData, callData;
{
    Widget toplevel;
    TiePointNode *tiept;

    toplevel = (Widget) clientData;
    XtDestroyWidget(toplevel);
    view_toplevel = NULL;
    viewback = NULL;

    tiept = tiepoints;
    while (tiept != NULL)
    {
       tiept->offset = NULL;
       tiept = tiept->next;
    }
    tiept_label_offset = NULL;
}

/************************************************************
*
*  MODULE NAME: return_live_tiepts()
*
*      PURPOSE: return_live_tiepts is the XtActionProc 
*		that is initiated when the user enters a value
*		directly into the float value widget and hits <CR>.
*		It will update the position of the source or destination
*		tiepoint in the image.
*
*        INPUT: 
*
*       OUTPUT: the green source tiepoint moves to the new position
*
*   WRITTEN BY: Danielle Argiro 
*
***************************************************************/

void return_live_tiepts(widget, event, params, num_params)
Widget widget;
XEvent *event;
String *params;
Cardinal *num_params;
{
        TiePointNode *tiept;
	int new_x, new_y;
	char temp[MaxLength];
	
	/*
	 *  get the new tiept coordinate from the text widget
	 */
	if (!get_new_tiept_coord(widget, &new_x, &new_y)) return;

	/* 
	 *  see if we are to move the tiepoint 
	 *  from the src image or dest image 
	 */
	tiept = tiepoints;
	while ((widget != tiept->src) && (widget != tiept->dest))
	    tiept = tiept->next;


	/* 
	 * move the source tiept 
	 */
	if (widget == tiept->src)
	{
	    if (new_x > src_image->image->row_size || new_x < 0)
	    {
                   sprintf(temp,
                        "An invalid source X tiepoint position entered. Tiepoint X location is %d, valid range is 0 - %d",
                          new_x, src_image->image->row_size);
                   xvf_error_wait(temp, "return_live_tiepts", NULL);
	           return;
	    }
	    if (new_y > src_image->image->col_size || new_y < 0)
	    {
                   sprintf(temp,
                        "An invalid source Y tiepoint position entered. Tiepoint Y location is %d, valid range is 0 - %d",
                          new_y, src_image->image->col_size);
                   xvf_error_wait(temp, "return_live_tiepts", NULL);
	           return;
	    }
	    /* delete the old src tiept by restoring orig values. */
	    restore_pixel_values(src_image, tiept->src_old_pixel, 
				 tiept->src_x, tiept->src_y);

	    /* save the pixel values in the position of the new tiept */
	    save_pixel_values(src_image, tiept->src_old_pixel, 
				new_x, new_y);

	    /* put the tiept in new position */
	     display_tiept(src_image->ximage, src_image->pixmap, new_x, new_y, green);

	    /* refresh the display */
            refresh_workspace(src_image->raster, src_image->ximage, src_zoom);

	    tiept->src_x = new_x;
	    tiept->src_y = new_y;
	}

	/* 
	 * move the destination tiept 
	 */

	else if (widget == tiept->dest)
	{
	    if (new_x > dest_image->image->row_size || new_x < 0)
	    {
                   sprintf(temp,
                        "An invalid target X tiepoint position entered. Tiepoint X location is %d, valid range is 0 - %d",
                          new_x, dest_image->image->row_size);
                   xvf_error_wait(temp, "return_live_tiepts", NULL);
	           return;
	    }
	    if (new_y > dest_image->image->col_size || new_y < 0)
	    {
                   sprintf(temp,
                        "An invalid target Y tiepoint position entered. Tiepoint Y location is %d, valid range is 0 - %d",
                          new_y, dest_image->image->col_size);
                   xvf_error_wait(temp, "return_live_tiepts", NULL);
	           return;
	    }
	    /* delete the old src tiept by restoring orig values. */
	    restore_pixel_values(dest_image, tiept->dest_old_pixel, 
				 tiept->dest_x, tiept->dest_y);

	    /* save the pixel values in the position of the new tiept */
            save_pixel_values(dest_image, tiept->dest_old_pixel,
                              new_x, new_y);

            /* put the tiept in new position */
             display_tiept(dest_image->ximage, dest_image->pixmap, new_x, new_y, green);

	    /* refresh the display */
            refresh_workspace(dest_image->raster, dest_image->ximage, dest_zoom);
	    tiept->dest_x = new_x;
	    tiept->dest_y = new_y;

	}
	
}

/************************************************************
*
*  MODULE NAME: get_new_tiept_coord()
*
*      PURPOSE: get_new_tiept_coord takes a text widget from the 
*		View Tiepoints display (either the src or dest widget)
*		and gets the (x,y) coordinate out of it.
*
*        INPUT: widget - the source or destination text widget
*
*       OUTPUT: x - the new x coordinate of the tiept
*		y - the new y coordinate of the tiept
*
*   WRITTEN BY: Danielle Argiro
*
************************************************************/

int get_new_tiept_coord(widget, x, y)
Widget widget;
int *x, *y;
{
	int i, status;
	Arg arg[MaxArgs];
	char *string_return, leftover1[50], leftover2[50];
	char dummy;
	char temp[MaxLength];

	bzero(leftover1, 50);
	bzero(leftover2, 50);

	/*
	 *  get the string representation of the 
	 *  specified (x, y) position out of the widget
	 */
	i = 0;
        XtSetArg(arg[i], XtNstring, &string_return);    i++;
        XtGetValues(widget, arg, i);

	status = sscanf(string_return,"%d%s",x, leftover1);
	if (status != 2)
	{
            sprintf(temp,
                  "The incorrect syntax of the tiepoint coordinate was entered. Use X-coord, Y-coord.");
                   xvf_error_wait(temp, "get_new_tiept_coord", NULL);
	    return(False);
	}

	dummy = ' ';
	while ( (dummy == ' ')  || 
		(dummy == '\t') || 
		(dummy == ',') )
	{
	        sscanf(leftover1, "%c%s", &dummy, leftover2);
		sprintf(leftover1,"%s", leftover2);
	}
	sprintf(leftover1, "%c%s", dummy, leftover2);

	status = sscanf(leftover1,"%d%s", y, leftover2);
	if (status != 1)
	{
            sprintf(temp,
                  "The incorrect syntax of the tiepoint coordinate was entered. Use X-coord, Y-coord.");
                   xvf_error_wait(temp, "get_new_tiept_coord", NULL);
	    return(False);
	}
	return(True);
}
