 /*
  * Khoros: $Id: stack.c,v 1.1 1991/05/10 15:58:30 khoros Exp $
  */

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

 /*
  * $Log: stack.c,v $
 * Revision 1.1  1991/05/10  15:58:30  khoros
 * Initial revision
 *
  */ 

/*
 *----------------------------------------------------------------------
 *
 * Copyright 1990, University of New Mexico.  All rights reserved.
 * 
 * Permission to copy and modify this software and its documen-
 * tation only for internal use in your organization is hereby
 * granted, provided that this notice is retained thereon and
 * on all copies.  UNM makes no representations as too the sui-
 * tability and operability 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 OTHER DAMAGES WHAT-
 * SOEVER 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 PER-
 * FORMANCE OF THIS SOFTWARE.
 * 
 * No other rights, including for example, the right to redis-
 * tribute this software and its documentation or the right to
 * prepare derivative works, are granted unless specifically
 * provided in a separate license agreement.
 *----------------------------------------------------------------------
 */

#include "unmcopyright.h"	 /* Copyright 1990 by UNM */
#include "editimage.h"

/* >>>>>>>>>>>>>>>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
   >>>>                                                       <<<<
   >>>>         	Editimage Stack Utilities	      <<<<
   >>>>                                                       <<<<
   >>>>			push_cstack()			      <<<<
   >>>>			pop_cstack()			      <<<<
   >>>>			destroy_cstack()		      <<<<
   >>>>			push_rstack()			      <<<<
   >>>>			pop_rstack()			      <<<<
   >>>>			destroy_rstack()		      <<<<
   >>>>                                                       <<<<
   >>>>>>>>>>>>>>>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< */



static RoiStack   *roistack   = NULL;
static ColorStack *colorstack = NULL;

/************************************************************
*
*  Module Name: push_cstack
*
*      Purpose: the purpose of this routine is to save the
*		values of current color array defined between
*		index and index+num onto the stack.  The index1
*		and index2 are global variables that are also pushed
*		onto the stack.  These variables are used by the
*		display routines to represent what part of the X
*		color array that is being modified.  The routine can
*		then pop_cstack() be used to restore the X color array
*		to the previous state, and set these globals .
*
*        Input: None
*
*       Output: None
*
*   Written By: Mark Young
*
*************************************************************/


push_cstack(xcolors, index1, index2)

XColor *xcolors;
int    index1, index2;
{
	int	   num, index;
	unsigned   int size;
	ColorStack *current;


	current = (ColorStack *) XtMalloc(sizeof(ColorStack));
	current->index1 = index1;
	current->index2 = index2;

	num    = abs(index1 - index2) +1;
	index  = MIN(index1, index2);

	size = sizeof(XColor) * num;
	current->xcolors = (XColor *) XtMalloc(size);
	bcopy(&xcolors[index], current->xcolors, size);
	current->prev  = colorstack;
	colorstack = current;
}



/************************************************************
*
*  Module Name: pop_cstack
*
*      Purpose: the purpose of this routine is to restore the
*		values of current color array defined between
*		index1 and index2 from the stack.  The routine
*		push_cstack() was used to originally store the
*		values onto the color stack, and the user has
*		requested an "undo" of the last coloring operation.
*
*        Input: None
*
*       Output: xcolors  - the xcolor array to store the pop'ed values
*		index1   - the first index into the color array
*		index2   - the second index into the color array
*
*   Written By: Mark Young
*
*************************************************************/


int pop_cstack(xcolors, index1, index2)

XColor *xcolors;
int    *index1, *index2;
{
	int	   num, index;
	unsigned   int size;
	ColorStack *current;

	if (colorstack == NULL)
	{
	   xvf_error_wait("Error! Color stack is currently empty.  You must \
first change the image's colormap before trying to 'undo' those changes.",
			  "pop_cstack", NULL);
	   return(False);
	}

	current	= colorstack;
	*index1 = current->index1;
	*index2 = current->index2;
	index  = MIN(current->index1, current->index2);
	num    = abs(current->index2 - current->index1) +1;

	size = sizeof(XColor) * num;
	bcopy(current->xcolors, &xcolors[index], size);
	if (current->prev != NULL)
	{
	   colorstack = current->prev;
	   XtFree((char *) current->xcolors);
	   XtFree((char *) current);
	}
	return(True);
}



/************************************************************
*
*  Module Name: destroy_cstack
*
*      Purpose: the purpose of this routine is to destroy the
*		entire color stack and free all associated memory.
*
*        Input: None
*
*       Output: None
*
*   Written By: Mark Young
*
*************************************************************/


destroy_cstack()
{
	ColorStack *current;


	current = colorstack;
	while (current != NULL)
	{
	   colorstack = current->prev;
	   XtFree((char *) current->xcolors);
	   XtFree((char *) current);
	   current = colorstack;
	}
	colorstack = NULL;
}



/************************************************************
*
*  Module Name: push_rstack
*
*      Purpose: the purpose of this routine is to save the
*		region of interest 
*		index and index+num onto the stack.  The index1
*		and index2 are global variables that are also pushed
*		onto the stack.  These variables are used by the
*		display routines to represent what part of the X
*		color array that is being modified.  The routine can
*		then pop_cstack() be used to restore the X color array
*		to the previous state, and set these globals .
*
*        Input: region - image to be stored on the stack
*
*       Output: None
*
*   Written By: Mark Young & Danielle Argiro
*
*************************************************************/


push_rstack(region)

struct xvimage *region;
{
	RoiStack *current;

	current = (RoiStack *) XtMalloc(sizeof(RoiStack));
	current->region = region;
	current->mask   = NULL;
	current->prev   = roistack;
	roistack        = current;
}



/************************************************************
*
*  Module Name: pop_cstack
*
*      Purpose: the purpose of this routine is to restore the
*		values of current color array defined between
*		index1 and index2 from the stack.  The routine
*		push_cstack() was used to originally store the
*		values onto the color stack, and the user has
*		requested an "undo" of the last coloring operation.
*
*        Input: image - the image in which we will insert the
*			region into.
*
*       Output: None
*
*   Written By: Mark Young & Danielle Argiro
*
*************************************************************/


pop_rstack(image)

struct xvimage *image;
{
	RoiStack *current;
	struct   xvimage *region;

	if (roistack == NULL)
	{
	   xvf_error_wait("Error! ROI stack is currently empty.  You must \
use the region of interest 'command' or 'insert' functions before attempting \
to 'undo' those changes.", "pop_rstack", NULL);
	   return;
	}

	current	= roistack;
	region = current->region;

	if (!lvinsert(image, region, region->startx, region->starty, 0.0, 0.0))
	{
	   xvf_error_wait("Error!  lvinsert failed to re-insert the original \
extracted region back into the display image.  Therefore this region will not \
be inserted.", "pop_rstack", NULL);
	}
	else
	   update_image(NULL);

	roistack = current->prev;
	freeimage(region);
	XtFree((char *) current);
}



/************************************************************
*
*  Module Name: destroy_rstack
*
*      Purpose: the purpose of this routine is to destroy the
*		entire roi stack and free all associated memory.
*
*        Input: None
*
*       Output: None
*
*   Written By: Mark Young
*
*************************************************************/


destroy_rstack()
{
	RoiStack *current;


	current = roistack;
	while (current != NULL)
	{
	   roistack = current->prev;
	   freeimage(current->region);
	   XtFree((char *) current);
	   current = roistack;
	}
	roistack = NULL;
}
