/*  Audacious-DUMB Plug-in to enable audacious to use DUMB for IT/XM/S3M/MOD files
 *  Copyright (C) 2006-2011 Christian Birchinger
 *  Audacious port based on previous plugins for XMMS and BMP
 *  Copyright (C) 2002-2003  Ben Davis
 *  Incorporates code from the wav plug-in,
 *  Copyright (C) 1998-2000  Peter Alm, Mikael Alm, Olle Hallnas, Thomas Nilsson and 4Front Technologies
 *
 *  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.
 */
#ifndef INC_DUMB_audacious_H
#define INC_DUMB_audacious_H

#include <dumb.h>

#if DUMB_VERSION < 903
#error You must get DUMB v0.9.3 or later. Prior versions do
#error not have the thread safety required by this plug-in.
#endif

#define VERSION "0.82"
#define VERSIONSTRING "DUMB Audio Plugin " VERSION

#include <pthread.h>

#include <stdlib.h>
#include <string.h>
#include <stdio.h>

#include <audacious/misc.h>
#include <audacious/plugin.h>
#include <libaudgui/libaudgui.h>
#include <libaudgui/libaudgui-gtk.h>
#include <audacious/preferences.h>
#include <libaudcore/audstrings.h>

extern InputPlugin duh_ip;

typedef struct
{
	DUH *duh;
	DUH_SIGRENDERER *file;
	short channels, bits_per_sample;
	long samples_per_sec;
	int seek_to;
	int eof;
	pid_t pid;
}
DuhFile;

static gboolean duh_init(void);
static void duh_cleanup(void);
static int is_our_file_from_vfs(const gchar *filename, VFSFile *file);
static gboolean play_start(InputPlayback *playback, const gchar *filename, VFSFile *file, gint start_time, gint stop_time, gboolean pause);
static void stop(InputPlayback *data);
static void mseek(InputPlayback *data, gint time);
static void duh_pause(InputPlayback *data, gboolean p);

static Tuple *duh_probe_for_tuple(const gchar *filename, VFSFile *fd);
static void file_info_box(const gchar *filename);
static void duh_about(void);

static PluginPreferences preferences;

/* duh_universal_load_vfs() */
#define UNIREAD_MOD (1 << 0)
#define	UNIREAD_DUH (1 << 1)
#define UNIREAD_ALL (UNIREAD_MOD | UNIREAD_DUH)

typedef DUH *(*uniread_func_t)(DUMBFILE *filedumb);

typedef struct
{
	const uniread_func_t  read;
	const char            *ext;
	const short           testmask;
	const char            *description;
} uniread_struct_t;

const uniread_struct_t uniread[] =
{
	{read_duh, "duh", UNIREAD_DUH, "DUMB Tracker Module"},
	{dumb_read_it, "it", UNIREAD_MOD, "ImpulseTracker Module"},
	{dumb_read_xm, "xm", UNIREAD_MOD, "FastTracker Extended Module"},
	{dumb_read_s3m, "s3m", UNIREAD_MOD, "ScreamTracker 3 Module"},
	{dumb_read_mod, "mod", UNIREAD_MOD, "Sound/Noise/Protracker Module"}
};

enum {  COL_N = 0,
	COL_NAME,
	COL_FILE,
	NUM_COLS
};

typedef struct {
	gboolean disable_amiga_mods;
	gint output_frequency;
	gboolean use_custom_title;
} dumb_config_t;

extern dumb_config_t dumb_config;

/* Module files have their magic deep inside the file, at offset 1080; source: http://www.onicos.com/staff/iz/formats/mod.html and information by Michael Doering from UADE */
#define MOD_MAGIC_PROTRACKER4   (unsigned char [4]) { 0x4D, 0x2E, 0x4B, 0x2E }  // "M.K." - Protracker 4 channel
#define MOD_MAGIC_PROTRACKER4X  (unsigned char [4]) { 0x4D, 0x21, 0x4B, 0x21 }  // "M!K!" - Protracker 4 channel
#define MOD_MAGIC_NOISETRACKER  (unsigned char [4]) { 0x4D, 0x26, 0x4B, 0x21 }  // "M&K!" - Noisetracker 1.3 by Kaktus & Mahoney
#define MOD_MAGIC_STARTRACKER4  (unsigned char [4]) { 0x46, 0x4C, 0x54, 0x34 }  // "FLT4" - Startracker 4 channel (Startrekker/AudioSculpture)
#define MOD_MAGIC_STARTRACKER8  (unsigned char [4]) { 0x46, 0x4C, 0x54, 0x38 }  // "FLT8" - Startracker 8 channel (Startrekker/AudioSculpture) 
#define MOD_MAGIC_STARTRACKER4X (unsigned char [4]) { 0x45, 0x58, 0x30, 0x34 }  // "EX04" - Startracker 4 channel (Startrekker/AudioSculpture)
#define MOD_MAGIC_STARTRACKER8X (unsigned char [4]) { 0x45, 0x58, 0x30, 0x38 }  // "EX08" - Startracker 8 channel (Startrekker/AudioSculpture) 
#define MOD_MAGIC_FASTTRACKER4  (unsigned char [4]) { 0x34, 0x43, 0x48, 0x4E }  // "4CHN" - Fasttracker 4 channel
#define MOD_MAGIC_FASTTRACKER6  (unsigned char [4]) { 0x36, 0x43, 0x48, 0x4E }  // "6CHN" - Fasttracker 6 channel
#define MOD_MAGIC_FASTTRACKER8  (unsigned char [4]) { 0x38, 0x43, 0x48, 0x4E }  // "8CHN" - Fasttracker 8 channel

#define S3M_MAGIC       (unsigned char [4]) { 0x53, 0x43, 0x52, 0x4D }                  /* This is the SCRM string at offset 44 to 47 in the S3M header */

/* These nicer formats have the magic bytes at the front of the file where they belong */
#define XM_MAGIC        (unsigned char [4]) { 0x45, 0x78, 0x74, 0x65 }                  /* Exte(nded Module) */
#define IT_MAGIC        (unsigned char [4]) { 0x49, 0x4D, 0x50, 0x4D }                  /* IMPM */

#endif /* INC_DUMB_audacious_H */
