/**
 * Simple Read
 * 
 * Read data from the serial port and change the color of a rectangle
 * when a switch connected to a Wiring or Arduino board is pressed and released.
 * This example works with the Wiring / Arduino program that follows below.
 */


import processing.serial.*;

Serial myPort;  // Create object from Serial class
int val;      // Data received from the serial port

int NUM_CHANNELS = 128;
int[] spectral_data_raw = new int[NUM_CHANNELS];
int[] spectral_data_baseline = new int[NUM_CHANNELS];
int[] spectral_data_difference = new int[NUM_CHANNELS];

PFont fontA;
int screenshot_number = 0;

// Called whenever there is something available to read
void serialEvent(Serial port) {
  // Data from the Serial port is read in serialEvent() using the readStringUntil() function with * as the end character.
  String input = port.readStringUntil(char(10)); 
  
  if (input != null) {
    // Print message received   
    //    println( "Receiving:" + input);
    input = input.trim();    
    int split_point = input.indexOf(',');
    if (split_point <= 0) return;
      // The data is split into an array of Strings with a comma or asterisk as a delimiter and converted into an array of integers.
      int[] vals = int(splitTokens(input, ","));          
      int idx = vals[0];
      int value = vals[1];
      if (idx < spectral_data_raw.length ) {
        spectral_data_raw[idx] = value;
      }
      println ("idx:" + idx + "  value:" + value);
  }
  
}

void draw_spectrum(int x, int y, int sizex, int sizey, int autoscale, int[] spectral_data, String label) {
    int data_max = 16384;
    int data_min = 0;
  
    // Autoscaling 
    if (autoscale == 1) {
      data_max = 0;
      data_min = 16384;

      for (int i=0; i<NUM_CHANNELS; i++) {
        if (spectral_data[i] > data_max) {
          data_max = spectral_data[i]; 
        }
        if (spectral_data[i] < data_min) { 
          data_min = spectral_data[i]; 
        }
      }
    }
    int delta = data_max - data_min;
    float mult_x = (float)sizex / (float)NUM_CHANNELS;

    // Draw background
      fill(192);                   // set fill to black
      stroke(128);
      rect(x, y, sizex, sizey);
      stroke(0);
    
    
    // Draw spectrum
    for (int i=1; i<NUM_CHANNELS; i++) {
      int ch0 = ceil( (((float)spectral_data[i-1] - (float)data_min) / (float)delta) * sizey  );
      int ch1 = ceil( (((float)spectral_data[i] - (float)data_min) / (float)delta) * sizey  );
      line ( x + ((i-1)*mult_x), y + sizey - ch0, x + (i*mult_x), y + sizey - ch1);
    }   
 
    // Draw text labels
    fill(128);
    float label_min = ((float)data_min / 16384.0f) * 1000.0f;
    float label_max = ((float)data_max / 16384.0f) * 1000.0f;
    text((float)label_min / 1000.0, x - 37, y + sizey + 5);
    text((float)label_max / 1000.0, x - 37, y + 5);
    text(label, x + (sizex/2), y - 10);
    
}


void setup() 
{
  size(NUM_CHANNELS*3, 600);
  // I know that the first port in the serial list on my mac
  // is always my  FTDI adaptor, so I open Serial.list()[0].
  // On Windows machines, this generally opens COM1.
  // Open whatever port is the one you're using.
  println (Serial.list());
  
  String portName = Serial.list()[3];  
  myPort = new Serial(this, portName, 115200);
  
//  fontA = loadFont("Ziggurat-HTF-Black-32.vlw");
  fontA = createFont("Arial-black", 20);
  textFont(fontA, 12);
}

void draw()
{

  int size_y = 200;
  
  background(255);             // Set background to white


  draw_spectrum (50, 50, 300, 100, 1, spectral_data_raw, "raw");
  draw_spectrum (50, 250, 300, 100, 1, spectral_data_baseline, "baseline");
  
  for (int i=0; i<NUM_CHANNELS; i++) {
    spectral_data_difference[i] = spectral_data_raw[i] - spectral_data_baseline[i]; 
  }   
  draw_spectrum (50, 450, 300, 100, 1, spectral_data_difference, "difference");

}

void keyPressed() {
  if (key == ' ') {
   saveFrame("screenshot-" + screenshot_number + ".png"); 
   screenshot_number += 1;
  }
  
  if (key == 'a') {  
    for (int i=0; i<NUM_CHANNELS; i++) {
      spectral_data_baseline[i] = spectral_data_raw[i]; 
    } 
  }
}
