/* Gaim - X Multimedia System current song (gaim xmms current song)
 * Based on the sourceforge project:
 * [Gaim - X Multimedia System current song
 * originally written by Elekis on
 * elekis@gawab.com]
 *
 * for bugs running gaimxmmsed on gaim 2.0.0beta3 -> cristian_gavril_olar@yahoo.com
 * subject [bug_gaimxmmsed]
 *
 * 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, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 */
/*to compile make LDFLAGS =-lxmms plugin.so*/
#include <stdlib.h>
#include <xmms/xmmsctrl.h>
#include <stdio.h>
#include <glib.h>
#include <pthread.h> 
#include <unistd.h>
#include "internal.h"
#include "debug.h"
#include "plugin.h"
#include "savedstatuses.h"
#include "version.h"
#include "gtkplugin.h"
#include "protocols/msn/msn.h"
#include "connection.h"
#define BUDDY_ALIAS_MAXLEN 387 /*Left it here, according to Elekis this is 
the maximum length of the status on MSN accounts, maybe I'll use this sometime
in the future*/
#define MAX_LEN_WORD 1000

/*If you want to change the text displayed before the song title then change the text
below*/
#define MESSAGE_PREFIX  "Listening to "
/*If you want to change the text displayed after the song title then change the text 
below*/
#define MESSAGE_SUFFIX ". "
#define MESSAGE_NOT_PLAYING " X Multimedia System is quiet."
#define SAVED_STATUS_TITLE "Listening to music"
/*char name[BUDDY_ALIAS_MAXLEN];*//*This is an inherited line from the*/

char stat_name[MAX_LEN_WORD];

typedef void* (*threadfunc)(void*);
typedef struct thread_info_enum{
  int ret;
  pthread_t tid;
}thread_info_t;


typedef struct needed_info_enum{
  GList* active_accounts;
  thread_info_t* thredinf;
}needed_info_t;

void set_new_status_message(char* statmes,GaimAccount* account);
void function(void* unu);
int check_conected(needed_info_t* info);
char* add_char(char* str,char c,int* len,int* lenmax);

/*When I say "status" I don't mean the same status as gaim developers include
inside their gaim_status* functions. I mean the status that is displayed when you
put your cursor on a buddy; the text displayed under the buddy icon*/
void set_new_status_message(char* statmes,GaimAccount* account)
{
  GaimPresence *gp;
  GaimStatus *gs;
  GaimStatusType *gst;
  GaimSavedStatus *gss,*current;
  const char* currentmess;
  char *statusmes;
  char stat_all[MAX_LEN_WORD];
  int totallen=0,strlength;
  /*I thought it would be nice to keep the same status and just change*/
  /*the message so I got the account's current status and left from there*/
  gp=gaim_account_get_presence(account);
  gs=gaim_account_get_active_status(account);
  /*printf("Current status name:%s\n",gaim_status_get_name(gs));
    printf("Current status ID:%s\n",gaim_status_get_id(gs));*/
  gst=gaim_status_get_type(gs);
  /*The following lines are important. First, to properly update the savedstatus*/
  /*we will delete it first*/
  gaim_savedstatus_delete(SAVED_STATUS_TITLE);
  /*Now we recreate the saved status*/
  current=gaim_savedstatus_get_current();
  currentmess=gaim_savedstatus_get_message(current);
  gss=gaim_savedstatus_new(SAVED_STATUS_TITLE,gaim_status_type_get_primitive(gst));
  /*Now let's build the new status message by adding your current status message
   to the currently played track by xmms and the selected MESSAGE_PREFIX and 
   MESSAGE_SUFFIX or alternatively MESSAGE_NOT_PLAYING*/
  /*statusmes=malloc(sizeof(char));statusmes[0]='\0';*/
  stat_all[0]='\0';
  /*strlength=strlen(statmes);*/
  /*statusmes=realloc(statusmes,sizeof(char)*(totallen+strlength));*/
  strcat(stat_all,currentmess);
  /*totallen+=strlength;*/
  /*strlength=strlen(currentmess);*/
  /*statusmes=realloc(statusmes,sizeof(char)*(totallen+strlength));*/
  strcat(stat_all,statmes);
  /*totallen+=strlength;*/
  /*printf("Changing status to %s\n",statusmes);*//*this is a debug line*/
  /*Now we set the message*/
  gaim_savedstatus_set_message(gss,stat_all);
  /*Finally we activate the new savedstatus*/
  gaim_savedstatus_activate_for_account(gss,account);
  /*printf("%s\n",name);*//*This line was here just for debugging*/
}

/*This is a function that checks if any accounts are connected*/
int check_conected(needed_info_t* info)
{
  int found;
  GList* accounts;
  accounts=info->active_accounts;
  found=0;
  while (accounts!=NULL){
    /*printf("Checking if connected.\n");*/
    if (gaim_account_is_connected((GaimAccount*)(accounts->data))){
      found=1;
    }
    accounts=accounts->next;
  }
  return found;
}


/*This function is not used for now. Maybe in the future.*/
char* add_char(char* str,char c,int* len,int* lenmax)
{
  if ((*lenmax)<=(*len))
    {
      (*len)++;
      str[(*len)-1]=c;
    }
  else{
    (*lenmax)+=200;
    str=realloc(str,sizeof(char)*(*lenmax));
    (*len)++;
    str[(*len)-1]=c;
  }
  return str;
}

void function(void *unu)
{
  needed_info_t *info;
  gint pos = -1;
  int strlength,totallen;
  GaimAccount* account;
  GList* found_accounts;
  char *p=NULL;
  char *songname=NULL;
  info=(needed_info_t*)unu;/*Let's restore our needed info to it's correct type*/
  /*Our newly created thread will return(exit) when no account will be conected*/
  while(check_conected(info)){
    if (xmms_remote_is_running(0)){
      /*So, this is what to do if xmms is running*/
      /*printf("XMMS is running.\n");*/
      if(pos !=  xmms_remote_get_playlist_pos(0)){
	/*We only want to change someting if the song changed*/
	pos = xmms_remote_get_playlist_pos(0);
	/*Now let's build the string to display as status message*/
	/*if (p!=NULL) {
	  free(p);
	}
	p=NULL;totallen=1;p=malloc(sizeof(char));p[0]='\0';*/
	stat_name[0]='\0';
	songname=xmms_remote_get_playlist_title(0, pos);
	strlength=strlen(MESSAGE_PREFIX);
	/*p=realloc(p,sizeof(char)*(strlength+totallen));*/
	strcat(stat_name,MESSAGE_PREFIX);
	totallen+=strlength;
	strlength=strlen(songname);
	/*p=realloc(p,sizeof(char)*(strlength+totallen));*/
	strcat(stat_name,songname);
	totallen+=strlength;
	strlength=strlen(MESSAGE_SUFFIX);
	/*p=realloc(p,sizeof(char)*(strlength+totallen));*/
	strcat(stat_name,MESSAGE_SUFFIX);
	totallen+=strlength;
	found_accounts=info->active_accounts;
	while (found_accounts != NULL){
	  account=(GaimAccount*)(found_accounts->data);
	  if(gaim_account_is_connected(account)){
	    /*We only want to bring conected accounts up-to-date*/
	    set_new_status_message(stat_name,account);
	  }
	  /*printf("Tot fac next pe accounts.\n");*/
	  found_accounts=found_accounts->next;
	}
      }
    }
    else{
      /*And now what to do if xmms is not running but our plugin is activated*/
      /*In this case we will let only the current status's message be displayed
       and a little message saying we're not listening to anything*/
      if (pos != -1){
	/*Firstly, pos is reseted to -1 so that when we restart XMMS we can detect
	 that it was restarted*/
	pos = -1;
	found_accounts=info->active_accounts;
	while (found_accounts != NULL){
	  account=(GaimAccount*)(found_accounts->data);
	  if(gaim_account_is_connected(account)){
	    /*if (p!=NULL) p=NULL;p=malloc(sizeof(char));p[0]='\0';*/
	    stat_name[0]='\0';
	    totallen=1;
	    strlength=strlen(MESSAGE_NOT_PLAYING);
	    /*p=realloc(p,sizeof(char)*(strlength+totallen));*/
	    totallen+=strlength;
	    strcat(stat_name,MESSAGE_NOT_PLAYING);
	    set_new_status_message(stat_name,account);
	    /*printf("%s\n",name);*/
	  }
	  found_accounts=found_accounts->next;
	}
      }
    }
    sleep(5);/*update status 5 by 5 seconds*/
  }
  return;
}

static void signed_on_cb(GaimConnection *gc, void* data)
{
  GList **lista_noua;
  lista_noua=(GList**)data;/*Restore the corect type of our passed data*/
  (*lista_noua)=gaim_accounts_get_all_active();/*refresh accounts*/
  return;
}

static void account_status_changed_cb(GaimAccount *account, 
				      GaimStatus* old,GaimStatus* new,gpointer data)
{
  GList **lista_noua;
  lista_noua=(GList**)data;/*Restore the corect type of our passed data*/
  (*lista_noua)=gaim_accounts_get_all_active();/*refresh accounts*/
  return;
}

static gboolean 
plugin_load(GaimPlugin *plugin)
{
  thread_info_t *th_inf=NULL;
  needed_info_t *info=NULL;
  void *conn_handle;
  GList* all_accounts=NULL;
  gaim_savedstatus_delete(SAVED_STATUS_TITLE);
  info=malloc(sizeof(needed_info_t));
  th_inf=malloc(sizeof(thread_info_t));
  all_accounts=gaim_accounts_get_all_active();
  info->active_accounts=all_accounts;
  info->thredinf=th_inf;
  conn_handle=gaim_connections_get_handle();
  gaim_signal_connect(conn_handle,"signed-on",plugin,
		      GAIM_CALLBACK(signed_on_cb),&(info->active_accounts));
  gaim_signal_connect(conn_handle,"account-status-changed",plugin,
		      GAIM_CALLBACK(account_status_changed_cb),&(info->active_accounts));
  th_inf->ret = pthread_create(&(th_inf->tid), NULL, (threadfunc)function, info);
  return TRUE;
}

static gboolean
plugin_unload(GaimPlugin *plugin)
{  
  return TRUE;
}

static GaimPluginInfo info =
  {
    GAIM_PLUGIN_MAGIC,
    GAIM_MAJOR_VERSION,
    GAIM_MINOR_VERSION,
    GAIM_PLUGIN_STANDARD,
    GAIM_GTK_PLUGIN_TYPE,
    0,                                           /**< flags          */
    NULL,                                             /**< dependencies   */
    GAIM_PRIORITY_DEFAULT,                            /**< priority       */
    
    NULL,                                             /**< id             */
    N_("X Multimedia Plugin"),                              /**< name           */
    VERSION,                                          /**< version        */
    /**  summary        */
    N_("X Multimedia System current song as status"),
    /**  description    */
    N_("Puts the current xmms played song as your status"),
    "Written by Cristian Gavril Olar <cristian_gavril_olar@yahoo.com> for gaim-2.0.0beta3\n but heavily based on plugin_gaim_xmms written by Elekis <elekis@gawab.com>",        /**< author         */
    GAIM_WEBSITE,                                          /**< homepage       */
    
    plugin_load,                                      /**< load           */
    plugin_unload,                                    /**< unload         */
    NULL,                                             /**< destroy        */
    
    NULL,                                             /**< ui_info        */
    NULL,                                             /**< extra_info     */
    NULL,
    NULL
  };

static void
init_plugin(GaimPlugin *plugin)
{
}

GAIM_INIT_PLUGIN(simple, init_plugin, info)
