/* A plugin for XMMS that sends the frequency data out over a UDP
   socket to a separate program (netdraw.py, in my example) */
#include <stdio.h>
#include <xmms/plugin.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>

// Forward declarations
static void netserve_init(void);
static void netserve_cleanup(void);
static void netserve_about(void);
static void netserve_configure(void);
static void netserve_playback_start(void);
static void netserve_playback_stop(void);
static void netserve_render_freq(gint16 freq_data[2][256]);

// Callback functions
VisPlugin netserve_vtable = {
  0, // Handle, filled in by xmms
  0, // Filename, filled in by xmms

  0,                     // Session ID
  "Network Server Plugin",       // description

  0, // # of PCM channels for render_pcm()
  1, // # of freq channels wanted for render_freq()

  netserve_init,           // Called when plugin is enabled
  netserve_cleanup,        // Called when plugin is disabled
  netserve_about,          // Show the about box
  netserve_configure,      // Show the configure box
  0,                     // Called to disable plugin, filled in by xmms
  netserve_playback_start, // Called when playback starts
  netserve_playback_stop,  // Called when playback stops
  0,                     // Render the PCM data, must return quickly
  netserve_render_freq     // Render the freq data, must return quickly
};

// XMMS entry point
VisPlugin *get_vplugin_info(void)
{
  return &netserve_vtable;
}

static int socket_;
static struct sockaddr_in destAddr_;

static void netserve_init(void) 
{
    struct sockaddr_in addr;
    struct hostent *hp;
    char * host = "127.0.0.1";
    socket_ = socket(AF_INET, SOCK_DGRAM, 0);
    if (socket_ == -1)
        {
        fprintf(stderr,"ERROR: netserve_init failed to create a socket\n");
        perror("socket");
        return;
        }
    memset(&addr, 0, sizeof(addr));
    addr.sin_addr.s_addr = INADDR_ANY;
    addr.sin_family = PF_INET;
    addr.sin_port = htons(0);
    if (bind(socket_, (struct sockaddr *) &addr, sizeof(addr)) < 0)
        {
        fprintf(stderr,"ERROR: netserve_init failed to bind to port %d\n",
                0);
        perror("bind");
        socket_ = -1;
        return;
        }
    if (!(hp = gethostbyname(host)))
        {
        fprintf(stderr,"ERROR: netserve_init::setDestination failed "
            "to get address for \"%s\"\n", host);
        perror("gethostbyname");
        return;
        }
    memset(&destAddr_, 0, sizeof(destAddr_));
    memcpy(&destAddr_.sin_addr, hp->h_addr, hp->h_length);
    destAddr_.sin_family = hp->h_addrtype;
    destAddr_.sin_port = htons(10000);
}

static void netserve_cleanup(void)
{
}

static void netserve_about(void)
{
}

static void netserve_configure(void)
{
}

static void netserve_playback_start(void)
{
}

static void netserve_playback_stop(void)
{
}

static void netserve_render_freq(gint16 freq_data[2][256])
{
    sendto(socket_, (void *)freq_data, 512*sizeof(gint16), 0, (struct sockaddr *)&destAddr_,
            sizeof(destAddr_));
}



