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

#include "EnvelopeUI.h"
// Envelope.cc
// Original ZynAddSubFX author Nasca Octavian Paul
// Copyright (C) 2002-2005 Nasca Octavian Paul
// Copyright 2009, Alan Calvert
// Copyright 2016-2022 Will Godfrey

// 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"
using std::to_string;

EnvelopeFreeEdit::EnvelopeFreeEdit(int x,int y, int w, int h, const char *label):Fl_Box(x,y,w,h,label) {
  env=NULL;
  pair=NULL;
}

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

void EnvelopeFreeEdit::init(EnvelopeParams *env_, int npart_, int kititem_, int engine_, int group_) {
  //
      env = env_;
      oldx = -1;
      currentpoint = -1;
      cpx = 0;
      lastpoint = -1;
      synth = env->getSynthEngine();
      npart = npart_;
      kititem = kititem_;
      engine = engine_;
      group = group_;
}

void EnvelopeFreeEdit::setpair(Fl_Box *pair_) {
  pair = pair_;
}

int EnvelopeFreeEdit::getpointx(int n) {
  //
      int lx = w()-10;
      int npoints = env->Penvpoints;
      float sum=0;
      for (int i = 1; i < npoints; i++)
          sum += (env->getdt(i) + 1);
  
      float sumbefore = 0; // the sum of all points before the computed point
      for (int i = 1; i <= n; i++)
          sumbefore += (env->getdt(i) + 1);
  
      return((int) (sumbefore / (float) sum * lx));
}

int EnvelopeFreeEdit::getpointy(int n) {
  int ly = h() - 10;
  
  return((int) ((1.0 - env->Penvval[n] / 127.0) * ly));
}

int EnvelopeFreeEdit::getnearest(int x,int y) {
  //
      x -= 5;
      y -= 5;
  
  int nearestpoint = 0;
  int nearestval = 1000000; // a big value
  for (int i = 0; i < env->Penvpoints; i++)
  {
     int distance = abs(x - getpointx(i)) + abs(y - getpointy(i));
     if (distance < nearestval)
     {
       nearestpoint = i;
       nearestval = distance;
     };
  };
  return(nearestpoint);
}

void EnvelopeFreeEdit::draw() {
  //
      int ox = x();
      int oy = y();
      int lx = w();
      float scale = lx / 500.0f;
      fl_line_style(0, int(1 * scale));
      int ly = h();
      if (env->Pfreemode==0)
          env->converttofree();
      int npoints=env->Penvpoints;
  
      if (active_r())
          fl_color(FL_BLACK);
      else
          fl_color(90,90,90);
      if (!active_r()) currentpoint=-1;
  
      fl_rectf(ox,oy,lx,ly);
  
      ox += 5;
      oy += 5;
      lx -= 10;
      ly -= 10;
  
      //draw the lines
      fl_color(FL_GRAY);
      fl_line(ox + 2, oy + ly / 2, ox + lx - 2, oy + ly / 2);
  
      //draws the evelope points and lines
      fl_line_style(0, int(2 *scale));
      Fl_Color alb = FL_WHITE;
      if (!active_r())
          alb = fl_rgb_color(180,180,180);
      fl_color(alb);
      int oldxx = 0;
      int xx = 0;
      int oldyy = 0;
      int yy = getpointy(0);
      fl_rectf(ox - 3, oy + yy - 3, 6, 6);
      for (int i = 1; i < npoints; i++)
      {
          oldxx = xx;
          oldyy = yy;
          xx = getpointx(i);
          yy = getpointy(i);
          if (i == currentpoint)
              fl_color(FL_RED);
          else
              fl_color(alb);
          fl_line(ox + oldxx, oy + oldyy, ox + xx, oy + yy);
          fl_rectf(ox+xx-3,oy+yy-3,6,6);
      };
  
      //draw the last moved point point (if exists)
      fl_line_style(0, int(1 * scale));
      if (lastpoint>=0)
      {
          fl_color(FL_CYAN);
          fl_rectf(ox+getpointx(lastpoint)-5,oy+getpointy(lastpoint)-5,10,10);
      };
  
      //draw the sustain position
      if (env->Penvsustain>0)
      {
          fl_color(FL_YELLOW);
          xx = getpointx(env->Penvsustain);
          fl_line(ox + xx, oy + 0, ox + xx, oy + ly);
      };
  
      //Show the envelope duration and the current line duration
      fl_font(FL_HELVETICA|FL_BOLD,10 * scale);
      float time = 0.0;
      if (currentpoint <= 0)
      {
          fl_color(alb);
          for (int i = 1; i < npoints; i++)
              time += env->getdt(i);
      }
      else
      {
          fl_color(255,0,0);
          time = env->getdt(currentpoint);
      };
      char tmpstr[40];
      if (time<1000.0)
          snprintf((char *)&tmpstr, 40, "%.1fms", time);
      else
          snprintf((char *)&tmpstr, 40, "%.2fs", time / 1000.0);
      fl_draw(tmpstr, ox + lx - 20 * scale, oy + ly - 10 * scale, 20 * scale, 10 * scale, FL_ALIGN_RIGHT, NULL, 0);
  
      //Draw formatted point value in the top right corner when dragging points
      if (currentpoint >= 0)
      {
          string valDesc;
          float val = (float) env->Penvval[currentpoint];
          switch(env->Envmode){
              case PART::envelope::groupmode::amplitudeLin: //linear amplitude
              case PART::envelope::groupmode::amplitudeLog: //db amplitude
                  if (env->Plinearenvelope)
                      valDesc = convert_value(VC_EnvelopeLinAmpSusVal, val);
                  else
                      valDesc = convert_value(VC_EnvelopeAmpSusVal, val);
                  break;
              case PART::envelope::groupmode::frequency: //frequency offset
                  valDesc = convert_value(VC_EnvelopeFreqVal, val);
                  break;
              case PART::envelope::groupmode::filter: //filter frequency offset
                  valDesc = convert_value(VC_EnvelopeFilterVal, val);
                  break;
              case PART::envelope::groupmode::bandwidth: //bandwidth offset (unformatted)
                  valDesc = convert_value(VC_EnvelopeBandwidthVal, val);
                  break;
              default:
                  valDesc = "unknown env. type";
          }
          strcpy(tmpstr, valDesc.c_str());
          fl_color(FL_CYAN);
          fl_draw(tmpstr, ox + lx - 30, oy, 30, 25, FL_ALIGN_RIGHT, NULL, 0);
  }
  fl_line_style(0,1);
}

int EnvelopeFreeEdit::handle(int event) {
  //
      int x_ = Fl::event_x() - x();
      int y_ = Fl::event_y() - y();
  
      if (event == FL_PUSH)
      {
          currentpoint = getnearest(x_, y_);
          cpx = x_;
          cpdt = env->Penvdt[currentpoint];
          lastpoint = currentpoint;
          redraw();
          if (pair != NULL)
          {
              pair->redraw();
              return(1);
          }
      }
  
      if (event == FL_RELEASE)
      {
          currentpoint = -1;
      }
  
      if ((event == FL_DRAG) && (currentpoint >= 0))
      {
          int ny = 127 - (int) (y_ * 127.0 / h());
          if (ny < 0)
              ny = 0;
          if (ny> 127)
              ny = 127;
  
          int dx = (int)((x_- cpx) * 0.1);
          int newdt = cpdt + dx;
          if (newdt < 0)
              newdt = 0;
          if (newdt > 127)
              newdt = 127;
  
          send_data(TOPLEVEL::action::forceUpdate, currentpoint, newdt, ny, TOPLEVEL::type::Write);
  }
  return(1);
}

void EnvelopeUI::cb_freemodeeditwindow_i(Fl_Double_Window*, void*) {
  freeClose->do_callback();
}
void EnvelopeUI::cb_freemodeeditwindow(Fl_Double_Window* o, void* v) {
  ((EnvelopeUI*)(o->user_data()))->cb_freemodeeditwindow_i(o,v);
}

void EnvelopeUI::cb_freemodebutton_i(Fl_Light_Button* o, void*) {
  //
        if (env->Pfreemode != 0)
        {
            bool answer = choice(synth, "", "Yes", "No", "Disable the free mode of the Envelope?") > 1;
            if (!answer)
            {
                o->value(1); // back as it was
                return;
            }
        }

        send_data(TOPLEVEL::action::forceUpdate, group, ENVELOPEINSERT::control::enableFreeMode, o->value(), TOPLEVEL::type::Write);
}
void EnvelopeUI::cb_freemodebutton(Fl_Light_Button* o, void* v) {
  ((EnvelopeUI*)(o->parent()->user_data()))->cb_freemodebutton_i(o,v);
}

void EnvelopeUI::cb_addpoint_i(Fl_Button*, void*) {
  //
        int curpoint = freeedit->lastpoint;
        if (curpoint<0)
            return;
        if (env->Penvpoints >= MAX_ENVELOPE_POINTS)
            return;

        int value = env->Penvval[curpoint];
        int offset = env->Penvdt[curpoint];

        send_data(TOPLEVEL::action::forceUpdate, group, curpoint, value, TOPLEVEL::type::Write, TOPLEVEL::insert::envelopePointAdd, offset);
}
void EnvelopeUI::cb_addpoint(Fl_Button* o, void* v) {
  ((EnvelopeUI*)(o->parent()->user_data()))->cb_addpoint_i(o,v);
}

void EnvelopeUI::cb_deletepoint_i(Fl_Button*, void*) {
  //
        int curpoint = freeedit->lastpoint;
        if (curpoint < 1)
            return;
        if (curpoint >= env->Penvpoints-1)
            return;
        if (env->Penvpoints <= 3)
            return;

send_data(TOPLEVEL::action::forceUpdate, group, curpoint, 0, TOPLEVEL::type::Write, TOPLEVEL::insert::envelopePointDelete);
}
void EnvelopeUI::cb_deletepoint(Fl_Button* o, void* v) {
  ((EnvelopeUI*)(o->parent()->user_data()))->cb_deletepoint_i(o,v);
}

void EnvelopeUI::cb_sustaincounter_i(Fl_Counter* o, void*) {
  //
        send_data(TOPLEVEL::action::forceUpdate, group, ENVELOPEINSERT::control::sustainPoint, o->value(), TOPLEVEL::type::Write);
}
void EnvelopeUI::cb_sustaincounter(Fl_Counter* o, void* v) {
  ((EnvelopeUI*)(o->parent()->user_data()))->cb_sustaincounter_i(o,v);
}

void EnvelopeUI::cb_envstretchdial_i(WidgetPDial* o, void*) {
  //
        send_data(TOPLEVEL::action::forceUpdate, group, ENVELOPEINSERT::control::stretch, o->value(), TOPLEVEL::type::Write);
}
void EnvelopeUI::cb_envstretchdial(WidgetPDial* o, void* v) {
  ((EnvelopeUI*)(o->parent()->user_data()))->cb_envstretchdial_i(o,v);
}

void EnvelopeUI::cb_linearenvelopecheck_i(Fl_Check_Button2* o, void*) {
  //
        send_data(TOPLEVEL::action::forceUpdate, group, ENVELOPEINSERT::control::linearEnvelope, o->value(), TOPLEVEL::type::Write);
}
void EnvelopeUI::cb_linearenvelopecheck(Fl_Check_Button2* o, void* v) {
  ((EnvelopeUI*)(o->parent()->user_data()))->cb_linearenvelopecheck_i(o,v);
}

void EnvelopeUI::cb_forcedreleasecheck_i(Fl_Check_Button2* o, void*) {
  //
        send_data(TOPLEVEL::action::forceUpdate, group, ENVELOPEINSERT::control::forcedRelease, o->value(), TOPLEVEL::type::Write);
}
void EnvelopeUI::cb_forcedreleasecheck(Fl_Check_Button2* o, void* v) {
  ((EnvelopeUI*)(o->parent()->user_data()))->cb_forcedreleasecheck_i(o,v);
}

void EnvelopeUI::cb_freecopy_i(Fl_Button*, void*) {
  synth->getGuiMaster()->getPresetsUi()->copy(env);
}
void EnvelopeUI::cb_freecopy(Fl_Button* o, void* v) {
  ((EnvelopeUI*)(o->parent()->user_data()))->cb_freecopy_i(o,v);
}

void EnvelopeUI::cb_freepaste_i(Fl_Button*, void*) {
  synth->getGuiMaster()->getPresetsUi()->paste(env,this);
}
void EnvelopeUI::cb_freepaste(Fl_Button* o, void* v) {
  ((EnvelopeUI*)(o->parent()->user_data()))->cb_freepaste_i(o,v);
}

void EnvelopeUI::cb_freeClose_i(Fl_Button*, void*) {
  freemodeeditwindow->hide();
saveWin(synth, freemodeeditwindow->w(), freemodeeditwindow->h(), freemodeeditwindow->x(), freemodeeditwindow->y(), false, "xEnvelope-free " + to_string(engine) + " " + to_string(group));
}
void EnvelopeUI::cb_freeClose(Fl_Button* o, void* v) {
  ((EnvelopeUI*)(o->parent()->user_data()))->cb_freeClose_i(o,v);
}

void EnvelopeUI::cb_e1adt_i(WidgetPDial* o, void*) {
  //
          send_data(TOPLEVEL::action::forceUpdate, group, ENVELOPEINSERT::control::attackTime, o->value(), TOPLEVEL::type::Write);
}
void EnvelopeUI::cb_e1adt(WidgetPDial* o, void* v) {
  ((EnvelopeUI*)(o->parent()->parent()->user_data()))->cb_e1adt_i(o,v);
}

void EnvelopeUI::cb_e1ddt_i(WidgetPDial* o, void*) {
  //
          send_data(TOPLEVEL::action::forceUpdate, group, ENVELOPEINSERT::control::decayTime, o->value(), TOPLEVEL::type::Write);
}
void EnvelopeUI::cb_e1ddt(WidgetPDial* o, void* v) {
  ((EnvelopeUI*)(o->parent()->parent()->user_data()))->cb_e1ddt_i(o,v);
}

void EnvelopeUI::cb_e1rdt_i(WidgetPDial* o, void*) {
  //
          send_data(TOPLEVEL::action::forceUpdate, group, ENVELOPEINSERT::control::releaseTime, o->value(), TOPLEVEL::type::Write);
}
void EnvelopeUI::cb_e1rdt(WidgetPDial* o, void* v) {
  ((EnvelopeUI*)(o->parent()->parent()->user_data()))->cb_e1rdt_i(o,v);
}

void EnvelopeUI::cb_e1sval_i(WidgetPDial* o, void*) {
  //
          send_data(TOPLEVEL::action::forceUpdate, group, ENVELOPEINSERT::control::sustainLevel, o->value(), TOPLEVEL::type::Write);
}
void EnvelopeUI::cb_e1sval(WidgetPDial* o, void* v) {
  ((EnvelopeUI*)(o->parent()->parent()->user_data()))->cb_e1sval_i(o,v);
}

void EnvelopeUI::cb_e1forcedrelease_i(Fl_Check_Button2* o, void*) {
  //
          send_data(TOPLEVEL::action::forceUpdate, group, ENVELOPEINSERT::control::forcedRelease, o->value(), TOPLEVEL::type::Write);
}
void EnvelopeUI::cb_e1forcedrelease(Fl_Check_Button2* o, void* v) {
  ((EnvelopeUI*)(o->parent()->parent()->user_data()))->cb_e1forcedrelease_i(o,v);
}

void EnvelopeUI::cb_e1envstretch_i(WidgetPDial* o, void*) {
  //
          send_data(TOPLEVEL::action::forceUpdate, group, ENVELOPEINSERT::control::stretch, o->value(), TOPLEVEL::type::Write);
}
void EnvelopeUI::cb_e1envstretch(WidgetPDial* o, void* v) {
  ((EnvelopeUI*)(o->parent()->parent()->user_data()))->cb_e1envstretch_i(o,v);
}

void EnvelopeUI::cb_e1E_i(Fl_Button* o, void*) {
  //
          showfree();
          send_data(0, group, ENVELOPEINSERT::control::edit, o->value(), TOPLEVEL::type::Write);
}
void EnvelopeUI::cb_e1E(Fl_Button* o, void* v) {
  ((EnvelopeUI*)(o->parent()->parent()->user_data()))->cb_e1E_i(o,v);
}

void EnvelopeUI::cb_e1linearenvelope_i(Fl_Check_Button2* o, void*) {
  //
          send_data(TOPLEVEL::action::forceUpdate, group, ENVELOPEINSERT::control::linearEnvelope, o->value(), TOPLEVEL::type::Write);
}
void EnvelopeUI::cb_e1linearenvelope(Fl_Check_Button2* o, void* v) {
  ((EnvelopeUI*)(o->parent()->parent()->user_data()))->cb_e1linearenvelope_i(o,v);
}

void EnvelopeUI::cb_e1C_i(Fl_Button*, void*) {
  //
          synth->getGuiMaster()->getPresetsUi()->copy(env);
}
void EnvelopeUI::cb_e1C(Fl_Button* o, void* v) {
  ((EnvelopeUI*)(o->parent()->parent()->user_data()))->cb_e1C_i(o,v);
}

void EnvelopeUI::cb_e1P_i(Fl_Button*, void*) {
  synth->getGuiMaster()->getPresetsUi()->paste(env,this);
}
void EnvelopeUI::cb_e1P(Fl_Button* o, void* v) {
  ((EnvelopeUI*)(o->parent()->parent()->user_data()))->cb_e1P_i(o,v);
}

void EnvelopeUI::cb_e2aval_i(WidgetPDial* o, void*) {
  //
          send_data(TOPLEVEL::action::forceUpdate, group, ENVELOPEINSERT::control::attackLevel, o->value(), TOPLEVEL::type::Write);
}
void EnvelopeUI::cb_e2aval(WidgetPDial* o, void* v) {
  ((EnvelopeUI*)(o->parent()->parent()->user_data()))->cb_e2aval_i(o,v);
}

void EnvelopeUI::cb_e2adt_i(WidgetPDial* o, void*) {
  //
          send_data(TOPLEVEL::action::forceUpdate, group, ENVELOPEINSERT::control::attackTime, o->value(), TOPLEVEL::type::Write);
}
void EnvelopeUI::cb_e2adt(WidgetPDial* o, void* v) {
  ((EnvelopeUI*)(o->parent()->parent()->user_data()))->cb_e2adt_i(o,v);
}

void EnvelopeUI::cb_e2rval_i(WidgetPDial* o, void*) {
  //
          send_data(TOPLEVEL::action::forceUpdate, group, ENVELOPEINSERT::control::releaseLevel, o->value(), TOPLEVEL::type::Write);
}
void EnvelopeUI::cb_e2rval(WidgetPDial* o, void* v) {
  ((EnvelopeUI*)(o->parent()->parent()->user_data()))->cb_e2rval_i(o,v);
}

void EnvelopeUI::cb_e2rdt_i(WidgetPDial* o, void*) {
  //
          send_data(TOPLEVEL::action::forceUpdate, group, ENVELOPEINSERT::control::releaseTime, o->value(), TOPLEVEL::type::Write);
}
void EnvelopeUI::cb_e2rdt(WidgetPDial* o, void* v) {
  ((EnvelopeUI*)(o->parent()->parent()->user_data()))->cb_e2rdt_i(o,v);
}

void EnvelopeUI::cb_e2envstretch_i(WidgetPDial* o, void*) {
  //
          send_data(TOPLEVEL::action::forceUpdate, group, ENVELOPEINSERT::control::stretch, o->value(), TOPLEVEL::type::Write);
}
void EnvelopeUI::cb_e2envstretch(WidgetPDial* o, void* v) {
  ((EnvelopeUI*)(o->parent()->parent()->user_data()))->cb_e2envstretch_i(o,v);
}

void EnvelopeUI::cb_e2forcedrelease_i(Fl_Check_Button2* o, void*) {
  //
          send_data(TOPLEVEL::action::forceUpdate, group, ENVELOPEINSERT::control::forcedRelease, o->value(), TOPLEVEL::type::Write);
}
void EnvelopeUI::cb_e2forcedrelease(Fl_Check_Button2* o, void* v) {
  ((EnvelopeUI*)(o->parent()->parent()->user_data()))->cb_e2forcedrelease_i(o,v);
}

void EnvelopeUI::cb_e2C_i(Fl_Button*, void*) {
  synth->getGuiMaster()->getPresetsUi()->copy(env);
}
void EnvelopeUI::cb_e2C(Fl_Button* o, void* v) {
  ((EnvelopeUI*)(o->parent()->parent()->user_data()))->cb_e2C_i(o,v);
}

void EnvelopeUI::cb_e2P_i(Fl_Button*, void*) {
  synth->getGuiMaster()->getPresetsUi()->paste(env,this);
}
void EnvelopeUI::cb_e2P(Fl_Button* o, void* v) {
  ((EnvelopeUI*)(o->parent()->parent()->user_data()))->cb_e2P_i(o,v);
}

void EnvelopeUI::cb_e2E_i(Fl_Button* o, void*) {
  //
      showfree();
      send_data(0, group, ENVELOPEINSERT::control::edit, o->value(), TOPLEVEL::type::Write);
}
void EnvelopeUI::cb_e2E(Fl_Button* o, void* v) {
  ((EnvelopeUI*)(o->parent()->user_data()))->cb_e2E_i(o,v);
}

void EnvelopeUI::cb_e3aval_i(WidgetPDial* o, void*) {
  //
          send_data(TOPLEVEL::action::forceUpdate, group, ENVELOPEINSERT::control::attackLevel, o->value(), TOPLEVEL::type::Write);
}
void EnvelopeUI::cb_e3aval(WidgetPDial* o, void* v) {
  ((EnvelopeUI*)(o->parent()->parent()->user_data()))->cb_e3aval_i(o,v);
}

void EnvelopeUI::cb_e3adt_i(WidgetPDial* o, void*) {
  //
          send_data(TOPLEVEL::action::forceUpdate, group, ENVELOPEINSERT::control::attackTime, o->value(), TOPLEVEL::type::Write);
}
void EnvelopeUI::cb_e3adt(WidgetPDial* o, void* v) {
  ((EnvelopeUI*)(o->parent()->parent()->user_data()))->cb_e3adt_i(o,v);
}

void EnvelopeUI::cb_e3dval_i(WidgetPDial* o, void*) {
  //
          send_data(TOPLEVEL::action::forceUpdate, group, ENVELOPEINSERT::control::decayLevel, o->value(), TOPLEVEL::type::Write);
}
void EnvelopeUI::cb_e3dval(WidgetPDial* o, void* v) {
  ((EnvelopeUI*)(o->parent()->parent()->user_data()))->cb_e3dval_i(o,v);
}

void EnvelopeUI::cb_e3ddt_i(WidgetPDial* o, void*) {
  //
          send_data(TOPLEVEL::action::forceUpdate, group, ENVELOPEINSERT::control::decayTime, o->value(), TOPLEVEL::type::Write);
}
void EnvelopeUI::cb_e3ddt(WidgetPDial* o, void* v) {
  ((EnvelopeUI*)(o->parent()->parent()->user_data()))->cb_e3ddt_i(o,v);
}

void EnvelopeUI::cb_e3rdt_i(WidgetPDial* o, void*) {
  //
          send_data(TOPLEVEL::action::forceUpdate, group, ENVELOPEINSERT::control::releaseTime, o->value(), TOPLEVEL::type::Write);
}
void EnvelopeUI::cb_e3rdt(WidgetPDial* o, void* v) {
  ((EnvelopeUI*)(o->parent()->parent()->user_data()))->cb_e3rdt_i(o,v);
}

void EnvelopeUI::cb_e3rval_i(WidgetPDial* o, void*) {
  //
          send_data(TOPLEVEL::action::forceUpdate, group, ENVELOPEINSERT::control::releaseLevel, o->value(), TOPLEVEL::type::Write);
}
void EnvelopeUI::cb_e3rval(WidgetPDial* o, void* v) {
  ((EnvelopeUI*)(o->parent()->parent()->user_data()))->cb_e3rval_i(o,v);
}

void EnvelopeUI::cb_e3envstretch_i(WidgetPDial* o, void*) {
  //
          send_data(TOPLEVEL::action::forceUpdate, group, ENVELOPEINSERT::control::stretch, o->value(), TOPLEVEL::type::Write);
}
void EnvelopeUI::cb_e3envstretch(WidgetPDial* o, void* v) {
  ((EnvelopeUI*)(o->parent()->parent()->user_data()))->cb_e3envstretch_i(o,v);
}

void EnvelopeUI::cb_e3forcedrelease_i(Fl_Check_Button2* o, void*) {
  //
          send_data(TOPLEVEL::action::forceUpdate, group, ENVELOPEINSERT::control::forcedRelease, o->value(), TOPLEVEL::type::Write);
}
void EnvelopeUI::cb_e3forcedrelease(Fl_Check_Button2* o, void* v) {
  ((EnvelopeUI*)(o->parent()->parent()->user_data()))->cb_e3forcedrelease_i(o,v);
}

void EnvelopeUI::cb_e3E_i(Fl_Button* o, void*) {
  //
          showfree();
          send_data(0, group, ENVELOPEINSERT::control::edit, o->value(), TOPLEVEL::type::Write);
}
void EnvelopeUI::cb_e3E(Fl_Button* o, void* v) {
  ((EnvelopeUI*)(o->parent()->parent()->user_data()))->cb_e3E_i(o,v);
}

void EnvelopeUI::cb_e3C_i(Fl_Button*, void*) {
  synth->getGuiMaster()->getPresetsUi()->copy(env);
}
void EnvelopeUI::cb_e3C(Fl_Button* o, void* v) {
  ((EnvelopeUI*)(o->parent()->parent()->user_data()))->cb_e3C_i(o,v);
}

void EnvelopeUI::cb_e3P_i(Fl_Button*, void*) {
  synth->getGuiMaster()->getPresetsUi()->paste(env,this);
}
void EnvelopeUI::cb_e3P(Fl_Button* o, void* v) {
  ((EnvelopeUI*)(o->parent()->parent()->user_data()))->cb_e3P_i(o,v);
}

void EnvelopeUI::cb_e4aval_i(WidgetPDial* o, void*) {
  //
          send_data(TOPLEVEL::action::forceUpdate, group, ENVELOPEINSERT::control::attackLevel, o->value(), TOPLEVEL::type::Write);
}
void EnvelopeUI::cb_e4aval(WidgetPDial* o, void* v) {
  ((EnvelopeUI*)(o->parent()->parent()->user_data()))->cb_e4aval_i(o,v);
}

void EnvelopeUI::cb_e4adt_i(WidgetPDial* o, void*) {
  //
          send_data(TOPLEVEL::action::forceUpdate, group, ENVELOPEINSERT::control::attackTime, o->value(), TOPLEVEL::type::Write);
}
void EnvelopeUI::cb_e4adt(WidgetPDial* o, void* v) {
  ((EnvelopeUI*)(o->parent()->parent()->user_data()))->cb_e4adt_i(o,v);
}

void EnvelopeUI::cb_e4rval_i(WidgetPDial* o, void*) {
  //
          send_data(TOPLEVEL::action::forceUpdate, group, ENVELOPEINSERT::control::releaseLevel, o->value(), TOPLEVEL::type::Write);
}
void EnvelopeUI::cb_e4rval(WidgetPDial* o, void* v) {
  ((EnvelopeUI*)(o->parent()->parent()->user_data()))->cb_e4rval_i(o,v);
}

void EnvelopeUI::cb_e4rdt_i(WidgetPDial* o, void*) {
  //
          send_data(TOPLEVEL::action::forceUpdate, group, ENVELOPEINSERT::control::releaseTime, o->value(), TOPLEVEL::type::Write);
}
void EnvelopeUI::cb_e4rdt(WidgetPDial* o, void* v) {
  ((EnvelopeUI*)(o->parent()->parent()->user_data()))->cb_e4rdt_i(o,v);
}

void EnvelopeUI::cb_e4envstretch_i(WidgetPDial* o, void*) {
  //
          send_data(TOPLEVEL::action::forceUpdate, group, ENVELOPEINSERT::control::stretch, o->value(), TOPLEVEL::type::Write);
}
void EnvelopeUI::cb_e4envstretch(WidgetPDial* o, void* v) {
  ((EnvelopeUI*)(o->parent()->parent()->user_data()))->cb_e4envstretch_i(o,v);
}

void EnvelopeUI::cb_e4forcedrelease_i(Fl_Check_Button2* o, void*) {
  //
          send_data(TOPLEVEL::action::forceUpdate, group, ENVELOPEINSERT::control::forcedRelease, o->value(), TOPLEVEL::type::Write);
}
void EnvelopeUI::cb_e4forcedrelease(Fl_Check_Button2* o, void* v) {
  ((EnvelopeUI*)(o->parent()->parent()->user_data()))->cb_e4forcedrelease_i(o,v);
}

void EnvelopeUI::cb_e4C_i(Fl_Button*, void*) {
  synth->getGuiMaster()->getPresetsUi()->copy(env);
}
void EnvelopeUI::cb_e4C(Fl_Button* o, void* v) {
  ((EnvelopeUI*)(o->parent()->parent()->user_data()))->cb_e4C_i(o,v);
}

void EnvelopeUI::cb_e4P_i(Fl_Button*, void*) {
  synth->getGuiMaster()->getPresetsUi()->paste(env,this);
}
void EnvelopeUI::cb_e4P(Fl_Button* o, void* v) {
  ((EnvelopeUI*)(o->parent()->parent()->user_data()))->cb_e4P_i(o,v);
}

void EnvelopeUI::cb_e4E_i(Fl_Button* o, void*) {
  //
        showfree();
        send_data(0, group, ENVELOPEINSERT::control::edit, o->value(), TOPLEVEL::type::Write);
}
void EnvelopeUI::cb_e4E(Fl_Button* o, void* v) {
  ((EnvelopeUI*)(o->parent()->user_data()))->cb_e4E_i(o,v);
}

void EnvelopeUI::cb_freeeditsmall_i(EnvelopeFreeEdit*, void*) {
  envfree->redraw();
}
void EnvelopeUI::cb_freeeditsmall(EnvelopeFreeEdit* o, void* v) {
  ((EnvelopeUI*)(o->parent()->parent()->user_data()))->cb_freeeditsmall_i(o,v);
}

void EnvelopeUI::cb_efC_i(Fl_Button*, void*) {
  synth->getGuiMaster()->getPresetsUi()->copy(env);
}
void EnvelopeUI::cb_efC(Fl_Button* o, void* v) {
  ((EnvelopeUI*)(o->parent()->user_data()))->cb_efC_i(o,v);
}

void EnvelopeUI::cb_efP_i(Fl_Button*, void*) {
  synth->getGuiMaster()->getPresetsUi()->paste(env,this);
}
void EnvelopeUI::cb_efP(Fl_Button* o, void* v) {
  ((EnvelopeUI*)(o->parent()->user_data()))->cb_efP_i(o,v);
}

void EnvelopeUI::cb_efE_i(Fl_Button* o, void*) {
  showfree();
          send_data(0, group, ENVELOPEINSERT::control::edit, o->value(), TOPLEVEL::type::Write);
}
void EnvelopeUI::cb_efE(Fl_Button* o, void* v) {
  ((EnvelopeUI*)(o->parent()->user_data()))->cb_efE_i(o,v);
}

EnvelopeUI::EnvelopeUI(int x,int y, int w, int h, const char *label):Fl_Group(x,y,w,h,label) {
  //
      synth = NULL;
      env=NULL;
      freemodeeditwindow=NULL;
      envADSR=NULL;
      envASR=NULL;
      envADSRfilter=NULL;
      envASRbw=NULL;
      envfree=NULL;
}

EnvelopeUI::~EnvelopeUI() {
  //
  	if (freemodeeditwindow->x() > 4)
              saveWin(synth, freemodeeditwindow->w(), freemodeeditwindow->h(), freemodeeditwindow->x(), freemodeeditwindow->y(),freemodeeditwindow->visible(), "xEnvelope-free " + to_string(engine) + " " + to_string(group));
          freemodeeditwindow->hide();
          delete (freemodeeditwindow);
          envwindow->hide();
          hide();
}

Fl_Double_Window* EnvelopeUI::make_freemode_edit_window() {
  { Fl_Double_Window* o = freemodeeditwindow = new Fl_Double_Window(575, 180, "Envelope");
    freemodeeditwindow->callback((Fl_Callback*)cb_freemodeeditwindow, (void*)(this));
    { EnvelopeFreeEdit* o = freeedit = new EnvelopeFreeEdit(5, 5, 565, 145, "Envelope");
      freeedit->box(FL_FLAT_BOX);
      freeedit->color(FL_FOREGROUND_COLOR);
      freeedit->selection_color(FL_BACKGROUND_COLOR);
      freeedit->labeltype(FL_NORMAL_LABEL);
      freeedit->labelfont(0);
      freeedit->labelsize(14);
      freeedit->labelcolor(FL_FOREGROUND_COLOR);
      freeedit->align(Fl_Align(FL_ALIGN_CENTER));
      freeedit->when(FL_WHEN_RELEASE);
      o->init(env, npart, kititem, engine, group);
    } // EnvelopeFreeEdit* freeedit
    { freemodebutton = new Fl_Light_Button(10, 154, 95, 22, "FreeMode");
      freemodebutton->tooltip("Enable or disable the freemode");
      freemodebutton->box(FL_PLASTIC_UP_BOX);
      freemodebutton->labelsize(11);
      freemodebutton->callback((Fl_Callback*)cb_freemodebutton);
    } // Fl_Light_Button* freemodebutton
    { Fl_Button* o = addpoint = new Fl_Button(112, 155, 80, 20, "Add point");
      addpoint->box(FL_THIN_UP_BOX);
      addpoint->labelsize(11);
      addpoint->callback((Fl_Callback*)cb_addpoint);
      if (env->Pfreemode==0) o->hide();
    } // Fl_Button* addpoint
    { Fl_Button* o = deletepoint = new Fl_Button(200, 155, 80, 20, "Delete point");
      deletepoint->box(FL_THIN_UP_BOX);
      deletepoint->labelsize(11);
      deletepoint->callback((Fl_Callback*)cb_deletepoint);
      if (env->Pfreemode==0) o->hide();
    } // Fl_Button* deletepoint
    { Fl_Counter* o = sustaincounter = new Fl_Counter(315, 158, 40, 15, "Sust");
      sustaincounter->tooltip("Sustain (0 is disabled)");
      sustaincounter->type(1);
      sustaincounter->labelsize(11);
      sustaincounter->minimum(0);
      sustaincounter->maximum(127);
      sustaincounter->step(1);
      sustaincounter->textfont(1);
      sustaincounter->textsize(12);
      sustaincounter->callback((Fl_Callback*)cb_sustaincounter);
      sustaincounter->align(Fl_Align(FL_ALIGN_LEFT));
      o->value(env->Penvsustain);
      if (env->Pfreemode==0) o->hide();
      o->maximum(env->Penvpoints-2);
    } // Fl_Counter* sustaincounter
    { WidgetPDial* o = envstretchdial = new WidgetPDial(380, 153, 25, 25, "Str.");
      envstretchdial->tooltip("Envelope stretch (on lower notes make the envelope longer)");
      envstretchdial->box(FL_ROUND_UP_BOX);
      envstretchdial->color(FL_BACKGROUND_COLOR);
      envstretchdial->selection_color(FL_INACTIVE_COLOR);
      envstretchdial->labeltype(FL_NORMAL_LABEL);
      envstretchdial->labelfont(0);
      envstretchdial->labelsize(10);
      envstretchdial->labelcolor(FL_FOREGROUND_COLOR);
      envstretchdial->maximum(127);
      envstretchdial->step(1);
      envstretchdial->callback((Fl_Callback*)cb_envstretchdial);
      envstretchdial->align(Fl_Align(FL_ALIGN_LEFT));
      envstretchdial->when(FL_WHEN_CHANGED);
      o->value(env->Penvstretch);
      if (env->Pfreemode==0) o->hide();
      o->setValueType(VC_EnvStretch);
    } // WidgetPDial* envstretchdial
    { Fl_Check_Button2* o = linearenvelopecheck = new Fl_Check_Button2(415, 151, 30, 15, "L");
      linearenvelopecheck->tooltip("Linear Envelope");
      linearenvelopecheck->box(FL_NO_BOX);
      linearenvelopecheck->down_box(FL_DOWN_BOX);
      linearenvelopecheck->color(FL_BACKGROUND_COLOR);
      linearenvelopecheck->selection_color(FL_FOREGROUND_COLOR);
      linearenvelopecheck->labeltype(FL_NORMAL_LABEL);
      linearenvelopecheck->labelfont(0);
      linearenvelopecheck->labelsize(10);
      linearenvelopecheck->labelcolor(FL_FOREGROUND_COLOR);
      linearenvelopecheck->callback((Fl_Callback*)cb_linearenvelopecheck);
      linearenvelopecheck->align(Fl_Align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE));
      linearenvelopecheck->when(FL_WHEN_RELEASE);
      o->value(env->Plinearenvelope);
      if ((env->Pfreemode==0)||(env->Envmode>2)) o->hide();
    } // Fl_Check_Button2* linearenvelopecheck
    { Fl_Check_Button2* o = forcedreleasecheck = new Fl_Check_Button2(415, 165, 40, 15, "frcR");
      forcedreleasecheck->tooltip("Forced Release");
      forcedreleasecheck->box(FL_NO_BOX);
      forcedreleasecheck->down_box(FL_DOWN_BOX);
      forcedreleasecheck->color(FL_BACKGROUND_COLOR);
      forcedreleasecheck->selection_color(FL_FOREGROUND_COLOR);
      forcedreleasecheck->labeltype(FL_NORMAL_LABEL);
      forcedreleasecheck->labelfont(0);
      forcedreleasecheck->labelsize(10);
      forcedreleasecheck->labelcolor(FL_FOREGROUND_COLOR);
      forcedreleasecheck->callback((Fl_Callback*)cb_forcedreleasecheck);
      forcedreleasecheck->align(Fl_Align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE));
      forcedreleasecheck->when(FL_WHEN_RELEASE);
      o->value(env->Pforcedrelease);
      if (env->Pfreemode==0) o->hide();
    } // Fl_Check_Button2* forcedreleasecheck
    { freecopy = new Fl_Button(465, 158, 16, 16, "C");
      freecopy->box(FL_THIN_UP_BOX);
      freecopy->color((Fl_Color)179);
      freecopy->labelfont(1);
      freecopy->labelsize(10);
      freecopy->labelcolor(FL_BACKGROUND2_COLOR);
      freecopy->callback((Fl_Callback*)cb_freecopy);
    } // Fl_Button* freecopy
    { freepaste = new Fl_Button(486, 158, 16, 16, "P");
      freepaste->box(FL_THIN_UP_BOX);
      freepaste->color((Fl_Color)179);
      freepaste->labelfont(1);
      freepaste->labelsize(10);
      freepaste->labelcolor(FL_BACKGROUND2_COLOR);
      freepaste->callback((Fl_Callback*)cb_freepaste);
    } // Fl_Button* freepaste
    { freeClose = new Fl_Button(519, 155, 44, 20, "Close");
      freeClose->box(FL_THIN_UP_BOX);
      freeClose->labelsize(12);
      freeClose->callback((Fl_Callback*)cb_freeClose);
    } // Fl_Button* freeClose
    freeDW = o->w(); freeDH = o->h();
    o->size_range(freeDW, freeDH, 0, 0, 0, 0, 1);
    freemodeeditwindow->end();
    freemodeeditwindow->resizable(freemodeeditwindow);
  } // Fl_Double_Window* freemodeeditwindow
  return freemodeeditwindow;
}

Fl_Group* EnvelopeUI::make_ADSR_window() {
  { envADSR = new Fl_Group(0, 0, 205, 70);
    envADSR->box(FL_FLAT_BOX);
    envADSR->color(FL_LIGHT1);
    envADSR->selection_color(FL_BACKGROUND_COLOR);
    envADSR->labeltype(FL_NO_LABEL);
    envADSR->labelfont(1);
    envADSR->labelsize(14);
    envADSR->labelcolor(FL_FOREGROUND_COLOR);
    envADSR->user_data((void*)(this));
    envADSR->align(Fl_Align(FL_ALIGN_TOP));
    envADSR->when(FL_WHEN_RELEASE);
    { e1name = new Fl_Group(0, 0, 205, 70, "Amplitude Env");
      e1name->box(FL_PLASTIC_UP_BOX);
      e1name->color(FL_CYAN);
      e1name->labelfont(1);
      e1name->labelsize(10);
      e1name->align(Fl_Align(FL_ALIGN_TOP|FL_ALIGN_INSIDE));
      { WidgetPDial* o = e1adt = new WidgetPDial(5, 20, 30, 30, "A.dt");
        e1adt->tooltip("Attack time");
        e1adt->box(FL_ROUND_UP_BOX);
        e1adt->color(FL_BACKGROUND_COLOR);
        e1adt->selection_color(FL_INACTIVE_COLOR);
        e1adt->labeltype(FL_NORMAL_LABEL);
        e1adt->labelfont(0);
        e1adt->labelsize(10);
        e1adt->labelcolor(FL_FOREGROUND_COLOR);
        e1adt->maximum(127);
        e1adt->step(1);
        e1adt->callback((Fl_Callback*)cb_e1adt);
        e1adt->align(Fl_Align(FL_ALIGN_BOTTOM));
        e1adt->when(FL_WHEN_CHANGED);
        o->setValueType(VC_EnvelopeDT);
        o->value(env->PA_dt);
      } // WidgetPDial* e1adt
      { WidgetPDial* o = e1ddt = new WidgetPDial(40, 20, 30, 30, "D.dt");
        e1ddt->tooltip("Decay time");
        e1ddt->box(FL_ROUND_UP_BOX);
        e1ddt->color(FL_BACKGROUND_COLOR);
        e1ddt->selection_color(FL_INACTIVE_COLOR);
        e1ddt->labeltype(FL_NORMAL_LABEL);
        e1ddt->labelfont(0);
        e1ddt->labelsize(10);
        e1ddt->labelcolor(FL_FOREGROUND_COLOR);
        e1ddt->maximum(127);
        e1ddt->step(1);
        e1ddt->callback((Fl_Callback*)cb_e1ddt);
        e1ddt->align(Fl_Align(FL_ALIGN_BOTTOM));
        e1ddt->when(FL_WHEN_CHANGED);
        o->setValueType(VC_EnvelopeDT);
        o->value(env->PD_dt);
      } // WidgetPDial* e1ddt
      { WidgetPDial* o = e1rdt = new WidgetPDial(110, 20, 30, 30, "R.dt ");
        e1rdt->tooltip("Release time");
        e1rdt->box(FL_ROUND_UP_BOX);
        e1rdt->color(FL_BACKGROUND_COLOR);
        e1rdt->selection_color(FL_INACTIVE_COLOR);
        e1rdt->labeltype(FL_NORMAL_LABEL);
        e1rdt->labelfont(0);
        e1rdt->labelsize(10);
        e1rdt->labelcolor(FL_FOREGROUND_COLOR);
        e1rdt->maximum(127);
        e1rdt->step(1);
        e1rdt->callback((Fl_Callback*)cb_e1rdt);
        e1rdt->align(Fl_Align(FL_ALIGN_BOTTOM));
        e1rdt->when(FL_WHEN_CHANGED);
        o->setValueType(VC_EnvelopeDT);
        o->value(env->PR_dt);
      } // WidgetPDial* e1rdt
      { WidgetPDial* o = e1sval = new WidgetPDial(75, 20, 30, 30, "S.val");
        e1sval->tooltip("Sustain value");
        e1sval->box(FL_ROUND_UP_BOX);
        e1sval->color(FL_BACKGROUND_COLOR);
        e1sval->selection_color(FL_INACTIVE_COLOR);
        e1sval->labeltype(FL_NORMAL_LABEL);
        e1sval->labelfont(0);
        e1sval->labelsize(10);
        e1sval->labelcolor(FL_FOREGROUND_COLOR);
        e1sval->maximum(127);
        e1sval->step(1);
        e1sval->callback((Fl_Callback*)cb_e1sval);
        e1sval->align(Fl_Align(FL_ALIGN_BOTTOM));
        e1sval->when(FL_WHEN_CHANGED);
        o->setValueType(VC_EnvelopeAmpSusVal);
        o->value(env->PS_val);
      } // WidgetPDial* e1sval
      { Fl_Check_Button2* o = e1forcedrelease = new Fl_Check_Button2(180, 35, 20, 15, "frcR");
        e1forcedrelease->tooltip("Forced Release");
        e1forcedrelease->box(FL_NO_BOX);
        e1forcedrelease->down_box(FL_DOWN_BOX);
        e1forcedrelease->color(FL_BACKGROUND_COLOR);
        e1forcedrelease->selection_color(FL_FOREGROUND_COLOR);
        e1forcedrelease->labeltype(FL_NORMAL_LABEL);
        e1forcedrelease->labelfont(0);
        e1forcedrelease->labelsize(10);
        e1forcedrelease->labelcolor(FL_FOREGROUND_COLOR);
        e1forcedrelease->callback((Fl_Callback*)cb_e1forcedrelease);
        e1forcedrelease->align(Fl_Align(FL_ALIGN_BOTTOM_LEFT));
        e1forcedrelease->when(FL_WHEN_RELEASE);
        o->value(env->Pforcedrelease);
      } // Fl_Check_Button2* e1forcedrelease
      { WidgetPDial* o = e1envstretch = new WidgetPDial(145, 25, 25, 25, "Stretch");
        e1envstretch->tooltip("Envelope stretch (on lower notes makes the envelope longer)");
        e1envstretch->box(FL_ROUND_UP_BOX);
        e1envstretch->color(FL_BACKGROUND_COLOR);
        e1envstretch->selection_color(FL_INACTIVE_COLOR);
        e1envstretch->labeltype(FL_NORMAL_LABEL);
        e1envstretch->labelfont(0);
        e1envstretch->labelsize(10);
        e1envstretch->labelcolor(FL_FOREGROUND_COLOR);
        e1envstretch->maximum(127);
        e1envstretch->step(1);
        e1envstretch->callback((Fl_Callback*)cb_e1envstretch);
        e1envstretch->align(Fl_Align(FL_ALIGN_BOTTOM));
        e1envstretch->when(FL_WHEN_CHANGED);
        o->value(env->Penvstretch);
        o->setValueType(VC_EnvStretch);
      } // WidgetPDial* e1envstretch
      { e1E = new Fl_Button(185, 5, 15, 15, "E");
        e1E->tooltip("Envelope window");
        e1E->box(FL_PLASTIC_UP_BOX);
        e1E->labelfont(1);
        e1E->labelsize(10);
        e1E->callback((Fl_Callback*)cb_e1E);
      } // Fl_Button* e1E
      { Fl_Check_Button2* o = e1linearenvelope = new Fl_Check_Button2(180, 20, 15, 15, "L");
        e1linearenvelope->tooltip("The envelope is linear");
        e1linearenvelope->box(FL_NO_BOX);
        e1linearenvelope->down_box(FL_DOWN_BOX);
        e1linearenvelope->color(FL_BACKGROUND_COLOR);
        e1linearenvelope->selection_color(FL_FOREGROUND_COLOR);
        e1linearenvelope->labeltype(FL_NORMAL_LABEL);
        e1linearenvelope->labelfont(0);
        e1linearenvelope->labelsize(10);
        e1linearenvelope->labelcolor(FL_FOREGROUND_COLOR);
        e1linearenvelope->callback((Fl_Callback*)cb_e1linearenvelope);
        e1linearenvelope->align(Fl_Align(FL_ALIGN_LEFT));
        e1linearenvelope->when(FL_WHEN_RELEASE);
        o->value(env->Plinearenvelope);
      } // Fl_Check_Button2* e1linearenvelope
      { e1C = new Fl_Button(150, 5, 15, 15, "C");
        e1C->box(FL_THIN_UP_BOX);
        e1C->color((Fl_Color)179);
        e1C->labelfont(1);
        e1C->labelsize(10);
        e1C->labelcolor(FL_BACKGROUND2_COLOR);
        e1C->callback((Fl_Callback*)cb_e1C);
      } // Fl_Button* e1C
      { e1P = new Fl_Button(167, 5, 15, 15, "P");
        e1P->box(FL_THIN_UP_BOX);
        e1P->color((Fl_Color)179);
        e1P->labelfont(1);
        e1P->labelsize(10);
        e1P->labelcolor(FL_BACKGROUND2_COLOR);
        e1P->callback((Fl_Callback*)cb_e1P);
      } // Fl_Button* e1P
      e1name->end();
    } // Fl_Group* e1name
    envADSR->end();
  } // Fl_Group* envADSR
  return envADSR;
}

Fl_Group* EnvelopeUI::make_ASR_window() {
  { envASR = new Fl_Group(0, 0, 210, 70);
    envASR->box(FL_FLAT_BOX);
    envASR->color(FL_BACKGROUND_COLOR);
    envASR->selection_color(FL_BACKGROUND_COLOR);
    envASR->labeltype(FL_NO_LABEL);
    envASR->labelfont(0);
    envASR->labelsize(14);
    envASR->labelcolor(FL_FOREGROUND_COLOR);
    envASR->user_data((void*)(this));
    envASR->align(Fl_Align(FL_ALIGN_TOP));
    envASR->when(FL_WHEN_RELEASE);
    { e2name = new Fl_Group(0, 0, 210, 70, "Frequency Env");
      e2name->box(FL_PLASTIC_UP_BOX);
      e2name->color(FL_CYAN);
      e2name->labelfont(1);
      e2name->labelsize(10);
      e2name->align(Fl_Align(FL_ALIGN_TOP|FL_ALIGN_INSIDE));
      { WidgetPDial* o = e2aval = new WidgetPDial(5, 20, 30, 30, "A.val");
        e2aval->tooltip("Starting value");
        e2aval->box(FL_ROUND_UP_BOX);
        e2aval->color(FL_BACKGROUND_COLOR);
        e2aval->selection_color(FL_INACTIVE_COLOR);
        e2aval->labeltype(FL_NORMAL_LABEL);
        e2aval->labelfont(0);
        e2aval->labelsize(10);
        e2aval->labelcolor(FL_FOREGROUND_COLOR);
        e2aval->maximum(127);
        e2aval->step(1);
        e2aval->callback((Fl_Callback*)cb_e2aval);
        e2aval->align(Fl_Align(FL_ALIGN_BOTTOM));
        e2aval->when(FL_WHEN_CHANGED);
        o->setValueType(VC_EnvelopeFreqVal);
        o->value(env->PA_val);
      } // WidgetPDial* e2aval
      { WidgetPDial* o = e2adt = new WidgetPDial(40, 20, 30, 30, "A.dt");
        e2adt->tooltip("Attack time");
        e2adt->box(FL_ROUND_UP_BOX);
        e2adt->color(FL_BACKGROUND_COLOR);
        e2adt->selection_color(FL_INACTIVE_COLOR);
        e2adt->labeltype(FL_NORMAL_LABEL);
        e2adt->labelfont(0);
        e2adt->labelsize(10);
        e2adt->labelcolor(FL_FOREGROUND_COLOR);
        e2adt->maximum(127);
        e2adt->step(1);
        e2adt->callback((Fl_Callback*)cb_e2adt);
        e2adt->align(Fl_Align(FL_ALIGN_BOTTOM));
        e2adt->when(FL_WHEN_CHANGED);
        o->setValueType(VC_EnvelopeDT);
        o->value(env->PA_dt);
      } // WidgetPDial* e2adt
      { WidgetPDial* o = e2rval = new WidgetPDial(110, 20, 30, 30, "R.val ");
        e2rval->tooltip("Release value");
        e2rval->box(FL_ROUND_UP_BOX);
        e2rval->color(FL_BACKGROUND_COLOR);
        e2rval->selection_color(FL_INACTIVE_COLOR);
        e2rval->labeltype(FL_NORMAL_LABEL);
        e2rval->labelfont(0);
        e2rval->labelsize(10);
        e2rval->labelcolor(FL_FOREGROUND_COLOR);
        e2rval->maximum(127);
        e2rval->step(1);
        e2rval->callback((Fl_Callback*)cb_e2rval);
        e2rval->align(Fl_Align(FL_ALIGN_BOTTOM));
        e2rval->when(FL_WHEN_CHANGED);
        o->setValueType(VC_EnvelopeFreqVal);
        o->value(env->PR_val);
      } // WidgetPDial* e2rval
      { WidgetPDial* o = e2rdt = new WidgetPDial(75, 20, 30, 30, "R.dt");
        e2rdt->tooltip("Release time");
        e2rdt->box(FL_ROUND_UP_BOX);
        e2rdt->color(FL_BACKGROUND_COLOR);
        e2rdt->selection_color(FL_INACTIVE_COLOR);
        e2rdt->labeltype(FL_NORMAL_LABEL);
        e2rdt->labelfont(0);
        e2rdt->labelsize(10);
        e2rdt->labelcolor(FL_FOREGROUND_COLOR);
        e2rdt->maximum(127);
        e2rdt->step(1);
        e2rdt->callback((Fl_Callback*)cb_e2rdt);
        e2rdt->align(Fl_Align(FL_ALIGN_BOTTOM));
        e2rdt->when(FL_WHEN_CHANGED);
        o->setValueType(VC_EnvelopeDT);
        o->value(env->PR_dt);
      } // WidgetPDial* e2rdt
      { WidgetPDial* o = e2envstretch = new WidgetPDial(145, 25, 25, 25, " Stretch");
        e2envstretch->tooltip("Envelope stretch (on lower notes makes the envelope longer)");
        e2envstretch->box(FL_ROUND_UP_BOX);
        e2envstretch->color(FL_BACKGROUND_COLOR);
        e2envstretch->selection_color(FL_INACTIVE_COLOR);
        e2envstretch->labeltype(FL_NORMAL_LABEL);
        e2envstretch->labelfont(0);
        e2envstretch->labelsize(10);
        e2envstretch->labelcolor(FL_FOREGROUND_COLOR);
        e2envstretch->maximum(127);
        e2envstretch->step(1);
        e2envstretch->callback((Fl_Callback*)cb_e2envstretch);
        e2envstretch->align(Fl_Align(FL_ALIGN_BOTTOM));
        e2envstretch->when(FL_WHEN_CHANGED);
        o->value(env->Penvstretch);
        o->setValueType(VC_EnvStretch);
      } // WidgetPDial* e2envstretch
      { Fl_Check_Button2* o = e2forcedrelease = new Fl_Check_Button2(185, 25, 15, 25, "frcR");
        e2forcedrelease->tooltip("Forced release");
        e2forcedrelease->box(FL_NO_BOX);
        e2forcedrelease->down_box(FL_DOWN_BOX);
        e2forcedrelease->color(FL_BACKGROUND_COLOR);
        e2forcedrelease->selection_color(FL_FOREGROUND_COLOR);
        e2forcedrelease->labeltype(FL_NORMAL_LABEL);
        e2forcedrelease->labelfont(0);
        e2forcedrelease->labelsize(10);
        e2forcedrelease->labelcolor(FL_FOREGROUND_COLOR);
        e2forcedrelease->callback((Fl_Callback*)cb_e2forcedrelease);
        e2forcedrelease->align(Fl_Align(FL_ALIGN_BOTTOM_LEFT));
        e2forcedrelease->when(FL_WHEN_RELEASE);
        o->value(env->Pforcedrelease);
      } // Fl_Check_Button2* e2forcedrelease
      { e2C = new Fl_Button(155, 5, 15, 15, "C");
        e2C->box(FL_THIN_UP_BOX);
        e2C->color((Fl_Color)179);
        e2C->labelfont(1);
        e2C->labelsize(10);
        e2C->labelcolor(FL_BACKGROUND2_COLOR);
        e2C->callback((Fl_Callback*)cb_e2C);
      } // Fl_Button* e2C
      { e2P = new Fl_Button(172, 5, 15, 15, "P");
        e2P->box(FL_THIN_UP_BOX);
        e2P->color((Fl_Color)179);
        e2P->labelfont(1);
        e2P->labelsize(10);
        e2P->labelcolor(FL_BACKGROUND2_COLOR);
        e2P->callback((Fl_Callback*)cb_e2P);
      } // Fl_Button* e2P
      e2name->end();
    } // Fl_Group* e2name
    { e2E = new Fl_Button(190, 5, 15, 15, "E");
      e2E->tooltip("Envelope window");
      e2E->box(FL_PLASTIC_UP_BOX);
      e2E->labelfont(1);
      e2E->labelsize(10);
      e2E->callback((Fl_Callback*)cb_e2E);
    } // Fl_Button* e2E
    envASR->end();
  } // Fl_Group* envASR
  return envASR;
}

Fl_Group* EnvelopeUI::make_ADSRfilter_window() {
  { envADSRfilter = new Fl_Group(0, 0, 275, 70);
    envADSRfilter->box(FL_FLAT_BOX);
    envADSRfilter->color(FL_LIGHT1);
    envADSRfilter->selection_color(FL_BACKGROUND_COLOR);
    envADSRfilter->labeltype(FL_NO_LABEL);
    envADSRfilter->labelfont(1);
    envADSRfilter->labelsize(14);
    envADSRfilter->labelcolor(FL_FOREGROUND_COLOR);
    envADSRfilter->user_data((void*)(this));
    envADSRfilter->align(Fl_Align(FL_ALIGN_TOP));
    envADSRfilter->when(FL_WHEN_RELEASE);
    { e3name = new Fl_Group(0, 0, 275, 70, "Filter Envelope");
      e3name->box(FL_PLASTIC_UP_BOX);
      e3name->color(FL_CYAN);
      e3name->labelfont(1);
      e3name->labelsize(10);
      e3name->align(Fl_Align(FL_ALIGN_TOP|FL_ALIGN_INSIDE));
      { WidgetPDial* o = e3aval = new WidgetPDial(5, 20, 30, 30, "A.val");
        e3aval->tooltip("Starting value");
        e3aval->box(FL_ROUND_UP_BOX);
        e3aval->color(FL_BACKGROUND_COLOR);
        e3aval->selection_color(FL_INACTIVE_COLOR);
        e3aval->labeltype(FL_NORMAL_LABEL);
        e3aval->labelfont(0);
        e3aval->labelsize(10);
        e3aval->labelcolor(FL_FOREGROUND_COLOR);
        e3aval->maximum(127);
        e3aval->step(1);
        e3aval->callback((Fl_Callback*)cb_e3aval);
        e3aval->align(Fl_Align(FL_ALIGN_BOTTOM));
        e3aval->when(FL_WHEN_CHANGED);
        o->setValueType(VC_EnvelopeFilterVal);
        o->value(env->PA_val);
      } // WidgetPDial* e3aval
      { WidgetPDial* o = e3adt = new WidgetPDial(40, 20, 30, 30, "A.dt");
        e3adt->tooltip("Attack time");
        e3adt->box(FL_ROUND_UP_BOX);
        e3adt->color(FL_BACKGROUND_COLOR);
        e3adt->selection_color(FL_INACTIVE_COLOR);
        e3adt->labeltype(FL_NORMAL_LABEL);
        e3adt->labelfont(0);
        e3adt->labelsize(10);
        e3adt->labelcolor(FL_FOREGROUND_COLOR);
        e3adt->maximum(127);
        e3adt->step(1);
        e3adt->callback((Fl_Callback*)cb_e3adt);
        e3adt->align(Fl_Align(FL_ALIGN_BOTTOM));
        e3adt->when(FL_WHEN_CHANGED);
        o->setValueType(VC_EnvelopeDT);
        o->value(env->PA_dt);
      } // WidgetPDial* e3adt
      { WidgetPDial* o = e3dval = new WidgetPDial(75, 20, 30, 30, "D.val");
        e3dval->tooltip("decay value");
        e3dval->box(FL_ROUND_UP_BOX);
        e3dval->color(FL_BACKGROUND_COLOR);
        e3dval->selection_color(FL_INACTIVE_COLOR);
        e3dval->labeltype(FL_NORMAL_LABEL);
        e3dval->labelfont(0);
        e3dval->labelsize(10);
        e3dval->labelcolor(FL_FOREGROUND_COLOR);
        e3dval->maximum(127);
        e3dval->step(1);
        e3dval->callback((Fl_Callback*)cb_e3dval);
        e3dval->align(Fl_Align(FL_ALIGN_BOTTOM));
        e3dval->when(FL_WHEN_CHANGED);
        o->setValueType(VC_EnvelopeFilterVal);
        o->value(env->PD_val);
      } // WidgetPDial* e3dval
      { WidgetPDial* o = e3ddt = new WidgetPDial(110, 20, 30, 30, "D.dt");
        e3ddt->tooltip("decay time");
        e3ddt->box(FL_ROUND_UP_BOX);
        e3ddt->color(FL_BACKGROUND_COLOR);
        e3ddt->selection_color(FL_INACTIVE_COLOR);
        e3ddt->labeltype(FL_NORMAL_LABEL);
        e3ddt->labelfont(0);
        e3ddt->labelsize(10);
        e3ddt->labelcolor(FL_FOREGROUND_COLOR);
        e3ddt->maximum(127);
        e3ddt->step(1);
        e3ddt->callback((Fl_Callback*)cb_e3ddt);
        e3ddt->align(Fl_Align(FL_ALIGN_BOTTOM));
        e3ddt->when(FL_WHEN_CHANGED);
        o->setValueType(VC_EnvelopeDT);
        o->value(env->PD_dt);
      } // WidgetPDial* e3ddt
      { WidgetPDial* o = e3rdt = new WidgetPDial(145, 20, 30, 30, "R.dt");
        e3rdt->tooltip("Release time");
        e3rdt->box(FL_ROUND_UP_BOX);
        e3rdt->color(FL_BACKGROUND_COLOR);
        e3rdt->selection_color(FL_INACTIVE_COLOR);
        e3rdt->labeltype(FL_NORMAL_LABEL);
        e3rdt->labelfont(0);
        e3rdt->labelsize(10);
        e3rdt->labelcolor(FL_FOREGROUND_COLOR);
        e3rdt->maximum(127);
        e3rdt->step(1);
        e3rdt->callback((Fl_Callback*)cb_e3rdt);
        e3rdt->align(Fl_Align(FL_ALIGN_BOTTOM));
        e3rdt->when(FL_WHEN_CHANGED);
        o->setValueType(VC_EnvelopeDT);
        o->value(env->PR_dt);
      } // WidgetPDial* e3rdt
      { WidgetPDial* o = e3rval = new WidgetPDial(180, 20, 30, 30, "R.val ");
        e3rval->tooltip("Release value");
        e3rval->box(FL_ROUND_UP_BOX);
        e3rval->color(FL_BACKGROUND_COLOR);
        e3rval->selection_color(FL_INACTIVE_COLOR);
        e3rval->labeltype(FL_NORMAL_LABEL);
        e3rval->labelfont(0);
        e3rval->labelsize(10);
        e3rval->labelcolor(FL_FOREGROUND_COLOR);
        e3rval->maximum(127);
        e3rval->step(1);
        e3rval->callback((Fl_Callback*)cb_e3rval);
        e3rval->align(Fl_Align(FL_ALIGN_BOTTOM));
        e3rval->when(FL_WHEN_CHANGED);
        o->setValueType(VC_EnvelopeFilterVal);
        o->value(env->PR_val);
      } // WidgetPDial* e3rval
      { WidgetPDial* o = e3envstretch = new WidgetPDial(215, 25, 25, 25, " Stretch");
        e3envstretch->tooltip("Envelope stretch (on lower notes makes the envelope longer)");
        e3envstretch->box(FL_ROUND_UP_BOX);
        e3envstretch->color(FL_BACKGROUND_COLOR);
        e3envstretch->selection_color(FL_INACTIVE_COLOR);
        e3envstretch->labeltype(FL_NORMAL_LABEL);
        e3envstretch->labelfont(0);
        e3envstretch->labelsize(10);
        e3envstretch->labelcolor(FL_FOREGROUND_COLOR);
        e3envstretch->maximum(127);
        e3envstretch->step(1);
        e3envstretch->callback((Fl_Callback*)cb_e3envstretch);
        e3envstretch->align(Fl_Align(FL_ALIGN_BOTTOM));
        e3envstretch->when(FL_WHEN_CHANGED);
        o->value(env->Penvstretch);
        o->setValueType(VC_EnvStretch);
      } // WidgetPDial* e3envstretch
      { Fl_Check_Button2* o = e3forcedrelease = new Fl_Check_Button2(250, 30, 15, 20, "frcR");
        e3forcedrelease->tooltip("Forced Release");
        e3forcedrelease->box(FL_NO_BOX);
        e3forcedrelease->down_box(FL_DOWN_BOX);
        e3forcedrelease->color(FL_BACKGROUND_COLOR);
        e3forcedrelease->selection_color(FL_FOREGROUND_COLOR);
        e3forcedrelease->labeltype(FL_NORMAL_LABEL);
        e3forcedrelease->labelfont(0);
        e3forcedrelease->labelsize(10);
        e3forcedrelease->labelcolor(FL_FOREGROUND_COLOR);
        e3forcedrelease->callback((Fl_Callback*)cb_e3forcedrelease);
        e3forcedrelease->align(Fl_Align(FL_ALIGN_BOTTOM_LEFT));
        e3forcedrelease->when(FL_WHEN_RELEASE);
        o->value(env->Pforcedrelease);
      } // Fl_Check_Button2* e3forcedrelease
      { e3E = new Fl_Button(255, 5, 15, 15, "E");
        e3E->box(FL_PLASTIC_UP_BOX);
        e3E->labelfont(1);
        e3E->labelsize(10);
        e3E->callback((Fl_Callback*)cb_e3E);
      } // Fl_Button* e3E
      { e3C = new Fl_Button(220, 5, 15, 15, "C");
        e3C->box(FL_THIN_UP_BOX);
        e3C->color((Fl_Color)179);
        e3C->labelfont(1);
        e3C->labelsize(10);
        e3C->labelcolor(FL_BACKGROUND2_COLOR);
        e3C->callback((Fl_Callback*)cb_e3C);
      } // Fl_Button* e3C
      { e3P = new Fl_Button(237, 5, 15, 15, "P");
        e3P->box(FL_THIN_UP_BOX);
        e3P->color((Fl_Color)179);
        e3P->labelfont(1);
        e3P->labelsize(10);
        e3P->labelcolor(FL_BACKGROUND2_COLOR);
        e3P->callback((Fl_Callback*)cb_e3P);
      } // Fl_Button* e3P
      e3name->end();
    } // Fl_Group* e3name
    envADSRfilter->end();
  } // Fl_Group* envADSRfilter
  return envADSRfilter;
}

Fl_Group* EnvelopeUI::make_ASRbw_window() {
  { envASRbw = new Fl_Group(0, 0, 210, 70);
    envASRbw->box(FL_FLAT_BOX);
    envASRbw->color(FL_BACKGROUND_COLOR);
    envASRbw->selection_color(FL_BACKGROUND_COLOR);
    envASRbw->labeltype(FL_NO_LABEL);
    envASRbw->labelfont(0);
    envASRbw->labelsize(14);
    envASRbw->labelcolor(FL_FOREGROUND_COLOR);
    envASRbw->user_data((void*)(this));
    envASRbw->align(Fl_Align(FL_ALIGN_TOP));
    envASRbw->when(FL_WHEN_RELEASE);
    { e4name = new Fl_Group(0, 0, 210, 70, "BandWidth Env");
      e4name->box(FL_PLASTIC_UP_BOX);
      e4name->color(FL_CYAN);
      e4name->labelfont(1);
      e4name->labelsize(10);
      e4name->align(Fl_Align(FL_ALIGN_TOP|FL_ALIGN_INSIDE));
      { WidgetPDial* o = e4aval = new WidgetPDial(8, 20, 30, 30, "A.val");
        e4aval->tooltip("Bandwidth multiplier, start");
        e4aval->box(FL_ROUND_UP_BOX);
        e4aval->color(FL_BACKGROUND_COLOR);
        e4aval->selection_color(FL_INACTIVE_COLOR);
        e4aval->labeltype(FL_NORMAL_LABEL);
        e4aval->labelfont(0);
        e4aval->labelsize(10);
        e4aval->labelcolor(FL_FOREGROUND_COLOR);
        e4aval->maximum(127);
        e4aval->step(1);
        e4aval->callback((Fl_Callback*)cb_e4aval);
        e4aval->align(Fl_Align(FL_ALIGN_BOTTOM));
        e4aval->when(FL_WHEN_CHANGED);
        o->value(env->PA_val);
        o->setValueType(VC_EnvelopeBandwidthVal);
      } // WidgetPDial* e4aval
      { WidgetPDial* o = e4adt = new WidgetPDial(43, 20, 30, 30, "A.dt");
        e4adt->tooltip("Attack time");
        e4adt->box(FL_ROUND_UP_BOX);
        e4adt->color(FL_BACKGROUND_COLOR);
        e4adt->selection_color(FL_INACTIVE_COLOR);
        e4adt->labeltype(FL_NORMAL_LABEL);
        e4adt->labelfont(0);
        e4adt->labelsize(10);
        e4adt->labelcolor(FL_FOREGROUND_COLOR);
        e4adt->maximum(127);
        e4adt->step(1);
        e4adt->callback((Fl_Callback*)cb_e4adt);
        e4adt->align(Fl_Align(FL_ALIGN_BOTTOM));
        e4adt->when(FL_WHEN_CHANGED);
        o->setValueType(VC_EnvelopeDT);
        o->value(env->PA_dt);
      } // WidgetPDial* e4adt
      { WidgetPDial* o = e4rval = new WidgetPDial(113, 20, 30, 30, "R.val");
        e4rval->tooltip("Bandwidth multiplier, release");
        e4rval->box(FL_ROUND_UP_BOX);
        e4rval->color(FL_BACKGROUND_COLOR);
        e4rval->selection_color(FL_INACTIVE_COLOR);
        e4rval->labeltype(FL_NORMAL_LABEL);
        e4rval->labelfont(0);
        e4rval->labelsize(10);
        e4rval->labelcolor(FL_FOREGROUND_COLOR);
        e4rval->maximum(127);
        e4rval->step(1);
        e4rval->callback((Fl_Callback*)cb_e4rval);
        e4rval->align(Fl_Align(FL_ALIGN_BOTTOM));
        e4rval->when(FL_WHEN_CHANGED);
        o->value(env->PR_val);
        o->setValueType(VC_EnvelopeBandwidthVal);
      } // WidgetPDial* e4rval
      { WidgetPDial* o = e4rdt = new WidgetPDial(78, 20, 30, 30, "R.dt");
        e4rdt->tooltip("Release time");
        e4rdt->box(FL_ROUND_UP_BOX);
        e4rdt->color(FL_BACKGROUND_COLOR);
        e4rdt->selection_color(FL_INACTIVE_COLOR);
        e4rdt->labeltype(FL_NORMAL_LABEL);
        e4rdt->labelfont(0);
        e4rdt->labelsize(10);
        e4rdt->labelcolor(FL_FOREGROUND_COLOR);
        e4rdt->maximum(127);
        e4rdt->step(1);
        e4rdt->callback((Fl_Callback*)cb_e4rdt);
        e4rdt->align(Fl_Align(FL_ALIGN_BOTTOM));
        e4rdt->when(FL_WHEN_CHANGED);
        o->setValueType(VC_EnvelopeDT);
        o->value(env->PR_dt);
      } // WidgetPDial* e4rdt
      { WidgetPDial* o = e4envstretch = new WidgetPDial(148, 25, 25, 25, "Stretch");
        e4envstretch->tooltip("Envelope stretch (on lower notes makes the envelope longer)");
        e4envstretch->box(FL_ROUND_UP_BOX);
        e4envstretch->color(FL_BACKGROUND_COLOR);
        e4envstretch->selection_color(FL_INACTIVE_COLOR);
        e4envstretch->labeltype(FL_NORMAL_LABEL);
        e4envstretch->labelfont(0);
        e4envstretch->labelsize(10);
        e4envstretch->labelcolor(FL_FOREGROUND_COLOR);
        e4envstretch->maximum(127);
        e4envstretch->step(1);
        e4envstretch->callback((Fl_Callback*)cb_e4envstretch);
        e4envstretch->align(Fl_Align(FL_ALIGN_BOTTOM));
        e4envstretch->when(FL_WHEN_CHANGED);
        o->value(env->Penvstretch);
        o->setValueType(VC_EnvStretch);
      } // WidgetPDial* e4envstretch
      { Fl_Check_Button2* o = e4forcedrelease = new Fl_Check_Button2(185, 25, 15, 25, "frcR");
        e4forcedrelease->tooltip("Forced release");
        e4forcedrelease->box(FL_NO_BOX);
        e4forcedrelease->down_box(FL_DOWN_BOX);
        e4forcedrelease->color(FL_BACKGROUND_COLOR);
        e4forcedrelease->selection_color(FL_FOREGROUND_COLOR);
        e4forcedrelease->labeltype(FL_NORMAL_LABEL);
        e4forcedrelease->labelfont(0);
        e4forcedrelease->labelsize(10);
        e4forcedrelease->labelcolor(FL_FOREGROUND_COLOR);
        e4forcedrelease->callback((Fl_Callback*)cb_e4forcedrelease);
        e4forcedrelease->align(Fl_Align(FL_ALIGN_BOTTOM_LEFT));
        e4forcedrelease->when(FL_WHEN_RELEASE);
        o->value(env->Pforcedrelease);
      } // Fl_Check_Button2* e4forcedrelease
      { e4C = new Fl_Button(155, 5, 15, 15, "C");
        e4C->box(FL_THIN_UP_BOX);
        e4C->color((Fl_Color)179);
        e4C->labelfont(1);
        e4C->labelsize(10);
        e4C->labelcolor(FL_BACKGROUND2_COLOR);
        e4C->callback((Fl_Callback*)cb_e4C);
      } // Fl_Button* e4C
      { e4P = new Fl_Button(172, 5, 15, 15, "P");
        e4P->box(FL_THIN_UP_BOX);
        e4P->color((Fl_Color)179);
        e4P->labelfont(1);
        e4P->labelsize(10);
        e4P->labelcolor(FL_BACKGROUND2_COLOR);
        e4P->callback((Fl_Callback*)cb_e4P);
      } // Fl_Button* e4P
      e4name->end();
    } // Fl_Group* e4name
    { e4E = new Fl_Button(190, 5, 15, 15, "E");
      e4E->box(FL_PLASTIC_UP_BOX);
      e4E->labelfont(1);
      e4E->labelsize(10);
      e4E->callback((Fl_Callback*)cb_e4E);
    } // Fl_Button* e4E
    envASRbw->end();
  } // Fl_Group* envASRbw
  return envASRbw;
}

Fl_Group* EnvelopeUI::make_free_window() {
  { envfree = new Fl_Group(0, 0, 205, 70);
    envfree->box(FL_FLAT_BOX);
    envfree->color(FL_LIGHT1);
    envfree->selection_color(FL_BACKGROUND_COLOR);
    envfree->labeltype(FL_NO_LABEL);
    envfree->labelfont(1);
    envfree->labelsize(14);
    envfree->labelcolor(FL_FOREGROUND_COLOR);
    envfree->user_data((void*)(this));
    envfree->align(Fl_Align(FL_ALIGN_TOP));
    envfree->when(FL_WHEN_RELEASE);
    { envfreegroup = new Fl_Group(0, 0, 205, 70, "Amplitude Env");
      envfreegroup->box(FL_PLASTIC_UP_BOX);
      envfreegroup->color(FL_CYAN);
      envfreegroup->labelfont(1);
      envfreegroup->labelsize(10);
      envfreegroup->align(Fl_Align(FL_ALIGN_TOP|FL_ALIGN_INSIDE));
      { EnvelopeFreeEdit* o = freeeditsmall = new EnvelopeFreeEdit(5, 20, 195, 45, "Envelope");
        freeeditsmall->box(FL_FLAT_BOX);
        freeeditsmall->color(FL_FOREGROUND_COLOR);
        freeeditsmall->selection_color(FL_BACKGROUND_COLOR);
        freeeditsmall->labeltype(FL_NORMAL_LABEL);
        freeeditsmall->labelfont(0);
        freeeditsmall->labelsize(14);
        freeeditsmall->labelcolor(FL_FOREGROUND_COLOR);
        freeeditsmall->callback((Fl_Callback*)cb_freeeditsmall);
        freeeditsmall->align(Fl_Align(FL_ALIGN_CENTER));
        freeeditsmall->when(FL_WHEN_RELEASE);
        Fl_Group::current()->resizable(freeeditsmall);
        o->init(env, npart, kititem, engine, group);
      } // EnvelopeFreeEdit* freeeditsmall
      envfreegroup->end();
      Fl_Group::current()->resizable(envfreegroup);
    } // Fl_Group* envfreegroup
    { efC = new Fl_Button(150, 5, 15, 15, "C");
      efC->box(FL_THIN_UP_BOX);
      efC->color((Fl_Color)179);
      efC->labelfont(1);
      efC->labelsize(10);
      efC->labelcolor(FL_BACKGROUND2_COLOR);
      efC->callback((Fl_Callback*)cb_efC);
    } // Fl_Button* efC
    { efP = new Fl_Button(168, 5, 15, 15, "P");
      efP->box(FL_THIN_UP_BOX);
      efP->color((Fl_Color)179);
      efP->labelfont(1);
      efP->labelsize(10);
      efP->labelcolor(FL_BACKGROUND2_COLOR);
      efP->callback((Fl_Callback*)cb_efP);
    } // Fl_Button* efP
    { efE = new Fl_Button(185, 5, 15, 15, "E");
      efE->box(FL_PLASTIC_UP_BOX);
      efE->labelfont(1);
      efE->labelsize(10);
      efE->callback((Fl_Callback*)cb_efE);
    } // Fl_Button* efE
    envfree->end();
  } // Fl_Group* envfree
  return envfree;
}

void EnvelopeUI::send_data(int action, int group, int control, float value, int type, int insert , int offset ) {
  //
      collect_data(synth, value, action, type, control, npart, kititem, engine, insert, group, offset);
}

void EnvelopeUI::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 insert = getData->data.insert;
      unsigned char param = getData->data.parameter;
      unsigned char offset = getData->data.offset;
  
      int value_int = lrint(value);
      bool value_bool = _SYS_::F2B(value);
      bool isFreemode = _SYS_::F2B(freemodebutton->value());
      bool NotUs = ((getData->data.source & TOPLEVEL::action::noAction) != TOPLEVEL::action::fromGUI || (getData->data.source & TOPLEVEL::action::forceUpdate));
  
      if (part != npart || (eng >= 128 && eng != engine))
          return;
  
      if (insert == TOPLEVEL::insert::envelopePointAdd || insert == TOPLEVEL::insert::envelopePointDelete || insert == TOPLEVEL::insert::envelopePointChange)
      {
          if (insert == TOPLEVEL::insert::envelopePointChange) // adjust point
              freeedit->lastpoint = control;
          else if (offset > 127) // delete point
              freeedit->lastpoint -= 1;
          else // add point
              freeedit->lastpoint += 1;
          freeedit->redraw();
          envfree->redraw();
          sustaincounter->value(env->Penvsustain);
          sustaincounter->maximum(env->Penvpoints-2);
          return;
      }
  
      bool change = true;
      switch(control)
      {
          case ENVELOPEINSERT::control::attackLevel:
              if (NotUs)
              {
                  switch (param)
                  {
                      case TOPLEVEL::insertType::frequency:
                          e2aval->value(value);
                          break;
                      case TOPLEVEL::insertType::filter:
                          e3aval->value(value);
                          break;
                      case TOPLEVEL::insertType::bandwidth:
                          e4aval->value(value);
                          break;
                  }
              }
              break;
  
          case ENVELOPEINSERT::control::attackTime:
              if (NotUs)
              {
                  switch (param)
                  {
                      case TOPLEVEL::insertType::amplitude:
                          e1adt->value(value);
                          break;
                      case TOPLEVEL::insertType::frequency:
                          e2adt->value(value);
                          break;
                      case TOPLEVEL::insertType::filter:
                          e3adt->value(value);
                          break;
                      case TOPLEVEL::insertType::bandwidth:
                          e4adt->value(value);
                          break;
                  }
              }
              break;
  
          case ENVELOPEINSERT::control::decayLevel:
              if (param == TOPLEVEL::insertType::filter && NotUs)
                  e3dval->value(value);
              break;
  
          case ENVELOPEINSERT::control::decayTime:
              if (NotUs)
              {
                  switch (param)
                  {
                      case TOPLEVEL::insertType::amplitude:
                          e1ddt->value(value);
                          break;
                      case TOPLEVEL::insertType::filter:
                          e3ddt->value(value);
                          break;
                  }
              }
              break;
  
          case ENVELOPEINSERT::control::sustainLevel:
              if (param == TOPLEVEL::insertType::amplitude && NotUs)
                  e1sval->value(value);
              break;
  
          case ENVELOPEINSERT::control::releaseTime:
              if (NotUs)
              {
                  switch (param)
                  {
                      case TOPLEVEL::insertType::amplitude:
                          e1rdt->value(value);
                          break;
                      case TOPLEVEL::insertType::frequency:
                          e2rdt->value(value);
                          break;
                      case TOPLEVEL::insertType::filter:
                          e3rdt->value(value);
                          break;
                      case TOPLEVEL::insertType::bandwidth:
                          e4rdt->value(value);
                          break;
                  }
              }
              break;
  
          case ENVELOPEINSERT::control::releaseLevel:
              if (NotUs)
              {
                  switch (param)
                  {
                      case TOPLEVEL::insertType::frequency:
                          e2rval->value(value);
                          break;
                      case TOPLEVEL::insertType::filter:
                          e3rval->value(value);
                          break;
                      case TOPLEVEL::insertType::bandwidth:
                          e4rval->value(value);
                          break;
                  }
              }
              break;
  
          case ENVELOPEINSERT::control::stretch:
              switch (param)
              {
                  case TOPLEVEL::insertType::amplitude:
                      e1envstretch->value(value);
                      break;
                  case TOPLEVEL::insertType::frequency:
                      e2envstretch->value(value);
                      break;
                  case TOPLEVEL::insertType::filter:
                      e3envstretch->value(value);
                      break;
                  case TOPLEVEL::insertType::bandwidth:
                      e4envstretch->value(value);
                      break;
              }
              envstretchdial->value(value);
              change = false;
              break;
  
          case ENVELOPEINSERT::control::forcedRelease:
              switch (param)
              {
                  case TOPLEVEL::insertType::amplitude:
                      e1forcedrelease->value(value_bool);
                      break;
                  case TOPLEVEL::insertType::frequency:
                      e2forcedrelease->value(value_bool);
                      break;
                  case TOPLEVEL::insertType::filter:
                      e3forcedrelease->value(value_bool);
                      break;
                  case TOPLEVEL::insertType::bandwidth:
                      e4forcedrelease->value(value_bool);
                      break;
              }
              forcedreleasecheck->value(value_bool);
              change = false;
              break;
  
          case ENVELOPEINSERT::control::linearEnvelope:
              if (param == TOPLEVEL::insertType::amplitude)
              {
                  e1linearenvelope->value(value_bool);
                  linearenvelopecheck->value(value_bool);
              }
              change = false;
              break;
  
          case ENVELOPEINSERT::control::enableFreeMode:
              reinitcore(value_bool);
              break;
  
          case ENVELOPEINSERT::control::sustainPoint:
              if (isFreemode && NotUs)
                  sustaincounter->value(value_int);
              break;
      }
      if (change)
          freeedit->redraw();
}

void EnvelopeUI::init(EnvelopeParams *env_, int npart_, int kititem_, int engine_, int group_) {
  //
      env=env_;
      synth = env->getSynthEngine();
      npart = npart_;
      kititem = kititem_;
      engine = engine_;
      group = group_;
      lastfreeX = lastfreeY = lastfreeW = 0xffff;
      make_ADSR_window();
      make_ASR_window();
      make_ADSRfilter_window();
      make_ASRbw_window();
      make_free_window();
      make_freemode_edit_window();
  
      envwindow=NULL;
  
      if (env->Envmode == PART::envelope::groupmode::frequency) envfreegroup->label("Frequency Env");
      if (env->Envmode == PART::envelope::groupmode::filter) envfreegroup->label("Filter Envelope");
      if (env->Envmode == PART::envelope::groupmode::bandwidth) envfreegroup->label("Bandwidth Env");
  
      freemodeeditwindow->label(this->label());
      freemodeeditwindow->hide();
  
      freeeditsmall->setpair(freeedit);
      freeedit->setpair(freeeditsmall);
  
      refresh();
}

void EnvelopeUI::reinitcore(bool freemode) {
  //
      if (freemode)
          freemodebutton->value(1);
      else
          freemodebutton->value(0);
  
      hide();
  
      envwindow->hide();
      Fl_Group *par = envwindow->parent();
      par->hide();
  
      refresh();
      envwindow->show();
      par->redraw();
  
      par->show();
      show();
  
      if (freemode)
      {
          freemodebutton->value(1);
          addpoint->show();
          deletepoint->show();
          forcedreleasecheck->show();
      }
      else
      {
          freemodebutton->value(0);
          addpoint->hide();
          deletepoint->hide();
          forcedreleasecheck->hide();
  }
}

void EnvelopeUI::refresh() {
  //
      freemodebutton->value(env->Pfreemode);
  
      sustaincounter->value(env->Penvsustain);
      if (env->Pfreemode==0)
          sustaincounter->hide();
      else
          sustaincounter->show();
      sustaincounter->maximum(env->Penvpoints-2);
  
      envstretchdial->value(env->Penvstretch);
      if (env->Pfreemode==0)
          envstretchdial->hide();
      else
          envstretchdial->show();
  
      linearenvelopecheck->value(env->Plinearenvelope);
      if ((env->Pfreemode==0)||(env->Envmode>2))
          linearenvelopecheck->hide();
      else
          linearenvelopecheck->show();
  
      forcedreleasecheck->value(env->Pforcedrelease);
      if (env->Pfreemode==0)
          forcedreleasecheck->hide();
  
      freeedit->redraw();
  
      if (env->Pfreemode==0)
      {
          switch(env->Envmode)
          {
              case(PART::envelope::groupmode::amplitudeLin):
              case(PART::envelope::groupmode::amplitudeLog):
                  e1adt->value(env->PA_dt);
                  e1ddt->value(env->PD_dt);
                  e1sval->value(env->PS_val);
                  setAmpSusVType(env->Plinearenvelope);
                  e1rdt->value(env->PR_dt);
                  e1envstretch->value(env->Penvstretch);
                  e1linearenvelope->value(env->Plinearenvelope);
                  e1forcedrelease->value(env->Pforcedrelease);
                  break;
              case(PART::envelope::groupmode::frequency):
                  e2aval->value(env->PA_val);
                  e2adt->value(env->PA_dt);
                  e2rdt->value(env->PR_dt);
                  e2rval->value(env->PR_val);
                  e2envstretch->value(env->Penvstretch);
                  e2forcedrelease->value(env->Pforcedrelease);
                  break;
              case(PART::envelope::groupmode::filter):
                  e3aval->value(env->PA_val);
                  e3adt->value(env->PA_dt);
                  e3dval->value(env->PD_val);
                  e3ddt->value(env->PD_dt);
                  e3rdt->value(env->PR_dt);
                  e3rval->value(env->PR_val);
                  e3envstretch->value(env->Penvstretch);
                  e3forcedrelease->value(env->Pforcedrelease);
                  break;
              case(PART::envelope::groupmode::bandwidth):
                  e4aval->value(env->PA_val);
                  e4adt->value(env->PA_dt);
                  e4rdt->value(env->PR_dt);
                  e4rval->value(env->PR_val);
                  e4envstretch->value(env->Penvstretch);
                  e4forcedrelease->value(env->Pforcedrelease);
                  break;
              default:
                  break;
          }
      }
      else
          envfree->redraw();
  
      envADSR->hide();
      envASR->hide();
      envADSRfilter->hide();
      envASRbw->hide();
      envfree->hide();
  /*
      We now always initialse and position related groups as well as the freemode one
      This is to ensure that resizing will have the correct starting size and position
      even if a part was loaded specifying the freemode form.
  */
      //if (env->Pfreemode==0)
      {
          switch(env->Envmode)
          {
              case(PART::envelope::groupmode::amplitudeLin):
              case(PART::envelope::groupmode::amplitudeLog):
                  envwindow=envADSR;
                  break;
              case(PART::envelope::groupmode::frequency):
                  envwindow=envASR;
                  break;
              case(PART::envelope::groupmode::filter):
                  envwindow=envADSRfilter;
                  break;
              case(PART::envelope::groupmode::bandwidth):
                  envwindow=envASRbw;
                  break;
              default:
                  break;
          }
          envwindow->resize(this->x(),this->y(),this->w(),this->h());
      }
      //else
      if (env->Pfreemode)
      {
          envwindow=envfree;
          envwindow->resize(this->x(),this->y(),this->w(),this->h());
      }
  
      //envwindow->resize(this->x(),this->y(),this->w(),this->h());
  
      envwindow->show();
}

void EnvelopeUI::showfree() {
  //
      int fetchW, fetchH, fetchX, fetchY, fetchO;
      loadWin(synth, fetchW, fetchH, fetchX, fetchY, fetchO, "xEnvelope-free " + to_string(engine) + " " + to_string(group));
  
      if (fetchW < freeDW || fetchH < freeDH)
      {
          fetchW = freeDW;
          fetchH = freeDH;
      }
      checkSane(fetchX, fetchY, fetchW, fetchH, freeDW, freeDH);
  
      freemodeeditwindow->resize(fetchX, fetchY, fetchW, fetchH);
      freemodeeditwindow->show();
      envfreeRtext();
}

void EnvelopeUI::wincheck() {
  //
      if (!freemodeeditwindow->visible())
          return;
      if (freemodeeditwindow->x() == lastfreeX && freemodeeditwindow->y() == lastfreeY && freemodeeditwindow->w() == lastfreeW)
          return;
      envfreeRtext();
      lastfreeX = freemodeeditwindow->x();
      lastfreeY = freemodeeditwindow->y();
      lastfreeW = freemodeeditwindow->w();
}

void EnvelopeUI::envfreeRtext() {
  //
          int w = freemodeeditwindow->w();
          int h = freemodeeditwindow->h();
          float defW = 575;
          float defH = 180;
          float dW = w / defW;
          float dH = h / defH;
          float dScale;
          if (dW < dH)
              dScale = dW;
          else
              dScale = dH;
          if (dScale < 0.2f)
              dScale = 0.2f;
  
          int size = int(10 * dScale);
          int size11 = int(11 * dScale);
          int size12 = int(12 * dScale);
  
          freemodebutton->labelsize(size11);
          addpoint->labelsize(size11);
          deletepoint->labelsize(size11);
          sustaincounter->labelsize(size11);
              sustaincounter->textsize(size12);
          envstretchdial->labelsize(size);
          linearenvelopecheck->labelsize(size);
          forcedreleasecheck->labelsize(size);
          freecopy->labelsize(size);
          freepaste->labelsize(size);
          freeClose->labelsize(size12);
}

void EnvelopeUI::envRtext(float dScale) {
  //
          int X = this->x();
          int Y = this->y();
          int W = this->w();
          int H = this->h();
  
          int size = int(dScale * 10);
  
  
          e1name->labelsize(size);
          e1adt->labelsize(size);
          e1ddt->labelsize(size);
          e1rdt->labelsize(size);
          e1sval->labelsize(size);
          e1forcedrelease->labelsize(size);
          e1envstretch->labelsize(size);
          e1E->labelsize(size);
          e1linearenvelope->labelsize(size);
          e1C->labelsize(size);
          e1P->labelsize(size);
  
          e2name->labelsize(size);
          e2aval->labelsize(size);
          e2adt->labelsize(size);
          e2rval->labelsize(size);
          e2rdt->labelsize(size);
          e2envstretch->labelsize(size);
          e2forcedrelease->labelsize(size);
          e2C->labelsize(size);
          e2P->labelsize(size);
          e2E->labelsize(size);
  
          e3name->labelsize(size);
          e3aval->labelsize(size);
          e3adt->labelsize(size);
          e3dval->labelsize(size);
          e3ddt->labelsize(size);
          e3rval->labelsize(size);
          e3rdt->labelsize(size);
          e3envstretch->labelsize(size);
          e3forcedrelease->labelsize(size);
          e3C->labelsize(size);
          e3P->labelsize(size);
          e3E->labelsize(size);
  
          e4name->labelsize(size);
          e4aval->labelsize(size);
          e4adt->labelsize(size);
          e4rval->labelsize(size);
          e4rdt->labelsize(size);
          e4envstretch->labelsize(size);
          e4forcedrelease->labelsize(size);
          e4C->labelsize(size);
          e4P->labelsize(size);
          e4E->labelsize(size);
  
          envfreegroup->labelsize(size);
          efC->labelsize(size);
          efP->labelsize(size);
          efE->labelsize(size);
  
          envfree->resize(X, Y, W, H);
  
          freeeditsmall->resize(int(X + 5*dScale), int(Y + 20*dScale), int(W - 9*dScale), int(H - 25*dScale));
}

void EnvelopeUI::setAmpSusVType(bool linear) {
  //
      if (linear)
          e1sval->setValueType(VC_EnvelopeLinAmpSusVal);
      else
          e1sval->setValueType(VC_EnvelopeAmpSusVal);
}
