//---------------------------------------------------------------------------

#ifndef SolverH
#define SolverH


#define mfloat double


struct __declspec(align(16)) vec
{
  mfloat x,y,z,w;
  vec():x(0),y(0),z(0),w(0){};
};


struct __declspec(align(16)) dvec
{
  mfloat x[2],y[2],z[2];

  dvec()
  {
      x[0]=0;
      x[1]=0;
      y[0]=0;
      y[1]=0;
      z[0]=0;
      z[1]=0;
  }

  void assign(vec &a, vec &b)
  {
      x[0]=a.x;
      x[1]=b.x;
      y[0]=a.y;
      y[1]=b.y;
      z[0]=a.z;
      z[1]=b.z;
  }
};


struct point
{
  vec pos;    // position
  vec vel;    // velocity
  vec acc;    // acceleration
  mfloat mas;

  mfloat rad;   // raduis for "collision potential"
  float prd;    // raduis for painting
  float clr[3]; // color
  float rotaxis[3];
  bool moveable;
};


struct dpoint
{
  dvec pos;     // position
  dvec acc;     // acceleration
  mfloat mas[2];
  mfloat rad[2];
};
 
#define MAX_DIM 1024
#define DMAX_DIM (MAX_DIM*2)


inline mfloat SQ(mfloat X)
{
  return X*X;
}


class nbsolverobj
{
  int gmodeltype;

  public:

  lightguidt lightguid1;
  lightguidt lightguid2;
  lightguidt lightguid3;
  lightguidt lightguid4;

  mfloat potenergy;     // potential energy
  mfloat cinenergy;     // kinetic energy
  mfloat energyleak;    // energy loss
  vec impulse;
  
  mfloat vfactor;                   
  mfloat quadfactor;
  mfloat linlfactor;
  __declspec(align(16)) dpoint dpts[MAX_DIM];
  __declspec(align(16)) point pts[DMAX_DIM];
  int len;  // length <= DMAX_DIM


  mfloat getpotenergy() { return potenergy; }
  mfloat getcinenergy() { return cinenergy; }
  mfloat getenergyleak() { return energyleak; }
  vec getimpulse() { return impulse; }

  void step(mfloat step);
  void evaluate();
  void devaluate();
  void drawobjects(sceneguidt sceneguid, float time);
  virtual mfloat precision();

  void setmodel1();
  void setmodel2();
  void setmodel3();
  void setmodel4();
  void setmodel5();
  void setmodel6();
  void setmodel7();

  void initlight1(sceneguidt sceneguid, float time);
  void initlight2(sceneguidt sceneguid, float time);
  void initlight3(sceneguidt sceneguid, float time);
  void initlight4(sceneguidt sceneguid, float time);
  void initlight5(sceneguidt sceneguid, float time);
  void initlight6(sceneguidt sceneguid, float time);
  void initlight7(sceneguidt sceneguid, float time);

  void init(int modeltype, int randseed);
  void initlight(int modeltype,sceneguidt sceneguid, float time);

  nbsolverobj():vfactor(1.0),linlfactor(0.0),quadfactor(1.0),len(0){}
};

extern nbsolverobj solver;

//---------------------------------------------------------------------------
#endif
