/* Module Name: "draw_tracks" (Mapper) (Subroutine)                      */
/* Author: John Tee                                                      */
/* Date Created: Wed Dec  2 11:45:28 1992                                */
/*                                                                       */
/* End of Module Description Comments                                    */

#include <stdio.h>
#include <avs/avs.h>
#include <avs/port.h>
#include <avs/field.h>
#include <avs/geom.h>
#include <avs/udata.h>
 
#define MAXPOINTS 500
#define MAXTRACKS 10
 
/* *****************************************/
/*  Module Description                     */
/* *****************************************/
int draw_tracks_desc()
{

	int in_port, out_port, param;
	extern int draw_tracks_compute();

	AVSset_module_name("draw tracks", MODULE_MAPPER);

	/* Input Port Specifications               */
	in_port = AVScreate_input_port("input", "field 2-vector float", 
		REQUIRED);
	in_port = AVScreate_input_port("pick information",
		        "struct upstream_geom", OPTIONAL | INVISIBLE);
	AVSset_input_class(in_port,"upstream_geom");

	/* Output Port Specifications              */
	out_port = AVScreate_output_port("tracks", "geom");
	param = AVSadd_parameter("info","string","","","");
	AVSadd_parameter_prop(param,"width","integer",4);

	AVSset_compute_proc(draw_tracks_compute);
	return(1);
}
 
/* *****************************************/
/* Module Compute Routine                  */
/* *****************************************/
int draw_tracks_compute( input, pick_info, tracks,info)
	AVSfield_float *input;
	upstream_geom *pick_info;
	GEOMedit_list *tracks;
	char *info;
{

GEOMobj *obj[MAXTRACKS], *sphere, *tether;
float verts[MAXPOINTS][3],colors[MAXPOINTS][3];
float *dataptr;
static float radius[1] = {0.02};
static float red[3] = {1.0, 0.0, 0.0};
static float yellow[3] = {1.0, 1.0, 0.0};
static float blue[3] = {0.0, 0.0, 1.0};
static float z_offset = 0.1;
int i,j,b,flags,npoints,ntracks,ndim,dims[10];
char trackname[50], message[20];

/* write something in the text field */
	sprintf(message,"picked position");
	info = message;
	AVSmodify_parameter("info",AVS_VALUE,info,"","");

/* Interpret the input track field */
	ndim = AVSfield_get_int(input,AVS_FIELD_NDIM);
	AVSfield_get_dimensions(input,dims);
	npoints = dims[0];
	if(ndim > 1) ntracks = dims[1];
	else ntracks = 1;

/* Deal with upstream data */
	*tracks = GEOMinit_edit_list(*tracks);
	flags = BUTTON_DOWN;
	GEOMedit_selection_mode(*tracks, "%top", "notify", flags);
	if (pick_info != NULL) {
	   sprintf(message,"(%f,%f)\n",pick_info->vertex[0],
					pick_info->vertex[1]);
	   AVSmodify_parameter("info",AVS_VALUE,info,"","");
	}

/* Draw the tracks */
	for (j=0; j<ntracks; j++) {
	   obj[j] = GEOMcreate_obj(GEOM_POLYTRI,GEOM_NULL);
	   sprintf(trackname,"track%d",j);
	   dataptr = input->data + 2*j*npoints;
	   for (i=0; i<npoints; i++) {
	      verts[i][0] = *(dataptr++);
	      verts[i][1] = *(dataptr++);
	      verts[i][2] = 0;
	      if ((pick_info != NULL) &&
	          (strncmp(trackname,pick_info->picked_obj,6) == 0))
	                for (b=0; b<3; b++) colors[i][b] = red[b];
	      else
	                for (b=0; b<3; b++) colors[i][b] = yellow[b];
	   }
	   GEOMadd_polyline(obj[j],verts,colors,npoints,GEOM_COPY_DATA);
	   GEOMedit_geometry(*tracks,trackname,obj[j]);
	}
/*
   Draw a sphere above the picked point, and join to the vertex with a line
*/
	if (pick_info != NULL) {
           verts[0][0] = pick_info->vertex[0];
           verts[0][1] = pick_info->vertex[1];
           verts[0][2] = z_offset;
           verts[1][0] = pick_info->vertex[0];
           verts[1][1] = pick_info->vertex[1];
           verts[1][2] = 0.0;
	   tether = GEOMcreate_obj(GEOM_POLYTRI,GEOM_NULL);
	   GEOMadd_disjoint_line(tether,verts,blue,2, GEOM_COPY_DATA);
	   GEOMedit_geometry(*tracks,"tether",tether);
	   sphere = GEOMcreate_sphere(GEOM_NULL,verts,radius,GEOM_NULL,
						GEOM_NULL,1,GEOM_COPY_DATA);
	   GEOMadd_float_colors(sphere,blue,1,GEOM_COPY_DATA);
	   GEOMedit_geometry(*tracks,"sphere",sphere);
	   GEOMdestroy_obj(tether);
	   GEOMdestroy_obj(sphere);
	}
	for (j=0; j<ntracks; j++) {
	   GEOMdestroy_obj(obj[j]);
	}
	return(1);
}
 
/* ***********************************************************************/
/* Initialization for modules contained in this file.                    */
/* ***********************************************************************/
int ((*mod_list[])()) = {
	draw_tracks_desc,
};
#define NMODS (sizeof(mod_list) / sizeof(char *))

AVSinit_modules()
{
	AVSinit_from_module_list(mod_list, NMODS);
}