#include <xmms/plugin.h>
#include <pthread.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>

// Functions predefined here
static void example_pcm_callback(gint16 data[2][512]);
static void example_init(void);
static void example_cleanup(void);
static void example_play(void);
static void example_stop(void);

void *example_worker(void *);

// Define global variables
gint16			databuffer[2][512];
static pthread_t	worker_thread;
static pthread_attr_t	worker_attr;
int			worker_running,
			worker_status,
			xmms_status;

// Visualization plugin structure
VisPlugin example_vp =
{
 NULL,NULL,0,
 "Autotools example 4",
 2,			// 2 pcm channels
 0,			// 0 freq channels
 example_init,
 example_cleanup,
 NULL,
 NULL,
 NULL,
 example_play,
 example_stop,
 example_pcm_callback,
 NULL
};

// -----------------------
// PCM callback routine
// -----------------------

static void example_pcm_callback(gint16 data[2][512]) 
{
 // Make a copy of pcm data for worker function
 if(worker_status==0)
 {
	memcpy(databuffer[0],data[0],512);
	memcpy(databuffer[1],data[1],512);
	worker_status=1;
 } else {
  // If for some reason we have new datapacket to 
  // process, but our worker is not ready, then
  // print out a warning
  printf("!");
 }
}

// -----------------------
// Worker routine
// -----------------------

void *example_worker(void *arg)
{
 int i;
 double left_val,right_val;
 
 // Thread mainloop
 while(worker_running==1)
 {
  // do work only if xmms is in playback state,
  // and we have something new to process
  if(xmms_status==1 && worker_status!=0)
  {
	// Calculate avarage value
	left_val=0;
	right_val=0;
	
	for(i=0; i<512; i++)
	{
	 left_val+=(double)databuffer[0][i];
	 right_val+=(double)databuffer[0][i];
	}
	
	left_val/=512.0;
	right_val/=512.0;
	
  	printf("(%.2f , %.2f)\n",left_val,right_val);
	
	// acknowledge datapacket
	worker_status=0;		
  } 
  
  // Wait about 4ms, and check loop status every 1ms
  // [ note. usleep gives cpu time to multitasking, so 
  // if machine is heavily loaded, this loop might 
  // take longer than 10ms ]
  for(i=0; i<4; i++)
  {
  	usleep(1000);
	if(worker_running==0) pthread_exit(0);
  }
 }
 
 // Exit thread
 pthread_exit(0);
}

// -----------------------
// START / STOP / INIT / CLEANUP
// -----------------------

static void example_init(void) 
{
 worker_running=1;		// enable worker loop
 worker_status=0;		// no new datapackets
 xmms_status=0;			// playback stopped

 // Create worker thread
 pthread_attr_init(&worker_attr);
 pthread_attr_setdetachstate(&worker_attr,PTHREAD_CREATE_JOINABLE);
 pthread_create(&worker_thread, &worker_attr, example_worker, NULL);
 pthread_attr_destroy(&worker_attr);
}

static void example_cleanup(void) { 
 // Disable worker loop
 worker_running=0;		
 // Wait a second, for worker to quit
 sleep(1);			
}

static void example_play(void) {
 xmms_status=1;
}

static void example_stop(void) { 
 xmms_status=0;
}

// -----------------------
// Function required by xmms
// -----------------------
VisPlugin *get_vplugin_info(void) { return &example_vp; }
