/*
 * XFCE plugin for the MOC player
 * 
 * Control the MOC (Media On Console) player from the XFCE panel!
 * 
 * Author: Jakub Krauz
 * E-mail: jakub.krauz@volny.cz
 * Univerzity of West Bohemia
 * Department of Computer Science and Engineering
 * Pilsen, 2012
 */

#include <errno.h>
#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>

#include "logger.h"
#include "protocol.h"


/* Function prototypes */
static void wait_for_data(int sock);



/**
 * Get an integer value from the socket.
 * @param sock Socket descriptor to read from.
 * @param value Pointer to integer in which to save the value.
 * @return 1 on succes, 0 on error
 */
int get_int(int sock, int *value)
{
	int res;

	res = recv(sock, value, sizeof(int), 0);
	if (res == -1)
		logit(ERR, "Protocol: recv() failed when getting int: %s", strerror(errno));
  
	return (res == sizeof(int)) ? 1 : 0;
}


/**
 * Get an integer value from the socket which arrives after the EV_DATA value.
 * @param sock Socket descriptor to read from.
 * @return read value on success, -1 on error
 */
int get_data_int(int sock) {
  int data;

  wait_for_data(sock);
  if (!get_int(sock, &data))
    return -1;
  
  return data;
}


/**
 * Send an integer value to the socket.
 * @param sock Socket descriptor to write in.
 * @param value Integer value to be written.
 * @return 1 on success, 0 on error
 */
int send_int(int sock, int value)
{
	int res;

	res = send(sock, &value, sizeof(int), 0);
	if (res == -1)
		logit(ERR, "Protocol: send() failed: %s", strerror(errno));
  
	return (res == sizeof(int)) ? 1 : 0;
}


/**
 * Ping the moc server.
 * @param sock Socket descriptor to ping.
 * @return 1 on success, 0 on error (no or bad server response)
 */
int ping_server(int sock) {
  int event;

  send_int(sock, CMD_PING);
  if (!get_int(sock, &event)) {
    logit(WARN, "Protocol: error receiving pong response.");
    return 0;
  }

  return (event == EV_PONG) ? 1 : 0;
}


/**
 * Read data from the socket until value equals EV_DATA.
 * @param sock Socket descriptor to read from.
 */
static void wait_for_data(int sock) {
  int event;

  do
  {
    if (!get_int(sock, &event))
      return;
  }
  while (event != EV_DATA);
}

