/***************************************************************************
                  simplemusic.c - Simple music playing plugin for eboxy
                             -------------------
    begin                : Sun Oct 13 2002
    copyright            : (C) 2002 by Paul Eggleton
    email                : bluelightning@bluelightning.org
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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.                                   *
 *                                                                         *
 ***************************************************************************/

#include "eboxyplugin.h"
#include "pluginconstants.h"
#include "string.h"
#include "SDL.h"
#include "SDL_mixer.h"

/* Globals */
Mix_Music *music = NULL;
char *musicfile = NULL;
int autorepeat = 0;

/* Prototypes */
char *sm_play(const char *sender, int numargs, const char *args[]);
char *sm_pause(const char *sender, int numargs, const char *args[]);
char *sm_stop(const char *sender, int numargs, const char *args[]);
char *sm_getfile(const char *sender);
int sm_setfile(const char *sender, const char *value);
char *sm_getautorepeat(const char *sender);
int sm_setautorepeat(const char *sender, const char *value);

void sm_musicdone(void);

int strtobool(const char *str);
const char *booltostr(int n);

/* Implementation */

int ebplugin_init(void) {
  int rc = 0;

  /* Audio parameters */
  int audio_rate = 44100;
  Uint16 audio_format = AUDIO_S16; /* 16-bit stereo */
  int audio_channels = 2;
  int audio_buffers = 4096;

  /* Initialise audio */
  if(Mix_OpenAudio(audio_rate, audio_format, audio_channels, audio_buffers)) {
    fprintf(stderr, "simplemusic: Unable to open audio!\n");
    return 1;
  }

  /* Set version info for the plugin */
  setPluginInfo("SimpleMusic", "0.2");

  /* Find out what audio parameters we actually got (FIXME: should probably check this) */
  Mix_QuerySpec(&audio_rate, &audio_format, &audio_channels);

  /* Register an object to be used in scripts */
  rc = registerObject("simplemusic");
  if(rc)
    return rc;
  rc = registerMethodDL("simplemusic", "play", 0, "sm_play");
  if(rc)
    return rc;
  rc = registerMethodDL("simplemusic", "pause", 0, "sm_pause");
  if(rc)
    return rc;
  rc = registerMethodDL("simplemusic", "stop", 0, "sm_stop");
  if(rc)
    return rc;
  rc = registerPropertyDL("simplemusic", "file", "sm_getfile", "sm_setfile");
  if(rc)
    return rc;
  rc = registerPropertyDL("simplemusic", "autorepeat", "sm_getautorepeat", "sm_setautorepeat");
  if(rc)
    return rc;

  /* Success */
  return 0;
}

int ebplugin_message(int msgcode, void *msgdata) {
  return 0;     /* return 0 here for future compatibility */
}

void ebplugin_deinit(void) {
  /* Stop music (if playing) */
  sm_stop("", 0, NULL);
  /* Free allocated memory */
  if(musicfile)
    free(musicfile);
  /* Close audio device */
  Mix_CloseAudio();
}

char *sm_play(const char *sender, int numargs, const char *args[]) {
  if(!musicfile) {
    fprintf(stderr, "SimpleMusic: no file to play specified\n");
    return NULL;
  }
  if(!music) {
    /* Actually loads up the music */
    music = Mix_LoadMUS(musicfile);

    if(music) {
      /* This begins playing the music - the first argument is a
         pointer to Mix_Music structure, and the second is how many
         times you want it to loop (use -1 for infinite, and 0 to
         have it just play once) */
      if(Mix_PlayMusic(music, 0) != 0) {
        /* Error occurred */
        fprintf(stderr, "SimpleMusic: %s\n", Mix_GetError());
        return NULL;
      }

      /* We want to know when our music has stopped playing so we
         can free it up and set 'music' back to NULL.  SDL_Mixer
         provides us with a callback routine we can use to do
         exactly that */
      Mix_HookMusicFinished(sm_musicdone);
    }
    else {
      /* Error occurred */
      fprintf(stderr, "SimpleMusic: %s\n", Mix_GetError());
      return NULL;
    }
  }
  else if(Mix_PausedMusic()) {
    Mix_ResumeMusic();
  }
  else {
    Mix_RewindMusic();
    Mix_PlayMusic(music, 0);
  }
  return NULL;
}         

char *sm_pause(const char *sender, int numargs, const char *args[]) {
  if(music) {
    /* Pause the music */
    if(Mix_PausedMusic())
      Mix_ResumeMusic();
    else
      Mix_PauseMusic();
  }
  return NULL;
}

char *sm_stop(const char *sender, int numargs, const char *args[]) {
  if(music) {
    /* Stop the music from playing */
    Mix_HaltMusic();
    /* Unload the music from memory */
    Mix_FreeMusic(music);
    music = NULL;
  }
  return NULL;
}

char *sm_getfile(const char *sender) {
  return strdup(musicfile);
}

int sm_setfile(const char *sender, const char *value) {
  sm_stop("", 0, NULL);
  if(musicfile)
    free(musicfile);
  musicfile = strdup(value);
  return 0;
}

char *sm_getautorepeat(const char *sender) {
  return strdup(booltostr(autorepeat));
}

int sm_setautorepeat(const char *sender, const char *value) {
  autorepeat = strtobool(value);
  return 0;
}

/* This is the function that we told SDL_Mixer to call when the music
   was finished. */
void sm_musicdone(void) {
  if(autorepeat)
    sm_play("", 0, NULL);
  else {
    sm_stop("", 0, NULL);
    fireEvent("simplemusic", "OnFinish");
  }
}

/* Convert a string value into a boolean */
int strtobool(const char *str) {
  if(strcasecmp(str, "true") == 0 || strcasecmp(str, "on") == 0 || strcasecmp(str, "yes") == 0 || atoi(str) != 0)
    return 1;
  else
    return 0;
}

/* Convert an integer to a string */
const char *booltostr(int n) {
  if(n)
    return "1";
  else
    return "0";
}


syntax highlighted by Code2HTML, v. 0.9.1