
/* Generated by Interface Builder */

#import <appkit/Application.h>
#import "evolverView.h"
#import <dpsclient/wraps.h>
#import "include.h"

id viewObject;
static int endcount=0;  /* for counting vertices selected */
static vertex_id point[5];  /* points chosen */

void NeXT_display()
{
   [viewObject show:nil];
}

@implementation evolverView

- initFrame:(const NXRect *)frameRect
{ [super initFrame:frameRect];
  viewObject = self;
  return self;
}

- show:sender
{  extern char datafilename[];
   [window setTitleAsFilename:datafilename];
   [self lockFocus];
   [self getVisibleRect:&theRect];
   display();
   endcount = 0;
   [self unlockFocus];

   return self;
}
- equiangulate:sender{ old_menu("u"); return self;}
- vertex_average:sender{ old_menu("V"); return self; }
- long_edges:sender{ old_menu("l");  return self;}
- short_edges:sender{ old_menu("t");  return self;}
- small_triangles:sender{ old_menu("w");  return self;}
- skinny_triangles:sender{ old_menu("K");  return self;}
- notch_ridges:sender{ old_menu("n");  return self;}
- pop_edges:sender{ old_menu("O");  return self;}
- pop_vertices:sender{ old_menu("o");  return self;}
- auto_display:sender{ old_menu("D");  return self;}
- reset:sender{ view_transform("R"); [self show:self]; return self;}
- zoom:sender{ view_transform("z"); [self show:self]; return self;}
- shrink:sender{ view_transform("s"); [self show:self]; return self;} 
- counts:sender{ old_menu("c");  return self;}
- checks: sender{ old_menu("C");  return self;}
- status_info:sender{ old_menu("i");  return self;}
- volumes:sender{ old_menu("v");  return self;}
- extrapolate:sender{ old_menu("e");  return self;}
- parameters:sender{ old_menu("A");  return self;}
- set_volumes:sender{ old_menu("b");  return self;}
- diffusion:sender{ old_menu("f");  return self;}
- gravity:sender{ old_menu("G");  return self;}
- gap_energy:sender{ old_menu("k");  return self;}
- ambient_pressure:sender{ old_menu("p");  return self;}
- quantities:sender{ old_menu("Q");  return self;}
- area_normalization:sender{ old_menu("a");  return self;}
- linear_quadratic:sender{ old_menu("M");  return self;}
- jiggling:sender{ old_menu("J");  return self;}
- scale_factor:sender{ old_menu("m");  return self;}
- help:sender{ old_menu("h");  return self;}
- dump:sender{ old_menu("d");  return self;}
- logging:sender{ old_menu("F");  return self;}
- graphics_file:sender{ old_menu("P");  return self;}
- jiggle:sender{ old_menu("j");  return self;}

- drawSelf:(const NXRect *)rects:(int)rectCount
{
   theRect = rects[0];
   display();
   endcount = 0;
   return self;
}


- mouseDown:(NXEvent *)thisEvent
{ 
  int oldMask;
  NXEvent *nextEvent;
  int shouldLoop = YES;
  NXPoint spot,here_spot;
  extern void fix_ctm(double,double);
  int drag_flag;  /* whether dragging to rotate */
  edge_id e_id = NULLID;
  facet_id f_id = NULLID;
  
  [self lockFocus];
  [self getVisibleRect:&theRect];
  
  /* set up first cursor position */
  spot = thisEvent->location;
  [self convertPointFromSuperview:&spot];
  oldMask = [window addToEventMask:NX_LMOUSEDRAGGEDMASK|NX_KEYDOWNMASK];
  drag_flag = YES;
  
   while ( shouldLoop )
    { nextEvent = [NXApp getNextEvent:
            (NX_LMOUSEUPMASK | NX_LMOUSEDRAGGEDMASK | NX_KEYDOWNMASK)];
    [self convertPointFromSuperview:&nextEvent->location];
    /* can't get proper coordinates out of this! */
   switch ( nextEvent->type ) 
        {
	   case NX_LMOUSEUP:
	    shouldLoop = NO;
	    if ( !drag_flag ) break;
	    fix_ctm(nextEvent->location.x-spot.x,nextEvent->location.y-spot.y);
             display();
	     endcount = 0;
	     break;
	     
	   case NX_LMOUSEDRAGGED:
	     break;
	     
	   case  NX_KEYDOWN:
             here_spot = nextEvent->location;  
	     switch (nextEvent->data.key.charCode)
	       { 
	         case 'p': /* selecting just one point */
		         point[0] = select_point(&spot); /*?!@$**?*/
			 highlight_vertex(point[0]);
			 vertex_dump(point[0],stdout);
			 break;
	         case 'e': /* selecting edge */
		         point[endcount] = select_point(&spot); /*?!@$**?*/
			 highlight_vertex(point[endcount]);
			 endcount++;
			 if ( endcount == 2 )
			   { e_id = select_edge(point);
			     edge_dump(e_id,stdout);
			     endcount = 0;
			    }
			 break;
		 case 'f': /* selecting facet */
		         point[endcount] = select_point(&spot); /*?!@$**?*/
			 highlight_vertex(point[endcount]);
			 endcount++;
			 if ( endcount == 3 )
			   { f_id = select_facet(point);
			     facet_dump(f_id,stdout);
			     endcount = 0;
			    }
			 break;
	         case 'r' : /* refine edge or point */
		         if ( valid_id(e_id) ) edge_refine(e_id);
			 else if ( valid_id(f_id) ) 
			   face_triangulate(f_id,FACET_EDGES);
			 if ( go_display_flag ) display();
			 break;
	         case 'd' : /* eliminate edge */
		         if ( valid_id(e_id) ) eliminate_edge(e_id);
			 if ( go_display_flag ) display();
			 break;
		}
	     drag_flag = NO;  /* not rotating */
             break;
	     
           default: break;
	 }
     }  
  [self unlockFocus];
  [window setEventMask:oldMask];
  
  return self;
}


@end
