#pragma once

#include "MidiEvent.h"
#include <string>

class MidiChannelEvent : public MidiEvent
{
public:
    enum class Type{
        NONE,
        NOTE_OFF,
        NOTE_ON,
        NOTE_AFTERTOUCH,
        CONTROLLER,
        PROGRAM,
        CHANNEL_AFTERTOUCH,
        PITCH_BEND,
        CHANNEL_MODE,
        SYS_EXCLUSIVE,
        SYS_SONG_POS,
        SYS_SONG_SELECT,
        SYS_TUNE_REQUEST,
        SYS_END_EXCLUSIVE,
        SYS_TIMING_CLOCK,
        SYS_START,
        SYS_CONTINUE,
        SYS_STOP,
        SYS_ACTIVE_SENSING,
        SYS_RESET
    };

private:
    static const int NOTE_OFF = 0x8;
    static const int NOTE_ON = 0x9;
    static const int NOTE_AFTERTOUCH = 0xA;
    static const int CONTROLLER = 0xB;
    static const int PROGRAM = 0xC;
    static const int CHANNEL_AFTERTOUCH = 0xD;
    static const int PITCH_BEND = 0xE;

    static const int SYS_EXCLUSIVE = 0x0;
    static const int SYS_SONG_POS = 0x2;
    static const int SYS_SONG_SELECT = 0x3;
    static const int SYS_TUNE_REQUEST = 0x6;
    static const int SYS_END_EXCLUSIVE = 0x7;
    static const int SYS_TIMING_CLOCK = 0x8;
    static const int SYS_START = 0xA;
    static const int SYS_CONTINUE = 0xB;
    static const int SYS_STOP = 0xC;
    static const int SYS_ACTIVE_SENSING = 0xE;
    static const int SYS_RESET = 0xF;

public:
    MidiChannelEvent();
    static std::unique_ptr<MidiChannelEvent> Create();

    void SetTypeAndChannel(char c);
    void SetType(Type type);
    Type GetType() const;

    void SetValues(int value0, int value1);
    int GetValue0() const;
    int GetValue1() const;

private:
    Type mType;
    int mChannel {0};
    int mValue0 {0};
    int mValue1 {1};
};

using MidiChannelEventPtr = std::unique_ptr<MidiChannelEvent>;
