//This code is the work of Booker C. Bense (benseb@next.sdsc.edu)
// You are free to change/distribute this code provided this notice
// remains intact in all versions. 
#import "LorenzViewPart.h"
#import "Thinker.h"
#import <appkit/NXImage.h>
#import <appkit/Panel.h>                // for NXRunAlertPanel()
#import <dpsclient/wraps.h>
#import <libc.h>
#import <math.h>

@implementation LorenzView

- oneStep
{
     float xx,yy,zz,ctheta,stheta,cphi,sphi;
     float mouse_x,mouse_y; 
  // Cycle indices
  p=n; 
  
  points[0] = n; 

  // points[0] is never actually used other than as a start point in 
  // this loop
 
      for( i = 1 ; i < CHASERS ; i++ )
      {
	  points[i] = (NUMPOINTS/(CHASERS)+points[i-1])%(NUMPOINTS); 
      }
  n=(n+1)%(NUMPOINTS);      

  // take an euler step   

     xdot = S * (Y - X);
     ydot = (R * X) - Y - (X * Z);
     zdot = (X * Y) - (B * Z);
     X = X + xdot * delta_T;
     Y = Y + ydot * delta_T;
     Z = Z + zdot * delta_T;

     // Draw the black stuff 

  PSsetrgbcolor(0.0,0.0,0.0);
  PSmoveto(xc[n], yc[n]);
  PSlineto(xc[n], yc[n]);
  PSstroke();
     //find out where the mouse is.  

    PScurrentmouse(winNum,&mouse_x,&mouse_y); 
    theta = (mouse_y/ury)*2.0*PI;
    phi = (mouse_x/urx)*2.0*PI; 
    ctheta = cos(theta);
    cphi = cos(phi); 
    stheta = sin(theta); 
    sphi = sin(phi); 

     //Convert to screen coordinates Update
     xx = (( X - Xmin)/ Xrange) - 0.5; 
     yy = (( Y - Ymin )/ Yrange) -0.5; 
     zz = (( Z - Zmin )/ Zrange) -0.5;
       
     xc[n] = (xx*cphi + zz*sphi)* urx + midx; 
     yc[n] = (ctheta*yy+stheta*zz )*ury + midy  ; 
 

  if ( [self shouldDrawColor ] )
  {
   red_shift = (CHASERS*4)/3;
   blue_shift = (CHASERS*2)/3; 
   clut = cl_clut; 
  }
  else
  {
      red_shift = 0; 
      blue_shift = 0;
      clut = twobit_clut;  
  }

  
  for ( i = 1; i < CHASERS ; i++)
  {
      PSsetrgbcolor(clut[(i+red_shift)%CHASERS],clut[i],clut[(i+blue_shift)%CHASERS]); 
      PSmoveto(xc[points[i]], yc[points[i]]);
      PSlineto(xc[points[i]], yc[points[i]]);
      PSstroke();
  }
 
  // Draw the White stuff
  
  PSsetrgbcolor(1.0, 1.0, 1.0);
  PSmoveto(xc[n], yc[n]); PSlineto(xc[n], yc[n]);
  PSstroke();
  
  
  return self;
}

- initFrame:(NXRect *)frameRect
{
	[super initFrame:frameRect];
	[self newSize];
        winNum=[[self window] windowNum];
	return self;
}

- sizeTo:(NXCoord)width :(NXCoord)height
{
	[super sizeTo:width :height];
	[self newSize];
	return self;
}

- newSize
{
  urx=bounds.size.width;
  ury=bounds.size.height;
  
  midx=urx/2;
  midy=ury/2;
 
  n = 0;
//  t = 0;
 
  // Starting points 
#ifdef ROTATE
  X[0] = 0.1;
  Y[0] = 0.1;
  Z[0] = 0.1; 
#else
  X = 0.1;
  Y = 0.1;
  Z = 0.1; 
#endif
  for(i=0; i< NUMPOINTS; i++)
  {
      xc[i] = midx;
      yc[i] = midy; 

  }
  //this will probably look really ugly in color ????
  for(i=0; i < CHASERS ; i++ )
     { cos_arg = ((float)i)/((float)CHASERS)*PI; 
       cl_clut[i] = (cos(cos_arg)+1.0)/2.0;
       twobit_clut[i] = (float)(i%4)/3.0; 
      } 

  return self;
}

@end
