#import "LorenzCrossViewPart.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 LorenzCrossView

- oneStep
{
  // 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   

      for ( i = 0 ; i < 5 ; i++ )
      {
	  xdot = S * (Y[i] - X[i]);
	  ydot = (R * X[i]) - Y[i] - (X[i] * Z[i]);
	  zdot = (X[i] * Y[i]) - (B * Z[i]);
	  X[i] = X[i] + xdot * delta_T;
	  Y[i] = Y[i] + ydot * delta_T;
	  Z[i] = Z[i] + zdot * delta_T; }



  // Draw the black stuff 

  PSsetrgbcolor(0.0,0.0,0.0);
  PSmoveto(xc[n][CENTER], yc[n][CENTER]);
  PSlineto(xc[n][RIGHT], yc[n][RIGHT]);
  PSmoveto(xc[n][CENTER], yc[n][CENTER]);
  PSlineto(xc[n][LEFT], yc[n][LEFT]);
  PSmoveto(xc[n][CENTER], yc[n][CENTER]);
  PSlineto(xc[n][UP], yc[n][UP]);
  PSmoveto(xc[n][CENTER], yc[n][CENTER]);
  PSlineto(xc[n][DOWN], yc[n][DOWN]);
  PSstroke();

  //Convert to screen coordinates Update

      for( i= 0 ; i< 5 ; i++)
      { xc[n][i] = (( X[i] - Xmin)/ Xrange )* urx; 
	yc[n][i] = (( Y[i] - Ymin )/ Yrange )* ury;}


  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]][CENTER], yc[points[i]][CENTER]);
      PSlineto(xc[points[i]][RIGHT], yc[points[i]][RIGHT]);
      PSmoveto(xc[points[i]][CENTER], yc[points[i]][CENTER]);
      PSlineto(xc[points[i]][LEFT], yc[points[i]][LEFT]);
      PSmoveto(xc[points[i]][CENTER], yc[points[i]][CENTER]);
      PSlineto(xc[points[i]][UP], yc[points[i]][UP]);
      PSmoveto(xc[points[i]][CENTER], yc[points[i]][CENTER]);
      PSlineto(xc[points[i]][DOWN], yc[points[i]][DOWN]);
      PSstroke();
  }
 
  // Draw the White stuff
  
  PSsetrgbcolor(1.0, 1.0, 1.0);
  PSmoveto(xc[n][CENTER], yc[n][CENTER]);
  PSlineto(xc[n][RIGHT], yc[n][RIGHT]);
  PSmoveto(xc[n][CENTER], yc[n][CENTER]);
  PSlineto(xc[n][LEFT], yc[n][LEFT]);
  PSmoveto(xc[n][CENTER], yc[n][CENTER]);
  PSlineto(xc[n][UP], yc[n][UP]);
  PSmoveto(xc[n][CENTER], yc[n][CENTER]);
  PSlineto(xc[n][DOWN], yc[n][DOWN]);
  PSstroke();
  
  
  return self;
}

- initFrame:(NXRect *)frameRect
{
	[super initFrame:frameRect];
	[self newSize];
	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 

  X[CENTER] = 0.1;
  Y[CENTER] = 0.1;
  Z[CENTER] = 0.1; 

  X[RIGHT] = 0.11;
  Y[RIGHT] = 0.1;
  Z[RIGHT] = 0.1; 

  X[LEFT] = 0.99;
  Y[LEFT] = 0.1;
  Z[LEFT] = 0.1; 

  X[UP] = 0.1;
  Y[UP] = 0.11;
  Z[UP] = 0.1; 

  X[DOWN] = 0.1;
  Y[DOWN] = 0.99;
  Z[DOWN] = 0.1; 

  for(i=0; i< NUMPOINTS; i++)
  {
      for ( j = 0 ; j < 5 ; j++)
     { xc[i][j] = midx;
      yc[i][j] = 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
