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

#include "LFOUI.h"
// LFOUI.cc
// Original ZynAddSubFX author Nasca Octavian Paul
// Copyright (C) 2002-2005 Nasca Octavian Paul
// Copyright 2009, Alan Calvert
// Copyright 2017-2020, Will Godfrey & others

// This file is part of yoshimi, which is free software: you can redistribute
// it and/or modify it under the terms of the GNU General Public
// License as published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.

// yoshimi is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE.   See the GNU General Public License (version 2 or
// later) for more details.

// You should have received a copy of the GNU General Public License along with
// yoshimi; if not, write to the Free Software Foundation, Inc., 51 Franklin
// Street, Fifth Floor, Boston, MA  02110-1301, USA.

// This file is a derivative of the ZynAddSubFX original


#include "MasterUI.h"

void LFOUI::cb_bpm_i(Fl_Check_Button2* o, void*) {
  send_data(0, group, LFOINSERT::control::bpm, o->value(), TOPLEVEL::type::Integer);
updateLFOFreqType();
updateBpmControls();
}
void LFOUI::cb_bpm(Fl_Check_Button2* o, void* v) {
  ((LFOUI*)(o->parent()->parent()->user_data()))->cb_bpm_i(o,v);
}

void LFOUI::cb_continous_i(Fl_Check_Button2* o, void*) {
  //
          send_data(0, group, LFOINSERT::control::continuous, o->value(), TOPLEVEL::type::Integer);
}
void LFOUI::cb_continous(Fl_Check_Button2* o, void* v) {
  ((LFOUI*)(o->parent()->parent()->user_data()))->cb_continous_i(o,v);
}

void LFOUI::cb_freq_i(WidgetPDial* o, void*) {
  //
          send_data(0, group, LFOINSERT::control::speed, o->value(), 0);
}
void LFOUI::cb_freq(WidgetPDial* o, void* v) {
  ((LFOUI*)(o->parent()->parent()->user_data()))->cb_freq_i(o,v);
}

void LFOUI::cb_intensity_i(WidgetPDial* o, void*) {
  //
          int depth = lrint(o->value());
          if (engine >= PART::engine::addVoice1 && engine < PART::engine::addMod1 && group == 1) // special case to sync voice list vibrato
              synth->getGuiMaster()->partui->adnoteui->voicelistitem[engine - PART::engine::addVoice1]->voicelistvibratto->value(depth);
          send_data(0, group, LFOINSERT::control::depth, depth, TOPLEVEL::type::Integer);
}
void LFOUI::cb_intensity(WidgetPDial* o, void* v) {
  ((LFOUI*)(o->parent()->parent()->user_data()))->cb_intensity_i(o,v);
}

void LFOUI::cb_delay_i(WidgetPDial* o, void*) {
  //
          send_data(0, group, LFOINSERT::control::delay, o->value(), TOPLEVEL::type::Integer);
}
void LFOUI::cb_delay(WidgetPDial* o, void* v) {
  ((LFOUI*)(o->parent()->parent()->user_data()))->cb_delay_i(o,v);
}

void LFOUI::cb_startphase_i(WidgetPDial* o, void*) {
  //
          send_data(0, group, LFOINSERT::control::start, o->value(), TOPLEVEL::type::Integer);
}
void LFOUI::cb_startphase(WidgetPDial* o, void* v) {
  ((LFOUI*)(o->parent()->parent()->user_data()))->cb_startphase_i(o,v);
}

void LFOUI::cb_LFOtype_i(Fl_Choice* o, void*) {
  //
          send_data(0, group, LFOINSERT::control::type, o->value(), TOPLEVEL::type::Integer);
}
void LFOUI::cb_LFOtype(Fl_Choice* o, void* v) {
  ((LFOUI*)(o->parent()->parent()->user_data()))->cb_LFOtype_i(o,v);
}

void LFOUI::cb_randomness_i(WidgetPDial* o, void*) {
  //
          send_data(0, group, LFOINSERT::control::amplitudeRandomness, o->value(), TOPLEVEL::type::Integer);
}
void LFOUI::cb_randomness(WidgetPDial* o, void* v) {
  ((LFOUI*)(o->parent()->parent()->user_data()))->cb_randomness_i(o,v);
}

void LFOUI::cb_freqrand_i(WidgetPDial* o, void*) {
  //
          send_data(0, group, LFOINSERT::control::frequencyRandomness, o->value(), TOPLEVEL::type::Integer);
}
void LFOUI::cb_freqrand(WidgetPDial* o, void* v) {
  ((LFOUI*)(o->parent()->parent()->user_data()))->cb_freqrand_i(o,v);
}

void LFOUI::cb_stretch_i(WidgetPDial* o, void*) {
  //
          send_data(0, group, LFOINSERT::control::stretch, o->value(), TOPLEVEL::type::Integer);
}
void LFOUI::cb_stretch(WidgetPDial* o, void* v) {
  ((LFOUI*)(o->parent()->parent()->user_data()))->cb_stretch_i(o,v);
}

void LFOUI::cb_lfoC_i(Fl_Button*, void*) {
  //
          synth->getGuiMaster()->getPresetsUi()->copy(pars);
}
void LFOUI::cb_lfoC(Fl_Button* o, void* v) {
  ((LFOUI*)(o->parent()->parent()->user_data()))->cb_lfoC_i(o,v);
}

void LFOUI::cb_lfoP_i(Fl_Button*, void*) {
  //
          synth->getGuiMaster()->getPresetsUi()->paste(pars,this);
}
void LFOUI::cb_lfoP(Fl_Button* o, void* v) {
  ((LFOUI*)(o->parent()->parent()->user_data()))->cb_lfoP_i(o,v);
}

LFOUI::LFOUI(int x,int y, int w, int h, const char *label):Fl_Group(x,y,w,h,label) {
  synth = NULL;
  pars=NULL;
}

LFOUI::~LFOUI() {
  lfoui->hide();
      hide();
}

Fl_Group* LFOUI::make_window() {
  { lfoui = new Fl_Group(0, 0, 275, 70);
    lfoui->box(FL_FLAT_BOX);
    lfoui->color(FL_LIGHT1);
    lfoui->selection_color(FL_BACKGROUND_COLOR);
    lfoui->labeltype(FL_NO_LABEL);
    lfoui->labelfont(1);
    lfoui->labelsize(12);
    lfoui->labelcolor(FL_FOREGROUND_COLOR);
    lfoui->user_data((void*)(this));
    lfoui->align(Fl_Align(FL_ALIGN_TOP));
    lfoui->when(FL_WHEN_RELEASE);
    { lfoparamswindow = new Fl_Group(0, 0, 275, 70, "LFO");
      lfoparamswindow->box(FL_PLASTIC_UP_BOX);
      lfoparamswindow->color(FL_CYAN);
      lfoparamswindow->labelfont(1);
      lfoparamswindow->labelsize(10);
      lfoparamswindow->align(Fl_Align(FL_ALIGN_TOP|FL_ALIGN_INSIDE));
      { bpm = new Fl_Check_Button2(230, 5, 45, 15, "BPM");
        bpm->tooltip("Lock LFO frequency to a multiple of the BPM.");
        bpm->box(FL_NO_BOX);
        bpm->down_box(FL_DOWN_BOX);
        bpm->color(FL_BACKGROUND_COLOR);
        bpm->selection_color(FL_FOREGROUND_COLOR);
        bpm->labeltype(FL_NORMAL_LABEL);
        bpm->labelfont(0);
        bpm->labelsize(10);
        bpm->labelcolor(FL_FOREGROUND_COLOR);
        bpm->callback((Fl_Callback*)cb_bpm);
        bpm->align(Fl_Align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE));
        bpm->when(FL_WHEN_RELEASE);
      } // Fl_Check_Button2* bpm
      { continous = new Fl_Check_Button2(230, 20, 15, 15, "Cont.");
        continous->tooltip("Continuous LFO\n\nRun the LFO continuously even when the sound is not playing\
. If BPM is on, then the LFO phase will be locked to the song position.");
        continous->box(FL_NO_BOX);
        continous->down_box(FL_DOWN_BOX);
        continous->color(FL_BACKGROUND_COLOR);
        continous->selection_color(FL_FOREGROUND_COLOR);
        continous->labeltype(FL_NORMAL_LABEL);
        continous->labelfont(0);
        continous->labelsize(10);
        continous->labelcolor(FL_FOREGROUND_COLOR);
        continous->callback((Fl_Callback*)cb_continous);
        continous->align(Fl_Align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE));
        continous->when(FL_WHEN_RELEASE);
      } // Fl_Check_Button2* continous
      { freq = new WidgetPDial(5, 20, 30, 30, "Freq.");
        freq->tooltip("LFO Frequency");
        freq->box(FL_ROUND_UP_BOX);
        freq->color(FL_BACKGROUND_COLOR);
        freq->selection_color(FL_INACTIVE_COLOR);
        freq->labeltype(FL_NORMAL_LABEL);
        freq->labelfont(0);
        freq->labelsize(10);
        freq->labelcolor(FL_FOREGROUND_COLOR);
        freq->step(1e-05);
        freq->callback((Fl_Callback*)cb_freq);
        freq->align(Fl_Align(FL_ALIGN_BOTTOM));
        freq->when(FL_WHEN_CHANGED);
      } // WidgetPDial* freq
      { WidgetPDial* o = intensity = new WidgetPDial(40, 20, 30, 30, "Depth");
        intensity->tooltip("LFO Amount");
        intensity->box(FL_ROUND_UP_BOX);
        intensity->color(FL_BACKGROUND_COLOR);
        intensity->selection_color(FL_INACTIVE_COLOR);
        intensity->labeltype(FL_NORMAL_LABEL);
        intensity->labelfont(0);
        intensity->labelsize(10);
        intensity->labelcolor(FL_FOREGROUND_COLOR);
        intensity->maximum(127);
        intensity->step(1);
        intensity->callback((Fl_Callback*)cb_intensity);
        intensity->align(Fl_Align(FL_ALIGN_BOTTOM));
        intensity->when(FL_WHEN_CHANGED);
        o->setValueType(getLFOdepthType(group));
      } // WidgetPDial* intensity
      { WidgetPDial* o = delay = new WidgetPDial(110, 20, 30, 30, "Delay");
        delay->tooltip("LFO delay");
        delay->box(FL_ROUND_UP_BOX);
        delay->color(FL_BACKGROUND_COLOR);
        delay->selection_color(FL_INACTIVE_COLOR);
        delay->labeltype(FL_NORMAL_LABEL);
        delay->labelfont(0);
        delay->labelsize(10);
        delay->labelcolor(FL_FOREGROUND_COLOR);
        delay->maximum(127);
        delay->step(1);
        delay->callback((Fl_Callback*)cb_delay);
        delay->align(Fl_Align(FL_ALIGN_BOTTOM));
        delay->when(FL_WHEN_CHANGED);
        o->setValueType(VC_LFOdelay);
      } // WidgetPDial* delay
      { WidgetPDial* o = startphase = new WidgetPDial(75, 20, 30, 30, "Start");
        startphase->tooltip("LFO Startphase (leftmost is Random)");
        startphase->box(FL_ROUND_UP_BOX);
        startphase->color(FL_BACKGROUND_COLOR);
        startphase->selection_color(FL_INACTIVE_COLOR);
        startphase->labeltype(FL_NORMAL_LABEL);
        startphase->labelfont(0);
        startphase->labelsize(10);
        startphase->labelcolor(FL_FOREGROUND_COLOR);
        startphase->maximum(127);
        startphase->step(1);
        startphase->callback((Fl_Callback*)cb_startphase);
        startphase->align(Fl_Align(FL_ALIGN_BOTTOM));
        startphase->when(FL_WHEN_CHANGED);
        o->setValueType(pars->Pbpm ? VC_LFOstartphase : VC_LFOstartphaseRand);
      } // WidgetPDial* startphase
      { Fl_Choice* o = LFOtype = new Fl_Choice(220, 50, 50, 15, "Type");
        LFOtype->tooltip("LFO function");
        LFOtype->down_box(FL_BORDER_BOX);
        LFOtype->labelsize(9);
        LFOtype->textfont(1);
        LFOtype->textsize(10);
        LFOtype->callback((Fl_Callback*)cb_LFOtype);
        LFOtype->align(Fl_Align(FL_ALIGN_TOP));
        o->add("Sine");o->add("Tri");o->add("Squr");o->add("R.up");o->add("R.dn");o->add("E1dn");o->add("E2dn");o->add("S&&H");o->add("RSqU");o->add("RSqD");
      } // Fl_Choice* LFOtype
      { WidgetPDial* o = randomness = new WidgetPDial(145, 30, 20, 20, "Amp. ");
        randomness->tooltip("LFO Amplitude Randomness");
        randomness->box(FL_ROUND_UP_BOX);
        randomness->color(FL_BACKGROUND_COLOR);
        randomness->selection_color(FL_INACTIVE_COLOR);
        randomness->labeltype(FL_NORMAL_LABEL);
        randomness->labelfont(0);
        randomness->labelsize(10);
        randomness->labelcolor(FL_FOREGROUND_COLOR);
        randomness->maximum(127);
        randomness->step(1);
        randomness->callback((Fl_Callback*)cb_randomness);
        randomness->align(Fl_Align(FL_ALIGN_TOP));
        randomness->when(FL_WHEN_CHANGED);
        o->setValueType(VC_percent127);
      } // WidgetPDial* randomness
      { WidgetPDial* o = freqrand = new WidgetPDial(170, 30, 20, 20, "  Freq.");
        freqrand->tooltip("LFO Frequency Randomness");
        freqrand->box(FL_ROUND_UP_BOX);
        freqrand->color(FL_BACKGROUND_COLOR);
        freqrand->selection_color(FL_INACTIVE_COLOR);
        freqrand->labeltype(FL_NORMAL_LABEL);
        freqrand->labelfont(0);
        freqrand->labelsize(10);
        freqrand->labelcolor(FL_FOREGROUND_COLOR);
        freqrand->maximum(127);
        freqrand->step(1);
        freqrand->callback((Fl_Callback*)cb_freqrand);
        freqrand->align(Fl_Align(FL_ALIGN_TOP));
        freqrand->when(FL_WHEN_CHANGED);
        o->setValueType(VC_percent127);
      } // WidgetPDial* freqrand
      { WidgetPDial* o = stretch = new WidgetPDial(200, 30, 20, 20, "Str.");
        stretch->tooltip("LFO frequency stretch");
        stretch->box(FL_ROUND_UP_BOX);
        stretch->color(FL_BACKGROUND_COLOR);
        stretch->selection_color(FL_INACTIVE_COLOR);
        stretch->labeltype(FL_NORMAL_LABEL);
        stretch->labelfont(0);
        stretch->labelsize(10);
        stretch->labelcolor(FL_FOREGROUND_COLOR);
        stretch->maximum(127);
        stretch->step(1);
        stretch->callback((Fl_Callback*)cb_stretch);
        stretch->align(Fl_Align(FL_ALIGN_BOTTOM));
        stretch->when(FL_WHEN_CHANGED);
        o->setValueType(VC_LFOStretch);
      } // WidgetPDial* stretch
      { lfoC = new Fl_Button(195, 5, 15, 15, "C");
        lfoC->box(FL_THIN_UP_BOX);
        lfoC->color((Fl_Color)179);
        lfoC->labelfont(1);
        lfoC->labelsize(10);
        lfoC->labelcolor(FL_BACKGROUND2_COLOR);
        lfoC->callback((Fl_Callback*)cb_lfoC);
      } // Fl_Button* lfoC
      { lfoP = new Fl_Button(212, 5, 15, 15, "P");
        lfoP->box(FL_THIN_UP_BOX);
        lfoP->color((Fl_Color)179);
        lfoP->labelfont(1);
        lfoP->labelsize(10);
        lfoP->labelcolor(FL_BACKGROUND2_COLOR);
        lfoP->callback((Fl_Callback*)cb_lfoP);
      } // Fl_Button* lfoP
      { randgroup = new Fl_Group(140, 49, 55, 15, "Rand.");
        randgroup->labelsize(11);
        randgroup->align(Fl_Align(FL_ALIGN_CENTER|FL_ALIGN_INSIDE));
        randgroup->end();
      } // Fl_Group* randgroup
      lfoparamswindow->end();
    } // Fl_Group* lfoparamswindow
    lfoui->end();
    lfoui->resizable(lfoui);
  } // Fl_Group* lfoui
  return lfoui;
}

void LFOUI::refresh() {
  //
      freq->value(pars->PfreqI / float(Fmul2I));
      intensity->value(pars->Pintensity);
      startphase->value(pars->Pstartphase);
      delay->value(pars->Pdelay);
      continous->value(pars->Pcontinous);
      bpm->value(pars->Pbpm);
      stretch->value(pars->Pstretch);
      randomness->value(pars->Prandomness);
      freqrand->value(pars->Pfreqrand);
      LFOtype->value(pars->PLFOtype);
  
      updateLFOFreqType();
      updateBpmControls();
}

void LFOUI::lfoRtext(float dScale) {
  //
      int size = int(dScale * 10);
      lfoparamswindow->labelsize(size);
      freq->labelsize(size);
      intensity->labelsize(size);
      delay->labelsize(size);
      startphase->labelsize(size);
      randomness->labelsize(size);
      freqrand->labelsize(size);
      stretch->labelsize(size);
      randgroup->labelsize(size);
  
      LFOtype->labelsize(int(9 * dScale));
          LFOtype->textsize(size);
  
      lfoC->labelsize(size);
      lfoP->labelsize(size);
  
      continous->labelsize(size);
      bpm->labelsize(size);
  
      lfoui->redraw();
}

void LFOUI::send_data(int action, int group, int control, float value, int type) {
  //
          type |= TOPLEVEL::type::Write;
          collect_data(synth, value, action, type, control, npart, kititem, engine, TOPLEVEL::insert::LFOgroup, group);
}

void LFOUI::returns_update(CommandBlock *getData) {
  //
      float value = getData->data.value;
      unsigned char control = getData->data.control;
      unsigned char part = getData->data.part;
      unsigned char eng = getData->data.engine;
      unsigned char par = getData->data.parameter;
  
      if (part != npart || (eng >= PART::engine::addVoice1 && eng != engine))
          return;
  
      switch(control)
      {
          case LFOINSERT::control::speed:
              freq->value(value);
              break;
  
          case LFOINSERT::control::depth:
              intensity->value(value);
              if (engine >= PART::engine::addVoice1 && engine < PART::engine::addMod1 && par == 1) // rather special to sync voice list vibrato
                  synth->getGuiMaster()->partui->adnoteui->voicelistitem[engine - PART::engine::addVoice1]->voicelistvibratto->value(value);
              break;
  
          case LFOINSERT::control::delay:
              delay->value(value);
              break;
  
          case LFOINSERT::control::start:
              startphase->value(value);
              break;
  
          case LFOINSERT::control::amplitudeRandomness:
              randomness->value(value);
              break;
  
          case LFOINSERT::control::type:
              LFOtype->value((int)value);
              break;
  
          case LFOINSERT::control::continuous:
              continous->value(value != 0);
              break;
  
          case LFOINSERT::control::bpm:
              bpm->value(value != 0);
              updateLFOFreqType();
              updateBpmControls();
              break;
  
          case LFOINSERT::control::frequencyRandomness:
              freqrand->value(value);
              break;
  
          case LFOINSERT::control::stretch:
              stretch->value(value);
              break;
      }
}

void LFOUI::init(LFOParams *lfopars_, int npart_, int kititem_, int engine_, int group_) {
  //
      pars=lfopars_;
      synth = pars->getSynthEngine();
      npart = npart_;
      kititem = kititem_;
      engine = engine_;
      group = group_;
      make_window();
      end();
  
      refresh();
  
      lfoui->resize(this->x(),this->y(),this->w(),this->h());
      lfoparamswindow->label(this->label());
}

void LFOUI::updateLFOFreqType() {
  freq->setValueType(getLFOFreqType(bpm->value()));
}

void LFOUI::updateBpmControls() {
  if (bpm->value() == 0)
  {
      freqrand->activate();
      stretch->activate();
      startphase->setValueType(VC_LFOstartphaseRand);
  }
  else
  {
      freqrand->deactivate();
      stretch->deactivate();
      startphase->setValueType(VC_LFOstartphase);
  }
}
