/****************************************************************
 * Filename  :	Curve.c
 * Functions :	
 *		Curve_New
 *		Curve_Delete
 *		Curve_Initialize
 *		Curve_Display
 *		Curve_DisplayAxes
 *		Curve_SetResources
 * Purpose   : 	Functions for the Curve class
 * Comment   : 	This class inherit from Item
 $Revision: 1.1 $
 ***************************************************************/

#include "dmvideo.h"			/* data manager definitions           */
#include "OVtypes.h"			/* video overlay type definitions     */
#include "dy4std.h"                     /* DY4 standard definitions           */
#include "video.h"                      /* DY4 video definitions              */
#include "mygraphics.h" 		/* graphics alignment definitions     */
#include "dy4driver.h" 			/* DY4 driver definitions             */
#include "Curve.h" 		    	/* curve definitions                  */


/*---------------------------------------------------------------
 | Function  :	Curve_New
 | Purpose   : 	Return a new curve structure
 | Inputs    :	none
 | Outputs   :	none
 | Side FX   :	none
 | comments  :
 | Author    :	sylvain.coudray MBARI-IFREMER/diti/dsi/ie
 ---------------------------------------------------------------*/
    OV_Curve *Curve_New(void)
{
    OV_Curve *p_curve;			/* a graphic curve */

    p_curve = (OV_Curve *) malloc ( sizeof(OV_Curve));

    return (p_curve);

} /* Curve_New */

/*---------------------------------------------------------------
 | Function  :	Curve_Delete
 | Purpose   : 	Free memory from structure passed in parameter
 | Inputs    :	none
 | Outputs   :	none
 | Side FX   :	none
 | comments  :
 | Author    :	sylvain.coudray MBARI-IFREMER/diti/dsi/ie
 | Modified  :  tarrant 8/7/96
 |                to free all malloced components of structure
 | Modified  :  tarrant 10/30/96
 |                added isUsed flag
 ---------------------------------------------------------------*/
    void
Curve_Delete(OV_Curve *p_curve)
{
    if (p_curve->isUsed)
    {
    	if (p_curve->line_width != NULL)
	    free(p_curve->line_width);

    	if (p_curve->line_style != NULL)
	    free(p_curve->line_style);
    }

    free(p_curve);

    return;

} /* Curve_Delete */


/*---------------------------------------------------------------
 | Function  :	Curve_Initialize
 | Purpose   : 	object initialization
 | Inputs    :	none
 | Outputs   :	none
 | Side FX   :	none
 | comments  :
 | Author    :	sylvain.coudray MBARI-IFREMER/diti/dsi/ie
 | Modified  :  tarrant 10/30/96
 |                added isUsed flag
 ---------------------------------------------------------------*/

	void
Curve_Initialize ( p_curve)
OV_Curve	*p_curve;
{

	/* ... Local Variables */
	/* ... Initializations */
	/* ... Begin */

/*debug
printf ( "Curve Initialize \n");
enddebug*/

	p_curve->isUsed = FALSE;
	p_curve->x_min  = 0.;
	p_curve->x_max  = 0.;
	p_curve->x_grad = 0.;
	p_curve->x_length = 1.;

	p_curve->y_min  = 0.;
	p_curve->y_max  = 0.;
	p_curve->y_grad = 0.;
	p_curve->y_length = 1.;

	p_curve->x_origin = 0.;
	p_curve->y_origin = 0.;
	p_curve->x_scale = 1.;
	p_curve->y_scale = 1.;

	p_curve->draw_axes = 1;

	p_curve->x_current = 0.;
	p_curve->y_current = 0.;

	/* ... End */

        return;

} /* Curve_Initialize */


/*---------------------------------------------------------------
 | Function  :	Curve_Display
 | Purpose   : 	Display the Curve vs time on the screen
 | Inputs    :	none
 | Outputs   :	none
 | Side FX   :	none
 | comments  :
 | Author    :	sylvain.coudray MBARI-IFREMER/diti/dsi/ie
 | Modified  :  tarrant 7/1/97 replaced globals with alignment structure
 ---------------------------------------------------------------*/
    void
Curve_Display(OV_alignment *alignment, OV_Item *p_item)
{
	uint32	kerr ;			/* error code */
	float   x_min, x_max;		/* X bounds (uu) */
	float   y_min, y_max;		/* Y bounds (uu) */
	float	xpnt, ypnt;		/* point coordinates (uu) */
	float	xpnt_old, ypnt_old; 	/* old point coordinates (uu) */

/*debug
printf ( "Curve Display \n");
enddebug*/

	x_min    = (float) p_item->p_curve->x_min;
	x_max    = (float) p_item->p_curve->x_max;
	y_min    = (float) p_item->p_curve->y_min;
	y_max    = (float) p_item->p_curve->y_max;

	/* .............................. */
	/* ... display axes only once ... */
	/* .............................. */
	
	if ( p_item->p_curve->draw_axes == 1)
	{
	    /* display both graduated axes */
	    Curve_DisplayAxes(alignment, p_item);

	    /* set current value to first point */
	    p_item->p_curve->x_current = 0. - x_min;
	    p_item->p_curve->y_current = 0. - y_min;
	}
	else 
	{

	/* ............................. */
	/* ... display the new value ... */
	/* ............................. */

	/* get coordinates of current point */
	xpnt_old = p_item->p_curve->x_current;
	ypnt_old = p_item->p_curve->y_current;

	/* calculate coordinates of next point */
	xpnt = xpnt_old + 1;
	sscanf(p_item->value, "%f", &ypnt);

	/* shift from minimum graduation */
	xpnt = xpnt - x_min;
	ypnt = ypnt - y_min;
/*debug
printf ( "xpnt, ypnt         = %f %f \n", xpnt, ypnt);
printf ( "xpnt_old, ypnt_old = %f %f \n", xpnt_old, ypnt_old);
enddebug*/

	/* clipping when out of graduations */
	if ( (xpnt > 2.) && (xpnt < (x_max - x_min)) && 
	     (ypnt > 0.) && (ypnt < (y_max - y_min)))
	{
     	   /* shift origin in millimeters */
	   My_shift_origin(alignment, p_item->p_curve->x_origin, 
	                   p_item->p_curve->y_origin);

	   /* change scale factors to be in user units */
	   My_set_scale(alignment, p_item->p_curve->x_scale, 
	                p_item->p_curve->y_scale);

	   /* draw a line from current point to next point*/
	   My_mov_point(alignment, xpnt_old, ypnt_old);
	   My_wri_line(alignment, xpnt, ypnt);

	   /* reset scale factors and origin */
	   My_reset_scale(alignment);
	   My_reset_origin(alignment);

	} /* endif*/

	} /* endelse */

	/* next point become current point */
	p_item->p_curve->x_current = xpnt;
	p_item->p_curve->y_current = ypnt;
	
	return;
}


/*---------------------------------------------------------------
 | Function  :	Curve_DisplayAxes
 | Purpose   : 	Display both X & Y axes
 | Inputs    :	none
 | Outputs   :	none
 | Side FX   :	none
 | comments  :
 | Author    :	sylvain.coudray MBARI-IFREMER/diti/dsi/ie
 | Modified  :  tarrant 7/1/97 replaced globals with alignment structure
 ---------------------------------------------------------------*/
    uint32
Curve_DisplayAxes(OV_alignment *alignment, OV_Item *p_item)
{
	uint32	kerr ;		/* error code */
	uint32	kaxe ;		/* axe type */
	uint32  nb_grad;	/* number of graduations */

	float   x_min, x_max;		/* X bounds (uu) */
	float   y_min, y_max;		/* Y bounds (uu) */
	float   x_grad,y_grad;		/* dist. betw. tic marks (uu) */
	float   x_length, y_length;	/* length of axis (mm) */
	float   xorg1, yorg1;		/* origin of axes (mm) */
	float   xscl1, yscl1;		/* scale factors (mm->uu) */
	float   xorg, yorg;		/* origin of axes (uu) */
	float	x_tic_size;		/* size of tic mark */
	float	y_tic_size;		/* size of tic mark */
	float	format;			/* graduation format "i.d" */

/*debug
printf ( "Curve Display Axes \n");
enddebug*/

	format	 = (float) p_item->p_context->value_format;
	x_min    = (float) p_item->p_curve->x_min;
	x_max    = (float) p_item->p_curve->x_max;
	x_grad   = (float) p_item->p_curve->x_grad;
	x_length = (float) p_item->p_curve->x_length;
	y_min    = (float) p_item->p_curve->y_min;
	y_max    = (float) p_item->p_curve->y_max;
	y_grad   = (float) p_item->p_curve->y_grad;
	y_length = (float) p_item->p_curve->y_length;
	x_tic_size = -2.;
	y_tic_size = -2.;

/*debug
printf (" x_min  = %f \n", x_min);
printf (" x_max  = %f \n", x_max);
printf (" x_grad  = %f \n", x_grad);
printf (" x_length  = %f \n", x_length);
printf (" y_min  = %f \n", y_min);
printf (" y_max  = %f \n", y_max);
printf (" y_grad  = %f \n", y_grad);
printf (" y_length  = %f \n", y_length);
enddebug*/

     	   /* shift origin in millimeters */
	   xorg1 = p_item->x;
	   yorg1 = p_item->y;
	   My_shift_origin(alignment, xorg1, yorg1);

	   /* change scale factors to be in user units */
	   xscl1 = x_length / (x_max - x_min);
	   yscl1 = y_length / (y_max - y_min);
	   My_set_scale(alignment, xscl1, yscl1);

	   /* origin of axes in user unit */
	   xorg = 0.;
	   yorg = 0.;

     	   /* display a graduated X axe */
	   kaxe = 0;
	   nb_grad = (int) ((x_max - x_min) / x_grad) + 1;
	   kerr = My_wri_grad_axis(alignment, kaxe, xorg, yorg, x_grad, nb_grad,
				   x_tic_size, x_min, format);

     	   /* display a graduated Y axe */
	   kaxe = 1;
	   nb_grad = (int) ((y_max - y_min) / y_grad) + 1;
	   kerr = My_wri_grad_axis(alignment, kaxe, xorg, yorg, y_grad, nb_grad,
				   y_tic_size, y_min, format);

	   /* reset scale factors and origin */
	   My_reset_scale(alignment);
	   My_reset_origin(alignment);

	   /* store origin and scale factors */
	   p_item->p_curve->x_origin = xorg1;
	   p_item->p_curve->y_origin = yorg1;
	   p_item->p_curve->x_scale = xscl1;
	   p_item->p_curve->y_scale = yscl1;

	   p_item->p_curve->draw_axes = 0;

	return(kerr);

} /* Curve_DisplayAxes */



/*---------------------------------------------------------------
 | Function  :	Curve_SetResources
 | Purpose   : 	Set specific resources for curves
 | Inputs    :	none
 | Outputs   :	none
 | Side FX   :	none
 | comments  :
 | Author    :	sylvain.coudray MBARI-IFREMER/diti/dsi/ie
 | Modified  :  tarrant 10/30/96
 |                added isUsed flag
 ---------------------------------------------------------------*/
    void
Curve_SetResources(OV_Curve *p_curve, OV_float x_min, OV_float x_max,
		   OV_float x_grad, OV_float x_length, OV_float y_min,
		   OV_float y_max, OV_float y_grad, OV_float y_length,
		   OV_width *line_width, OV_style *line_style)
{

	p_curve->isUsed = TRUE;

	p_curve->x_min  = x_min;
	p_curve->x_max  = x_max;
	p_curve->x_grad = x_grad;
	p_curve->x_length = x_length;

	p_curve->y_min  = y_min;
	p_curve->y_max  = y_max;
	p_curve->y_grad = y_grad;
	p_curve->y_length = y_length;

	p_curve->line_width = line_width;
	p_curve->line_style = line_style;

	/* ... End */

        return;

} /* Curve_SetResources */


/*---------------------------------------------------------------
 | Function  :	Curve_cccccc
 | Purpose   : 	
 | Inputs    :	none
 | Outputs   :	none
 | Side FX   :	none
 | comments  :
 | Author    :	sylvain.coudray MBARI-IFREMER/diti/dsi/ie
 ---------------------------------------------------------------*/

	void
Curve_cccccc ()
{

	/* ... Local Variables */


	/* ... Initializations */


	/* ... Begin */


	/* ... End */

        return;

} /* Curve_cccccc */


