#import <appkit/NXImage.h>
#import <appkit/Window.h>
#import <appkit/Panel.h>                // for NXRunAlertPanel()
#import <dpsclient/wraps.h>
#import <libc.h>
#import <math.h>
#import "Spiro3View.h"



@implementation Spiro3View:View                

- oneStep
{
  float mx, my;
  
// Get mouse pos 
  PScurrentmouse(winNum, &mx, &my);

//  A rather overwrought way of setting drho and drad, see 'pinc' later
//  xdif=(mx-midx)/bounds.size.width;
//  ydif=(my-midy)/bounds.size.height;
//  drho=pinc*(20*xdif);	// Increment for angle
//  drad=pinc*(5*ydif);		// Number of increments

// A simple way of setting drho and drad
  drho=0.11*(mx-midx);
  drad=0.11*(my-midy);

//Prevent context-change during drawing? I dunno...
//[self lockFocus];

// Set color to erase 
  PSsetrgbcolor(0,0,0);	

// Wait till postscript server is done drawing
//  DPSWaitContext(DPSGetCurrentContext());
//  NXPing();

//  PSsetlinewidth( LINEWIDTH );

// Erase old user path to Postscript server
  DPSDoUserPath(pts, p, dps_float, ops, NUMLINES, bbox, dps_ustroke);

// Set initial values 
  if (c>MAXINT) c=0;
  c++;
  ops[0] = dps_moveto;
  rho[0] = rho[NUMLINES-1];
  rad = sin(c*drad);
  pts[0] = (cos(rho[0])*rad*xscale) + midx;
  pts[1] = (sin(rho[0])*rad*yscale) + midy;
  p=2;

  for ( n = 1; n < NUMLINES; ++n)
  {  c++;
     rho[n] = rho[n-1]+drho; 	if(rho[n]>(TWOP)) rho[n]-=(TWOP);
     rad = sin(c*drad);

     // Store the op in da user path
     ops[n] = dps_lineto;

     // Store x/y of the current point in the user path 
     pts[p++] = (cos(rho[n])*rad*xscale) + midx;
     pts[p++] = (sin(rho[n])*rad*yscale) + midy;
  }
  PSsetrgbcolor(0,1,1);

// Sync with server, needed when Numlines is high. Slows things down
//  NXPing();

// DRAW the pattern: Send user path to Postscript server
  DPSDoUserPath(pts, p, dps_float, ops, NUMLINES, bbox, dps_ustroke);

// [self unlockFocus];
  return self;
}


- initFrame:(NXRect *)frameRect
{
// Wait till postscript server is done drawing
//  DPSWaitContext(DPSGetCurrentContext());
//  DPSFlushContext(DPSGetCurrentContext());
//  NXPing();

  [super initFrame:frameRect];
  [self newSize];
  winNum=[[self window] windowNum];
  return self;
}


- sizeTo:(NXCoord)width :(NXCoord)height
{
// Wait till postscript server is done drawing
//  DPSWaitContext(DPSGetCurrentContext());
//  DPSFlushContext(DPSGetCurrentContext());
//  NXPing();

  [super sizeTo:width :height];
  [self newSize];
  return self;
}

- newSize
{
  int jkl;

// Wait till postscript server is done drawing
//  DPSWaitContext(DPSGetCurrentContext());
//  DPSFlushContext(DPSGetCurrentContext());
//  NXPing();
  
// Set up an array called boundingbox (req'd for user path)
  bbox[0]=bounds.origin.x;
  bbox[1]=bounds.origin.y;
  bbox[2]=bounds.origin.x+bounds.size.width-1;
  bbox[3]=bounds.origin.y+bounds.size.height-1;

// Reset c counter
  c=0;

// Store middle of view.  
  midx=bounds.origin.x+bounds.size.width/2;
  midy=bounds.origin.y+bounds.size.height/2;

// Set value that scales drawing size.  Maintain 1 to 1 aspext ratio
  xscale=0.29*bounds.size.width;
  yscale=0.37*bounds.size.height;

// When a new view is initialized, ONESTEP will not have calculated
// the lines to erase yet, so we have to do this for it...
  for(jkl=0;jkl<TWONUMLN;jkl++){
    pts[jkl]=midx;
    pts[jkl]=midy;
  }
  for(jkl=0;jkl<NUMLINES;jkl++){
    ops[0] = dps_moveto;}

  return self;
}

@end
