// ----
// ---- file   : SamplePadButton.tks
// ---- author : Bastian Spiegel <bs@tkscript.de>
// ---- legal  : (c) 2022-2024 by Bastian Spiegel.
// ----          Distributed under terms of the GNU LESSER GENERAL PUBLIC LICENSE (LGPL). See
// ----          http://www.gnu.org/licenses/licenses.html#LGPL or COPYING for further information.
// ----
// ---- info   : This is part of the "syntracker" midi/audio sequencer.
// ----           (note) adapted from DrumPadDialog
// ----
// ---- created: 01Jul2022
// ---- changed: 02Jul2022, 03Jul2022, 04Jul2022, 08Jul2022, 09Jul2022, 10Jul2022, 17Jul2022
// ----          22Jul2022, 14Jun2023, 21Sep2023, 04Nov2023, 19Jan2024, 22Mar2024, 05Jul2024
// ----          13Sep2024, 14Sep2024
// ----
// ----
// ----

module MSamplePadButton;

use namespace ui;
use namespace st2;


// <class.png>
class SamplePadButton extends Button {

   SamplePadForm *parent_form;
   int note_nr;
   int pad_idx;

   Button *bt_mute;
   Button *bt_solo;


   // <ui_mouse.png>
   public virtual onMouseDoubleClick(MouseEvent _ev) : boolean {
      // trace "xxx onMouseDoubleClick";
   }

   // <ui_mouse.png>
   public virtual onMouse(MouseEvent _ev) : boolean {
      // trace "xxx onMouseDoubleClick";
      if(_ev.wheelUp())
      {
         parent_form.editPreviousPad();
         return true;
      }
      else if(_ev.wheelDown())
      {
         parent_form.editNextPad();
         return true;
      }
   }

   // <method_get.png>
   public method getSamplePad() : SamplePad {
      SamplePadKit samplePadKit <= parent_form.sample_pad_kit;
      SamplePadKitVariation kv <= samplePadKit.getEditKitVariation();
      return kv.pads.get(pad_idx);
   }

   // <method_get.png>
   public method getSamplePadCommon() : SamplePadCommon {
      SamplePadKit samplePadKit <= parent_form.sample_pad_kit;
      SamplePadKitVariation kv <= samplePadKit.getEditKitVariation();
      SamplePadCommon padCommon <= samplePadKit.pads.get(pad_idx);
      return padCommon;
   }

   // <method.png>
   public method printPadInfo(String _prefix) {
      local Integer io = note_nr;
      SamplePad pad <= getSamplePad();
      Global.Print(_prefix+" \""+getCaption()+"\" note="+(MIDI.midi_notes.get(note_nr))+" ("+note_nr+" / $"+io.printf("%02x")+")"+((-1 != pad.sample_id) ? (" sample=\""+pad.getSampleName()+"\" ("+(pad.sample_id+1)+")") : ""));
   }

   // <ui_mouse.png>
   public virtual onMouseEnter(MouseEvent _ev) : boolean {
      SamplePad pad <= getSamplePad();
      printPadInfo( (-1 != pad.sample_id) ? "Pad" : "Unassigned pad");
      // // parent_form.refocusDefault();
      return Button::onMouseEnter(_ev);
   }

   // <ui_handle.png>
   public =replay= virtual onDropFiles(StringArray _fileNames) : boolean {
      Global.Debug("SamplePadButton::onDropFiles: filenames="+#(_fileNames));

      // // Audio.ResetAllTempSamples();
      // // Audio.ResetAllSampleVoices(sample);
      // // Audio.UpdateTemporarySampleFromWaveform(null);
      // // Audio.UpdateTempRefSample(null);

      String pathName <= _fileNames[0];
      local String baseName <= Utils.BaseName(pathName);
      int drumNamespaceIdx = parent_form.sample_pad_kit.getKitNamespaceIdxForImport();

      SamplePadKit samplePadKit <= parent_form.sample_pad_kit;
      SamplePadKitVariation kv <= samplePadKit.getEditKitVariation();
      SamplePadCommon padCommon <= samplePadKit.pads.get(pad_idx);
      SamplePad pad <= kv.pads.get(pad_idx);
      Sample *sample;
      boolean bLoadOk = false;
      local String msg;
      if( (pathName.toLower()) >= ".wav")
      {
         sample <= current_project.newSample(baseName/*suggestedUniqueName*/, -1);
         if(sample.initFromWavFile(pathName, false/*bForceLoop*/))
         {
            bLoadOk = true;
            msg = "Load pad WAV sample from \""+pathName+"\"";
         }
         else
         {
            Global.Error("Failed to load WAV from \""+pathName+"\"");
         }
      }
      else if( (pathName.toLower()) >= Global.SAMPLE_FILE_SUFFIX/*.esa*/)
      {
         sample <= current_project.newSample(baseName/*suggestedUniqueName*/, -1);
         if(sample.loadFile(pathName, STConfig.sample_rootpath, false/*bProject*/, true/*bReloadPatchPlugins*/))
         {
            bLoadOk = true;
            msg = "Load pad sample patch from \""+pathName+"\"";
         }
         else
         {
            Global.Error("Failed to load sample patch from \""+pathName+"\"");
         }
      }

      if(bLoadOk)
      {
         sample.b_autoload = false;
         sample.analyzeAndUpdatePartials();
         sample.setNamespaceIdx(drumNamespaceIdx);
         padCommon.namespace_idx = drumNamespaceIdx;
         pad.sample_id = current_project.getSampleIdx(sample);
         samplePadKit.edit_pad_idx = pad_idx;
         parent_form.showTrack(parent_form.parent_track);
         Global.Success(msg);
      }

      return true;
   }

   public virtual beginXFMTag(AbstractXMLForm _form, HashTable _attributes) : boolean {
      if(Button::beginXFMTag(_form, _attributes))
      {
         setLayout(SuperBorderLayout);

         bt_mute <= Button.New();
         bt_mute.setEnableLabelButton(true);
         bt_mute.setCaption("M");
         bt_mute.setRequiredSize2fScaled(10, 8);
         bt_mute.setAlignment(Layout.TOP);
         bt_mute.setPadding4f(0,0,0,0);
         bt_mute.setInnerPadding4f(0,0,0,0);
         bt_mute.setFontByName("big12");
         bt_mute.setEnableFillBackground(false);
         bt_mute.setLinkedRedraw(this);
         bt_mute.setEnableKbdFocusOnMouse(false);
         bt_mute.setAlpha(#28);
         addLayer(bt_mute, Layout.RIGHT);

         bt_solo <= Button.New();
         bt_solo.setEnableLabelButton(true);
         bt_solo.setCaption("S");
         bt_solo.setRequiredSize2fScaled(10, 8);
         bt_solo.setAlignment(Layout.TOP);
         bt_solo.setPadding4f(0,0,0,0);
         bt_solo.setInnerPadding4f(0,0,0,0);
         bt_solo.setFontByName("big12");
         bt_solo.setEnableFillBackground(false);
         bt_solo.setLinkedRedraw(this);
         bt_solo.setEnableKbdFocusOnMouse(false);
         bt_solo.setAlpha(#28);
         addLayer(bt_solo, Layout.RIGHT);

         return true;
      }
      return false;
   }

   // <ui_update.png>
   public method updateMuteSolo() {
      SamplePadCommon padCommon <= getSamplePadCommon();

      if(padCommon.play_state == SamplePadCommon.STATE_MUTE || padCommon.b_force_mute)
      {
         bt_mute.setAlpha(255);
         bt_mute.setCaptionTint(#b0f03030);
         bt_solo.setAlpha(#28);
         bt_solo.setCaptionTint(0);
         bt_solo.setFontByName("big12");
      }
      else switch(padCommon.play_state)
      {
         default:
         case SamplePadCommon.STATE_PLAY:
            bt_mute.setAlpha(#28);
            bt_mute.setCaptionTint(0);
            bt_solo.setAlpha(#28);
            bt_solo.setCaptionTint(0);
            bt_solo.setFontByName("big12");
            break;

         case SamplePadCommon.STATE_SOLO:
            bt_mute.setAlpha(#28);
            bt_mute.setCaptionTint(0);
            bt_solo.setAlpha(255);
            bt_solo.setCaptionTint(#e0ffff00);
            bt_solo.setFontByName("big11");
            break;
      }
      redraw();
   }

   // <ui_consume.png>
   public virtual consumeAction(Action _action) : boolean {
      ActionProvider ap <= _action.getActionProvider();
      String acName <= _action.getActionName();

      SamplePadCommon padCommon <= getSamplePadCommon();

      switch(@(ap))
      {
         case @(bt_mute):
            // trace "xxx bt_mute";
            if(SamplePadCommon.STATE_MUTE != padCommon.play_state)
               padCommon.setPlayState(SamplePadCommon.STATE_MUTE);
            else
               padCommon.setPlayState(SamplePadCommon.STATE_PLAY);
            parent_form.updatePadMuteSolo();
            current_project.markAsModified();
            return true;

         case @(bt_solo):
            // trace "xxx bt_solo";
            if(SamplePadCommon.STATE_SOLO != padCommon.play_state)
               padCommon.setPlayState(SamplePadCommon.STATE_SOLO);
            else
               padCommon.setPlayState(SamplePadCommon.STATE_PLAY);
            parent_form.updatePadMuteSolo();
            current_project.markAsModified();
            return true;
      }

      return Button::consumeAction(_action);
   }

}
