/*
 *  FrequencyPlot.cpp
 *  lsystems_one
 *
 *  Created by lewhill2 on Mon Mar 08 2004.
 *  Copyright (c) 2004 __MyCompanyName__. All rights reserved.
 *
 */

#include "MidiVizFrequencyPlot.h"


MidiVizFrequencyPlot::MidiVizFrequencyPlot(){
}


MidiVizFrequencyPlot::~MidiVizFrequencyPlot(){
}

void MidiVizFrequencyPlot::init(){
}

void MidiVizFrequencyPlot::drawOneCurve(int note, float thetaBegin, float thetaEnd, float xsize, float ysize){
  
  float thetaRange = thetaEnd - thetaBegin;
  float thetaStep = thetaRange/NUM_PLOT_POINTS;
  float frequencyTheta = midiToFrequency.getFrequency(note)/100.0;
  
  float amplitude = ysize * note_values[note];
  
  float xstep = xsize/(float) NUM_PLOT_POINTS;
  
  float currentY = 0;
  float currentX = 0;
  float currentTheta = thetaBegin;
  float attColor[3]; 
  
  float* color= note_color_table.getValue(note%12);
  attColor[0] = color[0] * (.09 + .91 * note_values[note]);
  attColor[1] = color[1] * (.09 + .91 * note_values[note]);
  attColor[2] = color[2] * (.09 + .91 * note_values[note]);

 glColor3fv(attColor);
  
  glBegin(GL_TRIANGLE_STRIP);
  for(int i = 0; i < NUM_PLOT_POINTS; i++){
    currentY = cos(frequencyTheta * currentTheta) * amplitude;
    glVertex3f(currentX, currentY, 0);
    glVertex3f(currentX, currentY *.80, 0);

    sum_array[i][1] += currentY;

    sum_array[i][0] = currentX;
    //move indices
    currentX += xstep;
    currentTheta += thetaStep;
  }
  glEnd();
  
}

void MidiVizFrequencyPlot::drawSumCurve(float thetaBegin, float thetaEnd, float xsize, float ysize){
  // redraws the sum of the values from above
  

  glBegin(GL_TRIANGLE_STRIP);
  
  for(int i=0; i < NUM_PLOT_POINTS; i++){
    
    glVertex3f(sum_array[i][0], sum_array[i][1], 0);
    glVertex3f(sum_array[i][0], sum_array[i][1]*.80, 0);
    
  }

  glEnd();
}	

void MidiVizFrequencyPlot::drawSumTube(){
  // redraws the sum of the values from above
  
  glColor3f(0.0, 0.5, 1.5);
  
  glPushMatrix();
  for (int i=1; i < NUM_PLOT_POINTS-1; i++){
    glBegin(GL_TRIANGLE_STRIP);
    for(float phi = 0; phi <= 6.28; phi+= .4){
      
      float cos_phi = cos(phi);
      float sin_phi = sin(phi);
      float amplitude = sum_array[i][1]/2 + 10;
      float next_amplitude = sum_array[i+1][1]/2 + 10;
      
      glNormal3f(cos_phi, sin_phi, (sum_array[i-1][0]+sum_array[i+1][0])/2.0);
      
      glVertex3f(cos_phi * amplitude, sin_phi * amplitude,
		 sum_array[i][0]);
      glVertex3f(cos_phi * next_amplitude, sin_phi * next_amplitude,
		 sum_array[i+1][0]);
    }
    glEnd();
  }
  glPopMatrix();
}	


void MidiVizFrequencyPlot::drawSumTubeWire(){
  // redraws the sum of the values from above
  
  glColor3f(1.0, 1.0, 1.0);
  
  glPushMatrix();
  for (int i=0; i < NUM_PLOT_POINTS; i++){
    glBegin(GL_LINE_LOOP);
    for(float phi = 0; phi < 6.28; phi+= .4){
      glVertex3f(cos(phi)*sum_array[i][1], sin(phi)*sum_array[i][1],
		 sum_array[i][0]);
    }
    glEnd();
  }
  glPopMatrix();
}	



void MidiVizFrequencyPlot::clearSumArray(){
  
  for (int i = 0; i < NUM_PLOT_POINTS; i++){
    sum_array[i][0] = 0;
    sum_array[i][1] = 0;
  }
  
}

void MidiVizFrequencyPlot::frame(){
  
  /*
  for (int i = 0; i < 128; i++){
    note_values[i] *= .93;
  }
  */

  offset+=.03;
  if (offset > 12.54){
    offset -= 12.54;
  }
  
  clearSumArray();

}

void MidiVizFrequencyPlot::draw(){
  int xsize = 100;
  int ysize = 30;
    
  glPushMatrix();
  
  glTranslatef(position[0], position[1], position[2]);
  glRotatef(rotation[2], 0.0, 0.0, 1.0); 
  glRotatef(rotation[1], 0.0, 1.0, 0.0); 
  glRotatef(rotation[0], 1.0, 0.0, 0.0); 
  glScalef(scale[0], scale[1], scale[2]);
  
  glTranslatef(-50,30,0);
  glLineWidth(1);
  
  glColor3f(.3, .3, .3);
  glBegin(GL_LINES);
  glVertex3f(0,0,0);
  glVertex3f(100,0,0);
  glVertex3f(0,  ysize*0.5, 0);
  glVertex3f(0, -ysize*0.5, 0);
  glEnd();
  
  for (int i = 0; i < 128 ; i++){
    if (note_values[i] > .0001){
      drawOneCurve(i, 0+offset, 12.54+offset, xsize, ysize);
    }
  }
  
  glTranslatef(0, -60, 0);
  
  glColor3f(.3, .3, .3);
  glBegin(GL_LINES);
  glVertex3f(0,0,0);
  glVertex3f(100,0,0);
  glVertex3f(0,  ysize*0.5, 0);
  glVertex3f(0, -ysize*0.5, 0);
  glEnd();
 
  drawSumCurve(0+offset, 12.54+offset, 100, 30);
  
  glPopMatrix();
  
  
  /*
    glPushMatrix();
    //  drawSumTube();
    glTranslatef(-50, 0,0);
    // drawSumTubeWire();
    glPopMatrix();
  */  
    
}

void MidiVizFrequencyPlot::processMidiEvent(MidiEvent event){
  
  int note = event.getNote();
  int velocity = event.getVelocity();
  
  //  if(velocity > 0){
    note_values[note] = velocity/127.0;	
    //}
 
}

