#ifndef __mp3_H__
#define __mp3_H__

#include "SerialMP3Player.h"

class mp3
{
private:
    const byte FADESTEP_WITH = 5;
    const char* STARTED_STRING = "Status: playing";
    const char* STOPPED_STRING = "Status: stopped";

    SerialMP3Player *player;
    size_t _rx_pin,_tx_pin;
    unsigned long _play_since_ms = 0;

    const byte _MAX_FADE_STEP = 255;
    const byte _MIN_FADE_STEP = 0;
    byte _current_max_fade_step;
    byte _current_min_fade_step;
    static const unsigned long  _FADE_DELAY_MS = 10;

    byte _fade_step;
    unsigned long  _last_faded_ms;
    unsigned long  _delay_ms;

    bool _fade(bool fade_up);
    void _vol(byte val);

public:
    mp3(size_t rx_pin, size_t tx_pin);
    ~mp3();
    void stop();
    bool fade_out();
    bool fade_in();
    void play(size_t nr);
    unsigned long is_playing();    
    void begin(byte vol=30);
    void play_vol(size_t nr, byte vol);
    void vol(byte val);
};

mp3::mp3(size_t rx_pin, size_t tx_pin)
{
    _rx_pin = rx_pin;
    _tx_pin = tx_pin;
    player = new SerialMP3Player(_rx_pin, _tx_pin);
    _fade_step = 0;
    _last_faded_ms = 0;
    _delay_ms = _FADE_DELAY_MS;
    _current_max_fade_step = _MAX_FADE_STEP;
    _current_min_fade_step = _MIN_FADE_STEP;    
}

mp3::~mp3()
{
}

void mp3::begin(byte vol)
{
    _current_max_fade_step = vol;
    player->begin(9600); 
    delay(500);          
    player->sendCommand(CMD_SEL_DEV, 0, 2);   //select sd-card
    delay(500);
    player->setVol(vol);
}

void mp3::play_vol(size_t nr, byte vol)
{
    _current_max_fade_step = vol;
    _vol(vol);
    player->play(nr); 
    _play_since_ms = millis();
}


void mp3::play(size_t nr)
{
    player->playSL(nr);
    _play_since_ms = millis();
}

void mp3::vol(byte val)
{
    _current_max_fade_step = val;
    _vol(val);
}

void mp3::_vol(byte val)
{
    _fade_step = val;
    Serial.printf("MP3 players volume set to %d.\n", val);
    player->setVol(val);
}


unsigned long mp3::is_playing()
{
    player->qStatus();
    if (player->available()){
        String answer = player->decodeMP3Answer();
        if(answer.indexOf(STARTED_STRING) > -1)
        {
            return(millis() - _play_since_ms);
        }
    }
    Serial.printf("MP3 Player is not playing\n");
    return 0;
}

void mp3::stop()
{
    player->stop();
}


bool mp3::_fade(bool fade_up)
{
    if(millis() - _last_faded_ms > _delay_ms)
    {
        _last_faded_ms = millis();
        if(true == fade_up)
        {
            if(_current_max_fade_step > _fade_step)
            {
                if(_fade_step + FADESTEP_WITH > _current_max_fade_step)
                    _fade_step = _current_max_fade_step;
                else 
                    _fade_step = FADESTEP_WITH + _fade_step;
                _fade_step = _fade_step + FADESTEP_WITH;
            }
            else
                return false;
        }
        else
        {
            if(_current_min_fade_step < _fade_step)
                if(_fade_step - FADESTEP_WITH < _current_min_fade_step)
                    _fade_step = _current_min_fade_step;
                else 
                    _fade_step = _fade_step - FADESTEP_WITH;
            else
                return false;
        }
        _vol(_fade_step); 
    }
    return true;
}

bool mp3::fade_out()
{
    if(_fade(false) == true)
        return(true);
    else
    {
        player->stop();
        return(false);
    }
}

bool mp3::fade_in()
{
    return(_fade(true));
}

#endif
