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

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

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

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

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

// This file is derivative of original ZynAddSubFX code.


#include "MasterUI.h"
#include "Misc/FormatFuncs.h"
    using func::string2int;
    using func::asString;
#include "Misc/TextMsgBuffer.h"

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

void BankProcess_::process(void) {
  ;
}

BankSlot::BankSlot(int x,int y, int w, int h, const char *label):Fl_Button(x,y,w,h,label) {
  //
      what = NULL;
      whatslot = NULL;
      nslot = 0;
      nselected = NULL;
}

int BankSlot::handle(int event) {
  //
      if (what == NULL)
          return 0;
      if (Fl::event_inside(this))
      {
          *what = 0;
          *whatslot = nslot;
          if (event == FL_RELEASE)
              *what = Fl::event_button();
          if (event == FL_PUSH)
              highlight = 1;
      }
      else
          highlight = 0;
      int tmp = Fl_Button::handle(event);
      if (*what != 0 && Fl::event_inside(this))
          (bp->*fnc)();
      return tmp;
}

void BankSlot::init(int nslot_, int *what_, int *whatslot_, void (BankProcess_:: *fnc_)(void), BankProcess_ *bp_, Bank *bank_, int *nselected_) {
  //
          nslot = nslot_;
          what = what_;
          whatslot = whatslot_;
          fnc = fnc_;
          bp = bp_;
          bank = bank_;
          nselected = nselected_;
          box(FL_THIN_UP_FRAME);
          labelfont(0);
          labelsize(13);
          align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE|FL_ALIGN_CLIP);
          highlight = 0;
}

void BankSlot::refresh(int bk, int rt, int last) {
  //
      string instrName = bank->getnamenumbered(nslot, bk, rt);
      copy_label(instrName.c_str());
      rootID = rt;
      bankID = bk;
      lastSeen = last;
      if (bank->engines_used(rt, bk, nslot) & 8)
          labelcolor(YOSHI_COLOUR);
      else
          labelcolor(0);
}

/**
 overrides button's draw()
*/
void BankSlot::draw() {
  //
      if (type() == FL_HIDDEN_BUTTON) return;
      int acol, scol, pcol, bcol;
      int wid = w() * 0.334;
      int engine = bank->engines_used(rootID, bankID, nslot);
      if (*nselected == nslot)
      {
          acol = 6;
          scol = 6;
          pcol = 6;
      }
      else if (bank->emptyslot(rootID, bankID, nslot))
      {
          if (nslot < 128)
          {
              acol = 46;
              scol = 46;
              pcol = 46;
          }
          else
          {
              acol = 16;
              scol = 16;
              pcol = 16;
          }
      }
      else
      {
          if (nslot < 128)
              bcol = 51;
          else
              bcol = 17;
          if (engine & 1)
              acol = ADD_COLOUR;
          else
              acol = bcol;
          if (engine & 2)
              scol = SUB_COLOUR;
          else
              scol = bcol;
          if (engine & 4)
              pcol = PAD_COLOUR;
          else
              pcol = bcol;
  
          if ((lastSeen & 0x7f) == rootID && ((lastSeen >> 8) & 0x7f) == bankID  && ((lastSeen >> 15) == nslot))
              labelfont(1);
          else
              labelfont(0);
      }
      draw_box(FL_FLAT_BOX, x(), y(), wid, h(), (Fl_Color) acol);
      draw_box(FL_FLAT_BOX, x() + wid, y(), wid, h(), (Fl_Color) scol);
      draw_box(FL_FLAT_BOX, x() + wid * 2, y(), wid, h(), (Fl_Color) pcol);
  
      //frame for label
      draw_box(value() ? (down_box() ? down_box() : fl_down(box())) : box(), x(), y(), w(), h(), (Fl_Color) BASE_COLOUR);
  
      //draw_backdrop();
  
      Fl_Color col = value() ? selection_color() : color();
      if (labeltype() == FL_NORMAL_LABEL && value())
      {
          Fl_Color c = labelcolor();
          labelcolor(fl_contrast(c, col));
          draw_label();
          labelcolor(c);
      }
      else
          draw_label();
  
      if (Fl::focus() == this) draw_focus();
}

void RootProcess_::rootprocess(void) {
  ;
}

RootSlot::RootSlot(int x,int y, int w, int h, const char *label):Fl_Button(x,y,w,h,label) {
  //
      what = NULL;
      whatslot = NULL;
      nslot = 0;
      nselected = NULL;
}

int RootSlot::handle(int event) {
  //
      if (what == NULL)
          return 0;
      if (Fl::event_inside(this))
      {
          *what = 0;
          *whatslot = nslot;
          if (event == FL_RELEASE)
              *what = Fl::event_button();
          if (event == FL_PUSH)
              highlight = 1;
      }
      else
          highlight = 0;
  
      int tmp = Fl_Button::handle(event);
      if (*what != 0 && Fl::event_inside(this))
          (rp->*fnr)();
      return tmp;
}

void RootSlot::init(int nslot_, int *what_, int *whatslot_, void (RootProcess_:: *fnr_)(void), RootProcess_ *rp_, Bank *root_, int *rselected_) {
  //
          nslot = nslot_;
          what = what_;
          whatslot = whatslot_;
          fnr = fnr_;
          rp = rp_;
          root = root_;
          rselected = rselected_;
          box(FL_THIN_UP_BOX);
          labelfont(0);
          labelsize(13);
          align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE|FL_ALIGN_CLIP);
          highlight = 0;
}

void RootSlot::rootrefresh(unsigned int currentBank, unsigned int rootID) {
  //
          string bankName = root->getBankName(nslot, rootID);
          if (bankName.empty())
              color(46);
          else
          {
               bankName = std::to_string(nslot) + ". " + bankName;
               if ((unsigned int) nslot == currentBank)
                  color(252);
              else
                  color(51);
              if (*rselected == nslot)
                  color(6);
          }
          copy_label(bankName.c_str());
}

void BankUI::cb_instrumentuiwindow_i(Fl_Double_Window*, void*) {
  Hide(0);
}
void BankUI::cb_instrumentuiwindow(Fl_Double_Window* o, void* v) {
  ((BankUI*)(o->user_data()))->cb_instrumentuiwindow_i(o,v);
}

void BankUI::cb_banklist_i(Fl_Choice* o, void*) {
  //
        int n = o->value();
        if (n < 0)
            return;

        const Fl_Menu_Item &item = o->menu()[n];
        int nbank = reinterpret_cast<long>(item.user_data());
        send_data(TOPLEVEL::action::lowPrio | TOPLEVEL::action::forceUpdate, BANK::control::selectBank, nbank, TOPLEVEL::type::Integer, TOPLEVEL::section::bank);
}
void BankUI::cb_banklist(Fl_Choice* o, void* v) {
  ((BankUI*)(o->parent()->user_data()))->cb_banklist_i(o,v);
}

void BankUI::cb_B_search_i(Fl_Button*, void*) {
  //
        if (!fetchData(0, PART::control::enable, synth->getGuiMaster()->activePart))
            alert(synth, "Active part disabled");
        else
            ShowSearch();
}
void BankUI::cb_B_search(Fl_Button* o, void* v) {
  ((BankUI*)(o->parent()->user_data()))->cb_B_search_i(o,v);
}

void BankUI::cb_insRoots_i(Fl_Button*, void*) {
  //
        ShowRoot();
        if ((Fl::event_button() == 3))
        {
            rootFrom = 3;
            Hide(0);
            setVisible(synth, false, "Bank-instrument");
        }
        instFrom = 0;
}
void BankUI::cb_insRoots(Fl_Button* o, void* v) {
  ((BankUI*)(o->parent()->user_data()))->cb_insRoots_i(o,v);
}

void BankUI::cb_insBanks_i(Fl_Button*, void*) {
  //
        Showbank();
        if ((Fl::event_button() == 3))
        {
            bankFrom = 3;
            Hide(0);
            setVisible(synth, false, "Bank-instrument");
        }
        instFrom = 0;
}
void BankUI::cb_insBanks(Fl_Button* o, void* v) {
  ((BankUI*)(o->parent()->user_data()))->cb_insBanks_i(o,v);
}

void BankUI::cb_writebutton_i(Fl_Light_Button* o, void*) {
  //
          if (_SYS_::F2B(o->value()))
              mode = 2;
          removeselection();
}
void BankUI::cb_writebutton(Fl_Light_Button* o, void* v) {
  ((BankUI*)(o->parent()->parent()->user_data()))->cb_writebutton_i(o,v);
}

void BankUI::cb_readbutton_i(Fl_Light_Button* o, void*) {
  //
          if (_SYS_::F2B(o->value()))
              mode = 1;
          removeselection();
}
void BankUI::cb_readbutton(Fl_Light_Button* o, void* v) {
  ((BankUI*)(o->parent()->parent()->user_data()))->cb_readbutton_i(o,v);
}

void BankUI::cb_clearbutton_i(Fl_Light_Button* o, void*) {
  //
          if (_SYS_::F2B(o->value()))
              mode = 3;
          removeselection();
}
void BankUI::cb_clearbutton(Fl_Light_Button* o, void* v) {
  ((BankUI*)(o->parent()->parent()->user_data()))->cb_clearbutton_i(o,v);
}

void BankUI::cb_swapbutton_i(Fl_Light_Button* o, void*) {
  //
          if (_SYS_::F2B(o->value()))
              mode = 4;
          removeselection();
}
void BankUI::cb_swapbutton(Fl_Light_Button* o, void* v) {
  ((BankUI*)(o->parent()->parent()->user_data()))->cb_swapbutton_i(o,v);
}

void BankUI::cb_renamebutton_i(Fl_Light_Button* o, void*) {
  //
          if (_SYS_::F2B(o->value()))
              mode = 5;
          removeselection();
}
void BankUI::cb_renamebutton(Fl_Light_Button* o, void* v) {
  ((BankUI*)(o->parent()->parent()->user_data()))->cb_renamebutton_i(o,v);
}

void BankUI::cb_insClose_i(Fl_Button*, void*) {
  //
        if (Fl::event_button() == 3)
        {
            if (instFrom == 2)
            {
                bankFrom = 3;
                Showbank();
            }
            else if (instFrom == 4)
            {
                ; // todo open mixer panel
            }
        }
        instFrom = 0; // to avoid later confusion!
        Hide(0);
        saveWin(synth, instrumentuiwindow->w(), instrumentuiwindow->h(), instrumentuiwindow->x(), instrumentuiwindow->y(), false, "Bank-instrument");
}
void BankUI::cb_insClose(Fl_Button* o, void* v) {
  ((BankUI*)(o->parent()->user_data()))->cb_insClose_i(o,v);
}

void BankUI::cb_searchwin_i(Fl_Double_Window*, void*) {
  Hide(3);
}
void BankUI::cb_searchwin(Fl_Double_Window* o, void* v) {
  ((BankUI*)(o->user_data()))->cb_searchwin_i(o,v);
}

void BankUI::cb_searchbrowse_i(Fl_Browser* o, void*) {
  //
        if (!o->value())
            return;
        int result = o->value();
        if (result < 0)
            return;
        string line = string(o->text(result));
        int root = string2int(line.substr(0, 3));
        int bank = string2int(line.substr(5, 3));
        int inst = (string2int(line.substr(10, 3))) - 1;
        if (!fetchData(0, PART::control::enable, synth->getGuiMaster()->activePart))
            alert(synth, "Active part disabled");
        else
            send_data(TOPLEVEL::action::forceUpdate, MAIN::control::loadInstrumentFromBank, inst, TOPLEVEL::type::Integer, TOPLEVEL::section::main, synth->getGuiMaster()->activePart, bank, root);
}
void BankUI::cb_searchbrowse(Fl_Browser* o, void* v) {
  ((BankUI*)(o->parent()->user_data()))->cb_searchbrowse_i(o,v);
}

void BankUI::cb_searchClose_i(Fl_Button*, void*) {
  //
        Hide(3);
}
void BankUI::cb_searchClose(Fl_Button* o, void* v) {
  ((BankUI*)(o->parent()->user_data()))->cb_searchClose_i(o,v);
}

void BankUI::cb_searchType_i(Fl_Choice* o, void*) {
  //
          searchbrowse->clear();
          int result = o->value();
          if (result >= 0)
          {
              fillBrowser(result);
              noEntries->hide();
          }
          else
              noEntries->show();
}
void BankUI::cb_searchType(Fl_Choice* o, void* v) {
  ((BankUI*)(o->parent()->parent()->user_data()))->cb_searchType_i(o,v);
}

void BankUI::cb_bankuiwindow_i(Fl_Double_Window*, void*) {
  Hide(1);
}
void BankUI::cb_bankuiwindow(Fl_Double_Window* o, void* v) {
  ((BankUI*)(o->user_data()))->cb_bankuiwindow_i(o,v);
}

void BankUI::cb_bankroot_i(Fl_Button*, void*) {
  //
        ShowRoot();
        if ((Fl::event_button() == 3))
        {
            rootFrom = 2;
            Hide(1);
        }
        else
            rootFrom = 0;
}
void BankUI::cb_bankroot(Fl_Button* o, void* v) {
  ((BankUI*)(o->parent()->user_data()))->cb_bankroot_i(o,v);
}

void BankUI::cb_bankinst_i(Fl_Button*, void*) {
  //
        instFrom = 2;
        ShowInst();
        if (Fl::event_button() == 3)
        {
            Hide(1);};
}
void BankUI::cb_bankinst(Fl_Button* o, void* v) {
  ((BankUI*)(o->parent()->user_data()))->cb_bankinst_i(o,v);
}

void BankUI::cb_rootreadbutton_i(Fl_Light_Button* o, void*) {
  //
          if (_SYS_::F2B(o->value()))
              r_mode = 1;
          removeselection();
}
void BankUI::cb_rootreadbutton(Fl_Light_Button* o, void* v) {
  ((BankUI*)(o->parent()->parent()->user_data()))->cb_rootreadbutton_i(o,v);
}

void BankUI::cb_rootrenamebutton_i(Fl_Light_Button* o, void*) {
  //
          if (_SYS_::F2B(o->value()))
              r_mode = 5;
          removeselection();
}
void BankUI::cb_rootrenamebutton(Fl_Light_Button* o, void* v) {
  ((BankUI*)(o->parent()->parent()->user_data()))->cb_rootrenamebutton_i(o,v);
}

void BankUI::cb_rootwritebutton_i(Fl_Light_Button* o, void*) {
  //
          if (_SYS_::F2B(o->value()))
              r_mode = 2;
          removeselection();
}
void BankUI::cb_rootwritebutton(Fl_Light_Button* o, void* v) {
  ((BankUI*)(o->parent()->parent()->user_data()))->cb_rootwritebutton_i(o,v);
}

void BankUI::cb_rootclearbutton_i(Fl_Light_Button* o, void*) {
  //
          if (_SYS_::F2B(o->value()))
              r_mode = 3;
          removeselection();
}
void BankUI::cb_rootclearbutton(Fl_Light_Button* o, void* v) {
  ((BankUI*)(o->parent()->parent()->user_data()))->cb_rootclearbutton_i(o,v);
}

void BankUI::cb_rootswapbutton_i(Fl_Light_Button* o, void*) {
  //
          if (_SYS_::F2B(o->value()))
              r_mode = 4;
          removeselection();
}
void BankUI::cb_rootswapbutton(Fl_Light_Button* o, void* v) {
  ((BankUI*)(o->parent()->parent()->user_data()))->cb_rootswapbutton_i(o,v);
}

void BankUI::cb_rootimportbutton_i(Fl_Light_Button* o, void*) {
  //
          if (_SYS_::F2B(o->value()))
              r_mode = 6;
          removeselection();
}
void BankUI::cb_rootimportbutton(Fl_Light_Button* o, void* v) {
  ((BankUI*)(o->parent()->parent()->user_data()))->cb_rootimportbutton_i(o,v);
}

void BankUI::cb_rootexportbutton_i(Fl_Light_Button* o, void*) {
  //
          if (_SYS_::F2B(o->value()))
              r_mode = 7;
          removeselection();
}
void BankUI::cb_rootexportbutton(Fl_Light_Button* o, void* v) {
  ((BankUI*)(o->parent()->parent()->user_data()))->cb_rootexportbutton_i(o,v);
}

void BankUI::cb_bankClose_i(Fl_Button*, void*) {
  //
            Hide(1);
            if (Fl::event_button() == 3)
            {
                if (bankFrom == 1)
                {
                    rootFrom = 2;
                    ShowRoot();
                }
                else if (bankFrom == 3)
                {
                    instFrom = 2;
                    ShowInst();
                }
            }
            else
                bankFrom = 0;
}
void BankUI::cb_bankClose(Fl_Button* o, void* v) {
  ((BankUI*)(o->parent()->user_data()))->cb_bankClose_i(o,v);
}

void BankUI::cb_rootuiwindow_i(Fl_Double_Window*, void*) {
  Hide(2);
}
void BankUI::cb_rootuiwindow(Fl_Double_Window* o, void* v) {
  ((BankUI*)(o->user_data()))->cb_rootuiwindow_i(o,v);
}

void BankUI::cb_rootsbrowse_i(Fl_Browser* o, void*) {
  int tmp = o->value();
        activatebutton_rootdir(tmp!=0);
        if (tmp)
        {
            selectedRootID = reinterpret_cast<long>(o->data(tmp));
        }

        changeIDbutton->value(recoverID());
        oldrootID = changeIDbutton->value();
        Pend->hide();
}
void BankUI::cb_rootsbrowse(Fl_Browser* o, void* v) {
  ((BankUI*)(o->parent()->user_data()))->cb_rootsbrowse_i(o,v);
}

void BankUI::cb_addrootdirbutton_i(Fl_Button*, void*) {
  //
        // using 'false' here as we want to test for it
        // rather than automatically create it.
        string dirname = setfiler(synth,"Path to Bank Root dirs", "", false, TOPLEVEL::XML::Dir);
        if (dirname.length() < 3)
            return;
        int newdef = UNUSED;
        if (!file::isDirectory(dirname))
        {
            if (choice(synth, "", "Yes", "No", "Directory is missing, or doesn't have at least \n one bank with at least one instrument. \nCreate missing entries?") != 2)
                return;
            newdef = 0;
        }
        send_data(TOPLEVEL::action::lowPrio | TOPLEVEL::action::forceUpdate, BANK::control::addNamedRoot, 0, TOPLEVEL::type::Write, TOPLEVEL::section::bank, newdef, UNUSED, UNUSED, UNUSED, textMsgBuffer.push(dirname));
        Pend->hide();
}
void BankUI::cb_addrootdirbutton(Fl_Button* o, void* v) {
  ((BankUI*)(o->parent()->user_data()))->cb_addrootdirbutton_i(o,v);
}

void BankUI::cb_removerootdirbutton_i(Fl_Button*, void*) {
  //
        if (selectedRootID >= 0)
        {
            synth->getBankRef().removeRoot(selectedRootID);
            synth->saveBanks();
            readbankcfg();
        }
        activatebutton_rootdir(false);
        rescan_for_banks();
        Pend->hide();
}
void BankUI::cb_removerootdirbutton(Fl_Button* o, void* v) {
  ((BankUI*)(o->parent()->user_data()))->cb_removerootdirbutton_i(o,v);
}

void BankUI::cb_makedefaultrootdirbutton_i(Fl_Button*, void*) {
  //
        if (selectedRootID >= 0)
        {
            send_data(TOPLEVEL::action::lowPrio | TOPLEVEL::action::forceUpdate, BANK::control::selectRoot, selectedRootID, TOPLEVEL::type::Integer, TOPLEVEL::section::bank);

            banklist->value(0);
        }
        activatebutton_rootdir(false);
        Pend->hide();
}
void BankUI::cb_makedefaultrootdirbutton(Fl_Button* o, void* v) {
  ((BankUI*)(o->parent()->user_data()))->cb_makedefaultrootdirbutton_i(o,v);
}

void BankUI::cb_showdefaultrootdirbutton_i(Fl_Button*, void*) {
  //
        Showbank();
        if (Fl::event_button() == 3)
        {
            bankFrom = 1;
            Hide(2);
        }
        else
            rootFrom = 0;
}
void BankUI::cb_showdefaultrootdirbutton(Fl_Button* o, void* v) {
  ((BankUI*)(o->parent()->user_data()))->cb_showdefaultrootdirbutton_i(o,v);
}

void BankUI::cb_changeIDbutton_i(WidgetSpinner*, void*) {
  Pend->show();
}
void BankUI::cb_changeIDbutton(WidgetSpinner* o, void* v) {
  ((BankUI*)(o->parent()->user_data()))->cb_changeIDbutton_i(o,v);
}

void BankUI::cb_Pend_i(Fl_Button* o, void*) {
  //
        int tmp = changeIDbutton->value();
        if (tmp == oldrootID)
        {
            o->hide();
            return;
        }
        if (selectedRootID >= 0)
        {
            send_data(TOPLEVEL::action::lowPrio | TOPLEVEL::action::forceUpdate, BANK::control::changeRootId, tmp, TOPLEVEL::type::Integer, TOPLEVEL::section::bank, UNUSED, selectedRootID);
        }
        oldrootID = tmp;
        activatebutton_rootdir(false);
        o->hide();
}
void BankUI::cb_Pend(Fl_Button* o, void* v) {
  ((BankUI*)(o->parent()->user_data()))->cb_Pend_i(o,v);
}

void BankUI::cb_rootClose_i(Fl_Button*, void*) {
  //
        if (Fl::event_button() == 3)
        {
            if (rootFrom == 2)
            Showbank();
        }
        else
            rootFrom = 0;
        Hide(2);
}
void BankUI::cb_rootClose(Fl_Button* o, void* v) {
  ((BankUI*)(o->parent()->user_data()))->cb_rootClose_i(o,v);
}

Fl_Double_Window* BankUI::make_window() {
  { Fl_Double_Window* o = instrumentuiwindow = new Fl_Double_Window(780, 570, "Bank");
    instrumentuiwindow->labelsize(12);
    instrumentuiwindow->callback((Fl_Callback*)cb_instrumentuiwindow, (void*)(this));
    { banklist = new Fl_Choice(5, 8, 199, 20);
      banklist->down_box(FL_BORDER_BOX);
      banklist->selection_color(FL_BACKGROUND2_COLOR);
      banklist->labelfont(1);
      banklist->labelsize(12);
      banklist->textsize(12);
      banklist->callback((Fl_Callback*)cb_banklist);
      banklist->align(Fl_Align(FL_ALIGN_CENTER));
    } // Fl_Choice* banklist
    { B_search = new Fl_Button(230, 5, 93, 25, "Search");
      B_search->tooltip("Select instrument from list, by type");
      B_search->box(FL_PLASTIC_UP_BOX);
      B_search->labelfont(1);
      B_search->labelsize(12);
      B_search->callback((Fl_Callback*)cb_B_search);
      B_search->align(Fl_Align(FL_ALIGN_WRAP));
    } // Fl_Button* B_search
    { insRoots = new Fl_Button(350, 5, 93, 25, "Roots");
      insRoots->tooltip("Show root paths. Right click: also close this");
      insRoots->box(FL_PLASTIC_UP_BOX);
      insRoots->labelfont(1);
      insRoots->labelsize(12);
      insRoots->callback((Fl_Callback*)cb_insRoots);
      insRoots->align(Fl_Align(FL_ALIGN_WRAP));
    } // Fl_Button* insRoots
    { insBanks = new Fl_Button(496, 5, 93, 25, "Banks");
      insBanks->tooltip("Show banks in current root. Right click: also close this");
      insBanks->box(FL_PLASTIC_UP_BOX);
      insBanks->labelfont(1);
      insBanks->labelsize(12);
      insBanks->callback((Fl_Callback*)cb_insBanks);
      insBanks->align(Fl_Align(FL_ALIGN_WRAP));
    } // Fl_Button* insBanks
    { insT1 = new Fl_Text_Display(624, 17, 136, 3, "This column uses MIDI");
      insT1->box(FL_NO_BOX);
      insT1->labelsize(12);
      insT1->align(Fl_Align(33));
    } // Fl_Text_Display* insT1
    { insT2 = new Fl_Text_Display(610, 30, 162, 3, "Extended Program Change");
      insT2->box(FL_NO_BOX);
      insT2->labelsize(12);
      insT2->align(Fl_Align(33));
    } // Fl_Text_Display* insT2
    { insgroup = new Fl_Group(1, 31, 779, 494);
      insgroup->labelsize(12);
      { Fl_Group* o = insframe1 = new Fl_Group(4, 31, 158, 494);
        insframe1->labelsize(12);
        o->box(FL_NO_BOX);
        for (int i = 0; i < 32; ++i)
            {
                bs[i] = new BankSlot (0, 0, o->w(), 15, " ");
                bs[i]->init(i, &what, &slot, &BankProcess_::process,
                            (BankProcess_ *)this, bank, &nselected);
            }
        insframe1->end();
      } // Fl_Group* insframe1
      { Fl_Group* o = insframe2 = new Fl_Group(161, 31, 152, 494);
        insframe2->labelsize(12);
        o->box(FL_NO_BOX);
        for (int i = 32; i < 64; ++i)
            {
                bs[i] = new BankSlot (0, 0, o->w(), 15, " ");
                bs[i]->init(i, &what, &slot, &BankProcess_::process,
                            (BankProcess_ *)this, bank, &nselected);
            }
        insframe2->end();
      } // Fl_Group* insframe2
      { Fl_Group* o = insframe3 = new Fl_Group(316, 31, 150, 494);
        insframe3->labelsize(12);
        o->box(FL_NO_BOX);
        for (int i = 64; i < 96; ++i)
            {
                bs[i] = new BankSlot (0, 0, o->w(), 15, " ");
                bs[i]->init(i, &what, &slot, &BankProcess_::process,
                            (BankProcess_ *)this, bank, &nselected);
            }
        insframe3->end();
      } // Fl_Group* insframe3
      { Fl_Group* o = insframe4 = new Fl_Group(469, 31, 150, 494);
        insframe4->labelsize(12);
        o->box(FL_NO_BOX);
        for (int i = 96; i < 128; ++i)
            {
                bs[i] = new BankSlot (0, 0, o->w(), 15, " ");
                bs[i]->init(i, &what, &slot, &BankProcess_::process,
                            (BankProcess_ *)this, bank, &nselected);
            }
        insframe4->end();
      } // Fl_Group* insframe4
      { Fl_Group* o = insframe5 = new Fl_Group(622, 31, 156, 494);
        insframe5->color((Fl_Color)48);
        insframe5->labelsize(12);
        o->box(FL_NO_BOX);
        for (int i = 128; i < 160; ++i)
            {
                bs[i] = new BankSlot (0, 0, o->w(), 15, " ");
                bs[i]->init(i, &what, &slot, &BankProcess_::process,
                            (BankProcess_ *)this, bank, &nselected);
            }
        insframe5->end();
      } // Fl_Group* insframe5
      insgroup->end();
    } // Fl_Group* insgroup
    { modeselect = new Fl_Group(5, 528, 458, 42);
      modeselect->box(FL_ENGRAVED_BOX);
      modeselect->labelsize(12);
      { writebutton = new Fl_Light_Button(190, 534, 85, 30, "SAVE");
        writebutton->type(102);
        writebutton->box(FL_PLASTIC_UP_BOX);
        writebutton->down_box(FL_THIN_DOWN_BOX);
        writebutton->selection_color((Fl_Color)3);
        writebutton->labelfont(9);
        writebutton->labelsize(12);
        writebutton->callback((Fl_Callback*)cb_writebutton);
      } // Fl_Light_Button* writebutton
      { Fl_Light_Button* o = readbutton = new Fl_Light_Button(10, 534, 85, 30, "SELECT");
        readbutton->type(102);
        readbutton->box(FL_PLASTIC_UP_BOX);
        readbutton->down_box(FL_THIN_DOWN_BOX);
        readbutton->selection_color((Fl_Color)101);
        readbutton->labelfont(9);
        readbutton->labelsize(12);
        readbutton->callback((Fl_Callback*)cb_readbutton);
        o->value(1);
      } // Fl_Light_Button* readbutton
      { clearbutton = new Fl_Light_Button(280, 534, 85, 30, "DELETE");
        clearbutton->type(102);
        clearbutton->box(FL_PLASTIC_UP_BOX);
        clearbutton->down_box(FL_THIN_DOWN_BOX);
        clearbutton->selection_color((Fl_Color)1);
        clearbutton->labelfont(9);
        clearbutton->labelsize(12);
        clearbutton->callback((Fl_Callback*)cb_clearbutton);
      } // Fl_Light_Button* clearbutton
      { swapbutton = new Fl_Light_Button(370, 534, 85, 30, "SWAP");
        swapbutton->type(102);
        swapbutton->box(FL_PLASTIC_UP_BOX);
        swapbutton->down_box(FL_THIN_DOWN_BOX);
        swapbutton->selection_color((Fl_Color)227);
        swapbutton->labelfont(9);
        swapbutton->labelsize(12);
        swapbutton->callback((Fl_Callback*)cb_swapbutton);
      } // Fl_Light_Button* swapbutton
      { renamebutton = new Fl_Light_Button(100, 534, 85, 30, "RENAME");
        renamebutton->type(102);
        renamebutton->box(FL_PLASTIC_UP_BOX);
        renamebutton->down_box(FL_THIN_DOWN_BOX);
        renamebutton->selection_color((Fl_Color)5);
        renamebutton->labelfont(9);
        renamebutton->labelsize(12);
        renamebutton->callback((Fl_Callback*)cb_renamebutton);
      } // Fl_Light_Button* renamebutton
      modeselect->end();
    } // Fl_Group* modeselect
    { insT3 = new Fl_Text_Display(495, 546, 96, 3, "Engines Used");
      insT3->box(FL_NO_BOX);
      insT3->labelsize(12);
      insT3->textsize(12);
      insT3->align(Fl_Align(33));
    } // Fl_Text_Display* insT3
    { insClose = new Fl_Button(665, 539, 70, 24, "Close");
      insClose->tooltip("Right click: also reopen previous");
      insClose->box(FL_THIN_UP_BOX);
      insClose->labelsize(12);
      insClose->callback((Fl_Callback*)cb_insClose);
    } // Fl_Button* insClose
    { Fl_Group* o = new Fl_Group(468, 528, 151, 42);
      o->box(FL_ENGRAVED_FRAME);
      o->labelsize(12);
      { Fl_Button* o = addpatch = new Fl_Button(473, 550, 47, 16, "Add");
        addpatch->box(FL_FLAT_BOX);
        addpatch->labelsize(12);
        addpatch->align(Fl_Align(FL_ALIGN_TEXT_OVER_IMAGE));
        o->color(ADD_COLOUR);
      } // Fl_Button* addpatch
      { Fl_Button* o = subpatch = new Fl_Button(520, 550, 47, 16, "Sub");
        subpatch->box(FL_FLAT_BOX);
        subpatch->labelsize(12);
        subpatch->align(Fl_Align(FL_ALIGN_TEXT_OVER_IMAGE));
        o->color(SUB_COLOUR);
      } // Fl_Button* subpatch
      { Fl_Button* o = padpatch = new Fl_Button(567, 550, 47, 16, "Pad");
        padpatch->box(FL_FLAT_BOX);
        padpatch->color((Fl_Color)29);
        padpatch->labelsize(12);
        padpatch->align(Fl_Align(FL_ALIGN_TEXT_OVER_IMAGE));
        o->color(PAD_COLOUR);
      } // Fl_Button* padpatch
      { Fl_Button* o = new Fl_Button(474, 549, 139, 17);
        o->box(FL_THIN_UP_FRAME);
        o->labelsize(12);
      } // Fl_Button* o
      o->end();
    } // Fl_Group* o
    instDW = o->w(), instDH = o->h();
    o->size_range((instDW * 8 / 10), (instDH * 8 / 10), 0,0,0,0,1);
    instrumentuiwindow->end();
    instrumentuiwindow->resizable(instrumentuiwindow);
  } // Fl_Double_Window* instrumentuiwindow
  { Fl_Double_Window* o = searchwin = new Fl_Double_Window(305, 485, "Bank Search");
    searchwin->box(FL_PLASTIC_THIN_UP_BOX);
    searchwin->color((Fl_Color)22);
    searchwin->labelsize(12);
    searchwin->callback((Fl_Callback*)cb_searchwin, (void*)(this));
    { searchbrowse = new Fl_Browser(12, 65, 282, 374);
      searchbrowse->type(1);
      searchbrowse->labelsize(12);
      searchbrowse->textsize(12);
      searchbrowse->callback((Fl_Callback*)cb_searchbrowse);
    } // Fl_Browser* searchbrowse
    { searchClose = new Fl_Button(228, 451, 65, 24, "Close");
      searchClose->labelsize(12);
      searchClose->callback((Fl_Callback*)cb_searchClose);
      searchClose->align(Fl_Align(192));
    } // Fl_Button* searchClose
    { searchT = new Fl_Button(12, 40, 282, 4, "Root Bank Instrument");
      searchT->box(FL_NO_BOX);
      searchT->labelfont(1);
      searchT->labelsize(12);
      searchT->align(Fl_Align(FL_ALIGN_BOTTOM_LEFT));
    } // Fl_Button* searchT
    { noEntries = new Fl_Text_Display(70, 195, 177, 0, "No Entries");
      noEntries->labelfont(1);
      noEntries->labelsize(30);
      noEntries->labelcolor(FL_RED);
      noEntries->textsize(12);
      noEntries->hide();
      noEntries->deactivate();
    } // Fl_Text_Display* noEntries
    { Fl_Group* o = new Fl_Group(25, 1, 210, 35);
      o->labelsize(12);
      { searchType = new Fl_Choice(70, 15, 159, 20, "Type:");
        searchType->down_box(FL_BORDER_BOX);
        searchType->labelfont(1);
        searchType->labelsize(12);
        searchType->textfont(1);
        searchType->textsize(12);
        searchType->callback((Fl_Callback*)cb_searchType);
        fillSearchChoice();
      } // Fl_Choice* searchType
      o->end();
    } // Fl_Group* o
    searchDW = o->w(); searchDH = o->h();
    searchwin->size_range(searchDW, searchDH, 0, 0, 0, 0, 1);
    searchwin->end();
    searchwin->resizable(searchwin);
  } // Fl_Double_Window* searchwin
  { Fl_Double_Window* o = bankuiwindow = new Fl_Double_Window(780, 570, "Root");
    bankuiwindow->labelsize(12);
    bankuiwindow->callback((Fl_Callback*)cb_bankuiwindow, (void*)(this));
    { bankroot = new Fl_Button(248, 5, 93, 25, "Roots");
      bankroot->tooltip("Show root paths. Right click: also close this");
      bankroot->box(FL_PLASTIC_UP_BOX);
      bankroot->labelfont(1);
      bankroot->labelsize(12);
      bankroot->callback((Fl_Callback*)cb_bankroot);
      bankroot->align(Fl_Align(FL_ALIGN_WRAP));
    } // Fl_Button* bankroot
    { bankcurrent = new Fl_Button(394, 10, 178, 15, "current bank");
      bankcurrent->tooltip("Show instruments in current bank");
      bankcurrent->box(FL_THIN_UP_BOX);
      bankcurrent->down_box(FL_THIN_UP_BOX);
      bankcurrent->color((Fl_Color)252);
      bankcurrent->selection_color((Fl_Color)252);
      bankcurrent->labelsize(12);
      bankcurrent->align(Fl_Align(FL_ALIGN_WRAP));
    } // Fl_Button* bankcurrent
    { bankinst = new Fl_Button(627, 5, 93, 25, "Instruments");
      bankinst->tooltip("Show instruments in current bank. Right click: also close this");
      bankinst->box(FL_PLASTIC_UP_BOX);
      bankinst->labelfont(1);
      bankinst->labelsize(12);
      bankinst->callback((Fl_Callback*)cb_bankinst);
      bankinst->align(Fl_Align(FL_ALIGN_WRAP));
    } // Fl_Button* bankinst
    { bankgroup = new Fl_Group(2, 30, 776, 499);
      bankgroup->labelsize(12);
      { Fl_Group* o = new Fl_Group(4, 30, 192, 496);
        o->labelsize(12);
        o->box(FL_NO_BOX);
        //
            for (int i = 0; i < 32; ++i)
            {
                rs[i] = new RootSlot (0, 0, o->w(), 15, " ");
                rs[i]->init(i, &what, &slot, &RootProcess_::rootprocess,
                            (RootProcess_ *)this, bank, &rselected);

          }
        o->end();
      } // Fl_Group* o
      { Fl_Group* o = new Fl_Group(200, 31, 189, 496);
        o->labelsize(12);
        o->box(FL_NO_BOX);
        //
            for (int i = 32; i < 64; ++i)
            {
                rs[i] = new RootSlot (0, 0, o->w(), 15, " ");
                rs[i]->init(i, &what, &slot, &RootProcess_::rootprocess,
                            (RootProcess_ *)this, bank, &rselected);

          }
        o->end();
      } // Fl_Group* o
      { Fl_Group* o = new Fl_Group(390, 30, 189, 496);
        o->labelsize(12);
        o->box(FL_NO_BOX);
        //
            for (int i = 64; i < 96; ++i)
            {
                rs[i] = new RootSlot (0, 0, o->w(), 15, " ");
                rs[i]->init(i, &what, &slot, &RootProcess_::rootprocess,
                            (RootProcess_ *)this, bank, &rselected);

          }
        o->end();
      } // Fl_Group* o
      { Fl_Group* o = new Fl_Group(580, 30, 196, 496);
        o->labelsize(12);
        o->box(FL_NO_BOX);
        //
            for (int i = 96; i < 128; ++i)
            {
                rs[i] = new RootSlot (0, 0, o->w(), 15, " ");
                rs[i]->init(i, &what, &slot, &RootProcess_::rootprocess,
                            (RootProcess_ *)this, bank, &rselected);

          }
        o->end();
      } // Fl_Group* o
      bankgroup->end();
    } // Fl_Group* bankgroup
    { rootmodeselect = new Fl_Group(5, 528, 570, 42);
      rootmodeselect->box(FL_ENGRAVED_BOX);
      rootmodeselect->labelsize(12);
      { Fl_Light_Button* o = rootreadbutton = new Fl_Light_Button(10, 534, 85, 30, "SELECT");
        rootreadbutton->type(102);
        rootreadbutton->box(FL_PLASTIC_UP_BOX);
        rootreadbutton->down_box(FL_THIN_DOWN_BOX);
        rootreadbutton->selection_color((Fl_Color)101);
        rootreadbutton->labelfont(9);
        rootreadbutton->labelsize(12);
        rootreadbutton->callback((Fl_Callback*)cb_rootreadbutton);
        o->value(1);
      } // Fl_Light_Button* rootreadbutton
      { rootrenamebutton = new Fl_Light_Button(105, 534, 85, 30, "RENAME");
        rootrenamebutton->type(102);
        rootrenamebutton->box(FL_PLASTIC_UP_BOX);
        rootrenamebutton->down_box(FL_THIN_DOWN_BOX);
        rootrenamebutton->selection_color((Fl_Color)5);
        rootrenamebutton->labelfont(9);
        rootrenamebutton->labelsize(12);
        rootrenamebutton->callback((Fl_Callback*)cb_rootrenamebutton);
      } // Fl_Light_Button* rootrenamebutton
      { rootwritebutton = new Fl_Light_Button(200, 534, 85, 30, "ADD");
        rootwritebutton->type(102);
        rootwritebutton->box(FL_PLASTIC_UP_BOX);
        rootwritebutton->down_box(FL_THIN_DOWN_BOX);
        rootwritebutton->selection_color((Fl_Color)3);
        rootwritebutton->labelfont(9);
        rootwritebutton->labelsize(12);
        rootwritebutton->callback((Fl_Callback*)cb_rootwritebutton);
      } // Fl_Light_Button* rootwritebutton
      { rootclearbutton = new Fl_Light_Button(295, 534, 85, 30, "DELETE");
        rootclearbutton->type(102);
        rootclearbutton->box(FL_PLASTIC_UP_BOX);
        rootclearbutton->down_box(FL_THIN_DOWN_BOX);
        rootclearbutton->selection_color((Fl_Color)1);
        rootclearbutton->labelfont(9);
        rootclearbutton->labelsize(12);
        rootclearbutton->callback((Fl_Callback*)cb_rootclearbutton);
      } // Fl_Light_Button* rootclearbutton
      { rootswapbutton = new Fl_Light_Button(390, 534, 85, 30, "SWAP");
        rootswapbutton->type(102);
        rootswapbutton->box(FL_PLASTIC_UP_BOX);
        rootswapbutton->down_box(FL_THIN_DOWN_BOX);
        rootswapbutton->selection_color((Fl_Color)227);
        rootswapbutton->labelfont(9);
        rootswapbutton->labelsize(12);
        rootswapbutton->callback((Fl_Callback*)cb_rootswapbutton);
      } // Fl_Light_Button* rootswapbutton
      { rootimportbutton = new Fl_Light_Button(485, 533, 85, 15, "IMPORT");
        rootimportbutton->type(102);
        rootimportbutton->box(FL_PLASTIC_UP_BOX);
        rootimportbutton->down_box(FL_THIN_DOWN_BOX);
        rootimportbutton->selection_color((Fl_Color)93);
        rootimportbutton->labelfont(8);
        rootimportbutton->labelsize(9);
        rootimportbutton->callback((Fl_Callback*)cb_rootimportbutton);
      } // Fl_Light_Button* rootimportbutton
      { rootexportbutton = new Fl_Light_Button(485, 550, 85, 15, "EXPORT");
        rootexportbutton->type(102);
        rootexportbutton->box(FL_PLASTIC_UP_BOX);
        rootexportbutton->down_box(FL_THIN_DOWN_BOX);
        rootexportbutton->selection_color((Fl_Color)78);
        rootexportbutton->labelfont(8);
        rootexportbutton->labelsize(9);
        rootexportbutton->callback((Fl_Callback*)cb_rootexportbutton);
      } // Fl_Light_Button* rootexportbutton
      rootmodeselect->end();
    } // Fl_Group* rootmodeselect
    { bankClose = new Fl_Button(647, 538, 70, 24, "Close");
      bankClose->tooltip("Right click: also reopen previous");
      bankClose->box(FL_THIN_UP_BOX);
      bankClose->labelsize(12);
      bankClose->callback((Fl_Callback*)cb_bankClose);
    } // Fl_Button* bankClose
    o->copy_label(bank->getRootFileTitle(fetchData(0, BANK::control::selectRoot, TOPLEVEL::section::bank)).c_str());
    bankDW = o->w();bankDH = o->h();
    o->size_range((instDW * 8 / 10), (instDH * 8 / 10), 0,0,0,0,1);
    bankuiwindow->end();
    bankuiwindow->resizable(bankuiwindow);
  } // Fl_Double_Window* bankuiwindow
  { Fl_Double_Window* o = rootuiwindow = new Fl_Double_Window(460, 270, "Bank Root Paths");
    rootuiwindow->labelsize(12);
    rootuiwindow->callback((Fl_Callback*)cb_rootuiwindow, (void*)(this));
    { rootsbrowse = new Fl_Browser(10, 10, 445, 200);
      rootsbrowse->type(2);
      rootsbrowse->labelsize(12);
      rootsbrowse->textsize(12);
      rootsbrowse->callback((Fl_Callback*)cb_rootsbrowse);
    } // Fl_Browser* rootsbrowse
    { addrootdirbutton = new Fl_Button(10, 225, 75, 35, "Add root directory...");
      addrootdirbutton->box(FL_THIN_UP_BOX);
      addrootdirbutton->labelsize(12);
      addrootdirbutton->callback((Fl_Callback*)cb_addrootdirbutton);
      addrootdirbutton->align(Fl_Align(FL_ALIGN_WRAP));
    } // Fl_Button* addrootdirbutton
    { Fl_Button* o = removerootdirbutton = new Fl_Button(94, 225, 75, 35, "Remove root dir...");
      removerootdirbutton->box(FL_THIN_UP_BOX);
      removerootdirbutton->labelsize(12);
      removerootdirbutton->callback((Fl_Callback*)cb_removerootdirbutton);
      removerootdirbutton->align(Fl_Align(FL_ALIGN_WRAP));
      removerootdirbutton->deactivate();
      o->deactivate();
    } // Fl_Button* removerootdirbutton
    { Fl_Button* o = makedefaultrootdirbutton = new Fl_Button(178, 225, 75, 35, "Make current");
      makedefaultrootdirbutton->box(FL_THIN_UP_BOX);
      makedefaultrootdirbutton->labelsize(12);
      makedefaultrootdirbutton->callback((Fl_Callback*)cb_makedefaultrootdirbutton);
      makedefaultrootdirbutton->align(Fl_Align(FL_ALIGN_WRAP));
      makedefaultrootdirbutton->deactivate();
      o->deactivate();
    } // Fl_Button* makedefaultrootdirbutton
    { showdefaultrootdirbutton = new Fl_Button(262, 225, 75, 35, "Open current");
      showdefaultrootdirbutton->tooltip("Right click: also close this");
      showdefaultrootdirbutton->box(FL_THIN_UP_BOX);
      showdefaultrootdirbutton->labelsize(12);
      showdefaultrootdirbutton->callback((Fl_Callback*)cb_showdefaultrootdirbutton);
      showdefaultrootdirbutton->align(Fl_Align(FL_ALIGN_WRAP));
    } // Fl_Button* showdefaultrootdirbutton
    { WidgetSpinner* o = changeIDbutton = new WidgetSpinner(344, 240, 45, 19, "New ID");
      changeIDbutton->box(FL_NO_BOX);
      changeIDbutton->color(FL_BACKGROUND_COLOR);
      changeIDbutton->selection_color(FL_BACKGROUND_COLOR);
      changeIDbutton->labeltype(FL_NORMAL_LABEL);
      changeIDbutton->labelfont(0);
      changeIDbutton->labelsize(12);
      changeIDbutton->labelcolor(FL_FOREGROUND_COLOR);
      changeIDbutton->minimum(0);
      changeIDbutton->maximum(126);
      changeIDbutton->textsize(12);
      changeIDbutton->callback((Fl_Callback*)cb_changeIDbutton);
      changeIDbutton->align(Fl_Align(FL_ALIGN_TOP_LEFT));
      changeIDbutton->when(FL_WHEN_RELEASE);
      changeIDbutton->deactivate();
      oldrootID = o->value();
    } // WidgetSpinner* changeIDbutton
    { Pend = new Fl_Button(340, 220, 56, 18, "Pending");
      Pend->tooltip("Click to set");
      Pend->box(FL_PLASTIC_UP_BOX);
      Pend->color((Fl_Color)90);
      Pend->labelsize(10);
      Pend->callback((Fl_Callback*)cb_Pend);
      Pend->hide();
    } // Fl_Button* Pend
    { rootClose = new Fl_Button(402, 225, 51, 35, "Close");
      rootClose->tooltip("Right click: also reopen previous");
      rootClose->box(FL_THIN_UP_BOX);
      rootClose->labelsize(12);
      rootClose->callback((Fl_Callback*)cb_rootClose);
    } // Fl_Button* rootClose
    readbankcfg();
    o->copy_label(synth->makeUniqueName("Bank Root Paths").c_str());
    rootDW = o->w(); rootDH = o->h();
    o->size_range(rootDW, rootDH, 0,0,0,0,1);
    rootuiwindow->end();
    rootuiwindow->resizable(rootuiwindow);
  } // Fl_Double_Window* rootuiwindow
  return rootuiwindow;
}

void BankUI::fillSearchChoice() {
  //
  
          int i = 0;
          string entry = type_list[i];
          while (entry != "@end")
          {
              searchType->add(entry.c_str());
              ++ i;
              entry = type_list[i];
          }
}

void BankUI::fillBrowser(int group) {
  //
            string line;
            do
            {
                line = textMsgBuffer.fetch(fetchData(0, BANK::control::findInstrumentName, TOPLEVEL::section::bank, UNUSED, UNUSED, UNUSED, group));
                if (line !="@end")
                    searchbrowse->add(line.c_str());
            } while (line != "@end");
}

void BankUI::send_data(int action, int control, float value, int type, int part , int kititem , int engine , int insert , int parameter , int miscmsg ) {
  //
          type |= TOPLEVEL::type::Write;
          collect_data(synth, value, action, type, control, part, kititem, engine, insert, parameter, UNUSED, miscmsg);
}

float BankUI::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 BankUI::returns_update(CommandBlock *getData) {
  //
      //int value_int = getData->data.value;
      unsigned char control = getData->data.control;
      unsigned char kititem = getData->data.kit;
      //unsigned char engine= getData->data.engine;
      unsigned char insert = getData->data.insert;
  
      int source = getData->data.source & TOPLEVEL::action::noAction;
      string message = textMsgBuffer.fetch(getData->data.miscmsg);
      switch(control)
      {
          case BANK::control::exportBank:
              if (source == TOPLEVEL::action::fromGUI)
                  alert(synth, message);
              break;
          case BANK::control::renameInstrument:
              if (message.find("FAILED") != std::string::npos)
              {
                  if (source == TOPLEVEL::action::fromGUI)
                      alert(synth, message);
              }
              else
                  bs[insert]->copy_label(message.c_str());
              break;
          case BANK::control::saveInstrument:
              if (message.find("FAILED") != std::string::npos)
              {
                  if (source == TOPLEVEL::action::fromGUI)
                      alert(synth, message);
              }
              else
                  refreshinstrumentwindow();
              break;
          case BANK::control::deleteInstrument:
              if (message.find("FAILED") != std::string::npos)
              {
                  if (source == TOPLEVEL::action::fromGUI)
                      alert(synth, message);
              }
              else
                  rescan_for_banks();
              break;
          case BANK::control::selectFirstInstrumentToSwap:
              break;
          case BANK::control::selectSecondInstrumentAndSwap:
  
              if (message.find("FAILED") != std::string::npos)
                  if (source == TOPLEVEL::action::fromGUI)
                      alert(synth, message);
              rescan_for_banks();
              break;
  
          case BANK::control::selectBank:
              rescan_for_banks();
              break;
          case BANK::control::renameBank:
          if (message.find("FAILED") != std::string::npos)
                  if (source == TOPLEVEL::action::fromGUI)
                      alert(synth, message);
              rescan_for_banks();
              break;
          case BANK::control::createBank:
              if (message.find("FAILED") != std::string::npos)
                  if (source == TOPLEVEL::action::fromGUI)
                      alert(synth, message);
              readbankcfg();
              rescan_for_banks();
              break;
  
          case BANK::control::selectFirstBankToSwap:
              break;
          case BANK::control::selectSecondBankAndSwap:
              if (message.find("FAILED") != std::string::npos)
                  if (source == TOPLEVEL::action::fromGUI)
                      alert(synth, message);
              rescan_for_banks();
              break;
  
          case BANK::control::selectRoot:
              readbankcfg();
              rescan_for_banks();
              break;
          case BANK::control::changeRootId:
              readbankcfg();
              rescan_for_banks();
              break;
          case BANK::control::addNamedRoot:
              readbankcfg();
              rescan_for_banks();
              if (kititem != UNUSED)
                  synth->getGuiMaster()->updatepart();
              break;
          case BANK::control::deselectRoot:
              readbankcfg();
              rescan_for_banks();
              break;
          case BANK::control::refreshDefaults:
              readbankcfg();
              break;
      }
}

BankUI::BankUI(SynthEngine *_synth) {
  //
      synth = _synth;
      fnr = &RootProcess_::rootprocess;
      root = synth->getBankPtr();
      fnc = &BankProcess_::process;
      bank = synth->getBankPtr();
      what = 0;
      nselected = -1;
      rselected = -1;
      instrumentSeen = false;
      bankSeen = false;
      rootSeen = false;
      searchSeen = false;
      make_window();
      r_mode = 1;
      mode = 1;
      bankS = 0;
      rootFrom = 0;
      bankFrom = 0;
      instFrom = 0;
}

BankUI::~BankUI() {
  //
          if (instrumentSeen)
              saveWin(synth, instrumentuiwindow->w(), instrumentuiwindow->h(), instrumentuiwindow->x(), instrumentuiwindow->y(), true, "Bank-instrument");
          instrumentuiwindow->hide();
          delete instrumentuiwindow;
          if (bankSeen)
              saveWin(synth, bankuiwindow->w(), bankuiwindow->h(), bankuiwindow->x(),  bankuiwindow->y(), true, "Bank-bank");
          bankuiwindow->hide();
          delete bankuiwindow;
          if (rootSeen)
              saveWin(synth,rootuiwindow->w(), rootuiwindow->h(),  rootuiwindow->x(),  rootuiwindow->y(), true, "Bank-root");
          rootuiwindow->hide();
          if (searchSeen)
              saveWin(synth,searchwin->w(), searchwin->h(),  searchwin->x(),  searchwin->y(), true, "Bank-search");
          searchwin->hide();
          delete searchwin;
  
          delete rootuiwindow;
}

void BankUI::Show() {
  // called from part UI
      rescan_for_banks();
      set_bank_slot();
      ShowInst();
      readbutton->value(1);
      mode = 1;
      removeselection();
      refreshmainwindow();
}

void BankUI::ShowInst() {
  //
  
      int X, Y, W, H, O;
      loadWin(synth, W, H, X, Y, O, "Bank-instrument");
      if (W < instDW || H < instDH)
      {
          W = instDW;
          H = instDH;
      }
      checkSane(X, Y, W, H, instDW, instDH);
  
      instrumentuiwindow->resize(X, Y, W, H);
      lastinstrumentW = 0;
      instrumentuiwindow->show();
      instrumentSeen = true;
}

void BankUI::Showbank() {
  //
  
      int X, Y, W, H, O;
      loadWin(synth, W, H, X, Y, O, "Bank-bank");
      if (W < bankDW || H < bankDH)
      {
          W = bankDW;
          H = bankDH;
      }
      checkSane(X, Y, W, H, bankDW, bankDH);
  
      bankuiwindow->resize(X, Y, W, H);
      bankuiwindow->show();
      lastbankW = 0;
      bankSeen = true;
}

void BankUI::ShowRoot() {
  //
  
      int X, Y, W, H, O;
      loadWin(synth, W, H, X, Y, O, "Bank-root");
      if (W < rootDW || H < rootDH)
      {
          W = rootDW;
          H = rootDH;
      }
      checkSane(X, Y, W, H, rootDW, rootDH);
  
      rootuiwindow->resize(X, Y, W, H);
      rootuiwindow->show();
      lastrootW = 0;
      rootSeen = true;
}

void BankUI::ShowSearch() {
  //
  
      int X, Y, W, H, O;
      loadWin(synth, W, H, X, Y, O, "Bank-search");
      if (W < searchDW || H < searchDH)
      {
          W = searchDW;
          H = searchDH;
      }
      checkSane(X, Y, W, H, searchDW, searchDH);
  
      searchwin->resize(X, Y, W, H);
      if (unsearched)
      {
          fillBrowser(1);
          unsearched = false;
      }
      searchwin->show();
      lastsearchW = 0;
      searchSeen = true;
}

void BankUI::Hide(int type ) {
  // also called from master UI
      switch (type)
      {
          case 0:
              saveWin(synth,instrumentuiwindow->w(), instrumentuiwindow->h(), instrumentuiwindow->x(), instrumentuiwindow->y(), false, "Bank-instrument");
              instrumentuiwindow->hide();
              lastinstrumentW = 0;
              instrumentSeen = false;
              break;
          case 1:
              saveWin(synth, bankuiwindow->w(), bankuiwindow->h(), bankuiwindow->x(),  bankuiwindow->y(), false, "Bank-bank");
              bankuiwindow->hide();
              lastbankW = 0;
              bankSeen = false;
              break;
          case 2:
              saveWin(synth,rootuiwindow->w(), rootuiwindow->h(),  rootuiwindow->x(),  rootuiwindow->y(), false, "Bank-root");
              rootuiwindow->hide();
              lastrootW = 0;
              rootSeen = false;
              break;
          case 3:
              saveWin(synth,searchwin->w(), searchwin->h(),  searchwin->x(),  searchwin->y(), false, "Bank-search");
              searchwin->hide();
              lastsearchW = 0;
              searchSeen = false;
              break;
          default:
              break;
      }
}

void BankUI::init(Fl_Spinner *cbwig_) {
  //
      cbwig = cbwig_;
      rescan_for_banks();
      unsearched = true;
      searchType->value(1);
      lastinstrumentW = 0;
      lastbankW = 0;
      lastrootW = 0;
      lastsearchW = 0;
}

void BankUI::process() {
  //
          int slot = this->slot;
          int curPart = synth->getRuntime().currentPart;
          string thisname =  textMsgBuffer.fetch(fetchData(0, BANK::control::readInstrumentName, TOPLEVEL::section::bank, UNUSED, UNUSED, UNUSED, slot));
          bool slotFilled = (thisname > "!");
          if ((what == 1 || what == 3) && mode == 1 && slotFilled)
          {
              if (!fetchData(0, PART::control::enable, synth->getGuiMaster()->activePart))
              {
                  alert(synth, "Active part disabled");
                  return;
              }
              send_data(TOPLEVEL::action::forceUpdate, MAIN::control::loadInstrumentFromBank, slot, TOPLEVEL::type::Integer, TOPLEVEL::section::main, synth->getGuiMaster()->activePart);
              // Reads from slot
              if (what == 3)
                  Hide(0);
              return;
          }
  
          if (mode == 5)
          {   // Rename slot
              if (slotFilled)
              {
                  string newname = input_text(synth, "Instrument name:", thisname);
                  if (newname == DEFAULT_NAME)
                      alert(synth, "Can't use name of default sound");
                  else if (newname != thisname)
                      send_data(TOPLEVEL::action::lowPrio | TOPLEVEL::action::forceUpdate, BANK::control::renameInstrument, 0, TOPLEVEL::type::Integer, TOPLEVEL::section::bank, UNUSED, UNUSED, slot, UNUSED, synth->textMsgBuffer.push(newname));
              }
              setread();
          }
  
          if (mode == 2)
          {   // save(write) to slot (choices reversed for 'No' priority)
              bool doit = true;
              if (synth->part[curPart]->Pname == DEFAULT_NAME)
              {
                  alert(synth, "Can't store instrument with default name");
                  setread();
                  doit = false;
              }
              else if (synth->part[curPart]->info.Ptype == 0)
              {
                  if (choice(synth, "", "Save", "Cancel", "Please set instrument type before saving.\nCopyright info also recommended.") != 2)
                      doit = false;
              }
              else if (slotFilled)
              {
                  if (choice(synth, "", "Yes", "No", "Overwrite the slot no." + to_string(slot + 1) + "?") < 2)
                  {
                      setread();
                      doit = false;
                  }
              }
              if (doit)
              {
                  send_data(TOPLEVEL::action::lowPrio | TOPLEVEL::action::forceUpdate, BANK::control::saveInstrument, 0, TOPLEVEL::type::Integer, TOPLEVEL::section::bank, UNUSED, UNUSED, slot);
                  setread();
              }
          }
  
          if (mode == 3)
          {   // Clears the slot (choices reversed for 'No' priority)
              if (slotFilled)
              {
                  if (choice(synth, "", "Yes", "No", "Clear the slot no. " + to_string(slot + 1) + "?") > 1)
                      send_data(TOPLEVEL::action::lowPrio | TOPLEVEL::action::forceUpdate, BANK::control::deleteInstrument, slot, TOPLEVEL::type::Write, TOPLEVEL::section::bank);
              }
              setread();
          }
  
          if (mode == 4)
          {   // swap
              bool done = false;
              if (what == 1 && nselected >= 0)
              {
                  send_data(TOPLEVEL::action::lowPrio | TOPLEVEL::action::forceUpdate, BANK::control::selectSecondInstrumentAndSwap, 0, TOPLEVEL::type::Integer, TOPLEVEL::section::bank, UNUSED, UNUSED, slot);
                  nselected = -1;
                  setread();
                  done = true;
              }
              if ((nselected < 0 || what == 2) && !done)
              {
                  send_data(TOPLEVEL::action::lowPrio, BANK::control::selectFirstInstrumentToSwap, 0, TOPLEVEL::type::Integer, TOPLEVEL::section::bank, UNUSED, UNUSED, slot);
                  nselected = slot;
              }
          }
          if (mode != 4)
              refreshinstrumentwindow();
}

void BankUI::rootprocess() {
  //
      unsigned int slot = this->slot;
      int rt = fetchData(0, BANK::control::selectRoot, TOPLEVEL::section::bank);
      int bt = fetchData(0, BANK::control::selectBank, TOPLEVEL::section::bank);
      string thisname = bank->getBankName(slot, rt);
  
      if ((what == 1 || what == 3) && r_mode == 1 && !thisname.empty())
      {
          // Selects from slot
          send_data(TOPLEVEL::action::lowPrio | TOPLEVEL::action::forceUpdate, BANK::control::selectBank, slot, TOPLEVEL::type::Integer, TOPLEVEL::section::bank);
  
          instFrom = 2;
          if (what == 3)
              Hide(1);
  
          cbwig->do_callback();
  
          ShowInst();
          set_bank_slot(); // needed by 'old' menu selector
          refreshinstrumentwindow();
          return;
      }
  
      if (r_mode == 7)
      {
          string dirname = setfiler(synth,"Path for Bank Export", thisname, true, TOPLEVEL::XML::Bank);
          if (dirname.length() > 2)
              send_data(TOPLEVEL::action::lowPrio | TOPLEVEL::action::forceUpdate, MAIN::control::exportBank, slot, TOPLEVEL::type::Integer, TOPLEVEL::section::main, UNUSED, UNUSED, UNUSED, UNUSED, textMsgBuffer.push(string(dirname)));
          setrootread();
      }
  
      if (r_mode == 6)
      {
          string dirname = setfiler(synth,"Bank to Import", "", false, TOPLEVEL::XML::Bank);
          if (dirname.length() > 2)
              send_data(TOPLEVEL::action::lowPrio | TOPLEVEL::action::forceUpdate, MAIN::control::importBank, slot, TOPLEVEL::type::Integer, TOPLEVEL::section::main, UNUSED, UNUSED, UNUSED, UNUSED, textMsgBuffer.push(string(dirname)));
          setrootread();
      }
  
      if (r_mode == 5 && !thisname.empty())
      {   // Rename bank
          string tmp = input_text(synth, "Bank name:", thisname);
          if (tmp != thisname)
                  send_data(TOPLEVEL::action::lowPrio | TOPLEVEL::action::forceUpdate, BANK::control::renameBank, slot, TOPLEVEL::type::Integer, TOPLEVEL::section::bank, UNUSED, UNUSED, UNUSED, UNUSED, textMsgBuffer.push(tmp));
          setrootread();
      }
  
      if (r_mode == 2)
      {   // Create new bank and save to file
          if (!thisname.empty())
          {
              setrootread();
              alert(synth, "Bank " + to_string(slot) + " already in use for " + thisname);
              return;
          }
          string dirname;
          dirname = input_text(synth, "New empty Bank:", "");
          if (!dirname.empty())
              send_data(TOPLEVEL::action::lowPrio | TOPLEVEL::action::forceUpdate, BANK::control::createBank, slot, TOPLEVEL::type::Integer | TOPLEVEL::type::Write, TOPLEVEL::section::bank, slot, UNUSED, UNUSED, UNUSED, textMsgBuffer.push(dirname));
          setrootread();
          refreshmainwindow();
      }
  
      if (r_mode == 3 && !thisname.empty())
      {
          if (choice(synth, "", "Yes", "No", "Completely clear " + thisname + "?") > 1)
          {
              int clearit = true;
              int count = bank->getBankSize(slot, rt);
              if (count > 1)
                  clearit = choice(synth, "Yes", "", "STOP!", "There are " + to_string(count) + " instruments in this bank\nThey will be permanently deleted") == 3;
              if (clearit)
              {
                  send_data(TOPLEVEL::action::lowPrio | TOPLEVEL::action::forceUpdate, MAIN::control::deleteBank, slot, TOPLEVEL::type::Integer, TOPLEVEL::section::main);
              }
          }
          setrootread();
          refreshmainwindow();
      }
  
      if (r_mode == 4)
      {   // Swap banks
  
              bool done = false;
              if (what == 1 && rselected >= 0)
              {
                  send_data(TOPLEVEL::action::lowPrio | TOPLEVEL::action::forceUpdate, BANK::control::selectSecondBankAndSwap, 0, TOPLEVEL::type::Integer, TOPLEVEL::section::bank, slot);
                  rselected = -1;
                  rescan_for_banks();
                  setrootread();
                  done = true;
              }
              if ((rselected < 0 || what == 2) && !done)
              {
                  send_data(TOPLEVEL::action::lowPrio, BANK::control::selectFirstBankToSwap, 0, TOPLEVEL::type::Integer, TOPLEVEL::section::bank, slot);
                  rselected = slot;
                  rs[slot]->rootrefresh(bt, rt);
              }
      }
}

void BankUI::setread() {
  //
      mode = 1;
      readbutton->value(1);
      writebutton->value(0);
      clearbutton->value(0);
      swapbutton->value(0);
      renamebutton->value(0);
}

void BankUI::setrootread() {
  //
      r_mode = 1;
      rootreadbutton->value(1);
      rootwritebutton->value(0);
      rootimportbutton->value(0);
      rootexportbutton->value(0);
      rootclearbutton->value(0);
      rootswapbutton->value(0);
      rootrenamebutton->value(0);
}

void BankUI::refreshmainwindow() {
  //
      int bk = fetchData(0, BANK::control::selectBank, TOPLEVEL::section::bank);
      int rt = fetchData(0, BANK::control::selectRoot, TOPLEVEL::section::bank);
      int last = fetchData(0, BANK::control::lastSeenInBank, TOPLEVEL::section::bank);
  
      instrumentuiwindow->copy_label(bank->getBankFileTitle(rt, bk).c_str());
  
      bankuiwindow->copy_label(bank->getRootFileTitle(rt).c_str());
  
      for (int i = 0; i < MAX_INSTRUMENTS_IN_BANK; ++i)
          bs[i]->refresh(bk, rt, last);
      for (int i = 0; i < MAX_BANKS_IN_ROOT; ++i)
          rs[i]->rootrefresh(bk, rt);
}

void BankUI::refreshinstrumentwindow() {
  //
      int bk = fetchData(0, BANK::control::selectBank, TOPLEVEL::section::bank);
      int rt = fetchData(0, BANK::control::selectRoot, TOPLEVEL::section::bank);
      int last = fetchData(0, BANK::control::lastSeenInBank, TOPLEVEL::section::bank);
      //std::cout << "here ins " << int(last >> 15) << "  bank " << int((last >> 8) & 0x7f) << "  root " << int(last & 0x7f) << std::endl;
      for (int i = 0; i < MAX_INSTRUMENTS_IN_BANK; ++i)
      {
          bs[i]->refresh(bk, rt, last);
      }
}

void BankUI::wincheck() {
  //
      if (instrumentSeen)
          instrumentRtext();
      if (searchSeen)
          searchRtext();
      if (bankSeen)
          bankRtext();
      if (rootSeen)
          rootRtext();
}

void BankUI::instrumentRtext() {
  //
      if (lastinstrumentW == instrumentuiwindow->w())
          return;
      lastinstrumentW = instrumentuiwindow->w();
  
      float dScale = instrumentuiwindow->w() / float(instDW);
      if (dScale < 0.2f)
          dScale = 0.2f;
  
      int size = int(12 * dScale);
  
      B_search->labelsize(size);
      insRoots->labelsize(size);
      insBanks->labelsize(size);
      insT1->labelsize(size);
      insT2->labelsize(size);
      writebutton->labelsize(size);
      readbutton->labelsize(size);
      clearbutton->labelsize(size);
      swapbutton->labelsize(size);
      renamebutton->labelsize(size);
      insT3->labelsize(size);
      addpatch->labelsize(size);
      subpatch->labelsize(size);
      padpatch->labelsize(size);
  
      insClose->labelsize(size);
  
      banklist->textsize(size);
      int lineX;
      int lineY;
      for (int i = 0; i < MAX_INSTRUMENTS_IN_BANK; ++i)
      {
          if (i < 32)
          {
              lineX = int(5 * dScale);
          }
          else if (i < 64)
          {
              lineX = int(160 * dScale);
          }
          else if (i < 96)
          {
              lineX = int(315 * dScale);
          }
          else if (i < 128)
          {
              lineX = int(470 * dScale);
          }
          else
          {
              lineX = int(625 * dScale);
          }
          lineY = int((((i & 31) * 15.4f) + 33) * dScale);
          bs[i]->resize(lineX,  lineY , int(152 * dScale), 15 * dScale);
          bs[i]->labelsize(int(13 * dScale));
      }
  
      instrumentuiwindow->redraw();
}

void BankUI::searchRtext() {
  //
      if (lastsearchW == searchwin->w())
          return;
      lastsearchW = searchwin->w();
  
      float dScale = searchwin->w() / float(searchDW);
      if (dScale < 0.2f)
          dScale = 0.2f;
  
      int size = int(13 * dScale);
  
      searchT->labelsize(size);
      searchClose->labelsize(size);
      searchType->labelsize(size);
          searchType->textsize(size);
      searchbrowse->textsize(size);
  
      noEntries->labelsize(int(30 * dScale));
  
      searchwin->redraw();
}

void BankUI::bankRtext() {
  //
      if (lastbankW == bankuiwindow->w())
          return;
      lastbankW = bankuiwindow->w();
  
      float dScale = bankuiwindow->w() / float(bankDW);
      if (dScale < 0.2f)
          dScale = 0.2f;
  
      int size = int(12 * dScale);
  
      bankroot->labelsize(size);
      bankinst->labelsize(size);
      bankcurrent->labelsize(size);
      rootwritebutton->labelsize(size);
      rootreadbutton->labelsize(size);
      rootclearbutton->labelsize(size);
      rootswapbutton->labelsize(size);
      rootrenamebutton->labelsize(size);
      rootimportbutton->labelsize(int(9 * dScale));
      rootexportbutton->labelsize(int(9 * dScale));
  
      bankClose->labelsize(size);
      int lineX;
      int lineY;
      for (int i = 0; i < MAX_BANKS_IN_ROOT; ++i)
      {
          if (i < 32)
          {
              lineX = int(6 * dScale);
          }
          else if (i < 64)
          {
              lineX = int(200 * dScale);
          }
          else if (i < 96)
          {
              lineX = int(393 * dScale);
          }
          else
          {
              lineX = int(586 * dScale);
          }
  
          lineY = int((((i & 31) * 15.4f) + 33) * dScale);
          rs[i]->resize(lineX,  lineY , int(188 * dScale), 15 * dScale);
          rs[i]->labelsize(int(13 * dScale) - 1);
      }
  
      bankuiwindow->redraw();
}

void BankUI::rootRtext() {
  //
      if (lastrootW == rootuiwindow->w())
          return;
      lastrootW = rootuiwindow->w();
  
      float dScale = rootuiwindow->w() / float(rootDW);
      if (dScale < 0.2f)
          dScale = 0.2f;
  
      int size = int(12 * dScale);
  
      addrootdirbutton->labelsize(size);
      removerootdirbutton->labelsize(size);
      makedefaultrootdirbutton->labelsize(size);
      showdefaultrootdirbutton->labelsize(size);
      Pend->labelsize(int(10 * dScale));
      changeIDbutton->labelsize(size);
          changeIDbutton->textsize(size);
  
      rootClose->labelsize(size);
      rootsbrowse->textsize(size);
  
      rootuiwindow->redraw();
}

void BankUI::refreshbankslot(int ins, int bk, int rt, int last) {
  //
          bs[ins]->refresh(bk, rt, last);
}

void BankUI::removeselection() {
  //
          if (nselected >= 0)
          {
              int ns = nselected;
              nselected = -1;
              bs[ns]->refresh(fetchData(0, BANK::control::selectBank, TOPLEVEL::section::bank), fetchData(0, BANK::control::selectRoot, TOPLEVEL::section::bank), fetchData(0, BANK::control::lastSeenInBank, TOPLEVEL::section::bank));
          }
          if (rselected >= 0)
          {
              int rsel = rselected;
              rselected = -1;
              rs[rsel]->rootrefresh(fetchData(0, BANK::control::selectBank, TOPLEVEL::section::bank), fetchData(0, BANK::control::selectRoot, TOPLEVEL::section::bank));
          }
}

void BankUI::rescan_for_banks() {
  //
      banklist->clear();
      const BankEntryMap &banks = bank->getBanks(fetchData(0, BANK::control::selectRoot, TOPLEVEL::section::bank));
      BankEntryMap::const_iterator it;
      for (it = banks.begin(); it != banks.end(); ++it)
      {
          if (!it->second.dirname.empty())
          {
              int n = banklist->add((asString(it->first) + ". " + it->second.dirname).c_str(), (const char *)0, (Fl_Callback*)0, reinterpret_cast<void *>(it->first));
              if (it->first == fetchData(0, BANK::control::selectBank, TOPLEVEL::section::bank))
              {
                  banklist->value(n); // ensure correct bank in list
              }
          }
      }
      refreshmainwindow();
}

void BankUI::set_bank_slot() {
  //
      size_t curID = fetchData(0, BANK::control::selectBank, TOPLEVEL::section::bank);
      const Fl_Menu_Item *curItem = 0;
      for (int i = 0; i < banklist->size(); i++)
      {
          const Fl_Menu_Item *item = banklist->menu() + i;
          if (item->label())
          {
              if (curID == reinterpret_cast<size_t>(item->user_data()))
              {
                  curItem = item;
              }
          }
      }
      if (curItem)
      {
          banklist->value(curItem);
      }
      else
      {
          banklist->value(0);
      }
}

void BankUI::activatebutton_rootdir(bool active) {
  //
          if (active)
          {
              removerootdirbutton->activate();
              makedefaultrootdirbutton->activate();
              changeIDbutton->activate();
          }
          else
          {
              removerootdirbutton->deactivate();
              makedefaultrootdirbutton->deactivate();
              changeIDbutton->deactivate();
              Pend->hide();
          }
}

void BankUI::readbankcfg() {
  //
      string tmp;
      rootsbrowse->clear();
      const RootEntryMap &roots = synth->getBankRef().getRoots();
      RootEntryMap::const_iterator it;
      for (it = roots.begin(); it != roots.end(); ++it)
      {
          if (!it->second.path.empty())
          {
              tmp = asString(it->first) + ". " + it->second.path;
              if (it->first == fetchData(0, BANK::control::selectRoot, TOPLEVEL::section::bank))
              {
                  tmp += " *";
              }
              rootsbrowse->add(tmp.c_str(), reinterpret_cast<void *>(static_cast<long>(it->first)));
          }
      }
}

int BankUI::recoverID() {
  //
      if (selectedRootID >= 0)
      {
          return selectedRootID;
      }
      return 0;
}
