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

#include "MicrotonalUI.h"
// Microtonal.cc
// Original ZynAddSubFX author Nasca Octavian Paul
// Copyright (C) 2002-2005 Nasca Octavian Paul
// Copyright 2009, Alan Calvert
// Copyright 2016-2024, 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 "Misc/FileMgrFuncs.h"
#include "Misc/TextMsgBuffer.h"

    namespace { // Implementation details...
        TextMsgBuffer& textMsgBuffer = TextMsgBuffer::instance();
    }

void MicrotonalUI::cb_microtonaluiwindow_i(ScaleTrackedWindow*, void*) {
  scaleClose->do_callback();
}
void MicrotonalUI::cb_microtonaluiwindow(ScaleTrackedWindow* o, void* v) {
  ((MicrotonalUI*)(o->user_data()))->cb_microtonaluiwindow_i(o,v);
}

void MicrotonalUI::cb_invertKeys_i(Fl_Check_Button2* o, void*) {
  //
            send_data(TOPLEVEL::action::forceUpdate, SCALES::control::invertScale, o->value(), TOPLEVEL::type::Integer);
}
void MicrotonalUI::cb_invertKeys(Fl_Check_Button2* o, void* v) {
  ((MicrotonalUI*)(o->parent()->parent()->user_data()))->cb_invertKeys_i(o,v);
}

void MicrotonalUI::cb_centerinvertcounter_i(WidgetSpinner* o, void*) {
  //
            send_data(0, SCALES::control::invertedScaleCenter, o->value(), TOPLEVEL::type::Integer);
}
void MicrotonalUI::cb_centerinvertcounter(WidgetSpinner* o, void* v) {
  ((MicrotonalUI*)(o->parent()->parent()->user_data()))->cb_centerinvertcounter_i(o,v);
}

void MicrotonalUI::cb_anotecounter_i(WidgetSpinner* o, void*) {
  //
            send_data(0, SCALES::control::refNote, o->value(), TOPLEVEL::type::Integer);
}
void MicrotonalUI::cb_anotecounter(WidgetSpinner* o, void* v) {
  ((MicrotonalUI*)(o->parent()->parent()->user_data()))->cb_anotecounter_i(o,v);
}

void MicrotonalUI::cb_afreqinput_i(Fl_Value_Input* o, void*) {
  //
            refFreq = o->value();
            afreqset->show();
            AsetBack->show();
}
void MicrotonalUI::cb_afreqinput(Fl_Value_Input* o, void* v) {
  ((MicrotonalUI*)(o->parent()->parent()->user_data()))->cb_afreqinput_i(o,v);
}

void MicrotonalUI::cb_AsetBack_i(Fl_Button* o, void*) {
  //
            if (refFreq < A_MIN)
            {
                refFreq = A_MIN;
                afreqinput->value(refFreq);
            }
            else if (refFreq > A_MAX)
            {
                refFreq = A_MAX;
                afreqinput->value(refFreq);
            }

            afreqset->hide();
            o->hide();

            send_data(0, SCALES::control::refFrequency, refFreq, 0);
}
void MicrotonalUI::cb_AsetBack(Fl_Button* o, void* v) {
  ((MicrotonalUI*)(o->parent()->parent()->user_data()))->cb_AsetBack_i(o,v);
}

void MicrotonalUI::cb_afreqset_i(Fl_Return_Button* o, void*) {
  //
            if (refFreq < A_MIN)
            {
                refFreq = A_MIN;
                afreqinput->value(refFreq);
            }
            else if (refFreq > A_MAX)
            {
                refFreq = A_MAX;
                afreqinput->value(refFreq);
            }
            AsetBack->hide();
            o->hide();

            send_data(0, SCALES::control::refFrequency, refFreq, 0);
}
void MicrotonalUI::cb_afreqset(Fl_Return_Button* o, void* v) {
  ((MicrotonalUI*)(o->parent()->parent()->user_data()))->cb_afreqset_i(o,v);
}

void MicrotonalUI::cb_nameinput_i(Fl_Input* o, void*) {
  //
            send_data(TOPLEVEL::action::lowPrio | TOPLEVEL::action::forceUpdate, SCALES::control::name, 0, TOPLEVEL::type::Integer, UNUSED, textMsgBuffer.push(string(o->value())));
}
void MicrotonalUI::cb_nameinput(Fl_Input* o, void* v) {
  ((MicrotonalUI*)(o->parent()->parent()->user_data()))->cb_nameinput_i(o,v);
}

void MicrotonalUI::cb_commentinput_i(Fl_Input* o, void*) {
  //
            send_data(TOPLEVEL::action::lowPrio | TOPLEVEL::action::forceUpdate, SCALES::control::comment, 0, TOPLEVEL::type::Integer, UNUSED, textMsgBuffer.push(string(o->value())));
}
void MicrotonalUI::cb_commentinput(Fl_Input* o, void* v) {
  ((MicrotonalUI*)(o->parent()->parent()->user_data()))->cb_commentinput_i(o,v);
}

void MicrotonalUI::cb_scaleShift_i(WidgetSpinner* o, void*) {
  //
            send_data(0, SCALES::control::scaleShift, o->value(), TOPLEVEL::type::Integer);
}
void MicrotonalUI::cb_scaleShift(WidgetSpinner* o, void* v) {
  ((MicrotonalUI*)(o->parent()->parent()->user_data()))->cb_scaleShift_i(o,v);
}

void MicrotonalUI::cb_octavesizeoutput_i(Fl_Value_Output* o, void*) {
  //
                  o->value(microtonal->getoctavesize());
}
void MicrotonalUI::cb_octavesizeoutput(Fl_Value_Output* o, void* v) {
  ((MicrotonalUI*)(o->parent()->parent()->parent()->user_data()))->cb_octavesizeoutput_i(o,v);
}

void MicrotonalUI::cb_importscl_i(Fl_Button*, void*) {
  //
              string filename = setfiler(synth,"", "", false, TOPLEVEL::XML::ScalaTune);
              if (filename.empty())
                  return;
              send_data(TOPLEVEL::action::lowPrio | TOPLEVEL::action::forceUpdate, SCALES::control::importScl, 0, TOPLEVEL::type::Integer, UNUSED, textMsgBuffer.push(filename));
              ;
}
void MicrotonalUI::cb_importscl(Fl_Button* o, void* v) {
  ((MicrotonalUI*)(o->parent()->parent()->parent()->user_data()))->cb_importscl_i(o,v);
}

void MicrotonalUI::cb_exportscl_i(Fl_Button*, void*) {
  //
                  int value = microtonal->texttotunings(tuningsinput->value());
                  if (value < 1)
                  {
                      errors(value, true);
                      return;
                  }
                  string filename = setfiler(synth,"", "", true, TOPLEVEL::XML::ScalaTune);
                  if (filename.empty())
                      return;
                  send_data(TOPLEVEL::action::lowPrio, SCALES::control::exportScl, 0, TOPLEVEL::type::Integer, UNUSED, textMsgBuffer.push(filename));
}
void MicrotonalUI::cb_exportscl(Fl_Button* o, void* v) {
  ((MicrotonalUI*)(o->parent()->parent()->parent()->user_data()))->cb_exportscl_i(o,v);
}

void MicrotonalUI::cb_firstnotecounter_i(WidgetSpinner* o, void*) {
  //
              int tmp = int (o->value());
              int max = middlenotecounter->value();
              if (tmp > max)
                      tmp = 0;
              else if (tmp < 0)
                  tmp = max;
              o->value(tmp);
              send_data(0, SCALES::control::lowKey, tmp, TOPLEVEL::type::Integer);
}
void MicrotonalUI::cb_firstnotecounter(WidgetSpinner* o, void* v) {
  ((MicrotonalUI*)(o->parent()->parent()->parent()->user_data()))->cb_firstnotecounter_i(o,v);
}

void MicrotonalUI::cb_middlenotecounter_i(WidgetSpinner* o, void*) {
  //
              int tmp = int(o->value());
              int min = firstnotecounter->value();
              int max = lastnotecounter->value();
              if (tmp < min)
                  tmp = max;
              else if (tmp > max)
                  tmp = min;
              o->value(tmp);

              send_data(0, SCALES::control::middleKey, o->value(), TOPLEVEL::type::Integer);
}
void MicrotonalUI::cb_middlenotecounter(WidgetSpinner* o, void* v) {
  ((MicrotonalUI*)(o->parent()->parent()->parent()->user_data()))->cb_middlenotecounter_i(o,v);
}

void MicrotonalUI::cb_lastnotecounter_i(WidgetSpinner* o, void*) {
  //
              int tmp = int(o->value());
              int min = middlenotecounter->value();
              if (tmp < min)
                  tmp = 127;
              else if (tmp > 127)
                  tmp = min;
              o->value(tmp);

              send_data(0, SCALES::control::highKey, tmp, TOPLEVEL::type::Integer);
}
void MicrotonalUI::cb_lastnotecounter(WidgetSpinner* o, void* v) {
  ((MicrotonalUI*)(o->parent()->parent()->parent()->user_data()))->cb_lastnotecounter_i(o,v);
}

void MicrotonalUI::cb_exportkbm_i(Fl_Button*, void*) {
  //
              string filename = setfiler(synth,"", "", true, TOPLEVEL::XML::ScalaMap);
              if (filename.empty())
                  return;
              retune();
              send_data(TOPLEVEL::action::lowPrio | TOPLEVEL::action::forceUpdate, SCALES::control::exportKbm, 0, TOPLEVEL::type::Integer, UNUSED, textMsgBuffer.push(filename));
}
void MicrotonalUI::cb_exportkbm(Fl_Button* o, void* v) {
  ((MicrotonalUI*)(o->parent()->parent()->parent()->user_data()))->cb_exportkbm_i(o,v);
}

void MicrotonalUI::cb_mappingenabledbutton_i(Fl_Check_Button2* o, void*) {
  //
            o->show();

            send_data(TOPLEVEL::action::forceUpdate, SCALES::control::enableKeyboardMap, o->value(), TOPLEVEL::type::Integer);
}
void MicrotonalUI::cb_mappingenabledbutton(Fl_Check_Button2* o, void* v) {
  ((MicrotonalUI*)(o->parent()->parent()->user_data()))->cb_mappingenabledbutton_i(o,v);
}

void MicrotonalUI::cb_retunebutton_i(Fl_Button*, void*) {
  //
            retune();
            send_data(0, SCALES::control::tuning, 1, TOPLEVEL::type::Integer);
            send_data(0, SCALES::control::keyboardMap, 1, TOPLEVEL::type::Integer);
            ;
}
void MicrotonalUI::cb_retunebutton(Fl_Button* o, void* v) {
  ((MicrotonalUI*)(o->parent()->parent()->user_data()))->cb_retunebutton_i(o,v);
}

void MicrotonalUI::cb_clearbutton_i(Fl_Button*, void*) {
  //
            send_data(TOPLEVEL::action::forceUpdate, SCALES::control::clearAll, 0, TOPLEVEL::type::Integer);
}
void MicrotonalUI::cb_clearbutton(Fl_Button* o, void* v) {
  ((MicrotonalUI*)(o->parent()->parent()->user_data()))->cb_clearbutton_i(o,v);
}

void MicrotonalUI::cb_importkbm_i(Fl_Button*, void*) {
  //
              string filename = setfiler(synth,"", "", false, TOPLEVEL::XML::ScalaMap);
              if (filename.empty())
                  return;

              send_data(TOPLEVEL::action::lowPrio | TOPLEVEL::action::forceUpdate, SCALES::control::importKbm, 0, TOPLEVEL::type::Integer, UNUSED, textMsgBuffer.push(filename));
              ;
}
void MicrotonalUI::cb_importkbm(Fl_Button* o, void* v) {
  ((MicrotonalUI*)(o->parent()->parent()->user_data()))->cb_importkbm_i(o,v);
}

void MicrotonalUI::cb_enableMicrotonal_i(Fl_Check_Button2* o, void*) {
  //
          send_data(TOPLEVEL::action::forceUpdate, SCALES::control::enableMicrotonal, o->value(), TOPLEVEL::type::Integer);
}
void MicrotonalUI::cb_enableMicrotonal(Fl_Check_Button2* o, void* v) {
  ((MicrotonalUI*)(o->parent()->user_data()))->cb_enableMicrotonal_i(o,v);
}

void MicrotonalUI::cb_scaleClose_i(Fl_Button*, void*) {
  //
      saveWin(synth, microtonaluiwindow->w(), microtonaluiwindow->h(), microtonaluiwindow->x(), microtonaluiwindow->y(), false, "Scales");
      microtonaluiwindow->hide();
      lastscaleSeen = false;
}
void MicrotonalUI::cb_scaleClose(Fl_Button* o, void* v) {
  ((MicrotonalUI*)(o->parent()->user_data()))->cb_scaleClose_i(o,v);
}

ScaleTrackedWindow* MicrotonalUI::make_window() {
  { ScaleTrackedWindow* o = microtonaluiwindow = new ScaleTrackedWindow(410, 485, "Scales");
    microtonaluiwindow->box(FL_FLAT_BOX);
    microtonaluiwindow->color(FL_BACKGROUND_COLOR);
    microtonaluiwindow->selection_color(FL_BACKGROUND_COLOR);
    microtonaluiwindow->labeltype(FL_NO_LABEL);
    microtonaluiwindow->labelfont(0);
    microtonaluiwindow->labelsize(14);
    microtonaluiwindow->labelcolor(FL_FOREGROUND_COLOR);
    microtonaluiwindow->callback((Fl_Callback*)cb_microtonaluiwindow, (void*)(this));
    microtonaluiwindow->align(Fl_Align(FL_ALIGN_TOP));
    microtonaluiwindow->when(FL_WHEN_RELEASE);
    { Fl_Group* o = new Fl_Group(248, 2, 157, 48);
      o->tooltip("Center where the note\'s freqs. are inverted\n(not when keymapped)");
      o->box(FL_ENGRAVED_FRAME);
      { invertlabel = new Fl_Text_Display(273, 7, 5, 24, "Invert");
        invertlabel->box(FL_NO_BOX);
        invertlabel->selection_color((Fl_Color)64);
        invertlabel->labelfont(3);
        invertlabel->labelsize(12);
        invertlabel->labelcolor((Fl_Color)226);
        invertlabel->textsize(11);
        invertlabel->textcolor((Fl_Color)64);
        invertlabel->align(Fl_Align(136));
      } // Fl_Text_Display* invertlabel
      { keyslabel = new Fl_Text_Display(273, 18, 5, 30, "keys");
        keyslabel->box(FL_NO_BOX);
        keyslabel->labelfont(3);
        keyslabel->labelsize(12);
        keyslabel->labelcolor((Fl_Color)226);
        keyslabel->textsize(11);
        keyslabel->textcolor((Fl_Color)64);
        keyslabel->align(Fl_Align(136));
      } // Fl_Text_Display* keyslabel
      { Fl_Check_Button2* o = invertKeys = new Fl_Check_Button2(256, 16, 19, 19);
        invertKeys->tooltip("Turn upside-down the note frequencies");
        invertKeys->box(FL_NO_BOX);
        invertKeys->down_box(FL_DOWN_BOX);
        invertKeys->color(FL_LIGHT1);
        invertKeys->selection_color((Fl_Color)64);
        invertKeys->labeltype(FL_NORMAL_LABEL);
        invertKeys->labelfont(1);
        invertKeys->labelsize(14);
        invertKeys->labelcolor((Fl_Color)64);
        invertKeys->callback((Fl_Callback*)cb_invertKeys);
        invertKeys->align(Fl_Align(FL_ALIGN_RIGHT));
        invertKeys->when(FL_WHEN_RELEASE);
        o->value(microtonal->Pinvertupdown);
      } // Fl_Check_Button2* invertKeys
      { centerlabel = new Fl_Text_Display(336, 17, 50, 8, "Center");
        centerlabel->box(FL_NO_BOX);
        centerlabel->labelfont(3);
        centerlabel->labelsize(11);
        centerlabel->labelcolor((Fl_Color)226);
      } // Fl_Text_Display* centerlabel
      { WidgetSpinner* o = centerinvertcounter = new WidgetSpinner(339, 20, 47, 22);
        centerinvertcounter->box(FL_NO_BOX);
        centerinvertcounter->color(FL_BACKGROUND_COLOR);
        centerinvertcounter->selection_color(FL_BACKGROUND_COLOR);
        centerinvertcounter->labeltype(FL_NORMAL_LABEL);
        centerinvertcounter->labelfont(0);
        centerinvertcounter->labelsize(11);
        centerinvertcounter->labelcolor((Fl_Color)64);
        centerinvertcounter->minimum(-0);
        centerinvertcounter->maximum(127);
        centerinvertcounter->value(0);
        centerinvertcounter->textfont(1);
        centerinvertcounter->textsize(12);
        centerinvertcounter->textcolor((Fl_Color)64);
        centerinvertcounter->callback((Fl_Callback*)cb_centerinvertcounter);
        centerinvertcounter->align(Fl_Align(FL_ALIGN_TOP));
        centerinvertcounter->when(FL_WHEN_RELEASE);
        o->value(microtonal->Pinvertupdowncenter);
        if (microtonal->Pinvertupdown==0) o->deactivate();
        o->step(1.0);
      } // WidgetSpinner* centerinvertcounter
      o->end();
    } // Fl_Group* o
    { Fl_Group* o = new Fl_Group(108, 2, 141, 48);
      o->box(FL_ENGRAVED_FRAME);
      { reflabel = new Fl_Text_Display(155, 20, 50, 8, "Ref.");
        reflabel->box(FL_NO_BOX);
        reflabel->labelfont(1);
        reflabel->labelsize(12);
        reflabel->labelcolor((Fl_Color)64);
      } // Fl_Text_Display* reflabel
      { notelabel = new Fl_Text_Display(191, 20, 50, 6, "Note");
        notelabel->box(FL_NO_BOX);
        notelabel->labelfont(3);
        notelabel->labelsize(11);
        notelabel->labelcolor((Fl_Color)226);
        notelabel->textcolor((Fl_Color)64);
      } // Fl_Text_Display* notelabel
      { WidgetSpinner* o = anotecounter = new WidgetSpinner(192, 23, 44, 20);
        anotecounter->tooltip("Midi note range: 24 (C1) to 84 (C6)");
        anotecounter->box(FL_NO_BOX);
        anotecounter->color(FL_BACKGROUND_COLOR);
        anotecounter->selection_color(FL_BACKGROUND_COLOR);
        anotecounter->labeltype(FL_NORMAL_LABEL);
        anotecounter->labelfont(0);
        anotecounter->labelsize(11);
        anotecounter->labelcolor((Fl_Color)64);
        anotecounter->minimum(24);
        anotecounter->maximum(84);
        anotecounter->value(69);
        anotecounter->textfont(1);
        anotecounter->textsize(11);
        anotecounter->textcolor((Fl_Color)64);
        anotecounter->callback((Fl_Callback*)cb_anotecounter);
        anotecounter->align(Fl_Align(FL_ALIGN_TOP));
        anotecounter->when(FL_WHEN_RELEASE);
        o->value(microtonal->PrefNote);
      } // WidgetSpinner* anotecounter
      { Fl_Value_Input* o = afreqinput = new Fl_Value_Input(114, 20, 55, 20, "Freq.");
        afreqinput->tooltip("The frequency of the reference note -\'return\' to apply (default: A4=440.0)");
        afreqinput->labelsize(11);
        afreqinput->labelcolor((Fl_Color)64);
        afreqinput->minimum(30);
        afreqinput->maximum(1100);
        afreqinput->value(440);
        afreqinput->textfont(1);
        afreqinput->textsize(10);
        afreqinput->textcolor((Fl_Color)64);
        afreqinput->callback((Fl_Callback*)cb_afreqinput);
        afreqinput->align(Fl_Align(FL_ALIGN_TOP));
        o->step(0.001, 1);
        refFreq = microtonal->PrefFreq;
        o->value(refFreq);
      } // Fl_Value_Input* afreqinput
      { AsetBack = new Fl_Button(171, 22, 14, 17);
        AsetBack->box(FL_THIN_DOWN_BOX);
        AsetBack->color(FL_DARK2);
        AsetBack->labelcolor((Fl_Color)64);
        AsetBack->callback((Fl_Callback*)cb_AsetBack);
        AsetBack->hide();
      } // Fl_Button* AsetBack
      { afreqset = new Fl_Return_Button(166, 20, 14, 18);
        afreqset->box(FL_NO_BOX);
        afreqset->labelcolor((Fl_Color)64);
        afreqset->callback((Fl_Callback*)cb_afreqset);
        afreqset->hide();
      } // Fl_Return_Button* afreqset
      o->end();
    } // Fl_Group* o
    { Fl_Group* o = microtonalgroup = new Fl_Group(3, 49, 402, 485);
      microtonalgroup->box(FL_ENGRAVED_FRAME);
      { Fl_Input* o = nameinput = new Fl_Input(7, 64, 285, 25, "Name:");
        nameinput->labelfont(1);
        nameinput->labelsize(11);
        nameinput->labelcolor((Fl_Color)64);
        nameinput->textcolor((Fl_Color)64);
        nameinput->callback((Fl_Callback*)cb_nameinput);
        nameinput->align(Fl_Align(FL_ALIGN_TOP_LEFT));
        o->value(microtonal->Pname.c_str());
      } // Fl_Input* nameinput
      { Fl_Input* o = commentinput = new Fl_Input(7, 104, 394, 25, "Description:");
        commentinput->labelfont(1);
        commentinput->labelsize(11);
        commentinput->labelcolor((Fl_Color)64);
        commentinput->textcolor((Fl_Color)64);
        commentinput->callback((Fl_Callback*)cb_commentinput);
        commentinput->align(Fl_Align(FL_ALIGN_TOP_LEFT));
        o->value(microtonal->Pcomment.c_str());
      } // Fl_Input* commentinput
      { shiftlabel = new Fl_Text_Display(318, 65, 50, 8, "Shift");
        shiftlabel->box(FL_NO_BOX);
        shiftlabel->labelfont(3);
        shiftlabel->labelsize(11);
        shiftlabel->labelcolor((Fl_Color)226);
      } // Fl_Text_Display* shiftlabel
      { WidgetSpinner* o = scaleShift = new WidgetSpinner(320, 68, 47, 22);
        scaleShift->tooltip("Octave base offset");
        scaleShift->box(FL_NO_BOX);
        scaleShift->color(FL_BACKGROUND_COLOR);
        scaleShift->selection_color(FL_BACKGROUND_COLOR);
        scaleShift->labeltype(FL_NORMAL_LABEL);
        scaleShift->labelfont(0);
        scaleShift->labelsize(11);
        scaleShift->labelcolor((Fl_Color)64);
        scaleShift->minimum(-63);
        scaleShift->maximum(64);
        scaleShift->value(0);
        scaleShift->textfont(1);
        scaleShift->textsize(12);
        scaleShift->textcolor((Fl_Color)64);
        scaleShift->callback((Fl_Callback*)cb_scaleShift);
        scaleShift->align(Fl_Align(FL_ALIGN_TOP));
        scaleShift->when(FL_WHEN_RELEASE);
        o->value(microtonal->Pscaleshift-64);
        o->step(1.0);
      } // WidgetSpinner* scaleShift
      { Tuning = new Fl_Group(7, 144, 190, 300, "Tunings:");
        Tuning->box(FL_ENGRAVED_FRAME);
        Tuning->labelfont(1);
        Tuning->labelsize(11);
        Tuning->labelcolor((Fl_Color)64);
        Tuning->align(Fl_Align(FL_ALIGN_TOP_LEFT));
        { tuningsinput = new Fl_Input(10, 147, 182, 250);
          tuningsinput->tooltip("You must retune if you change this.");
          tuningsinput->type(4);
          tuningsinput->labelfont(1);
          tuningsinput->labelsize(11);
          tuningsinput->labelcolor((Fl_Color)64);
          tuningsinput->textcolor((Fl_Color)64);
          tuningsinput->align(Fl_Align(FL_ALIGN_TOP_LEFT));
          tuningsinput->when(FL_WHEN_NOT_CHANGED);
          updateTuningsInput();
        } // Fl_Input* tuningsinput
        { Fl_Value_Output* o = octavesizeoutput = new Fl_Value_Output(17, 415, 45, 20, "Notes / oct.");
          octavesizeoutput->tooltip("Notes/Octave");
          octavesizeoutput->labelsize(10);
          octavesizeoutput->labelcolor((Fl_Color)64);
          octavesizeoutput->maximum(500);
          octavesizeoutput->step(1);
          octavesizeoutput->value(12);
          octavesizeoutput->textfont(1);
          octavesizeoutput->textcolor((Fl_Color)64);
          octavesizeoutput->callback((Fl_Callback*)cb_octavesizeoutput);
          octavesizeoutput->align(Fl_Align(FL_ALIGN_TOP_LEFT));
          o->value(microtonal->getoctavesize());
        } // Fl_Value_Output* octavesizeoutput
        { importscl = new Fl_Button(85, 401, 100, 18, "Import .scl file");
          importscl->tooltip("Import Scala .scl file (tunnings)");
          importscl->box(FL_GTK_THIN_UP_BOX);
          importscl->color((Fl_Color)198);
          importscl->labelfont(1);
          importscl->labelsize(10);
          importscl->labelcolor((Fl_Color)64);
          importscl->callback((Fl_Callback*)cb_importscl);
        } // Fl_Button* importscl
        { exportscl = new Fl_Button(85, 422, 100, 18, "Export .scl file");
          exportscl->tooltip("Export Scala .scl file (tunnings)");
          exportscl->box(FL_GTK_THIN_UP_BOX);
          exportscl->color((Fl_Color)198);
          exportscl->labelfont(1);
          exportscl->labelsize(10);
          exportscl->labelcolor((Fl_Color)64);
          exportscl->callback((Fl_Callback*)cb_exportscl);
        } // Fl_Button* exportscl
        Tuning->end();
      } // Fl_Group* Tuning
      { Keymap = new Fl_Group(196, 144, 205, 300, "Keyboard Map:");
        Keymap->box(FL_ENGRAVED_FRAME);
        Keymap->labelfont(1);
        Keymap->labelsize(11);
        Keymap->labelcolor((Fl_Color)64);
        { mappinginput = new Fl_Input(251, 147, 146, 250);
          mappinginput->tooltip("You must retune if you change this.");
          mappinginput->type(4);
          mappinginput->labelfont(1);
          mappinginput->labelsize(11);
          mappinginput->labelcolor((Fl_Color)64);
          mappinginput->textcolor((Fl_Color)64);
          mappinginput->align(Fl_Align(FL_ALIGN_TOP_LEFT));
          mappinginput->when(FL_WHEN_NOT_CHANGED);
          updateMappingInput();
        } // Fl_Input* mappinginput
        { first1 = new Fl_Box(197, 204, 50, 8, "First");
          first1->labelfont(3);
          first1->labelsize(11);
          first1->labelcolor((Fl_Color)226);
        } // Fl_Box* first1
        { first2 = new Fl_Box(198, 214, 50, 8, "note");
          first2->labelfont(3);
          first2->labelsize(11);
          first2->labelcolor((Fl_Color)226);
        } // Fl_Box* first2
        { WidgetSpinner* o = firstnotecounter = new WidgetSpinner(203, 228, 44, 20);
          firstnotecounter->tooltip("First MIDI note number");
          firstnotecounter->box(FL_NO_BOX);
          firstnotecounter->color(FL_BACKGROUND_COLOR);
          firstnotecounter->selection_color((Fl_Color)64);
          firstnotecounter->labeltype(FL_NORMAL_LABEL);
          firstnotecounter->labelfont(0);
          firstnotecounter->labelsize(11);
          firstnotecounter->labelcolor((Fl_Color)64);
          firstnotecounter->minimum(-1);
          firstnotecounter->maximum(128);
          firstnotecounter->textfont(1);
          firstnotecounter->textsize(11);
          firstnotecounter->textcolor((Fl_Color)64);
          firstnotecounter->callback((Fl_Callback*)cb_firstnotecounter);
          firstnotecounter->align(Fl_Align(FL_ALIGN_TOP));
          firstnotecounter->when(FL_WHEN_RELEASE);
          o->value(microtonal->Pfirstkey);
          o->step(1.0);
        } // WidgetSpinner* firstnotecounter
        { middle1 = new Fl_Box(197, 269, 50, 8, "Middle");
          middle1->labelfont(3);
          middle1->labelsize(11);
          middle1->labelcolor((Fl_Color)226);
        } // Fl_Box* middle1
        { middle2 = new Fl_Box(198, 279, 50, 8, "note");
          middle2->labelfont(3);
          middle2->labelsize(11);
          middle2->labelcolor((Fl_Color)226);
        } // Fl_Box* middle2
        { WidgetSpinner* o = middlenotecounter = new WidgetSpinner(203, 293, 44, 20);
          middlenotecounter->tooltip("Middle note (where scale degree 0 is mapped to)");
          middlenotecounter->box(FL_NO_BOX);
          middlenotecounter->color(FL_BACKGROUND_COLOR);
          middlenotecounter->selection_color(FL_BACKGROUND_COLOR);
          middlenotecounter->labeltype(FL_NORMAL_LABEL);
          middlenotecounter->labelfont(0);
          middlenotecounter->labelsize(11);
          middlenotecounter->labelcolor((Fl_Color)64);
          middlenotecounter->minimum(-1);
          middlenotecounter->maximum(128);
          middlenotecounter->value(60);
          middlenotecounter->textfont(1);
          middlenotecounter->textsize(11);
          middlenotecounter->textcolor((Fl_Color)64);
          middlenotecounter->callback((Fl_Callback*)cb_middlenotecounter);
          middlenotecounter->align(Fl_Align(FL_ALIGN_TOP));
          middlenotecounter->when(FL_WHEN_RELEASE);
          o->value(microtonal->Pmiddlenote);
        } // WidgetSpinner* middlenotecounter
        { last1 = new Fl_Box(197, 334, 50, 8, "Last");
          last1->labelfont(3);
          last1->labelsize(11);
          last1->labelcolor((Fl_Color)226);
        } // Fl_Box* last1
        { last2 = new Fl_Box(198, 344, 50, 8, "note");
          last2->labelfont(3);
          last2->labelsize(11);
          last2->labelcolor((Fl_Color)226);
        } // Fl_Box* last2
        { WidgetSpinner* o = lastnotecounter = new WidgetSpinner(203, 357, 44, 20);
          lastnotecounter->tooltip("Last MIDI note number");
          lastnotecounter->box(FL_NO_BOX);
          lastnotecounter->color(FL_BACKGROUND_COLOR);
          lastnotecounter->selection_color(FL_BACKGROUND_COLOR);
          lastnotecounter->labeltype(FL_NORMAL_LABEL);
          lastnotecounter->labelfont(0);
          lastnotecounter->labelsize(11);
          lastnotecounter->labelcolor((Fl_Color)64);
          lastnotecounter->minimum(0);
          lastnotecounter->maximum(128);
          lastnotecounter->value(127);
          lastnotecounter->textfont(1);
          lastnotecounter->textsize(11);
          lastnotecounter->textcolor((Fl_Color)64);
          lastnotecounter->callback((Fl_Callback*)cb_lastnotecounter);
          lastnotecounter->align(Fl_Align(FL_ALIGN_TOP));
          lastnotecounter->when(FL_WHEN_RELEASE);
          o->value(microtonal->Plastkey);
        } // WidgetSpinner* lastnotecounter
        { WidgetSpinner* o = mapsizecounter = new WidgetSpinner(203, 415, 42, 22, "Map Size");
          mapsizecounter->tooltip("The actual kemap size. This can be greater or smaller than the number of entr"
"ies in the map");
          mapsizecounter->box(FL_NO_BOX);
          mapsizecounter->color(FL_BACKGROUND_COLOR);
          mapsizecounter->selection_color(FL_BACKGROUND_COLOR);
          mapsizecounter->labeltype(FL_NORMAL_LABEL);
          mapsizecounter->labelfont(0);
          mapsizecounter->labelsize(11);
          mapsizecounter->labelcolor((Fl_Color)64);
          mapsizecounter->minimum(0);
          mapsizecounter->maximum(127);
          mapsizecounter->value(0);
          mapsizecounter->textfont(1);
          mapsizecounter->textsize(11);
          mapsizecounter->textcolor((Fl_Color)64);
          mapsizecounter->align(Fl_Align(FL_ALIGN_TOP));
          mapsizecounter->when(FL_WHEN_RELEASE);
          o->value(microtonal->Pmapsize);
        } // WidgetSpinner* mapsizecounter
        { exportkbm = new Fl_Button(273, 422, 104, 18, "Export .kbm file");
          exportkbm->tooltip("Export Scala .kbm file (keyboard mapping)");
          exportkbm->box(FL_GTK_THIN_UP_BOX);
          exportkbm->color((Fl_Color)198);
          exportkbm->labelfont(1);
          exportkbm->labelsize(10);
          exportkbm->labelcolor((Fl_Color)64);
          exportkbm->callback((Fl_Callback*)cb_exportkbm);
        } // Fl_Button* exportkbm
        Keymap->end();
      } // Fl_Group* Keymap
      { Fl_Check_Button2* o = mappingenabledbutton = new Fl_Check_Button2(212, 166, 20, 21, "ON");
        mappingenabledbutton->tooltip("Enable the Mapping (otherwise the mapping is linear)");
        mappingenabledbutton->box(FL_NO_BOX);
        mappingenabledbutton->down_box(FL_DOWN_BOX);
        mappingenabledbutton->color(FL_LIGHT1);
        mappingenabledbutton->selection_color((Fl_Color)64);
        mappingenabledbutton->labeltype(FL_NORMAL_LABEL);
        mappingenabledbutton->labelfont(3);
        mappingenabledbutton->labelsize(14);
        mappingenabledbutton->labelcolor((Fl_Color)226);
        mappingenabledbutton->callback((Fl_Callback*)cb_mappingenabledbutton);
        mappingenabledbutton->align(Fl_Align(33));
        mappingenabledbutton->when(FL_WHEN_RELEASE);
        o->value(microtonal->Pmappingenabled);
        if (microtonal->Pmappingenabled==0) Keymap->deactivate();
      } // Fl_Check_Button2* mappingenabledbutton
      { retunebutton = new Fl_Button(169, 448, 107, 28, "Retune");
        retunebutton->tooltip("Retune the synth according to the inputs from \"Tunnings\" and \"Keyboard Map"
"ping\"");
        retunebutton->box(FL_PLASTIC_UP_BOX);
        retunebutton->color((Fl_Color)228);
        retunebutton->labeltype(FL_EMBOSSED_LABEL);
        retunebutton->labelfont(1);
        retunebutton->labelcolor((Fl_Color)64);
        retunebutton->callback((Fl_Callback*)cb_retunebutton);
      } // Fl_Button* retunebutton
      { clearbutton = new Fl_Button(25, 448, 107, 28, "Clear All");
        clearbutton->tooltip("Return to default scale settings");
        clearbutton->box(FL_PLASTIC_UP_BOX);
        clearbutton->color((Fl_Color)89);
        clearbutton->labelfont(1);
        clearbutton->labelcolor((Fl_Color)64);
        clearbutton->callback((Fl_Callback*)cb_clearbutton);
      } // Fl_Button* clearbutton
      { importkbm = new Fl_Button(273, 401, 104, 18, "Import .kbm file");
        importkbm->tooltip("Import Scala .kbm file (keyboard mapping)");
        importkbm->box(FL_GTK_THIN_UP_BOX);
        importkbm->color((Fl_Color)198);
        importkbm->labelfont(1);
        importkbm->labelsize(10);
        importkbm->labelcolor((Fl_Color)64);
        importkbm->callback((Fl_Callback*)cb_importkbm);
      } // Fl_Button* importkbm
      if (microtonal->Penabled==0) o->deactivate();
      microtonalgroup->end();
    } // Fl_Group* microtonalgroup
    { enablelabel = new Fl_Text_Display(27, 24, 50, 8, "Enable");
      enablelabel->box(FL_NO_BOX);
      enablelabel->labelfont(1);
      enablelabel->labelsize(12);
      enablelabel->labelcolor((Fl_Color)64);
    } // Fl_Text_Display* enablelabel
    { microtonallabel = new Fl_Text_Display(40, 40, 50, 8, "Microtonal");
      microtonallabel->box(FL_NO_BOX);
      microtonallabel->labelfont(1);
      microtonallabel->labelsize(12);
      microtonallabel->labelcolor((Fl_Color)64);
    } // Fl_Text_Display* microtonallabel
    { Fl_Check_Button2* o = enableMicrotonal = new Fl_Check_Button2(4, 13, 21, 22);
      enableMicrotonal->box(FL_NO_BOX);
      enableMicrotonal->down_box(FL_DOWN_BOX);
      enableMicrotonal->color(FL_LIGHT1);
      enableMicrotonal->selection_color((Fl_Color)64);
      enableMicrotonal->labeltype(FL_NORMAL_LABEL);
      enableMicrotonal->labelfont(1);
      enableMicrotonal->labelsize(14);
      enableMicrotonal->labelcolor((Fl_Color)64);
      enableMicrotonal->callback((Fl_Callback*)cb_enableMicrotonal);
      enableMicrotonal->align(Fl_Align(FL_ALIGN_LEFT));
      enableMicrotonal->when(FL_WHEN_RELEASE);
      o->value(microtonal->Penabled);
    } // Fl_Check_Button2* enableMicrotonal
    { scaleClose = new Fl_Button(315, 448, 67, 28, "Close");
      scaleClose->box(FL_THIN_UP_BOX);
      scaleClose->down_box(FL_THIN_DOWN_BOX);
      scaleClose->color((Fl_Color)196);
      scaleClose->labelcolor((Fl_Color)64);
      scaleClose->callback((Fl_Callback*)cb_scaleClose);
    } // Fl_Button* scaleClose
    microtonaluiwindow->resizable(microtonaluiwindow);
    scaleDW = o->w(); scaleDH = o->h();
    o->size_range(scaleDW, scaleDH, 0, 0, 0, 0, 1);
    microtonaluiwindow->end();
  } // ScaleTrackedWindow* microtonaluiwindow
  return microtonaluiwindow;
}

void MicrotonalUI::send_data(int action, int control, float value, int type, int par , int miscmsg ) {
  //
          type |= TOPLEVEL::type::Write;
          collect_writeData(synth, value, action, type, control, TOPLEVEL::section::scales, UNUSED, UNUSED, UNUSED, par, UNUSED, miscmsg);
}

float MicrotonalUI::fetchData(float value, int control, int part, int kititem , int engine , int insert , int parameter , int offset , int miscmsg , int request ) {
  //
          return collect_readData(synth, value, control, part, kititem, engine, insert, parameter, offset, miscmsg, request);
}

void MicrotonalUI::returns_update(CommandBlock *getData) {
  //
      float value = getData->data.value;
      bool wasFromUs = ((getData->data.source & TOPLEVEL::action::noAction) == TOPLEVEL::action::fromGUI);
      unsigned char control = getData->data.control;
      unsigned char parameter = getData->data.parameter;
      unsigned char miscmsg = getData->data.miscmsg;
      int value_int = lrint(value);
      bool value_bool = _SYS_::F2B(value);
      string msg;

      switch (control)
      {
          case SCALES::control::refFrequency:
              afreqinput->value(value);
              break;
          case SCALES::control::refNote:
              anotecounter->value(value_int);
              break;
          case SCALES::control::invertScale:
              invertKeys->value(value_bool);
              checkInvert();
              break;
          case SCALES::control::invertedScaleCenter:
              centerinvertcounter->value(value_int);
              break;
          case SCALES::control::scaleShift:
              scaleShift->value(value_int);
              break;

          case SCALES::control::enableMicrotonal:
              enableMicrotonal->value(value_bool);
              mappingenabledbutton->value(false);
              Keymap->deactivate();
              checkInvert();
              if (value_bool)
              {
                  microtonalgroup->activate();
              }
              else
              {
                  microtonalgroup->deactivate();
              }
              break;

          case SCALES::control::enableKeyboardMap:
              mappingenabledbutton->value(value_bool);
              checkInvert();
              if (value_bool)
                  Keymap->activate();
              else
                  Keymap->deactivate();
              break;
          case SCALES::control::lowKey:
              firstnotecounter->value(value_int);
              break;
          case SCALES::control::middleKey:
              middlenotecounter->value(value_int);
              break;
          case SCALES::control::highKey:
              lastnotecounter->value(value_int);
              break;

          case SCALES::control::tuning:
          case SCALES::control::importScl:
              msg = (textMsgBuffer.fetch(miscmsg));
              if (value_int > 0)
              {
                  tuningsinput->value(msg.c_str());
              }
              else if (wasFromUs)
                  errors(value_int, true);
              break;
          case SCALES::control::keyboardMap:
          { // this only uses the mapped notes
              msg = (textMsgBuffer.fetch(miscmsg));
              mappinginput->value(msg.c_str());
          }
          break;
          case SCALES::control::keymapSize:
          { // the map size only
              mapsizecounter->value(value_int);
          }
          break;
          case SCALES::control::importKbm:
              if (value_int > 0)
              { // this sets ALL mapping entries
                  mappingenabledbutton->value(true);
                  checkInvert();
                  Keymap->activate();
                  msg = (textMsgBuffer.fetch(parameter));
                  int mapsize = func::string2int(splitline(msg));
                  mapsizecounter->value(mapsize);
                  firstnotecounter->value(func::string2int(splitline(msg)));
                  lastnotecounter->value(func::string2int(splitline(msg)));
                  middlenotecounter->value(func::string2int(splitline(msg)));
                  anotecounter->value(func::string2int(splitline(msg)));
                  afreqinput->value(func::string2float(splitline(msg)));
                  //octavesizeoutput->value(func::string2float(splitline(msg))); // temporarily disabled
                  //int formalOctave = func::string2float(splitline(msg)); // temporarily disabled
                  string map;
                  for (int i = 0; i < mapsize; ++i)
                      map += (splitline(msg) + char(10));
                  mappinginput->value(map.c_str());
              }
              else if (wasFromUs)
                  errors(value_int, false);
              break;

          case SCALES::control::name:
              nameinput->value(textMsgBuffer.fetch(miscmsg).c_str());
              break;
          case SCALES::control::comment:
              commentinput->value(textMsgBuffer.fetch(miscmsg).c_str());
              break;

          case SCALES::control::clearAll:
              microtonaluiwindow->hide();
              make_window();
              showScales();
              break;
  }
}

void MicrotonalUI::updateTuningsInput() {
  //
      char *tmpbuf = new char[100];
      tuningsinput->cut(0, tuningsinput->maximum_size());
      for (int i = 0; i < microtonal->getoctavesize(); ++i)
      {
          string line = "";
          microtonal->tuningtoline(i, line);
          if (!microtonal->octave[i].comment.empty())
          {
              line += " ! ";
              line += microtonal->octave[i].comment;
          }

          line += "\n";
          snprintf(tmpbuf, 100, "%s", line.c_str());
          tuningsinput->insert(tmpbuf);
      }
      delete [] tmpbuf;
}

void MicrotonalUI::updateMappingInput() {
  //
      char *tmpbuf = new char[100];
      mappinginput->cut(0, tuningsinput->maximum_size());
      for (int i = 0; i < microtonal->Pmapsize; ++i)
      {
          string line = "";
          if ((microtonal->Pmapping[i]) == -1)
              line = 'x';
          else
              line = to_string(microtonal->Pmapping[i]);
          if (!microtonal->PmapComment[i].empty())
          {
              line += " ! ";
              line += microtonal->PmapComment[i];
          }
          line += "\n";
          snprintf(tmpbuf, 100, "%s", line.c_str());
          mappinginput->insert(tmpbuf);
      }
      delete [] tmpbuf;
}

string MicrotonalUI::splitline(string& page) {
  //
          const char ch = 10;
          string line = "";
          do{
              size_t pos = page.find(ch);
              if (pos != string::npos)
              {
                  line = page.substr(0, pos);
                  page = page.substr(pos + 1, page.length());
              }
              else
              {
                  line = page;
                  page = "";
                  func::trimEnds(line);
              }
          } while (line[0] == '!'); // don't want comment lines
          return line;
}

MicrotonalUI::MicrotonalUI(Microtonal *microtonal_, SynthEngine *synth_) {
  //
      synth = synth_;
      microtonal=microtonal_;
      lastscaleW = 0;
      lastscaleSeen = false;
      make_window();
}

MicrotonalUI::~MicrotonalUI() {
  //
      if (lastscaleSeen)
          saveWin(synth, microtonaluiwindow->w(), microtonaluiwindow->h(), microtonaluiwindow->x(), microtonaluiwindow->y(), true, "Scales");
      microtonaluiwindow->hide();
      delete tuningsinput;
      delete mappinginput;
      delete microtonaluiwindow;
}

void MicrotonalUI::showScales() {
  //
      int fetchX, fetchY, fetchW, fetchH, fetchO;

      loadWin(synth, fetchW, fetchH, fetchX, fetchY, fetchO, "Scales");
      if (fetchW < scaleDW || fetchH < scaleDH)
      {
          fetchW = scaleDW;
          fetchH = scaleDH;
      }
      checkSane(fetchX, fetchY, fetchW, fetchH, scaleDW, scaleDH);

      microtonaluiwindow->resize(fetchX, fetchY, fetchW, fetchH);
      lastscaleW = 0;
      lastscaleSeen = true;
      microtonaluiwindow->show();
}

void MicrotonalUI::scaleRtext() {
  //
      if (lastscaleW == microtonaluiwindow->w())
          return;
      lastscaleW = microtonaluiwindow->w();

      float dScale = microtonaluiwindow->w() / float(scaleDW);

      int size = int(10 * dScale);
      int size11 = int(11 * dScale);
      int size12 = int(12 * dScale);
      int size14 = int(14 * dScale);

      invertlabel->labelsize(size12);
      keyslabel->labelsize(size12);
      invertKeys->labelsize(size14);

      centerlabel->labelsize(size11);

      centerinvertcounter->labelsize(size11);
          centerinvertcounter->textsize(size12);

      reflabel->labelsize(size12);
      notelabel->labelsize(size11);
      anotecounter->labelsize(size11);
          anotecounter->textsize(size11);

      afreqinput->labelsize(size11);
          afreqinput->textsize(size);

      AsetBack->labelsize(size14);
      afreqset->labelsize(size14);

      nameinput->labelsize(size11);
          nameinput->textsize(size14);

      commentinput->labelsize(size11);
          commentinput->textsize(size14);

      shiftlabel->labelsize(size11);
      scaleShift->labelsize(size11);
          scaleShift->textsize(size12);

      Tuning->labelsize(size11);
      tuningsinput->textsize(size14);
      octavesizeoutput->textsize(size14);
      importscl->labelsize(size);
      exportscl->labelsize(size);
      Keymap->labelsize(size11);
      mappinginput->textsize(size14);

      first1->labelsize(size11);
      first2->labelsize(size11);
      firstnotecounter->labelsize(size11);
          firstnotecounter->textsize(size11);

      middle1->labelsize(size11);
      middle2->labelsize(size11);
      middlenotecounter->labelsize(size11);
          middlenotecounter->textsize(size11);

      last1->labelsize(size11);
      last2->labelsize(size11);
      lastnotecounter->labelsize(size11);
          lastnotecounter->textsize(size11);

      mapsizecounter->labelsize(size11);
          mapsizecounter->textsize(size11);
      importkbm->labelsize(size);
      exportkbm->labelsize(size);
      mappingenabledbutton->labelsize(size14);
      retunebutton->labelsize(size14);
      clearbutton->labelsize(size14);
      enablelabel->labelsize(size12);
      microtonallabel->labelsize(size12);
      enableMicrotonal->labelsize(size14);
      scaleClose->labelsize(size14);

      microtonaluiwindow->redraw();
}

void MicrotonalUI::retune() {
  //
      int value = microtonal->texttotunings(tuningsinput->value());
      if (value < 1)
      {
          errors(value, true);
          return;
      }
      octavesizeoutput->do_callback();

      send_data(TOPLEVEL::action::lowPrio, SCALES::control::keymapSize, mapsizecounter->value(), TOPLEVEL::type::Integer);
      value = microtonal->texttomapping(mappinginput->value());
      if (value < 0)
      {
          errors(value, false);
          return;
      }
      anotecounter->do_callback();
}

void MicrotonalUI::checkInvert() {
  //
      if (!invertKeys->value())
          centerinvertcounter->deactivate();
      else
          centerinvertcounter->activate();
}

void MicrotonalUI::errors(int value, bool type) {
  //
      string message;
      if (type)
          message = "Tuning: ";
      else
          message = "Keymap: ";
      /*  TODO sort this!
       * no response to 'type' always Tuning"
              we always see this:
                  "Must be numbers (like 232.59) or divisions (like 121/64)"
              Keymap should see this
                  "Invalid characters"
      */
      // incoming negative values inverted for text list
      alert(synth, message + scale_errors[0 - value]);
}
