// generated by Fast Light User Interface Designer (fluid) version 1.0300

#include "fabla.h"

void FablaUI::cb_w_i(Fl_Double_Window* o, void*) {
  close_cb( o, 0 );
}
void FablaUI::cb_w(Fl_Double_Window* o, void* v) {
  ((FablaUI*)(o->user_data()))->cb_w_i(o,v);
}

void FablaUI::cb_compressor_i(Compressor* o, void*) {
  if ( o->mouseRightClicked )
{
  float tmp = 0.0f;
  if ( o->active )
    tmp = 1.f;
  writeFunction(controller, COMP_ENABLE, sizeof(float), 0, (const void*) &tmp);
}
else
{
  float tmp = o->getMakeup();
  writeFunction(controller, COMP_MAKEUP, sizeof(float), 0, (const void*) &tmp);
};
}
void FablaUI::cb_compressor(Compressor* o, void* v) {
  ((FablaUI*)(o->parent()->user_data()))->cb_compressor_i(o,v);
}

void FablaUI::cb_masterVol_i(Volume* o, void*) {
  float tmp = o->value();
writeFunction(controller, MASTER_VOL, sizeof(float), 0, (const void*) &tmp);
}
void FablaUI::cb_masterVol(Volume* o, void* v) {
  ((FablaUI*)(o->parent()->user_data()))->cb_masterVol_i(o,v);
}

void FablaUI::cb_compRelease_i(Dial* o, void*) {
  float tmp = o->value();
//compressor->release( tmp );
writeFunction(controller, COMP_DECAY, sizeof(float), 0, (const void*) &tmp);
}
void FablaUI::cb_compRelease(Dial* o, void* v) {
  ((FablaUI*)(o->parent()->user_data()))->cb_compRelease_i(o,v);
}

void FablaUI::cb_p13_i(Pad* o, void*) {
  pad_click( o->ID(), o->mouseRightClicked );
}
void FablaUI::cb_p13(Pad* o, void* v) {
  ((FablaUI*)(o->parent()->user_data()))->cb_p13_i(o,v);
}

void FablaUI::cb_p14_i(Pad* o, void*) {
  pad_click( o->ID(), o->mouseRightClicked );
}
void FablaUI::cb_p14(Pad* o, void* v) {
  ((FablaUI*)(o->parent()->user_data()))->cb_p14_i(o,v);
}

void FablaUI::cb_p15_i(Pad* o, void*) {
  pad_click( o->ID(), o->mouseRightClicked );
}
void FablaUI::cb_p15(Pad* o, void* v) {
  ((FablaUI*)(o->parent()->user_data()))->cb_p15_i(o,v);
}

void FablaUI::cb_p16_i(Pad* o, void*) {
  pad_click( o->ID(), o->mouseRightClicked );
}
void FablaUI::cb_p16(Pad* o, void* v) {
  ((FablaUI*)(o->parent()->user_data()))->cb_p16_i(o,v);
}

void FablaUI::cb_p9_i(Pad* o, void*) {
  pad_click( o->ID(), o->mouseRightClicked );
}
void FablaUI::cb_p9(Pad* o, void* v) {
  ((FablaUI*)(o->parent()->user_data()))->cb_p9_i(o,v);
}

void FablaUI::cb_p5_i(Pad* o, void*) {
  pad_click( o->ID(), o->mouseRightClicked );
}
void FablaUI::cb_p5(Pad* o, void* v) {
  ((FablaUI*)(o->parent()->user_data()))->cb_p5_i(o,v);
}

void FablaUI::cb_p1_i(Pad* o, void*) {
  pad_click( o->ID(), o->mouseRightClicked );
}
void FablaUI::cb_p1(Pad* o, void* v) {
  ((FablaUI*)(o->parent()->user_data()))->cb_p1_i(o,v);
}

void FablaUI::cb_p10_i(Pad* o, void*) {
  pad_click( o->ID(), o->mouseRightClicked );
}
void FablaUI::cb_p10(Pad* o, void* v) {
  ((FablaUI*)(o->parent()->user_data()))->cb_p10_i(o,v);
}

void FablaUI::cb_p6_i(Pad* o, void*) {
  pad_click( o->ID(), o->mouseRightClicked );
}
void FablaUI::cb_p6(Pad* o, void* v) {
  ((FablaUI*)(o->parent()->user_data()))->cb_p6_i(o,v);
}

void FablaUI::cb_p2_i(Pad* o, void*) {
  pad_click( o->ID(), o->mouseRightClicked );
}
void FablaUI::cb_p2(Pad* o, void* v) {
  ((FablaUI*)(o->parent()->user_data()))->cb_p2_i(o,v);
}

void FablaUI::cb_p11_i(Pad* o, void*) {
  pad_click( o->ID(), o->mouseRightClicked );
}
void FablaUI::cb_p11(Pad* o, void* v) {
  ((FablaUI*)(o->parent()->user_data()))->cb_p11_i(o,v);
}

void FablaUI::cb_p7_i(Pad* o, void*) {
  pad_click( o->ID(), o->mouseRightClicked );
}
void FablaUI::cb_p7(Pad* o, void* v) {
  ((FablaUI*)(o->parent()->user_data()))->cb_p7_i(o,v);
}

void FablaUI::cb_p3_i(Pad* o, void*) {
  pad_click( o->ID(), o->mouseRightClicked );
}
void FablaUI::cb_p3(Pad* o, void* v) {
  ((FablaUI*)(o->parent()->user_data()))->cb_p3_i(o,v);
}

void FablaUI::cb_p12_i(Pad* o, void*) {
  pad_click( o->ID(), o->mouseRightClicked );
}
void FablaUI::cb_p12(Pad* o, void* v) {
  ((FablaUI*)(o->parent()->user_data()))->cb_p12_i(o,v);
}

void FablaUI::cb_p8_i(Pad* o, void*) {
  pad_click( o->ID(), o->mouseRightClicked );
}
void FablaUI::cb_p8(Pad* o, void* v) {
  ((FablaUI*)(o->parent()->user_data()))->cb_p8_i(o,v);
}

void FablaUI::cb_p4_i(Pad* o, void*) {
  pad_click( o->ID(), o->mouseRightClicked );
}
void FablaUI::cb_p4(Pad* o, void* v) {
  ((FablaUI*)(o->parent()->user_data()))->cb_p4_i(o,v);
}

void FablaUI::cb_compAttack_i(Dial* o, void*) {
  float tmp = o->value();
//compressor->attack( tmp );
writeFunction(controller, COMP_ATTACK, sizeof(float), 0, (const void*) &tmp);
}
void FablaUI::cb_compAttack(Dial* o, void* v) {
  ((FablaUI*)(o->parent()->user_data()))->cb_compAttack_i(o,v);
}

void FablaUI::cb_compThres_i(Dial* o, void*) {
  float tmp = o->value();
compressor->threshold( tmp );
writeFunction(controller, COMP_THRES, sizeof(float), 0, (const void*) &tmp);
}
void FablaUI::cb_compThres(Dial* o, void* v) {
  ((FablaUI*)(o->parent()->user_data()))->cb_compThres_i(o,v);
}

void FablaUI::cb_compRatio_i(Dial* o, void*) {
  float tmp = o->value();
compressor->ratio( tmp );
writeFunction(controller, COMP_RATIO, sizeof(float), 0, (const void*) &tmp);
}
void FablaUI::cb_compRatio(Dial* o, void* v) {
  ((FablaUI*)(o->parent()->user_data()))->cb_compRatio_i(o,v);
}

void FablaUI::cb_gain_i(Dial* o, void*) {
  float tmp = o->value();
int port = int(PAD_GAIN) + selectedPad;
padData[selectedPad].gain = tmp;
writeFunction(controller, port, sizeof(float), 0, (const void*) &tmp);
//printf("gain on pad# %i, port# %i, value %f\n", selectedPad, port, tmp);
}
void FablaUI::cb_gain(Dial* o, void* v) {
  ((FablaUI*)(o->parent()->user_data()))->cb_gain_i(o,v);
}

void FablaUI::cb_d_i(Dial* o, void*) {
  adsr->decay( o->value() );

float tmp = o->value();
int port = int(PAD_DECAY) + selectedPad;
padData[selectedPad].d = tmp;
writeFunction(controller, port, sizeof(float), 0, (const void*) &tmp);
printf("decay on pad# %i, port# %i, value %f\n", selectedPad, port, tmp);
}
void FablaUI::cb_d(Dial* o, void* v) {
  ((FablaUI*)(o->parent()->user_data()))->cb_d_i(o,v);
}

void FablaUI::cb_speed_i(Dial* o, void*) {
  float tmp = o->value();
int port = int(PAD_SPEED) + selectedPad;
padData[selectedPad].speed = tmp;
writeFunction(controller, port, sizeof(float), 0, (const void*) &tmp);
printf("speed on pad# %i, port# %i, value %f\n", selectedPad, port, tmp);
}
void FablaUI::cb_speed(Dial* o, void* v) {
  ((FablaUI*)(o->parent()->user_data()))->cb_speed_i(o,v);
}

void FablaUI::cb_a_i(Dial* o, void*) {
  adsr->attack( o->value() );

float tmp = o->value();
int port = int(PAD_ATTACK) + selectedPad;
padData[selectedPad].a = tmp;
writeFunction(controller, port, sizeof(float), 0, (const void*) &tmp);
printf("attack on pad# %i, port# %i, value %f\n", selectedPad, port, tmp);
}
void FablaUI::cb_a(Dial* o, void* v) {
  ((FablaUI*)(o->parent()->user_data()))->cb_a_i(o,v);
}

void FablaUI::cb_r_i(Dial* o, void*) {
  adsr->release( o->value() );

float tmp = o->value();
int port = int(PAD_RELEASE) + selectedPad;
padData[selectedPad].r = tmp;
writeFunction(controller, port, sizeof(float), 0, (const void*) &tmp);
printf("release on pad# %i, port# %i, value %f\n", selectedPad, port, tmp);
}
void FablaUI::cb_r(Dial* o, void* v) {
  ((FablaUI*)(o->parent()->user_data()))->cb_r_i(o,v);
}

void FablaUI::cb_s_i(Dial* o, void*) {
  adsr->sustain( o->value() );

float tmp = o->value();
int port = int(PAD_SUSTAIN) + selectedPad;
padData[selectedPad].s = tmp;
writeFunction(controller, port, sizeof(float), 0, (const void*) &tmp);
printf("sustain on pad# %i, port# %i, value %f\n", selectedPad, port, tmp);
}
void FablaUI::cb_s(Dial* o, void* v) {
  ((FablaUI*)(o->parent()->user_data()))->cb_s_i(o,v);
}

void FablaUI::cb_pan_i(Dial* o, void*) {
  float tmp = o->value();
int port = int(PAD_PAN) + selectedPad;
padData[selectedPad].pan = tmp;
writeFunction(controller, port, sizeof(float), 0, (const void*) &tmp);
printf("pan on pad# %i, port# %i, value %f\n", selectedPad, port, tmp);
}
void FablaUI::cb_pan(Dial* o, void* v) {
  ((FablaUI*)(o->parent()->user_data()))->cb_pan_i(o,v);
}

FablaUI::FablaUI() {
  setupUI();
  w->show();
}

FablaUI::FablaUI(void* xParentWindow, Fabla* f) {
  setupUI();
  fabla = f;
  
  // embed drawn stuff into LV2 host provided area  
  fl_embed( w, (Window)xParentWindow );
}

Fl_Double_Window* FablaUI::setupUI() {
  // In case FLTK hasn't set up yet
  fl_open_display();
  
  lastUsedPath = getenv("HOME");
  
  selectedPad = 0;
  { w = new Fl_Double_Window(515, 490, "Fabla");
    w->box(FL_UP_BOX);
    w->color( fl_rgb_color( 10, 10, 10 ) );
    w->selection_color(FL_FOREGROUND_COLOR);
    w->labelcolor(FL_RED);
    w->callback((Fl_Callback*)cb_w, (void*)(this));
    { Background* o = new Background(346, 41, 159, 215, "Source");
      o->box(FL_UP_BOX);
      o->color(FL_BACKGROUND_COLOR);
      o->selection_color(FL_BACKGROUND_COLOR);
      o->labeltype(FL_NORMAL_LABEL);
      o->labelfont(0);
      o->labelsize(14);
      o->labelcolor(FL_FOREGROUND_COLOR);
      o->align(Fl_Align(FL_ALIGN_CENTER));
      o->when(FL_WHEN_RELEASE);
    } // Background* o
    { adsr = new ADSR(351, 66, 150, 84);
      adsr->box(FL_UP_BOX);
      adsr->color(FL_BACKGROUND_COLOR);
      adsr->selection_color(FL_BACKGROUND_COLOR);
      adsr->labeltype(FL_NORMAL_LABEL);
      adsr->labelfont(0);
      adsr->labelsize(14);
      adsr->labelcolor(FL_FOREGROUND_COLOR);
      adsr->align(Fl_Align(FL_ALIGN_CENTER));
      adsr->when(FL_WHEN_RELEASE);
      adsr->attack(0); adsr->decay(0.5);
      adsr->sustain(1); adsr->release(0.5);
    } // ADSR* adsr
    { Background* o = new Background(346, 265, 159, 215, "Master");
      o->box(FL_UP_BOX);
      o->color(FL_BACKGROUND_COLOR);
      o->selection_color(FL_BACKGROUND_COLOR);
      o->labeltype(FL_NORMAL_LABEL);
      o->labelfont(0);
      o->labelsize(14);
      o->labelcolor(FL_FOREGROUND_COLOR);
      o->align(Fl_Align(FL_ALIGN_CENTER));
      o->when(FL_WHEN_RELEASE);
    } // Background* o
    { compressor = new Compressor(352, 290, 97, 84, "Compressor");
      compressor->box(FL_UP_BOX);
      compressor->color(FL_BACKGROUND_COLOR);
      compressor->selection_color(FL_BACKGROUND_COLOR);
      compressor->labeltype(FL_NORMAL_LABEL);
      compressor->labelfont(0);
      compressor->labelsize(14);
      compressor->labelcolor(FL_FOREGROUND_COLOR);
      compressor->callback((Fl_Callback*)cb_compressor);
      compressor->align(Fl_Align(FL_ALIGN_CENTER));
      compressor->when(FL_WHEN_RELEASE);
      compressor->set_active( false );
    } // Compressor* compressor
    { compressorBox = new Fl_Box(351, 379, 97, 97);
      compressorBox->box(FL_BORDER_BOX);
      compressorBox->color( fl_rgb_color( 10, 10, 10 ) );
    } // Fl_Box* compressorBox
    { masterVol = new Volume(453, 290, 48, 186, "Vol");
      masterVol->box(FL_UP_BOX);
      masterVol->color(FL_BACKGROUND_COLOR);
      masterVol->selection_color(FL_BACKGROUND_COLOR);
      masterVol->labeltype(FL_NORMAL_LABEL);
      masterVol->labelfont(0);
      masterVol->labelsize(14);
      masterVol->labelcolor(FL_FOREGROUND_COLOR);
      masterVol->callback((Fl_Callback*)cb_masterVol);
      masterVol->align(Fl_Align(FL_ALIGN_CENTER));
      masterVol->when(FL_WHEN_RELEASE);
    } // Volume* masterVol
    { adsrBox = new Fl_Box(350, 155, 150, 98);
      adsrBox->box(FL_BORDER_BOX);
      adsrBox->color( fl_rgb_color( 10, 10, 10 ) );
    } // Fl_Box* adsrBox
    { compRelease = new Dial(406, 435, 30, 30, "Rel");
      compRelease->box(FL_UP_BOX);
      compRelease->color((Fl_Color)48);
      compRelease->selection_color(FL_BACKGROUND_COLOR);
      compRelease->labeltype(FL_NORMAL_LABEL);
      compRelease->labelfont(0);
      compRelease->labelsize(14);
      compRelease->labelcolor(FL_LIGHT3);
      compRelease->callback((Fl_Callback*)cb_compRelease);
      compRelease->align(Fl_Align(FL_ALIGN_CENTER));
      compRelease->when(FL_WHEN_RELEASE);
      compRelease->defaultValue(0.3);
    } // Dial* compRelease
    { Background* o = new Background(9, 41, 330, 132, "Waveform");
      o->box(FL_UP_BOX);
      o->color(FL_BACKGROUND_COLOR);
      o->selection_color(FL_BACKGROUND_COLOR);
      o->labeltype(FL_NORMAL_LABEL);
      o->labelfont(0);
      o->labelsize(14);
      o->labelcolor(FL_FOREGROUND_COLOR);
      o->align(Fl_Align(FL_ALIGN_CENTER));
      o->when(FL_WHEN_RELEASE);
    } // Background* o
    { Background* o = new Background(9, 180, 330, 300, "Pads");
      o->box(FL_UP_BOX);
      o->color(FL_BACKGROUND_COLOR);
      o->selection_color(FL_BACKGROUND_COLOR);
      o->labeltype(FL_NORMAL_LABEL);
      o->labelfont(0);
      o->labelsize(14);
      o->labelcolor(FL_FOREGROUND_COLOR);
      o->align(Fl_Align(FL_ALIGN_CENTER));
      o->when(FL_WHEN_RELEASE);
    } // Background* o
    { waveform = new Waveform(11, 64, 324, 107);
      waveform->box(FL_UP_BOX);
      waveform->color(FL_BACKGROUND_COLOR);
      waveform->selection_color(FL_BACKGROUND_COLOR);
      waveform->labeltype(FL_NORMAL_LABEL);
      waveform->labelfont(0);
      waveform->labelsize(14);
      waveform->labelcolor(FL_FOREGROUND_COLOR);
      waveform->align(Fl_Align(FL_ALIGN_CENTER));
      waveform->when(FL_WHEN_RELEASE);
    } // Waveform* waveform
    { image = new Image(0, 0, 515, 36, "header image");
      image->box(FL_UP_BOX);
      image->color(FL_BACKGROUND_COLOR);
      image->selection_color(FL_BACKGROUND_COLOR);
      image->labeltype(FL_NORMAL_LABEL);
      image->labelfont(0);
      image->labelsize(14);
      image->labelcolor(FL_FOREGROUND_COLOR);
      image->align(Fl_Align(FL_ALIGN_CENTER));
      image->when(FL_WHEN_RELEASE);
      image->setPixbuf(header.pixel_data,4);
    } // Image* image
    { p13 = new Pad(15, 205, 75, 64, "13");
      p13->box(FL_BORDER_BOX);
      p13->color(FL_BACKGROUND_COLOR);
      p13->selection_color(FL_BACKGROUND_COLOR);
      p13->labeltype(FL_NORMAL_LABEL);
      p13->labelfont(1);
      p13->labelsize(14);
      p13->labelcolor(FL_LIGHT3);
      p13->callback((Fl_Callback*)cb_p13);
      p13->align(Fl_Align(FL_ALIGN_CENTER));
      p13->when(FL_WHEN_RELEASE);
      p13->ID(12);
    } // Pad* p13
    { p14 = new Pad(97, 205, 75, 64, "14");
      p14->box(FL_BORDER_BOX);
      p14->color(FL_BACKGROUND_COLOR);
      p14->selection_color(FL_BACKGROUND_COLOR);
      p14->labeltype(FL_NORMAL_LABEL);
      p14->labelfont(1);
      p14->labelsize(14);
      p14->labelcolor(FL_LIGHT3);
      p14->callback((Fl_Callback*)cb_p14);
      p14->align(Fl_Align(FL_ALIGN_CENTER));
      p14->when(FL_WHEN_RELEASE);
      p14->ID(13);
    } // Pad* p14
    { p15 = new Pad(178, 205, 75, 64, "15");
      p15->box(FL_BORDER_BOX);
      p15->color(FL_BACKGROUND_COLOR);
      p15->selection_color(FL_BACKGROUND_COLOR);
      p15->labeltype(FL_NORMAL_LABEL);
      p15->labelfont(1);
      p15->labelsize(14);
      p15->labelcolor(FL_LIGHT3);
      p15->callback((Fl_Callback*)cb_p15);
      p15->align(Fl_Align(FL_ALIGN_CENTER));
      p15->when(FL_WHEN_RELEASE);
      p15->ID(14);
    } // Pad* p15
    { p16 = new Pad(259, 205, 75, 64, "16");
      p16->box(FL_BORDER_BOX);
      p16->color(FL_BACKGROUND_COLOR);
      p16->selection_color(FL_BACKGROUND_COLOR);
      p16->labeltype(FL_NORMAL_LABEL);
      p16->labelfont(1);
      p16->labelsize(14);
      p16->labelcolor(FL_LIGHT3);
      p16->callback((Fl_Callback*)cb_p16);
      p16->align(Fl_Align(FL_ALIGN_CENTER));
      p16->when(FL_WHEN_RELEASE);
      p16->ID(15);
    } // Pad* p16
    { p9 = new Pad(15, 273, 75, 64, "9");
      p9->box(FL_BORDER_BOX);
      p9->color(FL_BACKGROUND_COLOR);
      p9->selection_color(FL_BACKGROUND_COLOR);
      p9->labeltype(FL_NORMAL_LABEL);
      p9->labelfont(1);
      p9->labelsize(14);
      p9->labelcolor(FL_LIGHT3);
      p9->callback((Fl_Callback*)cb_p9);
      p9->align(Fl_Align(FL_ALIGN_CENTER));
      p9->when(FL_WHEN_RELEASE);
      p9->ID(8);
    } // Pad* p9
    { p5 = new Pad(15, 341, 75, 64, "5");
      p5->box(FL_BORDER_BOX);
      p5->color(FL_BACKGROUND_COLOR);
      p5->selection_color(FL_BACKGROUND_COLOR);
      p5->labeltype(FL_NORMAL_LABEL);
      p5->labelfont(1);
      p5->labelsize(14);
      p5->labelcolor(FL_LIGHT3);
      p5->callback((Fl_Callback*)cb_p5);
      p5->align(Fl_Align(FL_ALIGN_CENTER));
      p5->when(FL_WHEN_RELEASE);
      p5->ID(4);
    } // Pad* p5
    { p1 = new Pad(15, 411, 75, 64, "1");
      p1->box(FL_BORDER_BOX);
      p1->color(FL_BACKGROUND_COLOR);
      p1->selection_color(FL_BACKGROUND_COLOR);
      p1->labeltype(FL_NORMAL_LABEL);
      p1->labelfont(1);
      p1->labelsize(14);
      p1->labelcolor(FL_LIGHT3);
      p1->callback((Fl_Callback*)cb_p1);
      p1->align(Fl_Align(FL_ALIGN_CENTER));
      p1->when(FL_WHEN_RELEASE);
      p1->selected(true);
      p1->ID(0);
    } // Pad* p1
    { p10 = new Pad(97, 273, 75, 64, "10");
      p10->box(FL_BORDER_BOX);
      p10->color(FL_BACKGROUND_COLOR);
      p10->selection_color(FL_BACKGROUND_COLOR);
      p10->labeltype(FL_NORMAL_LABEL);
      p10->labelfont(1);
      p10->labelsize(14);
      p10->labelcolor(FL_LIGHT3);
      p10->callback((Fl_Callback*)cb_p10);
      p10->align(Fl_Align(FL_ALIGN_CENTER));
      p10->when(FL_WHEN_RELEASE);
      p10->ID(9);
    } // Pad* p10
    { p6 = new Pad(97, 341, 75, 64, "6");
      p6->box(FL_BORDER_BOX);
      p6->color(FL_BACKGROUND_COLOR);
      p6->selection_color(FL_BACKGROUND_COLOR);
      p6->labeltype(FL_NORMAL_LABEL);
      p6->labelfont(1);
      p6->labelsize(14);
      p6->labelcolor(FL_LIGHT3);
      p6->callback((Fl_Callback*)cb_p6);
      p6->align(Fl_Align(FL_ALIGN_CENTER));
      p6->when(FL_WHEN_RELEASE);
      p6->ID(5);
    } // Pad* p6
    { p2 = new Pad(97, 411, 75, 64, "2");
      p2->box(FL_BORDER_BOX);
      p2->color(FL_BACKGROUND_COLOR);
      p2->selection_color(FL_BACKGROUND_COLOR);
      p2->labeltype(FL_NORMAL_LABEL);
      p2->labelfont(1);
      p2->labelsize(14);
      p2->labelcolor(FL_LIGHT3);
      p2->callback((Fl_Callback*)cb_p2);
      p2->align(Fl_Align(FL_ALIGN_CENTER));
      p2->when(FL_WHEN_RELEASE);
      p2->ID(1);
    } // Pad* p2
    { p11 = new Pad(178, 273, 75, 64, "11");
      p11->box(FL_BORDER_BOX);
      p11->color(FL_BACKGROUND_COLOR);
      p11->selection_color(FL_BACKGROUND_COLOR);
      p11->labeltype(FL_NORMAL_LABEL);
      p11->labelfont(1);
      p11->labelsize(14);
      p11->labelcolor(FL_LIGHT3);
      p11->callback((Fl_Callback*)cb_p11);
      p11->align(Fl_Align(FL_ALIGN_CENTER));
      p11->when(FL_WHEN_RELEASE);
      p11->ID(10);
    } // Pad* p11
    { p7 = new Pad(178, 341, 75, 64, "7");
      p7->box(FL_BORDER_BOX);
      p7->color(FL_BACKGROUND_COLOR);
      p7->selection_color(FL_BACKGROUND_COLOR);
      p7->labeltype(FL_NORMAL_LABEL);
      p7->labelfont(1);
      p7->labelsize(14);
      p7->labelcolor(FL_LIGHT3);
      p7->callback((Fl_Callback*)cb_p7);
      p7->align(Fl_Align(FL_ALIGN_CENTER));
      p7->when(FL_WHEN_RELEASE);
      p7->ID(6);
    } // Pad* p7
    { p3 = new Pad(178, 411, 75, 64, "3");
      p3->box(FL_BORDER_BOX);
      p3->color(FL_BACKGROUND_COLOR);
      p3->selection_color(FL_BACKGROUND_COLOR);
      p3->labeltype(FL_NORMAL_LABEL);
      p3->labelfont(1);
      p3->labelsize(14);
      p3->labelcolor(FL_LIGHT3);
      p3->callback((Fl_Callback*)cb_p3);
      p3->align(Fl_Align(FL_ALIGN_CENTER));
      p3->when(FL_WHEN_RELEASE);
      p3->ID(2);
    } // Pad* p3
    { p12 = new Pad(259, 273, 75, 64, "12");
      p12->box(FL_BORDER_BOX);
      p12->color(FL_BACKGROUND_COLOR);
      p12->selection_color(FL_BACKGROUND_COLOR);
      p12->labeltype(FL_NORMAL_LABEL);
      p12->labelfont(1);
      p12->labelsize(14);
      p12->labelcolor(FL_LIGHT3);
      p12->callback((Fl_Callback*)cb_p12);
      p12->align(Fl_Align(FL_ALIGN_CENTER));
      p12->when(FL_WHEN_RELEASE);
      p12->ID(11);
    } // Pad* p12
    { p8 = new Pad(259, 341, 75, 64, "8");
      p8->box(FL_BORDER_BOX);
      p8->color(FL_BACKGROUND_COLOR);
      p8->selection_color(FL_BACKGROUND_COLOR);
      p8->labeltype(FL_NORMAL_LABEL);
      p8->labelfont(1);
      p8->labelsize(14);
      p8->labelcolor(FL_LIGHT3);
      p8->callback((Fl_Callback*)cb_p8);
      p8->align(Fl_Align(FL_ALIGN_CENTER));
      p8->when(FL_WHEN_RELEASE);
      p8->ID(7);
    } // Pad* p8
    { p4 = new Pad(259, 411, 75, 64, "4");
      p4->box(FL_BORDER_BOX);
      p4->color(FL_BACKGROUND_COLOR);
      p4->selection_color(FL_BACKGROUND_COLOR);
      p4->labeltype(FL_NORMAL_LABEL);
      p4->labelfont(1);
      p4->labelsize(14);
      p4->labelcolor(FL_LIGHT3);
      p4->callback((Fl_Callback*)cb_p4);
      p4->align(Fl_Align(FL_ALIGN_CENTER));
      p4->when(FL_WHEN_RELEASE);
      p4->ID(3);
    } // Pad* p4
    { compAttack = new Dial(365, 435, 30, 30, "Atk");
      compAttack->box(FL_UP_BOX);
      compAttack->color((Fl_Color)48);
      compAttack->selection_color(FL_BACKGROUND_COLOR);
      compAttack->labeltype(FL_NORMAL_LABEL);
      compAttack->labelfont(0);
      compAttack->labelsize(14);
      compAttack->labelcolor(FL_LIGHT3);
      compAttack->callback((Fl_Callback*)cb_compAttack);
      compAttack->align(Fl_Align(FL_ALIGN_CENTER));
      compAttack->when(FL_WHEN_RELEASE);
      compAttack->defaultValue(0.1);
    } // Dial* compAttack
    { compThres = new Dial(406, 395, 30, 30, "Thres");
      compThres->box(FL_UP_BOX);
      compThres->color((Fl_Color)48);
      compThres->selection_color(FL_BACKGROUND_COLOR);
      compThres->labeltype(FL_NORMAL_LABEL);
      compThres->labelfont(0);
      compThres->labelsize(14);
      compThres->labelcolor(FL_LIGHT3);
      compThres->callback((Fl_Callback*)cb_compThres);
      compThres->align(Fl_Align(FL_ALIGN_CENTER));
      compThres->when(FL_WHEN_RELEASE);
      compThres->defaultValue(0.7);
    } // Dial* compThres
    { compRatio = new Dial(365, 395, 30, 30, "Ratio");
      compRatio->box(FL_UP_BOX);
      compRatio->color((Fl_Color)48);
      compRatio->selection_color(FL_BACKGROUND_COLOR);
      compRatio->labeltype(FL_NORMAL_LABEL);
      compRatio->labelfont(0);
      compRatio->labelsize(14);
      compRatio->labelcolor(FL_LIGHT3);
      compRatio->callback((Fl_Callback*)cb_compRatio);
      compRatio->align(Fl_Align(FL_ALIGN_CENTER));
      compRatio->when(FL_WHEN_RELEASE);
      compRatio->defaultValue(0.3);
    } // Dial* compRatio
    { gain = new Dial(357, 210, 38, 38, "VOL");
      gain->box(FL_UP_BOX);
      gain->color((Fl_Color)48);
      gain->selection_color(FL_BACKGROUND_COLOR);
      gain->labeltype(FL_NORMAL_LABEL);
      gain->labelfont(0);
      gain->labelsize(14);
      gain->labelcolor(FL_LIGHT3);
      gain->callback((Fl_Callback*)cb_gain);
      gain->align(Fl_Align(FL_ALIGN_CENTER));
      gain->when(FL_WHEN_RELEASE);
      gain->drawLabel(true);
      gain->value( 0.5 );
      gain->defaultValue(0.5);
    } // Dial* gain
    { d = new Dial(393, 170, 30, 30, "D");
      d->box(FL_UP_BOX);
      d->color((Fl_Color)48);
      d->selection_color(FL_BACKGROUND_COLOR);
      d->labeltype(FL_NORMAL_LABEL);
      d->labelfont(1);
      d->labelsize(14);
      d->labelcolor(FL_LIGHT3);
      d->callback((Fl_Callback*)cb_d);
      d->align(Fl_Align(FL_ALIGN_CENTER));
      d->when(FL_WHEN_RELEASE);
      d->defaultValue(0.5);
    } // Dial* d
    { speed = new Dial(408, 210, 38, 38, "SPD");
      speed->box(FL_UP_BOX);
      speed->color((Fl_Color)48);
      speed->selection_color(FL_BACKGROUND_COLOR);
      speed->labeltype(FL_NORMAL_LABEL);
      speed->labelfont(0);
      speed->labelsize(14);
      speed->labelcolor(FL_LIGHT3);
      speed->callback((Fl_Callback*)cb_speed);
      speed->align(Fl_Align(FL_ALIGN_CENTER));
      speed->when(FL_WHEN_RELEASE);
      speed->drawLabel(true);
      speed->value( 0.5 );
      speed->defaultValue(0.5);
    } // Dial* speed
    { a = new Dial(358, 170, 30, 30, "A");
      a->box(FL_UP_BOX);
      a->color((Fl_Color)48);
      a->selection_color(FL_BACKGROUND_COLOR);
      a->labeltype(FL_NORMAL_LABEL);
      a->labelfont(1);
      a->labelsize(14);
      a->labelcolor(FL_LIGHT3);
      a->callback((Fl_Callback*)cb_a);
      a->align(Fl_Align(FL_ALIGN_CENTER));
      a->when(FL_WHEN_RELEASE);
      a->defaultValue(0.0);
    } // Dial* a
    { r = new Dial(463, 170, 30, 30, "R");
      r->box(FL_UP_BOX);
      r->color((Fl_Color)48);
      r->selection_color(FL_BACKGROUND_COLOR);
      r->labeltype(FL_NORMAL_LABEL);
      r->labelfont(1);
      r->labelsize(14);
      r->labelcolor(FL_LIGHT3);
      r->callback((Fl_Callback*)cb_r);
      r->align(Fl_Align(FL_ALIGN_CENTER));
      r->when(FL_WHEN_RELEASE);
      r->defaultValue(0.5);
    } // Dial* r
    { s = new Dial(428, 170, 30, 30, "S");
      s->box(FL_UP_BOX);
      s->color((Fl_Color)48);
      s->selection_color(FL_BACKGROUND_COLOR);
      s->labeltype(FL_NORMAL_LABEL);
      s->labelfont(1);
      s->labelsize(14);
      s->labelcolor(FL_LIGHT3);
      s->callback((Fl_Callback*)cb_s);
      s->align(Fl_Align(FL_ALIGN_CENTER));
      s->when(FL_WHEN_RELEASE);
      s->value(1.0);
      s->defaultValue(1.f);
    } // Dial* s
    { pan = new Dial(455, 210, 38, 38, "PAN");
      pan->box(FL_UP_BOX);
      pan->color((Fl_Color)48);
      pan->selection_color(FL_BACKGROUND_COLOR);
      pan->labeltype(FL_NORMAL_LABEL);
      pan->labelfont(0);
      pan->labelsize(14);
      pan->labelcolor(FL_LIGHT3);
      pan->callback((Fl_Callback*)cb_pan);
      pan->align(Fl_Align(FL_ALIGN_CENTER));
      pan->when(FL_WHEN_RELEASE);
      pan->drawLabel(true);
      pan->value( 0.5 );
      pan->defaultValue(0.5);
    } // Dial* pan
    w->end();
  } // Fl_Double_Window* w
  return w;
}

void FablaUI::idle() {
  // takes care of handling events
  Fl::check();
  Fl::flush();
}

void FablaUI::select_pad(int p) {
  switch(selectedPad + 1)
  {
    case 1:  p1->selected(false);  break;
    case 2:  p2->selected(false);  break;
    case 3:  p3->selected(false);  break;
    case 4:  p4->selected(false);  break;
    case 5:  p5->selected(false);  break;
    case 6:  p6->selected(false);  break;
    case 7:  p7->selected(false);  break;
    case 8:  p8->selected(false);  break;
    case 9:  p9->selected(false);  break;
    case 10: p10->selected(false); break;
    case 11: p11->selected(false); break;
    case 12: p12->selected(false); break;
    case 13: p13->selected(false); break;
    case 14: p14->selected(false); break;
    case 15: p15->selected(false); break;
    case 16: p16->selected(false); break;
    default: printf("unknown pad");
  }
  
  selectedPad = p;
  switch(selectedPad+1)
  {
    case 1:  p1->selected(true);  break;
    case 2:  p2->selected(true);  break;
    case 3:  p3->selected(true);  break;
    case 4:  p4->selected(true);  break;
    case 5:  p5->selected(true);  break;
    case 6:  p6->selected(true);  break;
    case 7:  p7->selected(true);  break;
    case 8:  p8->selected(true);  break;
    case 9:  p9->selected(true);  break;
    case 10: p10->selected(true); break;
    case 11: p11->selected(true); break;
    case 12: p12->selected(true); break;
    case 13: p13->selected(true); break;
    case 14: p14->selected(true); break;
    case 15: p15->selected(true); break;
    case 16: p16->selected(true); break;
    default: printf("unknown pad");
  }
  
  // set dial values
  gain->value( padData[selectedPad].gain );
  speed->value( padData[selectedPad].speed );
  pan->value( padData[selectedPad].pan );
  
  a->value( padData[selectedPad].a );
  d->value( padData[selectedPad].d );
  s->value( padData[selectedPad].s );
  r->value( padData[selectedPad].r );
  
  // set ADSR values
  adsr->attack ( a->value() );
  adsr->decay  ( d->value() );
  adsr->sustain( s->value() );
  adsr->release( r->value() );
  
  // set Waveform to draw new data
  if ( padData[selectedPad].loaded )
  {
    waveform->setData( UI_WAVEFORM_PIXELS, padData[selectedPad].waveformLength, padData[selectedPad].waveform, padData[selectedPad].name );
  }
  else
  {
    waveform->setData( 0, 0, 0, "" );
  }
}

void FablaUI::pad_click(int id, int rclick) {
  //printf("pad %i clicked, right = %i\n", id, rclick);
  
  if ( rclick )
  {
    // pop up "load sample" dialog, write Atom event to DSP
    
    /*
    Fl_File_Chooser* fnfc = new Fl_File_Chooser( getenv("HOME"),
    			"Wav\t*.wav",
    			0, // single file select
    			"Load Sample" );
    
    fnfc->show();
    printf("shown");
    while( fnfc->shown() )
    {
      printf("waiting...");
      Fl::wait();
      printf("waiting 2");
    }
    printf("done");
    const char* filename = fnfc->value();
    char * filename = fl_file_chooser ("Load Sample", "Wav\t*.wav", NULL, 0);
    
    if ( filename )
    {
      printf("Loading directory: %s\n", filename);    
      writeLoadSample(fabla, id, filename, strlen(filename) );
      free( (void*)filename );
    }
    //delete fnfc;
    */
    
    // pop up "load sample" dialog, write Atom event to DSP
    
    Fl_Native_File_Chooser fnfc;
    fnfc.title("Load Sample");
    fnfc.type(Fl_Native_File_Chooser::BROWSE_FILE);
    fnfc.filter("Audio\t{*.aiff,*.wav,*.flac}");
    fnfc.directory( lastUsedPath.c_str() );
    
    switch ( fnfc.show() )
    {
      case -1: printf("ERROR: %s\\n", fnfc.errmsg());    break;  // ERROR
      case  1: printf("CANCEL\\n");                      break;  // CANCEL
      default:
      {
        char* filename = strdup( fnfc.filename() );
        //printf("Loading directory: %s, %s\n", fnfc.filename(), dirname( filename ) );
        
        writeLoadSample(fabla, id, fnfc.filename(), strlen( fnfc.filename() ));
        lastUsedPath = dirname(filename);
        free (filename);
      }
      break;
   }
    
  }
  else
  {
    // write pad play Atom to DSP
    writePadPlay( fabla, id );
    
    // update the UI showing the ADSR / waveform of this pad
    select_pad( id );
  }
}

void FablaUI::close_cb(Fl_Widget* o, void*) {
  if ((Fl::event() == FL_KEYDOWN || Fl::event() == FL_SHORTCUT) && Fl::event_key() == FL_Escape)
    {
      return; // ignore ESC
    }
    else
    {
      o->hide();
    }
}
