// Lew Hill II
// MidiVizTrapezoid

#include "MidiVizTrapezoid.h"


 MidiVizTrapezoid::MidiVizTrapezoid(){

  color[0] = 1.0;
  color[1] = 0.0;
  color[2] = 0.0;

  coords[0][0] = 1;
  coords[0][1] = 1; 
  coords[0][2] = 0;

  coords[1][0] = 1;   
  coords[1][1] = -1; 
  coords[1][2] = 0;

  coords[2][0] = -1;   
  coords[2][1] = -1; 
  coords[2][2] = 0;

  coords[3][0] = -1;   
  coords[3][1] = 1; 
  coords[3][2] = 0;

  coords[4][0] = 1.25;   
  coords[4][1] = 1; 
  coords[4][2] = 0;

  coords[5][0] = -1.25;   
  coords[5][1] = 1; 
  coords[5][2] = 0;

  bottom_coords[0][0] = 1;
  bottom_coords[0][1] = 1; 
  bottom_coords[0][2] = -.23;

  bottom_coords[1][0] = 1;   
  bottom_coords[1][1] = -1; 
  bottom_coords[1][2] = -.23;
  
  bottom_coords[2][0] = -1;   
  bottom_coords[2][1] = -1; 
  bottom_coords[2][2] = -.23;

  bottom_coords[3][0] = -1;   
  bottom_coords[3][1] = 1; 
  bottom_coords[3][2] = -.23;
  
  bottom_coords[4][0] = 1.25;   
  bottom_coords[4][1] = 1; 
  bottom_coords[4][2] = -.23;
  
  bottom_coords[5][0] = -1.25;   
  bottom_coords[5][1] = 1; 
  bottom_coords[5][2] = -.23;
 
  scalefac = 10.0/16384.0;

  scale[0] = 1;  
  scale[1] = 1;  
  scale[2] = 1;
 
}

void MidiVizTrapezoid::draw(){

  glPushMatrix();

  glTranslatef(position[0], position[1], position[2]);
  glRotatef(rotation[2], 0.0, 0.0, 1.0); 
  glRotatef(rotation[1] + rotation_offset[1], 0.0, 1.0, 0.0); 
  glScalef(scale[0], scale[1], scale[2]);

  if (isAnimating()){
    
    glColor3fv(color_table.getValue(last_note_played %12));

  } else {
    glColor3fv(dark_color);
  }

  // draw top

  glBegin(GL_TRIANGLE_STRIP);
  glNormal3f(0,0,1);
  glVertex3fv(coords[2]);  
  glVertex3fv(coords[5]);  
  glVertex3fv(coords[1]);
  glVertex3fv(coords[4]);
  glEnd();


  // draw bottom
  glBegin(GL_TRIANGLE_STRIP);
  glNormal3f(0,0,-1);
  glVertex3fv(bottom_coords[2]);  
  glVertex3fv(bottom_coords[5]);  
  glVertex3fv(bottom_coords[1]);
  glVertex3fv(bottom_coords[4]);
  glEnd();

  // draw sides
  
  glBegin(GL_TRIANGLE_STRIP);
  glVertex3fv(coords[2]);
  glVertex3fv(bottom_coords[2]);

  glVertex3fv(coords[5]);
  glVertex3fv(bottom_coords[5]);

  glVertex3fv(coords[1]);
  glVertex3fv(bottom_coords[1]);

  glVertex3fv(coords[4]);
  glVertex3fv(bottom_coords[4]);

  glVertex3fv(coords[2]);
  glVertex3fv(bottom_coords[2]);

  glEnd();

  glPopMatrix();
}

void MidiVizTrapezoid::frame(double time){
  
  if (animationCounter > 0){

    // rotate around z
    
    rotation_offset[1] += animation_rot_speed;
    //    cout << "rotation_offset[1] =  " << rotation_offset[1] << endl;

    if (rotation_offset[1] > 360) rotation_offset[1] -= 360;
    
    if (rotation_offset[1] < 0) rotation_offset[1] += 360;
    
    animationCounter--;
  }

  if (animationCounter == 0){
    if (rotation_offset != 0){
      rotation_offset[1] *=0.7;
    }
  }
}


void MidiVizTrapezoid::startAnimation(MidiEvent* event){

  int note_played = event->getNote();
  int note_velocity = event->getVelocity();

  animationCounter = (int)((float)note_velocity/(float) 2.0);
  animation_rot_speed = note_velocity/(float)3.0;
  last_note_played = note_played;

}

bool MidiVizTrapezoid::isAnimating(){
  return (animationCounter != 0);
}

bool MidiVizTrapezoid::intersect(float in_position[]){
  float distance = calculateDistance(in_position[0], position[0], 
				     in_position[1], position[1], 
				     in_position[2], position[2]);
  //cout << "Distance = " << distance << endl;

  if (distance < .75){
    return true;
  } else {
    return false;
  }      
}

float MidiVizTrapezoid::calculateDistance(float x1, float x2, 
			float y1, float y2, 
			float z1, float z2){

  float distance_squared = (x1-x2)*(x1-x2) + (y1-y2)*(y1-y2) + (z1-z2)*(z1-z2);
  return (sqrt(distance_squared));
}

void MidiVizTrapezoid::setPosition(float x, float y, float z){
  position[0] = x;
  position[1] = y;
  position[2] = z;
}

void MidiVizTrapezoid::setRotation(float x, float y, float z){
  rotation[0] = x;
  rotation[1] = y;
  rotation[2] = z;
}

void MidiVizTrapezoid::setScale(float x, float y, float z){
  scale[0] = x;
  scale[1] = y;
  scale[2] = z;	
}

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

  dark_color[0] = r/4.0;
  dark_color[1] = g/4.0;
  dark_color[2] = b/4.0;

  inv_color[0] = 1.0 - r;
  inv_color[1] = 1.0 - g;
  inv_color[2] = 1.0 - b;
}

void MidiVizTrapezoid::setNote(int in_note){
  note = in_note;
}

void MidiVizTrapezoid::setChannel(int in_channel){
  channel = in_channel;
}

int MidiVizTrapezoid::getNote(){
  return note;
}

int MidiVizTrapezoid::getChannel(){
  return channel;
}

