/*
 * wmxmms2
 * Copyright (c)2005 Remy Bosch (remybosch@zonnet.nl)
 * 
 * This software covered by the GPL.  See COPYING file for details.
 *
 * xmms2cif.c
 *
 */
#include "xmms2cif.h"
#include <libgen.h> /* Needed by basename(char *uri)*/
#include "options.h"
static int res_has_keyword(xmmsc_result_t *res, const char *key);
static uint have_songname;
uint songlength;

/**
 * Initiate client for use
 */
void xmms2connect(void){
	srvr = xmmsc_init ("WMxmms2-dev");

	if (!srvr || !xmmsc_connect (srvr, varoptions.ip_address)) {
		fprintf (stderr, "Connection failed, error: %s\n", xmmsc_get_last_error (srvr));
		STATE=S_DOWN;
	}else{
		STATE=S_IDLE;
	}
}

/**
 * press play ;)
 */
void play_cmd(void){
	xmmsc_result_t *res;
	res = xmmsc_playback_start (srvr);
	xmmsc_result_wait (res);
	if (xmmsc_result_iserror (res)) {
		fprintf (stderr, "Couldn't start playback: %s\n",
				xmmsc_result_get_error (res));
		STATE=S_ERROR;
	}else
		STATE=S_PLAY;
	xmmsc_result_unref (res);
}

/**
 * Stop signal
 */
void stop_cmd(void){
	xmmsc_result_t *res;
	res = xmmsc_playback_stop (srvr);
	xmmsc_result_wait (res);
	if (xmmsc_result_iserror (res)) {
		fprintf (stderr, "Couldn't stop playback: %s\n",
				xmmsc_result_get_error (res));
		STATE=S_ERROR;
	}else
		STATE=S_IDLE;
	xmmsc_result_unref (res);
}

/**
 * Shuffle the songs
 */
void randomize_cmd(void){
	xmmsc_result_t *res;
	res = xmmsc_playlist_shuffle (srvr, NULL);
	xmmsc_result_wait (res);
	if (xmmsc_result_iserror (res)) {
		fprintf (stderr, "Couldn't randomize playlist: %s\n",
				xmmsc_result_get_error (res));
		STATE=S_ERROR;
	}
	xmmsc_result_unref (res);
}

/**
 * Pause for a while
 */
void pause_cmd(void){
	xmmsc_result_t *res;
	res = xmmsc_playback_pause(srvr);
	xmmsc_result_wait (res);
	if (xmmsc_result_iserror (res)) {
		fprintf (stderr, "Couldn't pause playback: %s\n",
				xmmsc_result_get_error (res));
		STATE=S_ERROR;
	}else
		STATE=S_PAUSE;
	xmmsc_result_unref (res);
}

/**
 * Lets jump around, shal we?
 */
void jmp_cmd(int places){
	xmmsc_result_t *res;
	res = xmmsc_playlist_set_next_rel(srvr, places);
	xmmsc_result_wait (res);
	if (xmmsc_result_iserror (res)) {
		fprintf (stderr, "Couldn't go to other file: %s\n",
				xmmsc_result_get_error (res));
		xmmsc_result_unref (res);
		STATE=S_ERROR;
		return;
	}
	xmmsc_result_unref (res);
	res = xmmsc_playback_tickle (srvr);
	if (xmmsc_result_iserror (res)) {
		fprintf (stderr, "Couldn't tickle playback: %s\n",
				xmmsc_result_get_error (res));
		xmmsc_result_unref (res);
		STATE=S_ERROR;
	}else
		STATE=S_PLAY;
	xmmsc_result_wait (res);
	xmmsc_result_unref (res);
}

/**
 * One hop back....
 */
void prev_cmd(void){
	jmp_cmd(-1);
}

/**
 * One hop foreward....
 */
void next_cmd(void){
	jmp_cmd(1);
}

/**
 * Determine if a keyword is available
 */
static int res_has_keyword(xmmsc_result_t *res, const char *key){
	return xmmsc_result_get_dict_entry_type (res, key) != XMMSC_RESULT_VALUE_TYPE_NONE;
}

/**
 * 
 */
void get_songdata(void){
	playtime();
	title_info();
}

/**
 * retreive playtime info
 */
void playtime(void){
	xmmsc_result_t *res;
	res = xmmsc_playback_playtime(srvr);
	xmmsc_result_wait (res);
	if (!xmmsc_result_get_uint (res, &(numinfo.played))) {
		printf ("No time data\n");
	}
	xmmsc_result_unref (res);
}

/**
 * Get title of song if possible...
 * Or the filename.
 */
void title_info(void){
	static uint id_hold=0;
	uint id;
	xmmsc_result_t *res;
	res = xmmsc_playback_current_id(srvr);
	xmmsc_result_wait (res);
	have_songname=0;
	if(xmmsc_result_iserror (res) ||
			!xmmsc_result_get_uint (res, &id)){
		printf( "Damn no id!\n");
		xmmsc_result_unref (res);
		return;
	}
	if (id!=0 && id!=id_hold){
		res = xmmsc_medialib_get_info (srvr, id);
		xmmsc_result_wait (res);
		xmmsc_result_get_dict_entry_int (res,"duration",&(numinfo.length));
		if (res_has_keyword(res, "title") &&
				res_has_keyword (res, "artist") ) {
			xmmsc_entry_format (numinfo.title_info,
					sizeof (numinfo.title_info),
					"${artist} - ${title}", res);
		} else if (res_has_keyword(res, "title")) {
			xmmsc_entry_format (numinfo.title_info,
					sizeof (numinfo.title_info),
					"${title}",res);
		} else if (res_has_keyword(res, "url")) {
			char *url, *filename;
			xmmsc_result_get_dict_entry_string (res, "url", &url);
			/* Taking a risk at segfault here ;-) */
			if ((filename=basename(url))!=NULL) {
				strncpy(numinfo.title_info,filename,
						sizeof(numinfo.title_info)-1);
			}
		}
		if (strlen(numinfo.title_info)>0)
			have_songname=1;
		id_hold=id;
	}
	if(id==id_hold)
		have_songname=1;

	xmmsc_result_unref (res);
}

/**
 * Get status update from xmms server.
 * Still playing, stopped or paused?
 */
void check_status(void){
	if(STATE==S_DOWN || STATE==S_ERROR){
		return;
	}
	xmmsc_result_t *res;
	unsigned int state;
	res =  xmmsc_playback_status(srvr);
	xmmsc_result_wait(res);
	if(xmmsc_result_iserror(res)) {
		printf( "Could not get playback status: %s\n", xmmsc_result_get_error(res) );
		state = S_ERROR;
	}
	else {
		xmmsc_result_get_uint(res, &state);
	}
	xmmsc_result_unref(res);
	STATE=state;
}

/**
 * We take steps of ten seconds
 */
void fwd_cmd(void){
	timelaps(10000);
}

/**
 * We take steps of ten seconds
 */
void rwnd_cmd(void){
	timelaps(-10000);
}

/**
 * Jump in time... Just say how far
 */
void timelaps(int delta){
	uint id;
	xmmsc_result_t *res;
	res = xmmsc_playback_current_id (srvr);
	xmmsc_result_wait (res);
	if (!xmmsc_result_get_uint (res, &id))
		printf("No Id!\n");
	xmmsc_result_unref (res);
	res = xmmsc_playback_playtime (srvr);
	xmmsc_result_wait (res);
	if (numinfo.length == 0 &&
			!xmmsc_result_get_uint (res, &(numinfo.played))){
		printf("No Timeinfo!\n");
		xmmsc_result_unref (res);
		return;
	}
	xmmsc_result_unref (res);
	
	if ((((int)numinfo.played)+delta)>((int)numinfo.length)){
		jmp_cmd(1);
	}else {
		if(((int)(numinfo.played+delta))<0){
			res = xmmsc_playback_seek_ms (srvr, 0);
		}else{
			res = xmmsc_playback_seek_ms (srvr,
					numinfo.played+delta);
		}
		xmmsc_result_wait (res);
		if (xmmsc_result_iserror (res))
			fprintf (stderr, "Couldn't seek \n%s\n", xmmsc_result_get_error (res));
		xmmsc_result_unref (res);
	}
}

/**
 * Close up
 */
void disconnect_server(void){
	xmmsc_unref (srvr);
}

