/*  Copyright (c) MediaArea.net SARL. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license that can
 *  be found in the License.html file in the root of the source tree.
 */

//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
// Public DLL interface implementation
// Wrapper for MediaInfo Library
// Please see MediaInfo.h for help
//
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/

#ifndef MediaInfoDLL_StaticH
#define MediaInfoDLL_StaticH

//***************************************************************************
// Platforms (from libzen)
//***************************************************************************

/*---------------------------------------------------------------------------*/
/*Win32*/
#if defined(__NT__) || defined(_WIN32) || defined(WIN32)
#ifndef WIN32
#define WIN32
#endif
#ifndef _WIN32
#define _WIN32
#endif
#ifndef __WIN32__
#define __WIN32__ 1
#endif
#endif

/*---------------------------------------------------------------------------*/
/*Win64*/
#if defined(_WIN64) || defined(WIN64)
#ifndef WIN64
#define WIN64
#endif
#ifndef _WIN64
#define _WIN64
#endif
#ifndef __WIN64__
#define __WIN64__ 1
#endif
#endif

/*---------------------------------------------------------------------------*/
/*Windows*/
#if defined(WIN32) || defined(WIN64)
#ifndef WINDOWS
#define WINDOWS
#endif
#ifndef _WINDOWS
#define _WINDOWS
#endif
#ifndef __WINDOWS__
#define __WINDOWS__ 1
#endif
#endif

/*---------------------------------------------------------------------------*/
/*Unix (Linux, HP, Sun, BeOS...)*/
#if defined(UNIX) || defined(_UNIX) || defined(__UNIX__)                    \
|| defined(__unix) || defined(__unix__)                                 \
|| defined(____SVR4____) || defined(__LINUX__) || defined(__sgi)        \
|| defined(__hpux) || defined(sun) || defined(__SUN__) || defined(_AIX) \
|| defined(__EMX__) || defined(__VMS) || defined(__BEOS__)
#ifndef UNIX
#define UNIX
#endif
#ifndef _UNIX
#define _UNIX
#endif
#ifndef __UNIX__
#define __UNIX__ 1
#endif
#endif

/*---------------------------------------------------------------------------*/
/*MacOS Classic*/
#if defined(macintosh)
#ifndef MACOS
#define MACOS
#endif
#ifndef _MACOS
#define _MACOS
#endif
#ifndef __MACOS__
#define __MACOS__ 1
#endif
#endif

/*---------------------------------------------------------------------------*/
/*MacOS X*/
#if defined(__APPLE__) && defined(__MACH__)
#ifndef MACOSX
#define MACOSX
#endif
#ifndef _MACOSX
#define _MACOSX
#endif
#ifndef __MACOSX__
#define __MACOSX__ 1
#endif
#endif

/*Test of targets*/
#if defined(WINDOWS) && defined(UNIX) && defined(MACOS) && defined(MACOSX)
#pragma message Multiple platforms???
#endif

#if !defined(WIN32) && !defined(UNIX) && !defined(MACOS) && !defined(MACOSX)
#pragma message No known platforms, assume default
#endif

/*-------------------------------------------------------------------------*/
#undef MEDIAINFO_EXP
#if defined(__WINDOWS__) && !defined(__MINGW32__) //MinGW32 does not support _declspec
#ifdef MEDIAINFO_DLL_EXPORT
#if defined(MEDIAINFODLL_EXPORTS_NODLLEXPORT)
#define MEDIAINFO_EXP extern
#else //!defined(MEDIAINFODLL_EXPORTS_NODLLEXPORT)
#define MEDIAINFO_EXP extern _declspec(dllexport)
#endif //!defined(MEDIAINFODLL_EXPORTS_NODLLEXPORT)
#else
#define MEDIAINFO_EXP extern _declspec(dllimport)
#endif
#else //defined(__WINDOWS__) && !defined(__MINGW32__)
#if __GNUC__ >= 4
#define MEDIAINFO_EXP __attribute__ ((visibility("default")))
#else
#define MEDIAINFO_EXP
#endif
#endif //defined(__WINDOWS__) && !defined(__MINGW32__)

#if !defined(__WINDOWS__)
#define __stdcall //Supported only on windows
#endif //!defined(__WINDOWS__)

/*-------------------------------------------------------------------------*/
#include <limits.h>
#include <stddef.h>

/*-------------------------------------------------------------------------*/
/*8-bit int                                                                */
#if UCHAR_MAX==0xff
#undef  MAXTYPE_INT
#define MAXTYPE_INT 8
typedef unsigned char       MediaInfo_int8u;
#else
#pragma message This machine has no 8-bit integertype?
#endif
/*-------------------------------------------------------------------------*/

/*-------------------------------------------------------------------------*/
/*64-bit int                                                               */
#if defined(__MINGW32__) || defined(__CYGWIN32__) || defined(__UNIX__) || defined(__MACOSX__)
#undef  MAXTYPE_INT
#define MAXTYPE_INT 64
typedef unsigned long long  MediaInfo_int64u;
#elif defined(__WIN32__) ||  defined(_WIN32)
#undef  MAXTYPE_INT
#define MAXTYPE_INT 64
typedef unsigned __int64    MediaInfo_int64u;
#else
#pragma message This machine has no 64-bit integer type?
#endif
/*-------------------------------------------------------------------------*/

/** @brief Kinds of Stream */
typedef enum MediaInfo_stream_t
{
    MediaInfo_Stream_General,
    MediaInfo_Stream_Video,
    MediaInfo_Stream_Audio,
    MediaInfo_Stream_Text,
    MediaInfo_Stream_Other,
    MediaInfo_Stream_Image,
    MediaInfo_Stream_Menu,
    MediaInfo_Stream_Max
} MediaInfo_stream_C;

/** @brief Kinds of Info */
typedef enum MediaInfo_info_t
{
    MediaInfo_Info_Name,
    MediaInfo_Info_Text,
    MediaInfo_Info_Measure,
    MediaInfo_Info_Options,
    MediaInfo_Info_Name_Text,
    MediaInfo_Info_Measure_Text,
    MediaInfo_Info_Info,
    MediaInfo_Info_HowTo,
    MediaInfo_Info_Max
} MediaInfo_info_C;

/** @brief Option if InfoKind = Info_Options */
typedef enum MediaInfo_infooptions_t
{
    MediaInfo_InfoOption_ShowInInform,
    MediaInfo_InfoOption_Reserved,
    MediaInfo_InfoOption_ShowInSupported,
    MediaInfo_InfoOption_TypeOfValue,
    MediaInfo_InfoOption_Max
} MediaInfo_infooptions_C;

/** @brief File opening options */
typedef enum MediaInfo_fileoptions_t
{
    MediaInfo_FileOption_Nothing     = 0x00,
    MediaInfo_FileOption_NoRecursive = 0x01,
    MediaInfo_FileOption_CloseAll    = 0x02,
    MediaInfo_FileOption_Max         = 0x04
} MediaInfo_fileoptions_C;

#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
    
    /***************************************************************************/
    /*! \file MediaInfoDll.h
     \brief DLL wrapper for MediaInfo.h.
     
     DLL wrapper for MediaInfo.h \n
     Can be used for C and C++\n
     "Handle" replaces class definition
     */
    /***************************************************************************/
    
#if defined(MEDIAINFO_DLL_EXPORT) || (defined(UNICODE) || defined(_UNICODE)) //DLL construction or Unicode
    /** @brief A 'new' MediaInfo interface, return a Handle, don't forget to delete it after using it*/
    MEDIAINFO_EXP void*             __stdcall MediaInfo_New (); /*you must ALWAYS call MediaInfo_Delete(Handle) in order to free memory*/
    /** @brief A 'new' MediaInfo interface (with a quick init of useful options : "**VERSION**;**APP_NAME**;**APP_VERSION**", but without debug information, use it only if you know what you do), return a Handle, don't forget to delete it after using it*/
    MEDIAINFO_EXP void*             __stdcall MediaInfo_New_Quick (const wchar_t* File, const wchar_t* Options); /*you must ALWAYS call MediaInfo_Delete(Handle) in order to free memory*/
    /** @brief Delete a MediaInfo interface*/
    MEDIAINFO_EXP void              __stdcall MediaInfo_Delete (void* Handle);
    /** @brief Wrapper for MediaInfoLib::MediaInfo::Open (with a filename)*/
    MEDIAINFO_EXP size_t            __stdcall MediaInfo_Open (void* Handle, const wchar_t* File);
    /** @brief Wrapper for MediaInfoLib::MediaInfo::Open (with a buffer) */
    MEDIAINFO_EXP size_t            __stdcall MediaInfo_Open_Buffer (void* Handle, const unsigned char* Begin, size_t Begin_Size, const unsigned char* End, size_t End_Size); /*return Handle*/
    /** @brief Wrapper for MediaInfoLib::MediaInfo::Open (with a buffer, Init) */
    MEDIAINFO_EXP size_t            __stdcall MediaInfo_Open_Buffer_Init (void* Handle, MediaInfo_int64u File_Size, MediaInfo_int64u File_Offset);
    /** @brief Wrapper for MediaInfoLib::MediaInfo::Open (with a buffer, Continue) */
    MEDIAINFO_EXP size_t            __stdcall MediaInfo_Open_Buffer_Continue (void* Handle, MediaInfo_int8u* Buffer, size_t Buffer_Size);
    /** @brief Wrapper for MediaInfoLib::MediaInfo::Open (with a buffer, Continue_GoTo_Get) */
    MEDIAINFO_EXP MediaInfo_int64u  __stdcall MediaInfo_Open_Buffer_Continue_GoTo_Get (void* Handle);
    /** @brief Wrapper for MediaInfoLib::MediaInfo::Open (with a buffer, Finalize) */
    MEDIAINFO_EXP size_t            __stdcall MediaInfo_Open_Buffer_Finalize (void* Handle);
    /** @brief Wrapper for MediaInfoLib::MediaInfo::Open (NextPacket) */
    MEDIAINFO_EXP size_t            __stdcall MediaInfo_Open_NextPacket (void* Handle);
    /** @brief Wrapper for MediaInfoLib::MediaInfo::Save */
    MEDIAINFO_EXP size_t            __stdcall MediaInfo_Save (void* Handle);
    /** @brief Wrapper for MediaInfoLib::MediaInfo::Close */
    MEDIAINFO_EXP void              __stdcall MediaInfo_Close (void* Handle);
    /** @brief Wrapper for MediaInfoLib::MediaInfo::Inform */
    MEDIAINFO_EXP const wchar_t*    __stdcall MediaInfo_Inform (void* Handle, size_t Reserved); /*Default : Reserved=0*/
    /** @brief Wrapper for MediaInfoLib::MediaInfo::Get */
    MEDIAINFO_EXP const wchar_t*    __stdcall MediaInfo_GetI (void* Handle, MediaInfo_stream_C StreamKind, size_t StreamNumber, size_t Parameter, MediaInfo_info_C InfoKind); /*Default : InfoKind=Info_Text*/
    /** @brief Wrapper for MediaInfoLib::MediaInfo::Get */
    MEDIAINFO_EXP const wchar_t*    __stdcall MediaInfo_Get (void* Handle, MediaInfo_stream_C StreamKind, size_t StreamNumber, const wchar_t* Parameter, MediaInfo_info_C InfoKind, MediaInfo_info_C SearchKind); /*Default : InfoKind=Info_Text, SearchKind=Info_Name*/
    /** @brief Wrapper for MediaInfoLib::MediaInfo::Set */
    MEDIAINFO_EXP size_t            __stdcall MediaInfo_SetI (void* Handle, const wchar_t* ToSet, MediaInfo_stream_C StreamKind, size_t StreamNumber, size_t Parameter, const wchar_t* OldParameter);
    /** @brief Wrapper for MediaInfoLib::MediaInfo::Set */
    MEDIAINFO_EXP size_t            __stdcall MediaInfo_Set (void* Handle, const wchar_t* ToSet, MediaInfo_stream_C StreamKind, size_t StreamNumber, const wchar_t* Parameter, const wchar_t* OldParameter);
    /** @brief Wrapper for MediaInfoLib::MediaInfo::Output_Buffer_Get */
    MEDIAINFO_EXP size_t            __stdcall MediaInfo_Output_Buffer_Get (void* Handle, const wchar_t* Value);
    /** @brief Wrapper for MediaInfoLib::MediaInfo::Output_Buffer_Get */
    MEDIAINFO_EXP size_t            __stdcall MediaInfo_Output_Buffer_GetI (void* Handle, size_t Pos);
    /** @brief Wrapper for MediaInfoLib::MediaInfo::Option */
    MEDIAINFO_EXP const wchar_t*    __stdcall MediaInfo_Option (void* Handle, const wchar_t* Option, const wchar_t* Value);
    /** @brief Wrapper for MediaInfoLib::MediaInfo::State_Get */
    MEDIAINFO_EXP size_t            __stdcall MediaInfo_State_Get (void* Handle);
    /** @brief Wrapper for MediaInfoLib::MediaInfo::Count_Get */
    MEDIAINFO_EXP size_t            __stdcall MediaInfo_Count_Get (void* Handle, MediaInfo_stream_C StreamKind, size_t StreamNumber); /*Default : StreamNumber=-1*/
#else //defined(MEDIAINFO_DLL_EXPORT) || (defined(UNICODE) || defined(_UNICODE))
#define MediaInfo_New               MediaInfoA_New
#define MediaInfo_New_Quick         MediaInfoA_New_Quick
#define MediaInfo_Delete            MediaInfoA_Delete
#define MediaInfo_Open              MediaInfoA_Open
#define MediaInfo_Open_Buffer       MediaInfoA_Open_Buffer
#define MediaInfo_Open_Buffer_Init              MediaInfoA_Open_Buffer_Init
#define MediaInfo_Open_Buffer_Continue          MediaInfoA_Open_Buffer_Continue
#define MediaInfo_Open_Buffer_Continue_GoTo_Get MediaInfoA_Open_Buffer_Continue_GoTo_Get
#define MediaInfo_Open_Buffer_Finalize          MediaInfoA_Open_Buffer_Finalize
#define MediaInfo_Open_NextPacket               MediaInfoA_Open_NextPacket
#define MediaInfo_Save              MediaInfoA_Save
#define MediaInfo_Close             MediaInfoA_Close
#define MediaInfo_Inform            MediaInfoA_Inform
#define MediaInfo_GetI              MediaInfoA_GetI
#define MediaInfo_Get               MediaInfoA_Get
#define MediaInfo_SetI              MediaInfoA_SetI
#define MediaInfo_Set               MediaInfoA_Set
#define MediaInfo_Output_Buffer_Get MediaInfoA_Output_Buffer_Get
#define MediaInfo_Output_Buffer_GetI MediaInfoA_Output_Buffer_GetI
#define MediaInfo_Option            MediaInfoA_Option
#define MediaInfo_State_Get         MediaInfoA_State_Get
#define MediaInfo_Count_Get         MediaInfoA_Count_Get
#endif //defined(MEDIAINFO_DLL_EXPORT) || (defined(UNICODE) || defined(_UNICODE))
    
    /** @brief A 'new' MediaInfo interface, return a Handle, don't forget to delete it after using it*/
    MEDIAINFO_EXP void*             __stdcall MediaInfoA_New (); /*you must ALWAYS call MediaInfo_Delete(Handle) in order to free memory*/
    /** @brief A 'new' MediaInfo interface (with a quick init of useful options : "**VERSION**;**APP_NAME**;**APP_VERSION**", but without debug information, use it only if you know what you do), return a Handle, don't forget to delete it after using it*/
    MEDIAINFO_EXP void*             __stdcall MediaInfoA_New_Quick (const char* File, const char* Options); /*you must ALWAYS call MediaInfo_Delete(Handle) in order to free memory*/
    /** @brief Delete a MediaInfo interface*/
    MEDIAINFO_EXP void              __stdcall MediaInfoA_Delete (void* Handle);
    /** @brief Wrapper for MediaInfoLib::MediaInfo::Open (with a filename)*/
    MEDIAINFO_EXP size_t            __stdcall MediaInfoA_Open (void* Handle, const char* File); /*you must ALWAYS call MediaInfo_Close(Handle) in order to free memory*/
    /** @brief Wrapper for MediaInfoLib::MediaInfo::Open (with a buffer) */
    MEDIAINFO_EXP size_t            __stdcall MediaInfoA_Open_Buffer (void* Handle, const unsigned char* Begin, size_t Begin_Size, const unsigned char* End, size_t End_Size); /*return Handle*/
    /** @brief Wrapper for MediaInfoLib::MediaInfo::Open (with a buffer, Init) */
    MEDIAINFO_EXP size_t            __stdcall MediaInfoA_Open_Buffer_Init (void* Handle, MediaInfo_int64u File_Size, MediaInfo_int64u File_Offset);
    /** @brief Wrapper for MediaInfoLib::MediaInfo::Open (with a buffer, Continue) */
    MEDIAINFO_EXP size_t            __stdcall MediaInfoA_Open_Buffer_Continue (void* Handle, MediaInfo_int8u* Buffer, size_t Buffer_Size);
    /** @brief Wrapper for MediaInfoLib::MediaInfo::Open (with a buffer, Continue_GoTo_Get) */
    MEDIAINFO_EXP MediaInfo_int64u  __stdcall MediaInfoA_Open_Buffer_Continue_GoTo_Get (void* Handle);
    /** @brief Wrapper for MediaInfoLib::MediaInfo::Open (with a buffer, Finalize) */
    MEDIAINFO_EXP size_t            __stdcall MediaInfoA_Open_Buffer_Finalize (void* Handle);
    /** @brief Wrapper for MediaInfoLib::MediaInfo::Open (NextPacket) */
    MEDIAINFO_EXP size_t            __stdcall MediaInfoA_Open_NextPacket (void* Handle);
    /** @brief Wrapper for MediaInfoLib::MediaInfo::Save */
    MEDIAINFO_EXP size_t            __stdcall MediaInfoA_Save (void* Handle);
    /** @brief Wrapper for MediaInfoLib::MediaInfo::Close */
    MEDIAINFO_EXP void              __stdcall MediaInfoA_Close (void* Handle);
    /** @brief Wrapper for MediaInfoLib::MediaInfo::Inform */
    MEDIAINFO_EXP const char*       __stdcall MediaInfoA_Inform (void* Handle, size_t Reserved); /*Default : Reserved=MediaInfo_*/
    /** @brief Wrapper for MediaInfoLib::MediaInfo::Get */
    MEDIAINFO_EXP const char*       __stdcall MediaInfoA_GetI (void* Handle, MediaInfo_stream_C StreamKind, size_t StreamNumber, size_t Parameter, MediaInfo_info_C InfoKind); /*Default : InfoKind=Info_Text*/
    /** @brief Wrapper for MediaInfoLib::MediaInfo::Get */
    MEDIAINFO_EXP const char*       __stdcall MediaInfoA_Get (void* Handle, MediaInfo_stream_C StreamKind, size_t StreamNumber, const char* Parameter, MediaInfo_info_C InfoKind, MediaInfo_info_C SearchKind); /*Default : InfoKind=Info_Text, SearchKind=Info_Name*/
    /** @brief Wrapper for MediaInfoLib::MediaInfo::Set */
    MEDIAINFO_EXP size_t            __stdcall MediaInfoA_SetI (void* Handle, const char* ToSet, MediaInfo_stream_C StreamKind, size_t StreamNumber, size_t Parameter, const char* OldParameter);
    /** @brief Wrapper for MediaInfoLib::MediaInfo::Set */
    MEDIAINFO_EXP size_t            __stdcall MediaInfoA_Set (void* Handle, const char* ToSet, MediaInfo_stream_C StreamKind, size_t StreamNumber, const char* Parameter, const char* OldParameter);
    /** @brief Wrapper for MediaInfoLib::MediaInfo::Output_Buffer_Get */
    MEDIAINFO_EXP size_t            __stdcall MediaInfoA_Output_Buffer_Get (void* Handle, const char* Value);
    /** @brief Wrapper for MediaInfoLib::MediaInfo::Output_Buffer_Get */
    MEDIAINFO_EXP size_t            __stdcall MediaInfoA_Output_Buffer_GetI (void* Handle, size_t Pos);
    /** @brief Wrapper for MediaInfoLib::MediaInfo::Option */
    MEDIAINFO_EXP const char*       __stdcall MediaInfoA_Option (void* Handle, const char* Option, const char* Value);
    /** @brief Wrapper for MediaInfoLib::MediaInfo::State_Get */
    MEDIAINFO_EXP size_t            __stdcall MediaInfoA_State_Get (void* Handle);
    /** @brief Wrapper for MediaInfoLib::MediaInfo::Count_Get */
    MEDIAINFO_EXP size_t            __stdcall MediaInfoA_Count_Get (void* Handle, MediaInfo_stream_C StreamKind, size_t StreamNumber); /*Default : StreamNumber=-1*/
    
    
#if defined(MEDIAINFO_DLL_EXPORT) || (defined(UNICODE) || defined(_UNICODE)) //DLL construction or Unicode
    /** @brief A 'new' MediaInfoList interface, return a Handle, don't forget to delete it after using it*/
    MEDIAINFO_EXP void*             __stdcall MediaInfoList_New (); /*you must ALWAYS call MediaInfoList_Delete(Handle) in order to free memory*/
    /** @brief A 'new' MediaInfoList interface (with a quick init of useful options : "**VERSION**;**APP_NAME**;**APP_VERSION**", but without debug information, use it only if you know what you do), return a Handle, don't forget to delete it after using it*/
    MEDIAINFO_EXP void*             __stdcall MediaInfoList_New_Quick (const wchar_t* Files, const wchar_t* Config); /*you must ALWAYS call MediaInfoList_Delete(Handle) in order to free memory*/
    /** @brief Delete a MediaInfoList interface*/
    MEDIAINFO_EXP void              __stdcall MediaInfoList_Delete (void* Handle);
    /** @brief Wrapper for MediaInfoListLib::MediaInfoList::Open (with a filename)*/
    MEDIAINFO_EXP size_t            __stdcall MediaInfoList_Open (void* Handle, const wchar_t* Files, const MediaInfo_fileoptions_C Options); /*Default : Options=MediaInfo_FileOption_Nothing*/
    /** @brief Wrapper for MediaInfoListLib::MediaInfoList::Open (with a buffer) */
    MEDIAINFO_EXP size_t            __stdcall MediaInfoList_Open_Buffer (void* Handle, const unsigned char* Begin, size_t Begin_Size, const unsigned char* End, size_t End_Size); /*return Handle*/
    /** @brief Wrapper for MediaInfoListLib::MediaInfoList::Save */
    MEDIAINFO_EXP size_t            __stdcall MediaInfoList_Save (void* Handle, size_t FilePos);
    /** @brief Wrapper for MediaInfoListLib::MediaInfoList::Close */
    MEDIAINFO_EXP void              __stdcall MediaInfoList_Close (void* Handle, size_t FilePos);
    /** @brief Wrapper for MediaInfoListLib::MediaInfoList::Inform */
    MEDIAINFO_EXP const wchar_t*    __stdcall MediaInfoList_Inform (void* Handle, size_t FilePos, size_t Reserved); /*Default : Reserved=0*/
    /** @brief Wrapper for MediaInfoListLib::MediaInfoList::Get */
    MEDIAINFO_EXP const wchar_t*    __stdcall MediaInfoList_GetI (void* Handle, size_t FilePos, MediaInfo_stream_C StreamKind, size_t StreamNumber, size_t Parameter, MediaInfo_info_C InfoKind); /*Default : InfoKind=Info_Text*/
    /** @brief Wrapper for MediaInfoListLib::MediaInfoList::Get */
    MEDIAINFO_EXP const wchar_t*    __stdcall MediaInfoList_Get (void* Handle, size_t FilePos, MediaInfo_stream_C StreamKind, size_t StreamNumber, const wchar_t* Parameter, MediaInfo_info_C InfoKind, MediaInfo_info_C SearchKind); /*Default : InfoKind=Info_Text, SearchKind=Info_Name*/
    /** @brief Wrapper for MediaInfoListLib::MediaInfoList::Set */
    MEDIAINFO_EXP size_t            __stdcall MediaInfoList_SetI (void* Handle, const wchar_t* ToSet, size_t FilePos, MediaInfo_stream_C StreamKind, size_t StreamNumber, size_t Parameter, const wchar_t* OldParameter);
    /** @brief Wrapper for MediaInfoListLib::MediaInfoList::Set */
    MEDIAINFO_EXP size_t            __stdcall MediaInfoList_Set (void* Handle, const wchar_t* ToSet, size_t FilePos, MediaInfo_stream_C StreamKind, size_t StreamNumber, const wchar_t* Parameter, const wchar_t* OldParameter);
    /** @brief Wrapper for MediaInfoListLib::MediaInfoList::Option */
    MEDIAINFO_EXP const wchar_t*    __stdcall MediaInfoList_Option (void* Handle, const wchar_t* Option, const wchar_t* Value);
    /** @brief Wrapper for MediaInfoListLib::MediaInfoList::State_Get */
    MEDIAINFO_EXP size_t            __stdcall MediaInfoList_State_Get (void* Handle);
    /** @brief Wrapper for MediaInfoListLib::MediaInfoList::Count_Get */
    MEDIAINFO_EXP size_t            __stdcall MediaInfoList_Count_Get (void* Handle, size_t FilePos, MediaInfo_stream_C StreamKind, size_t StreamNumber); /*Default : StreamNumber=-1*/
    /** @brief Wrapper for MediaInfoListLib::MediaInfoList::Count_Get */
    MEDIAINFO_EXP size_t            __stdcall MediaInfoList_Count_Get_Files (void* Handle);
#else //defined(MEDIAINFO_DLL_EXPORT) || (defined(UNICODE) || defined(_UNICODE))
#define MediaInfoList_New               MediaInfoListA_New
#define MediaInfoList_New_Quick         MediaInfoListA_New_Quick
#define MediaInfoList_Delete            MediaInfoListA_Delete
#define MediaInfoList_Open              MediaInfoListA_Open
#define MediaInfoList_Open_Buffer       MediaInfoListA_Open_Buffer
#define MediaInfoList_Save              MediaInfoListA_Save
#define MediaInfoList_Save_All          MediaInfoListA_Save_All
#define MediaInfoList_Close             MediaInfoListA_Close
#define MediaInfoList_Close_All         MediaInfoListA_Close_All
#define MediaInfoList_Inform            MediaInfoListA_Inform
#define MediaInfoList_Inform_All        MediaInfoListA_Inform_All
#define MediaInfoList_GetI              MediaInfoListA_GetI
#define MediaInfoList_Get               MediaInfoListA_Get
#define MediaInfoList_SetI              MediaInfoListA_SetI
#define MediaInfoList_Set               MediaInfoListA_Set
#define MediaInfoList_Option            MediaInfoListA_Option
#define MediaInfoList_State_Get         MediaInfoListA_State_Get
#define MediaInfoList_Count_Get         MediaInfoListA_Count_Get
#define MediaInfoList_Count_Get_Files   MediaInfoListA_Count_Get_Files
#endif //defined(MEDIAINFO_DLL_EXPORT) || (defined(UNICODE) || defined(_UNICODE))
    
    /* Warning : Deprecated, use MediaInfo_Option("Info_Version", "**YOUR VERSION COMPATIBLE**") instead */
    MEDIAINFO_EXP const char*       __stdcall MediaInfo_Info_Version ();
    
    
    /** @brief A 'new' MediaInfoList interface, return a Handle, don't forget to delete it after using it*/
    MEDIAINFO_EXP void*             __stdcall MediaInfoListA_New (); /*you must ALWAYS call MediaInfoList_Delete(Handle) in order to free memory*/
    /** @brief A 'new' MediaInfoList interface (with a quick init of useful options : "**VERSION**;**APP_NAME**;**APP_VERSION**", but without debug information, use it only if you know what you do), return a Handle, don't forget to delete it after using it*/
    MEDIAINFO_EXP void*             __stdcall MediaInfoListA_New_Quick (const char* Files, const char* Config); /*you must ALWAYS call MediaInfoList_Delete(Handle) in order to free memory*/
    /** @brief Delete a MediaInfoList interface*/
    MEDIAINFO_EXP void              __stdcall MediaInfoListA_Delete (void* Handle);
    /** @brief Wrapper for MediaInfoListLib::MediaInfoList::Open (with a filename)*/
    MEDIAINFO_EXP size_t            __stdcall MediaInfoListA_Open (void* Handle, const char* Files, const MediaInfo_fileoptions_C Options); /*Default : Options=0*/
    /** @brief Wrapper for MediaInfoListLib::MediaInfoList::Open (with a buffer) */
    MEDIAINFO_EXP size_t            __stdcall MediaInfoListA_Open_Buffer (void* Handle, const unsigned char* Begin, size_t Begin_Size, const unsigned char* End, size_t End_Size); /*return Handle*/
    /** @brief Wrapper for MediaInfoListLib::MediaInfoList::Save */
    MEDIAINFO_EXP size_t            __stdcall MediaInfoListA_Save (void* Handle, size_t FilePos);
    /** @brief Wrapper for MediaInfoListLib::MediaInfoList::Close */
    MEDIAINFO_EXP void              __stdcall MediaInfoListA_Close (void* Handle, size_t FilePos);
    /** @brief Wrapper for MediaInfoListLib::MediaInfoList::Inform */
    MEDIAINFO_EXP const char*       __stdcall MediaInfoListA_Inform (void* Handle, size_t FilePos, size_t Reserved); /*Default : Reserved=0*/
    /** @brief Wrapper for MediaInfoListLib::MediaInfoList::Get */
    MEDIAINFO_EXP const char*       __stdcall MediaInfoListA_GetI (void* Handle, size_t FilePos, MediaInfo_stream_C StreamKind, size_t StreamNumber, size_t Parameter, MediaInfo_info_C InfoKind); /*Default : InfoKind=Info_Text*/
    /** @brief Wrapper for MediaInfoListLib::MediaInfoList::Get */
    MEDIAINFO_EXP const char*       __stdcall MediaInfoListA_Get (void* Handle, size_t FilePos, MediaInfo_stream_C StreamKind, size_t StreamNumber, const char* Parameter, MediaInfo_info_C InfoKind, MediaInfo_info_C SearchKind); /*Default : InfoKind=Info_Text, SearchKind=Info_Name*/
    /** @brief Wrapper for MediaInfoListLib::MediaInfoList::Set */
    MEDIAINFO_EXP size_t            __stdcall MediaInfoListA_SetI (void* Handle, const char* ToSet, size_t FilePos, MediaInfo_stream_C StreamKind, size_t StreamNumber, size_t Parameter, const char* OldParameter);
    /** @brief Wrapper for MediaInfoListLib::MediaInfoList::Set */
    MEDIAINFO_EXP size_t            __stdcall MediaInfoListA_Set (void* Handles, const char* ToSet, size_t FilePos, MediaInfo_stream_C StreamKind, size_t StreamNumber, const char* Parameter, const char* OldParameter);
    /** @brief Wrapper for MediaInfoListLib::MediaInfoList::Option */
    MEDIAINFO_EXP const char*       __stdcall MediaInfoListA_Option (void* Handle, const char* Option, const char* Value);
    /** @brief Wrapper for MediaInfoListLib::MediaInfoList::State_Get */
    MEDIAINFO_EXP size_t            __stdcall MediaInfoListA_State_Get (void* Handle);
    /** @brief Wrapper for MediaInfoListLib::MediaInfoList::Count_Get */
    MEDIAINFO_EXP size_t            __stdcall MediaInfoListA_Count_Get (void* Handle, size_t FilePos, MediaInfo_stream_C StreamKind, size_t StreamNumber); /*Default : StreamNumber=-1*/
    /** @brief Wrapper for MediaInfoListLib::MediaInfoList::Count_Get */
    MEDIAINFO_EXP size_t            __stdcall MediaInfoListA_Count_Get_Files (void* Handle);
    
#ifdef __cplusplus
}
#endif /*__cplusplus*/



#ifdef __cplusplus
//DLL C++ wrapper for C functions
#if !defined(MediaInfoH) && !defined(MEDIAINFO_DLL_EXPORT) //No Lib include and No DLL construction

//---------------------------------------------------------------------------
#include <string>
//---------------------------------------------------------------------------

namespace MediaInfoDLL
{
    
    //---------------------------------------------------------------------------
    //Char types
#undef  __T
#define __T(__x)    __T(__x)
#if defined(UNICODE) || defined(_UNICODE)
    typedef wchar_t Char;
#undef  __T
#define __T(__x) L ## __x
#else
    typedef char Char;
#undef  __T
#define __T(__x) __x
#endif
    typedef std::basic_string<Char>        String;
    typedef std::basic_stringstream<Char>  StringStream;
    typedef std::basic_istringstream<Char> tiStringStream;
    typedef std::basic_ostringstream<Char> toStringStream;
    //---------------------------------------------------------------------------
    
    //---------------------------------------------------------------------------
    /// @brief Kinds of Stream
    enum stream_t
    {
        Stream_General,                 ///< StreamKind = General
        Stream_Video,                   ///< StreamKind = Video
        Stream_Audio,                   ///< StreamKind = Audio
        Stream_Text,                    ///< StreamKind = Text
        Stream_Other,                   ///< StreamKind = Other
        Stream_Image,                   ///< StreamKind = Image
        Stream_Menu,                    ///< StreamKind = Menu
        Stream_Max,
    };
    
    /// @brief Kind of information
    enum info_t
    {
        Info_Name,                      ///< InfoKind = Unique name of parameter
        Info_Text,                      ///< InfoKind = Value of parameter
        Info_Measure,                   ///< InfoKind = Unique name of measure unit of parameter
        Info_Options,                   ///< InfoKind = See infooptions_t
        Info_Name_Text,                 ///< InfoKind = Translated name of parameter
        Info_Measure_Text,              ///< InfoKind = Translated name of measure unit
        Info_Info,                      ///< InfoKind = More information about the parameter
        Info_HowTo,                     ///< InfoKind = Information : how data is found
        Info_Max
    };
    
    /// Get(...)[infooptions_t] return a string like "YNYN..." \n
    /// Use this enum to know at what correspond the Y (Yes) or N (No)
    /// If Get(...)[0]==Y, then :
    /// @brief Option if InfoKind = Info_Options
    enum infooptions_t
    {
        InfoOption_ShowInInform,        ///< Show this parameter in Inform()
        InfoOption_Reserved,            ///<
        InfoOption_ShowInSupported,     ///< Internal use only (info : Must be showed in Info_Capacities())
        InfoOption_TypeOfValue,         ///< Value return by a standard Get() can be : T (Text), I (Integer, warning up to 64 bits), F (Float), D (Date), B (Binary datas coded Base64) (Numbers are in Base 10)
        InfoOption_Max
    };
    
    /// @brief File opening options
    enum fileoptions_t
    {
        FileOption_Nothing     = 0x00,
        FileOption_NoRecursive = 0x01,  ///< Do not browse folders recursively
        FileOption_CloseAll    = 0x02,  ///< Close all files before open
        FileOption_Max         = 0x04
    };
    
    //---------------------------------------------------------------------------
    class MediaInfo
    {
        public :
        MediaInfo ()                {Handle=MediaInfo_New();};
        ~MediaInfo ()               {MediaInfo_Delete(Handle);};
        
        //File
        size_t Open (const String &File) {return MediaInfo_Open(Handle, File.c_str());};
        size_t Open (const unsigned char* Begin, size_t Begin_Size, const unsigned char* End=NULL, size_t End_Size=NULL) {return MediaInfo_Open_Buffer(Handle, Begin, Begin_Size, End, End_Size);};
        size_t Save () {return MediaInfo_Save(Handle);};
        void Close () {return MediaInfo_Close(Handle);};
        
        //General information
        String Inform ()  {return MediaInfo_Inform(Handle, 0);};
        String Get (stream_t StreamKind, size_t StreamNumber, size_t Parameter, info_t InfoKind=Info_Text)  {return MediaInfo_GetI (Handle, (MediaInfo_stream_C)StreamKind, StreamNumber, Parameter, (MediaInfo_info_C)InfoKind);};
        String Get (stream_t StreamKind, size_t StreamNumber, const String &Parameter, info_t InfoKind=Info_Text, info_t SearchKind=Info_Name)  {return MediaInfo_Get (Handle, (MediaInfo_stream_C)StreamKind, StreamNumber, Parameter.c_str(), (MediaInfo_info_C)InfoKind, (MediaInfo_info_C)SearchKind);};
        size_t Set (const String &ToSet, stream_t StreamKind, size_t StreamNumber, size_t Parameter, const String &OldValue=__T(""))  {return MediaInfo_SetI (Handle, ToSet.c_str(), (MediaInfo_stream_C)StreamKind, StreamNumber, Parameter, OldValue.c_str());};
        size_t Set (const String &ToSet, stream_t StreamKind, size_t StreamNumber, const String &Parameter, const String &OldValue=__T(""))  {return MediaInfo_Set (Handle, ToSet.c_str(), (MediaInfo_stream_C)StreamKind, StreamNumber, Parameter.c_str(), OldValue.c_str());};
        String        Option (const String &Option, const String &Value=__T(""))  {return MediaInfo_Option (Handle, Option.c_str(), Value.c_str());};
        static String Option_Static (const String &Option, const String &Value=__T(""))  {return MediaInfo_Option (NULL, Option.c_str(), Value.c_str());};
        size_t        State_Get ()  {return MediaInfo_State_Get(Handle);};
        size_t        Count_Get (stream_t StreamKind, size_t StreamNumber=-1)  {return MediaInfo_Count_Get(Handle, (MediaInfo_stream_C)StreamKind, StreamNumber);};
        
        private :
        void* Handle;
    };
    
    class MediaInfoList
    {
        public :
        MediaInfoList ()                {Handle=MediaInfoList_New();};
        ~MediaInfoList ()               {MediaInfoList_Delete(Handle);};
        
        //File
        size_t Open (const String &File, const fileoptions_t Options=FileOption_Nothing) {return MediaInfoList_Open(Handle, File.c_str(), (MediaInfo_fileoptions_C)Options);};
        size_t Open (const unsigned char* Begin, size_t Begin_Size, const unsigned char* End=NULL, size_t End_Size=NULL) {return MediaInfoList_Open_Buffer(Handle, Begin, Begin_Size, End, End_Size);};
        size_t Save (size_t FilePos) {return MediaInfoList_Save(Handle, FilePos);};
        void Close (size_t FilePos=-1) {return MediaInfoList_Close(Handle, FilePos);};
        
        //General information
        String Inform (size_t FilePos=-1)  {return MediaInfoList_Inform(Handle, FilePos, 0);};
        String Get (size_t FilePos, stream_t StreamKind, size_t StreamNumber, size_t Parameter, info_t InfoKind=Info_Text)  {return MediaInfoList_GetI (Handle, FilePos, (MediaInfo_stream_C)StreamKind, StreamNumber, Parameter, (MediaInfo_info_C)InfoKind);};
        String Get (size_t FilePos, stream_t StreamKind, size_t StreamNumber, const String &Parameter, info_t InfoKind=Info_Text, info_t SearchKind=Info_Name)  {return MediaInfoList_Get (Handle, FilePos, (MediaInfo_stream_C)StreamKind, StreamNumber, Parameter.c_str(), (MediaInfo_info_C)InfoKind, (MediaInfo_info_C)SearchKind);};
        size_t Set (const String &ToSet, size_t FilePos, stream_t StreamKind, size_t StreamNumber, size_t Parameter, const String &OldValue=__T(""))  {return MediaInfoList_SetI (Handle, ToSet.c_str(), FilePos, (MediaInfo_stream_C)StreamKind, StreamNumber, Parameter, OldValue.c_str());};
        size_t Set (const String &ToSet, size_t FilePos, stream_t StreamKind, size_t StreamNumber, const String &Parameter, const String &OldValue=__T(""))  {return MediaInfoList_Set (Handle, ToSet.c_str(), FilePos, (MediaInfo_stream_C)StreamKind, StreamNumber, Parameter.c_str(), OldValue.c_str());};
        String        Option (const String &Option, const String &Value=__T(""))  {return MediaInfoList_Option (Handle, Option.c_str(), Value.c_str());};
        static String Option_Static (const String &Option, const String &Value=__T(""))  {return MediaInfoList_Option (NULL, Option.c_str(), Value.c_str());};
        size_t        State_Get ()  {return MediaInfoList_State_Get(Handle);};
        size_t        Count_Get (size_t FilePos, stream_t StreamKind, size_t StreamNumber=-1)  {return MediaInfoList_Count_Get(Handle, FilePos, (MediaInfo_stream_C)StreamKind, StreamNumber);};
        size_t        Count_Get ()  {return MediaInfoList_Count_Get_Files(Handle);};
        
        private :
        void* Handle;
    };
    
} //NameSpace
#endif//#if !defined(MediaInfoH) && !defined(MEDIAINFO_DLL_EXPORT) && !(defined(UNICODE) || defined(_UNICODE))
#endif /*__cplusplus*/

#endif
