/*
  ==============================================================================

    This file was auto-generated by the Introjucer!

    It contains the basic framework code for a JUCE plugin processor.

  ==============================================================================
*/

#pragma once

#include <JuceHeader.h>

#include "Pad.h"

class SFXAudioProcessorEditor;
//==============================================================================
class SFXAudioProcessor : public gin::Processor,
                          private juce::MPESynthesiser
{
public:
    //==============================================================================
    SFXAudioProcessor();
    ~SFXAudioProcessor() override;

    //==============================================================================
    void prepareToPlay (double sampleRate, int samplesPerBlock) override;
    void releaseResources() override;

    void processBlock (juce::AudioSampleBuffer&, juce::MidiBuffer&) override;

    //==============================================================================
    void stateUpdated() override;
    void updateState() override;

    //==============================================================================
    juce::AudioProcessorEditor* createEditor() override;
    bool hasEditor() const override;
    
    Pad* getPadForNote (int note)
    {
        for (auto p : pads)
            if (p->note == note)
                return p;
        
        return nullptr;
    }

    Pad* getPad (int idx)                   { return pads[idx]; }
    const juce::OwnedArray<Pad>& getPads()  { return pads;      }
    
    juce::String uniqueName (juce::String prefix);

    bool getMidiLearn()                     { return midiLearn; }
    void setMidiLearn (bool m)              { midiLearn = m;    }
    void setCurrentPad (int c)              { currentPad = c;   }
    int getCurrentPad()                     { return currentPad;}
    
    //==============================================================================
    void midiNoteOn (int note, int velocity = 128);
    void midiNoteOff (int note, int velocity = 0);

    bool isMidiNoteDown (int n)         { return (n >= 0 && n <= 127) ? (midiOn[n] || midiCnt[n]) : false; }

    int midiOn[128] = {0}, midiCnt[128] = {0};

    std::function<void ()> onCurrentPageChanged;

private:
    void trackMidi (juce::MidiBuffer& midi, int numSamples);
    //==============================================================================
    
    juce::CriticalSection lock;
    juce::Component::SafePointer<SFXAudioProcessorEditor> editor;
    
    juce::OwnedArray<Pad> pads;

    juce::MidiBuffer userMidi;
    bool midiLearn = false;
    int currentPad = 0;

    //==============================================================================
    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (SFXAudioProcessor)
};
