/**
 * lastfm.c: Main file
 * 
 * Copyright: See COPYING file that comes with this distribution
 *
 * Author: Matthias Feistel <hitman_47@users.sourceforge.net>, (C) 2007
 */

#include <vdr/plugin.h>
#include <getopt.h>
#include "audio_control.h"
#include "config.h"
#include "web_serviceconnector.h"
#include "setup.h"
#include "utils.h"
#include "osd_userinterface.h"
#include "osd_userinterface_profileselection.h"
#include "settings.h"
#include "settings_xml.h"

// Int'l inspired and copied from epgsearch (C. Wieninger) 
#if APIVERSNUM < 10507
#include "i18n.h"
#define trNOOP(s) (s)
#endif

// Service:
#include "service.h" // submission-serviceconnector
#include "web_serviceconnector_scrobbler.h" // giving static Submission() to other plugins

static const char *VERSION = PLUGIN_VERSION;
static const char *DESCRIPTION = tr( "A player for the service of last.fm" );
static const char *MAINMENUENTRY = "Lastfm";

//// will be removed in next version:
static bool option_m = false;

class cPluginLastfm : public cPlugin
{
private:
	// Add any member variables or functions you may need here.

public:
	cPluginLastfm( void );
	virtual ~cPluginLastfm( );
	virtual const char *Version( void )
	{
		return VERSION;
	}
	virtual const char *Description( void )
	{
		return DESCRIPTION;
	}
	virtual const char *CommandLineHelp( void );
	virtual bool ProcessArgs( int argc, char *argv[] );
	virtual bool Initialize( void );
	virtual bool Start( void );
	virtual void Stop( void );
	virtual void Housekeeping( void );
	virtual void MainThreadHook( void );
	virtual cString Active( void );
	virtual time_t WakeupTime( void );
	virtual const char *MainMenuEntry( void )
	{
		return MAINMENUENTRY;
	}
	virtual cOsdObject *MainMenuAction( void );
	virtual cMenuSetupPage *SetupMenu( void );
	virtual bool SetupParse( const char *Name, const char *Value );
	virtual bool Service( const char *Id, void *Data = NULL );
	virtual const char **SVDRPHelpPages( void );
	virtual cString SVDRPCommand( const char *Command, const char *Option,
			int &ReplyCode );
};

cPluginLastfm::cPluginLastfm( void )
{
	// Initialize any member variables here.
	// DON'T DO ANYTHING ELSE THAT MAY HAVE SIDE EFFECTS, REQUIRE GLOBAL
	// VDR OBJECTS TO EXIST OR PRODUCE ANY OUTPUT!
}

cPluginLastfm::~cPluginLastfm( )
{
	// Clean up after yourself!
}

const char *cPluginLastfm::CommandLineHelp( void )
{
	// Return a string that describes all known command line options.

	//// will be removed in next version:
	return "  -m ,   --migratefavourites     load old style favourites into plugin and let them store to plugin's xml configfile\n";
}

bool cPluginLastfm::ProcessArgs( int argc, char *argv[] )
{
	// Implement command line argument processing here if applicable.

	//// will be removed in next version:	
	static struct option long_options[] =
	{
	{ "migratefavourites", no_argument, NULL, 'm' },
	{ NULL } };
	
	int c;
	while( (c = getopt_long( argc, argv, "m", long_options, NULL )) != -1 )
	{
		switch( c )
		{
			case 'm':
				option_m = true;
				break;
			default:
				return false;
		}
	}
	return true;
}

bool cPluginLastfm::Initialize( void )
{
	// Initialize any background activities the plugin shall perform.
#if APIVERSNUM < 10507
	RegisterI18n( Phrases );
#endif
	
	const char* configDir = ConfigDirectory( );
	
	if( configDir )
	{
		std::string s2 = std::string( configDir ) + "/lastfm_config.xml";
		
		cSettings::GetInstance().SetXmlconfig_Fileurl( s2.c_str( ) );
	}
	
	return true;
}

bool cPluginLastfm::Start( void )
{
	// Start any background activities the plugin shall perform.
	return true;
}

void cPluginLastfm::Stop( void )
{
	// Stop any background activities the plugin shall perform.
}

void cPluginLastfm::Housekeeping( void )
{
	// Perform any cleanup or other regular tasks.
}

void cPluginLastfm::MainThreadHook( void )
{
	// Perform actions in the context of the main program thread.
	// WARNING: Use with great care - see PLUGINS.html!
}

cString cPluginLastfm::Active( void )
{
	// Return a message string if shutdown should be postponed
	return NULL;
}

time_t cPluginLastfm::WakeupTime( void )
{
	// Return custom wakeup time for shutdown script
	return 0;
}

cOsdObject *cPluginLastfm::MainMenuAction( void )
{
	// Perform the action when selected from the main VDR menu.
	
	int rc = 0;
	
	
	// not running and no CurrentProfilename:
	if( !cSettings::GetInstance().Mp3decoderstate &&
			cSettings::GetInstance().CurrentProfilename.empty( )
	)
	{
		// Profileselection (or creation of a new profile):
		std::list<std::string> profilenames = cXmlconfig::GetProfilenames( );

		
		// if more than one profile exists, let the user decide:
		if( profilenames.size( ) > 1 )
			return new cUserInterface_Profileselection();
		// we load the first profile, ifthere is only one there
		else if( profilenames.size( ) == 1 )
		{
			std::string profilenames_front_str( profilenames.front( ) );
			cXmlconfig::Load(
					profilenames_front_str,
					cSettings::GetInstance().ParameterMap,
					cSettings::GetInstance().FavouriteList
					);
			
			cSettings::GetInstance().CurrentProfilename = profilenames_front_str;
		}
		
	}
	else
	{
		
		if( cXmlconfig::Load(
						cSettings::GetInstance().CurrentProfilename,
						cSettings::GetInstance().ParameterMap,
						cSettings::GetInstance().FavouriteList )
		)
		{
			Skins.Message( mtError,	tr( "Profile not found!" ) );
			cSettings::GetInstance().CurrentProfilename.clear();
			
			return 0;
		}

	}

	std::string username(cSettings::GetInstance().ParameterMap[ "Username" ]);
	std::string password_md5(cSettings::GetInstance().ParameterMap[ "Password_md5" ]);
	std::string session_id(cSettings::GetInstance().ParameterMap[ "Session ID" ]);
	std::string osd_Autostartmode(cSettings::GetInstance().ParameterMap[ "Osd_Autostartmode" ]);
	std::string osd_Mode(cSettings::GetInstance().ParameterMap[ "Osd_Mode" ]);
	
	
	/// Wenn noch kein User/Passphrase definiert wurden, soll eine Info darauf hinweisen:
	if( !username.compare( "" ) ||!password_md5.compare( "" ) )
	{
		Skins.Message( mtError,
				tr( "Please provide user information in setup of vdr-lastfm." ) );
		cSettings::GetInstance().CurrentProfilename.clear( );
		return 0;
	}
	
	///PLAYER
	if( !cSettings::GetInstance().Mp3decoderstate )
	{
		cWebServiceConnector *WebServiceConnector = new cWebServiceConnector();

		/// Handshake
		if( (rc = WebServiceConnector->Handshake( username, password_md5 ) )
				!= 0 )
		{
			cSettings::GetInstance().CurrentProfilename.clear();
			
			if( rc == 1 )
			{	
				Skins.Message( mtError, tr( "Handshake unsuccessful!" ) );
				delete WebServiceConnector;
				WebServiceConnector = 0;
				return 0;
			}
			
			if( rc == 2 )
			{
				Skins.Message( mtError,
						tr( "Handshake unsuccessful! Network failure" ) );
				delete WebServiceConnector;
				WebServiceConnector = 0;
				return 0;
			}
			
		} // HANDSHAKE
		std::string username(cSettings::GetInstance().ParameterMap[ "Username" ]);
		std::string password_md5(cSettings::GetInstance().ParameterMap[ "Password_md5" ]);
		
		delete WebServiceConnector;
		WebServiceConnector = 0;
		
		cControl::Launch( new cAudioControl );
		
		if( !atoi( osd_Autostartmode.c_str( ) ) )
		{
			return 0;
		}
		
	} // PLAYER

	///OSD
	if( atoi( osd_Mode.c_str( ) ) )
		return new cUserInterfaceTextbased;
	else if( !atoi( osd_Mode.c_str( ) ) )
		return new cUserInterface;
	
	return 0;
}

cMenuSetupPage *cPluginLastfm::SetupMenu( void )
{
	// Return a setup menu in case the plugin supports one.
	return new cSetupLastfm( );
}

bool cPluginLastfm::SetupParse( const char *Name, const char *Value )
{
	//// will be removed in next version:
	if( option_m )
	{
		int MAXFAVS = 99;
		// read favourites:

		for( int i = 0; i < MAXFAVS; i++ )
		{
			char buff[ 32 ];
			snprintf( buff, sizeof(buff ), "Favourite%d", i );
			if ( !strcasecmp( Name, buff ) )
			{
				cSettings::GetInstance().FavouriteList.push_back( Value );

				fflush( stdout );
			}

		}

		// sort favouritelist
		// data will be sorted here, because of new entered items by user;
		// these items have not been stored in setup.conf, yet.
		cSettings::GetInstance().FavouriteList.sort( cUtils::compare_nocase );
	}

	return true;
}

bool cPluginLastfm::Service( const char *Id, void *Data )
{
	// Handle custom service requests from other plugins

    struct SubmissionHandle_v1_0 *Handle = (struct SubmissionHandle_v1_0 *) Data;
    
    if ( strcmp(Id,LASTFM_SUBMISSION_HANDLE_v1_0) == 0 )
    {
    	
            if ( Data )
            {
                Handle->HandshakeV12 = &cWebServiceConnectorScrobbler::HandshakeV12;
                Handle->Submission = &cWebServiceConnectorScrobbler::Submission;
            }
            
            return true;
    }
    
    return false;
}

const char **cPluginLastfm::SVDRPHelpPages( void )
{
	// Return help text for SVDRP commands this plugin implements
	return NULL;
}

cString cPluginLastfm::SVDRPCommand( const char *Command, const char *Option,
		int &ReplyCode )
{
	// Process SVDRP commands this plugin implements
	return NULL;
}

VDRPLUGINCREATOR( cPluginLastfm ); // Don't touch this!
