/* 
 basic_drawing
 You can draw by simply adding points directly or converted
 cc teddavis.org 2017/18
 */

// import and create instance of XYscope
XYscope ms_xy;

int                ms_n_point = 30;
float                 ms_t;
float            ms_x[] = new float[2000];
float            ms_y[] = new float[2000];
float                ms_rx[] = new float[2000];
float                ms_ry[] = new float[2000];
float           []ms_channel = new float[128];
float           []ms_channel_amp = new float[128];
int              []ms_chan_index = new int [121];
int             ms_period = 0;
int            ms_activated_channels = 0;
int            ms_rect_circle = 0;

Star[]        ms_stars = new Star[500];

void midi_monophonic_synth(int status, int chan, int value)
{
      boolean swapped = false;
    
      if (status == -112)
      {
          //channel = (12f*(log((pow(2, (chan - 69f)/12))/440f)/log(2)) + 69f);
          for (int i = 0; i < 121; i++)
          {
              if (ms_channel[i] < 1)
              {
                  ms_channel[i] = pow(2, (chan - 69f) / 12) * 440;
                  ms_channel_amp[i] = map(value, 0, 127, 0, 1);
                  ms_chan_index[i] = chan;
                  break;
                  
              }
          }
          ms_activated_channels++;
      }
      if (status == -128)
      {
          for (int i = 0; i < 121; i++)
          {
              if(ms_chan_index[i] == chan && swapped == false)
              {
                   ms_channel[i] = 0;
                   ms_channel_amp[i] = 0;
                   ms_chan_index[i] = 0;
                   swapped = true;
              }
              if (swapped == true)
              {
                  ms_channel[i] = ms_channel[i + 1];
                  ms_channel_amp[i] = ms_channel_amp[i + 1];
                  ms_chan_index[i] = ms_chan_index[i+1];
                  if (ms_channel[i] < 1)
                      break;
              }
          }
          ms_activated_channels--;
      }
      if (chan == 7 && status == -80)
          ms_n_point = value * 2;
      if (chan == 7 && status == -79)
          ms_rect_circle = value;
}

void setup_monophonic_synth() {
    for (int i = 0; i < 2000; i++)
    {
        ms_rx[i] = random(-2000, 1000) / 1000.0;
        ms_ry[i] = random(-1000, 1000) / 1000.0;
    }
    for (int i = 0; i < 128; i++)
    {
        ms_channel[i] = 0;
        ms_channel_amp[i] = 0;
    }
    background(0);
    // initialize XYscope with default sound out
    ms_xy = new XYscope(this);
    //xy.getMixerInfo();
    ms_setup_star();
}


void draw_monophonic_synth() {
    strokeWeight(2);
    background(0);
    ms_xy.clearWaves();
    ms_t = millis() / 1000.0;
    ms_t = 1;
    //loadPixels();
    if (ms_activated_channels > 0)
    {
        ms_xy.freq(ms_channel[ms_period % ms_activated_channels]);
        ms_xy.amp(ms_channel_amp[ms_period % ms_activated_channels]);
    } else
        ms_xy.freq(0);
    for (int i = 0; i < ms_n_point; i++)
    {
        ms_x[i] = (-ms_rx[i] * ms_rx[i] + ms_rx[i] + ms_ry[i]) * (cos(ms_t) * 500) + width/2;
        ms_y[i] = (ms_rx[i] * (ms_rx[i] - ms_ry[i]) * ms_ry[i] - ms_rx[i] * ms_ry[i] + ms_ry[i]) * (sin(ms_t) * 500) * (cos(ms_rx[i]) * ms_rx[i]) + ms_ry[i] + height/2;
    }
    for (int i = 0; i < ms_activated_channels; i++)
    {
        for (int j = 127; j > 127 - ms_n_point; j--)
        {
            ms_xy.ellipse(map(ms_chan_index[i], 0, 120, 0, width), height / 2, j, j);
            ms_xy.ellipse(map(ms_chan_index[i], 0, 120, 0, width), map(ms_chan_index[i], 0, 120, 0, height), j, j);
            if (ms_rect_circle > 84)
            {
            ms_xy.rect(map(ms_chan_index[i], 0, 120, 0, width), 0, j / 2, j / 2);
            ms_xy.ellipse(map(ms_chan_index[i], 0, 120, 0, width), 0.66f * height, j / 2, j / 2);
            }
            else if (ms_rect_circle > 42)
                ms_xy.rect(map(ms_chan_index[i], 0, 120, 0, width), height/ 2, j / 2, j / 2);
            else
                ms_xy.ellipse(map(ms_chan_index[i], 0, 120, 0, width),  height /2, j / 2, j / 2);

        }
    }


    //updatePixels();
    // build audio from shapes
    ms_xy.buildWaves();

    // draw all analytics
    ms_xy.drawAll();
    ms_period++;
    ms_manage_star();
}

void keyPressed() {
    if (keyCode == DOWN) { // DELETE
        ms_xy.clearWaves();
    }
}
