// Copyright 2011, Alan Calvert
// Copyright 2015-2023, 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 "ConsoleUI.h"
#include "Misc/Config.h"
#include "MasterUI.h"

ConsoleTextDisplay::ConsoleTextDisplay(int x, int y, int w, int h, char* l ) : Fl_Text_Display(x,y,w,h,l) {
  // empty //
}

void ConsoleTextDisplay::scroll_to_last_line() {
  //
     if (mVScrollBar->visible() &&
         mVScrollBar->value() > mNBufferLines - mNVisibleLines)
      {
          insert_position(mBuffer->length());
          show_insert_position();
      }
}

void ConsoleUI::cb_logConsole_i(Fl_Double_Window* o, void*) {
  //
      o->hide();
}
void ConsoleUI::cb_logConsole(Fl_Double_Window* o, void* v) {
  ((ConsoleUI*)(o->user_data()))->cb_logConsole_i(o,v);
}

Fl_Double_Window* ConsoleUI::make_window() {
  { Fl_Double_Window* o = logConsole = new Fl_Double_Window(385, 185, "yoshimi console");
    logConsole->color(FL_LIGHT3);
    logConsole->selection_color((Fl_Color)36);
    logConsole->labelsize(13);
    logConsole->callback((Fl_Callback*)cb_logConsole, (void*)(this));
    logConsole->align(Fl_Align(FL_ALIGN_CENTER));
    logConsole->when(FL_WHEN_CHANGED);
    { logText = new ConsoleTextDisplay(0, 0, 385, 185);
      logText->box(FL_DOWN_FRAME);
      logText->color(FL_BACKGROUND2_COLOR);
      logText->selection_color((Fl_Color)64);
      logText->labeltype(FL_NO_LABEL);
      logText->labelfont(0);
      logText->labelsize(13);
      logText->labelcolor((Fl_Color)64);
      logText->textfont(4);
      logText->textsize(12);
      logText->textcolor((Fl_Color)64);
      logText->align(Fl_Align(FL_ALIGN_TOP));
      logText->when(FL_WHEN_CHANGED);
      Fl_Group::current()->resizable(logText);
    } // ConsoleTextDisplay* logText
    logDW = 385;logDH = 185;
    o->size_range(logDW,logDH);
    logConsole->end();
  } // Fl_Double_Window* logConsole
  return logConsole;
}

ConsoleUI::ConsoleUI(SynthEngine *_synth) {
  //
      synth = _synth;
      bufsize = 8192;
      make_window();
      txtbuf = new Fl_Text_Buffer(bufsize);
      lastlogW = 0;
      textSize = 12;
      logText->buffer(txtbuf);
      setLogText(synth->getRuntime().consoleTextSize);
}

ConsoleUI::~ConsoleUI() {
  //
        if (logConsole->visible())
        {
            saveWin(synth, logConsole->w(), logConsole->h(), logConsole->x(), logConsole->y(), 1, "System-log");
        }
        else
        {
             int fetchW, fetchH, fetchX, fetchY, fetchO;
             loadWin(synth, fetchW, fetchH, fetchX, fetchY, fetchO, "System-log");
             saveWin(synth, fetchW, fetchH, fetchX, fetchY, 0, "System-log");
        }
        logConsole->hide();
        delete logConsole;
}

void ConsoleUI::log(string msg) {
  //
      msg += "\n";
      txtbuf->append(msg.c_str());
      //Scroll to show last line unless manually scrolled elsewhere before
      logText->scroll_to_last_line();
      if (txtbuf->length() > (bufsize - 256))
          txtbuf->remove(0, txtbuf->line_end(256));
}

void ConsoleUI::Show(SynthEngine *synth) {
  //
      int fetchW, fetchH, fetchX, fetchY, fetchO;
      loadWin(synth, fetchW, fetchH, fetchX, fetchY, fetchO, "System-log");
      if (fetchW < logDW || fetchH < logDH)
      {
          fetchW = logDW;
          fetchH = logDH;
      }

      // can't use checkSane() here w/h are independent
      int maxW = Fl::w() - 5; // wiggle room
      int maxH = Fl::h() - 30; // space for minimal titlebar

      if ((fetchX + fetchW) > maxW) // position
          fetchX = maxW / 2;
      if ((fetchY + fetchH) > maxH)
          fetchY = maxH / 2;

      if(fetchW > maxW)
          fetchW = maxW;
      if(fetchH > maxH / 2) // sensible max height
          fetchH = maxH / 2;

      logConsole->resize(fetchX, fetchY, fetchW, fetchH);
      lastlogW = 0;
      logConsole->show();
}

void ConsoleUI::Hide(SynthEngine *synth) {
  //

        if (logConsole->visible())
        {
            saveWin(synth, logConsole->w(), logConsole->h(), logConsole->x(), logConsole->y(), 0, "System-log");
        }
        else
        {
             int fetchW, fetchH, fetchX, fetchY, fetchO;
             loadWin(synth, fetchW, fetchH, fetchX, fetchY, fetchO, "System-log");
             saveWin(synth, fetchW, fetchH, fetchX, fetchY, 0, "System-log");
        }

        logConsole->hide();
}

void ConsoleUI::setLogText(int size) {
  //

              lastlogW = 0;
              textSize = size;
}

void ConsoleUI::consoleRtext() {
  //
      if (lastlogW == logConsole->w())
          return;
      lastlogW = logConsole->w();

      saveWin(synth, logConsole->w(), logConsole->h(), logConsole->x(), logConsole->y(), 1, "System-log");
      logText->textsize(textSize);
      logConsole->redraw();
}
