// Copyright 2011, Alan Calvert
// Copyright 2014 - 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 for more details.

// You should have received a copy of the GNU General Public License
// along with yoshimi.  If not, see <http://www.gnu.org/licenses/>.


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

#include "ParametersUI.h"
#include "Misc/Config.h"
#include "MasterUI.h"
#include "Misc/TextMsgBuffer.h"

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

void ParametersUI::cb_Recent_i(ScaleTrackedWindow*, void*) {
  CloseRecent->do_callback();
}
void ParametersUI::cb_Recent(ScaleTrackedWindow* o, void* v) {
  ((ParametersUI*)(o->user_data()))->cb_Recent_i(o,v);
}

void ParametersUI::cb_BrowseRecent_i(Fl_Browser* o, void*) {
  //
          if (o->value() == 0)
              return;
          CloseRecent->hide();
          Loading->show();
          if (H_type <= TOPLEVEL::XML::MLearn)
          {
              vector<string> const& listType{synth->getHistory(H_type)};
              string const& file{listType.at(o->value()-1)};
              switch(H_type)
              {
                  case TOPLEVEL::XML::Instrument:
                      synth->getGuiMaster()->do_load_instrument(file);
                      break;
                  case TOPLEVEL::XML::Patch:
                      synth->getGuiMaster()->do_load_master(file);
                      break;
                  case TOPLEVEL::XML::Presets:
                      break; // not from here
                  case TOPLEVEL::XML::Scale:
                      synth->getGuiMaster()->do_load_scale(file);
                      break;
                  case TOPLEVEL::XML::State:
                      synth->getGuiMaster()->setState(file);
                      CloseRecent->hide();
                      Loading->show();
                      break;
                  case TOPLEVEL::XML::Vector:
                      synth->getGuiMaster()->vectorui->loadVector(file);
                      break;
                  case TOPLEVEL::XML::MLearn:
                      synth->getGuiMaster()->midilearnui->loadMidi(file);
                      break;
              }
          }
          Recent->hide();
}
void ParametersUI::cb_BrowseRecent(Fl_Browser* o, void* v) {
  ((ParametersUI*)(o->parent()->user_data()))->cb_BrowseRecent_i(o,v);
}

void ParametersUI::cb_CloseRecent_i(Fl_Button*, void*) {
  //
      saveWin(synth, Recent->w(), Recent->h(), Recent->x(), Recent->y(), false, "Master-recent");
      Recent->hide();
}
void ParametersUI::cb_CloseRecent(Fl_Button* o, void* v) {
  ((ParametersUI*)(o->parent()->user_data()))->cb_CloseRecent_i(o,v);
}

ScaleTrackedWindow* ParametersUI::make_window() {
  { ScaleTrackedWindow* o = Recent = new ScaleTrackedWindow(250, 180, "Yoshimi : Parameters");
    Recent->box(FL_FLAT_BOX);
    Recent->color(FL_BACKGROUND_COLOR);
    Recent->selection_color(FL_BACKGROUND_COLOR);
    Recent->labeltype(FL_NO_LABEL);
    Recent->labelfont(13);
    Recent->labelsize(12);
    Recent->labelcolor(FL_FOREGROUND_COLOR);
    Recent->callback((Fl_Callback*)cb_Recent, (void*)(this));
    Recent->align(Fl_Align(FL_ALIGN_CENTER));
    Recent->when(FL_WHEN_RELEASE);
    { Fl_Browser* o = BrowseRecent = new Fl_Browser(0, 0, 250, 157);
      BrowseRecent->type(1);
      BrowseRecent->labeltype(FL_NO_LABEL);
      BrowseRecent->labelfont(13);
      BrowseRecent->labelsize(12);
      BrowseRecent->labelcolor((Fl_Color)64);
      BrowseRecent->textsize(12);
      BrowseRecent->textcolor((Fl_Color)64);
      BrowseRecent->callback((Fl_Callback*)cb_BrowseRecent);
      BrowseRecent->align(Fl_Align(FL_ALIGN_CENTER));
      const int colwidths[] = { 150, 330, 0 };
          o->column_widths(colwidths);
          o->column_char('	');
    } // Fl_Browser* BrowseRecent
    { Loading = new Fl_Button(83, 159, 57, 20, "Loading");
      Loading->box(FL_THIN_DOWN_BOX);
      Loading->color((Fl_Color)22);
      Loading->labelfont(1);
      Loading->labelsize(11);
      Loading->labelcolor((Fl_Color)64);
    } // Fl_Button* Loading
    { CloseRecent = new Fl_Button(83, 159, 57, 20, "Close");
      CloseRecent->color((Fl_Color)196);
      CloseRecent->labelfont(13);
      CloseRecent->labelsize(12);
      CloseRecent->labelcolor((Fl_Color)64);
      CloseRecent->callback((Fl_Callback*)cb_CloseRecent);
    } // Fl_Button* CloseRecent
    { emptytext = new Fl_Text_Display(35, 122, 160, 11, "No Entries");
      emptytext->box(FL_NO_BOX);
      emptytext->labelsize(38);
      emptytext->labelcolor((Fl_Color)64);
      emptytext->textfont(1);
      emptytext->textcolor((Fl_Color)64);
      emptytext->align(Fl_Align(161));
    } // Fl_Text_Display* emptytext
    Recent->resizable(Recent);
    paramDW = o->w(); paramDH = o->h();
    o->size_range(paramDW, paramDH, 0, 0, 0, 0, 1);
    Recent->end();
  } // ScaleTrackedWindow* Recent
  return Recent;
}

ParametersUI::ParametersUI(SynthEngine *_synth) {
  //
      synth = _synth;
      lastParamW = 0;
      make_window();
}

void ParametersUI::Show(int _type) {
  //
      H_type = _type;

      unsigned int name_start;
      unsigned int name_end;
      string name = "Unknown";
      int partNo = UNUSED;
      switch (H_type)
      {
          case TOPLEVEL::XML::Instrument:
              name = + "Instruments";
              partNo = synth->getGuiMaster()->npart; // TODO find a better way!
              break;
          case TOPLEVEL::XML::Scale:
              name = "Scales";
              break;
          case TOPLEVEL::XML::MLearn:
              name = "Learn Lists";
              break;
          case TOPLEVEL::XML::Vector:
              name = "Vectors";
              break;
          case TOPLEVEL::XML::State:
              name = "States";
              break;
          case TOPLEVEL::XML::Patch:
              name = "Patch Sets";
              break;
      }
      name = textMsgBuffer.fetch(collect_readData(synth, textMsgBuffer.push(name), partNo, TOPLEVEL::windowTitle));
      Recent->copy_label(name.c_str());

      vector<string> const& listType{synth->getHistory(H_type)};
      BrowseRecent->clear();
      const int colwidths[] = { 64, 128, 0 };
      BrowseRecent->column_widths(colwidths);
      BrowseRecent->column_char('	');

      if (listType.empty())
          emptytext->show();
      else
      {
          emptytext->hide();
          for (auto const& historyEntry : listType)
          {
              name = historyEntry;
              name_start = name.rfind("/");
              name_end = name.rfind(".");
              name = name.substr(name_start + 1, name_end - name_start - 1);
              BrowseRecent->add(name.c_str());
          }
          BrowseRecent->set_changed();
      }
      int fetchW, fetchH, fetchX, fetchY, fetchO;
      loadWin(synth, fetchW, fetchH, fetchX, fetchY, fetchO, "Master-recent");
      if (fetchW < paramDW || fetchH < paramDH)
      {
          fetchW = paramDW;
          fetchH = paramDH;
      }
      checkSane(fetchX, fetchY,fetchW, fetchH, paramDW, paramDH);

      Recent->size(fetchW, fetchH);
      Recent->show();
      Loading->hide();
      CloseRecent->show();
}

void ParametersUI::Hide() {
  //
      Recent->hide();
}

ParametersUI::~ParametersUI() {
  //
      CloseRecent->do_callback();
}

void ParametersUI::paramRtext() {
  //
      if (lastParamW == Recent->w())
          return;
      lastParamW = Recent->w();

      float dScale = Recent->w() / float(paramDW);

      int size12 = int(12 * dScale);

      BrowseRecent->textsize(size12);
      Loading->labelsize(size12);
      CloseRecent->labelsize(size12);
      emptytext->labelsize(int(38 * dScale));

      Recent->redraw();
}
