/****************************************************************************************
 * Copyright (c) 2008 Dan Meltzer <parallelgrapefruit@gmail.com>                        *
 * Copyright (c) 2012 Matěj Laitl <matej@laitl.cz>                                      *
 *                                                                                      *
 * This program 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.                                                                             *
 *                                                                                      *
 * This program 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         *
 * this program.  If not, see <http://www.gnu.org/licenses/>.                           *
 ****************************************************************************************/

#include "LastFmMultiPlayableCapability.h"

#include "EngineController.h"

LastFmMultiPlayableCapability::LastFmMultiPlayableCapability( LastFm::Track *track )
    : Capabilities::MultiPlayableCapability()
    , m_url( track->internalUrl() )
    , m_track( track )
{
    connect( track, SIGNAL(skipTrack()), this, SLOT(skip()) );

    Q_ASSERT( The::mainWindow() );
    connect( The::mainWindow(), SIGNAL(skipTrack()), SLOT(skip()) );

    // we only update underlying Last.fm metadata once it starts playing, prevent wrong
    // metadata Last.fm submissions etc.
    Q_ASSERT( EngineController::instance() );
    connect( EngineController::instance(), SIGNAL(trackPlaying(Meta::TrackPtr)),
                                           SLOT(slotTrackPlaying(Meta::TrackPtr)) );
}

LastFmMultiPlayableCapability::~LastFmMultiPlayableCapability()
{
}

void
LastFmMultiPlayableCapability::fetchFirst()
{
    DEBUG_BLOCK
    m_tuner = new lastfm::RadioTuner( lastfm::RadioStation( m_track->uidUrl() ) );
    m_tuner->setParent( this ); // memory management

    connect( m_tuner, SIGNAL(trackAvailable()), SLOT(slotNewTrackAvailable()) );
    connect( m_tuner, SIGNAL(error(lastfm::ws::Error,QString)),
                      SLOT(error(lastfm::ws::Error)) );
}

void
LastFmMultiPlayableCapability::fetchNext()
{
    DEBUG_BLOCK
    m_currentTrack = m_tuner->takeNextTrack();
    emit playableUrlFetched( m_currentTrack.url() );
}

void
LastFmMultiPlayableCapability::slotTrackPlaying( const Meta::TrackPtr &track )
{
    // time to update underlying track with metadata
    // warning: this depends on MetaProxy::Track operator== returning true
    // between proxy and underlying track!
    if( track == m_track )
        m_track->setTrackInfo( m_currentTrack );
}

void
LastFmMultiPlayableCapability::slotNewTrackAvailable()
{
    DEBUG_BLOCK
    if( m_currentTrack.isNull() ) // we only force a track change at the beginning
    {
        fetchNext();
        // we update metadata immediatelly for the very first track
        m_track->setTrackInfo( m_currentTrack );
    }
}

void
LastFmMultiPlayableCapability::skip()
{
    DEBUG_BLOCK
    fetchNext();
}

void
LastFmMultiPlayableCapability::error( lastfm::ws::Error e )
{
    if( e == lastfm::ws::SubscribersOnly || e == lastfm::ws::AuthenticationFailed )
    {   // last.fm is returning an AuthenticationFailed message when the user is not a subscriber, even if the credentials are OK
        Amarok::Components::logger()->longMessage(
            i18n( "To listen to this stream you need to be a paying Last.fm subscriber. "
                  "All the other Last.fm features are unaffected." ) );
    }
    else
    {
        Amarok::Components::logger()->longMessage(
                    i18n( "Error starting track from Last.fm radio" ) );
    }
}
