// midiviz particle
// lewis c hill
// simple particle class for midiviz

#include "MidiVizParticle.h"

MidiVizParticle::MidiVizParticle(){
  init();
}

void MidiVizParticle::init(){
  pos[0] = 0.0;
  pos[1] = 0.0;
  pos[2] = 0.0;

  vel[0] = 0.0;
  vel[1] = 0.0;
  vel[2] = 0.0;

  accel[0] = 0.0;
  accel[1] = 0.0;
  accel[2] = 0.0;
}

void MidiVizParticle::step(float delta_t){

  for (int i = 0; i < 3; i++){
    vel[i] = vel[i] + accel[i] * delta_t;
    pos[i] = pos[i] + vel[i] * delta_t;  
    trail[0][i] = pos[i];
  }

  for (int i = TRAIL_LENGTH-1; i > 0; i--){
    for (int j = 0; j < 3; j++){
      trail[i][j] = trail[i-1][j];
    }
  }
  
}

void MidiVizParticle::setPosition(float x, float y, float z){
  pos[0] = x;
  pos[1] = y;
  pos[2] = z;

  for (int i = 0; i < TRAIL_LENGTH; i++){
    trail[i][0] = pos[0]; 
    trail[i][1] = pos[1];
    trail[i][2] = pos[2];
  }

}

float*  MidiVizParticle::getPosition(){
  return pos;
}

void MidiVizParticle::setVelocity(float x, float y, float z){
  vel[0] = x;
  vel[1] = y;
  vel[2] = z;
}

float*  MidiVizParticle::getVelocity(){
  return vel;
}

void MidiVizParticle::setAcceleration(float x, float y, float z){
  accel[0] = x;
  accel[1] = y;
  accel[2] = z;
}

bool MidiVizParticle::isMoving(){
  return moving;
}

void MidiVizParticle::stop(){
  moving = false;

  // erase trail

  for (int i = 0; i > TRAIL_LENGTH; i++){
    trail[i][0] = trail[i][1] = trail[i][2] = 0;
  }

}

void MidiVizParticle::start(){
  moving = true;
}


void MidiVizParticle::draw(int mode){
  if (mode == 1) {
    drawWater();
  }

}

void MidiVizParticle::setColor(float r, float g, float b){
  color[0] = r;
  color[1] = g;
  color[2] = b;
}

void MidiVizParticle::drawWater(){

  float particle_width = .15;
  float trail_width = .05;
  glLineWidth(1);
  glColor3fv(color);
  glPushMatrix();

  glTranslatef(pos[0], pos[1], pos[2]);
  glRotatef(pos[1]*10, vel[0], vel[2], 0);
  drawbox(-particle_width, particle_width, 
	  -particle_width, particle_width, 
	  -particle_width, particle_width, GL_QUADS);
  glPopMatrix();

  // line trail
  /*
  glColor3fv(color);
  glBegin(GL_LINES);
  for (int i = 0; i < TRAIL_LENGTH-1; i++){
    glVertex3f(trail[i][0], trail[i][1], trail[i][2]);
    glVertex3f(trail[i+1][0], trail[i+1][1], trail[i+1][2]);
  }
  glEnd();
  */

  // polygon trail

  glColor3fv(color);
  glBegin(GL_QUAD_STRIP);
  for (int i = 0; i < TRAIL_LENGTH-1; i++){
    glVertex3f(trail[i][0]-trail_width, 
	       trail[i][1]-trail_width, 
	       trail[i][2]-trail_width);
    glVertex3f(trail[i][0]+trail_width, 
	       trail[i][1]+trail_width, 
	       trail[i][2]+trail_width);
  }
  glEnd();

}

void MidiVizParticle::drawbox(GLdouble x0, GLdouble x1, GLdouble y0, GLdouble y1,
			    GLdouble z0, GLdouble z1, GLenum type) {
  static GLdouble n[6][3] = {
    {-1.0, 0.0, 0.0}, {0.0, 1.0, 0.0}, {1.0, 0.0, 0.0},
    {0.0, -1.0, 0.0}, {0.0, 0.0, 1.0}, {0.0, 0.0, -1.0}
  };
  static GLint faces[6][4] = {
    { 0, 1, 2, 3}, { 3, 2, 6, 7}, { 7, 6, 5, 4},
    { 4, 5, 1, 0}, { 5, 6, 2, 1}, { 7, 4, 0, 3}
  };
  GLdouble v[8][3], tmp;
  GLint i;
  
  if (x0 > x1)
    {
      tmp = x0; x0 = x1; x1 = tmp;
    }
  if (y0 > y1)
    {
      tmp = y0; y0 = y1; y1 = tmp;
    }
  if (z0 > z1)
    {
      tmp = z0; z0 = z1; z1 = tmp;
    }

  v[0][0] = v[1][0] = v[2][0] = v[3][0] = x0;
  v[4][0] = v[5][0] = v[6][0] = v[7][0] = x1;
  v[0][1] = v[1][1] = v[4][1] = v[5][1] = y0;
  v[2][1] = v[3][1] = v[6][1] = v[7][1] = y1;
  v[0][2] = v[3][2] = v[4][2] = v[7][2] = z0;
  v[1][2] = v[2][2] = v[5][2] = v[6][2] = z1;
  
  for (i = 0; i < 6; i++)
    {
      glBegin(type);
      glNormal3dv(&n[i][0]);
      glVertex3dv(&v[faces[i][0]][0]);
      glNormal3dv(&n[i][0]);
      glVertex3dv(&v[faces[i][1]][0]);
      glNormal3dv(&n[i][0]);
      glVertex3dv(&v[faces[i][2]][0]);
      glNormal3dv(&n[i][0]);
      glVertex3dv(&v[faces[i][3]][0]);
      glEnd();
    }
}


