/*
 * miniJSS - Main header file
 * Programmed and designed by Matti 'ccr' Hamalainen
 * (C) Copyright 2006-2007 Tecnic Software productions (TNSP)
 */
#ifndef JSS_H
#define JSS_H

#include "dmlib.h"

#ifdef __cplusplus
extern "C" {
#endif


/* Locking
 */
#ifdef JSS_SUP_THREADS
#    define JSS_LOCK(Q) dmMutexLock((Q)->mutex)
#    define JSS_UNLOCK(Q) dmMutexUnlock((Q)->mutex)
#else
#    warning DANGER! JSS threads support not included!
#    define JSS_LOCK(Q)
#    define JSS_UNLOCK(Q)
#endif


// Global settings
#define jsetNChannels   (64)        // Max number of channels
#define jsetNotSet      (-1)        // A global "not set" constant
#define jsetMinVol      (0)
#define jsetMaxVol      (255)

// Sample instrument flags
#define jsfLooped       (0x01)      // Is sample looped
#define jsfBiDi         (0x02)      // Bi-directional loop?
#define jsf16bit        (0x04)      // 16-bit?

#define JSFSET(a, b)    do { a |= b; } while (0)
#define JSFUNSET(a, b)  do { a &= (0xff ^ b); } while (0)

// Panning position
#define jchPanLeft      (0x00)      // Leftmost pan
#define jchPanMiddle    (0x80)      // Center pan
#define jchPanRight     (0xff)      // Rightmost pan

// Audio formats
enum
{
    JSS_AUDIO_U8,           // 8-bit formats
    JSS_AUDIO_S8,
    JSS_AUDIO_U16,          // 16-bit formats
    JSS_AUDIO_S16,
    JSS_AUDIO_U32,          // 32-bit (24+padding)
    JSS_AUDIO_S32
} JSS_AUDIO_FMT;


enum
{
    JSS_AUDIO_MONO = 1,
    JSS_AUDIO_STEREO = 2
} JSS_AUDIO_CHANNELS;


/* System initialization and shutdown
 */
int    jssInit(void);       // Initialization. Call before anything else!
int    jssClose(void);      // Shutdown. Do not call ANY JSS routines after this!


/* Error handling routines and related variables
 */
extern BOOL     jssWarningIsFatal,  // if TRUE, warnings are considered fatal -> function returns
                jssErrorIsFatal;    // if FALSE, error is considered non-fatal. this may cause strange problems.

#ifndef JSS_LIGHT
extern void     (*jssError)(int code, const char *filename, int linen, const char *fmt, ...);
extern void     (*jssWarning)(int code, const char *filename, int linen, const char *fmt, ...);
#endif


/* If JSS_LIGHT is NOT defined, we add code for verbose error-, warning-
 * and debug-messages. Otherwise use a macro stub.
 */
#ifndef JSS_LIGHT
#  define JSSERROR(MEVAL, MRET, ...) do { jssError(MEVAL, __FILE__, (int) __LINE__, __VA_ARGS__); if (jssErrorIsFatal) return MRET; } while (0)
#  define JSSWARNING(MEVAL, MRET, ...) do { jssWarning(MEVAL, __FILE__, (int) __LINE__, __VA_ARGS__); if (jssWarningIsFatal) return MRET; } while (0)
#  ifdef JSS_DEBUG
#    define JSSDEBUG(...) do { fprintf(stderr, "[%s:%d]: ", __FILE__, (int) __LINE__); fprintf(stderr, __VA_ARGS__); } while (0)
#  else
#    define JSSDEBUG(...) do { } while (0)
#  endif // NDEBUG
#else
#  define JSSERROR(MEVAL, MRET, ...) do { return MRET; } while (0)
#  define JSSWARNING(MEVAL, MRET, ...) do { } while (0)
#  define JSSDEBUG(...) do { } while (0)
#endif // JSS_LIGHT


#ifdef __cplusplus
}
#endif

#endif // JSS_H
