////////////////////////////////////////////////////////////////////////////////
//                                                                             /
// 2012-2019 (c) Baical                                                        /
//                                                                             /
// This library is free software; you can redistribute it and/or               /
// modify it under the terms of the GNU Lesser General Public                  /
// License as published by the Free Software Foundation; either                /
// version 3.0 of the License, or (at your option) any later version.          /
//                                                                             /
// This library 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           /
// Lesser General Public License for more details.                             /
//                                                                             /
// You should have received a copy of the GNU Lesser General Public            /
// License along with this library.                                            /
//                                                                             /
////////////////////////////////////////////////////////////////////////////////
#ifndef BK_API_PLUGINS_H
#define BK_API_PLUGINS_H

#include "PAPI.h"
#include "PAPI_Node.h"

#include "Prop.h"


namespace Bk
{
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// <summary> Plugin interface </summary>
    class IPlugin
    {
    public:
        /// <summary> Gets plugin base information </summary>
        /// <param name="o_rInfo"> plugin information </param>
        /// <returns>Bk::eResult::eOk in case of success</returns>  
        virtual Bk::eResult __stdcall Get_Info(Bk::stPluginInfo &o_rInfo) = 0;

        /// <summary> Gets plugin configuration node. Do not forget to call o_rNode.Release() </summary>
        /// <param name="o_rNode"> plugin configuration node </param>
        /// <returns>Bk::eResult::eOk in case of success</returns>  
        virtual Bk::eResult __stdcall Get_Node(Bk::IBNode *&o_rNode) = 0;

        /// <summary> Gets plugin properties. Do not forget to call o_rProp.Release() </summary>
        /// <param name="o_rProp"> plugin properties </param>
        /// <returns>Bk::eResult::eOk in case of success</returns>  
        virtual Bk::eResult __stdcall Get_Prop(CProperty *&o_rProp) = 0;

        /// <summary> Check does plugin support stream represented by GUID </summary>
        /// <param name="i_rGUID"> stream GUID </param>
        /// <returns>Bk::eResult::eOk in case of success</returns>  
        virtual Bk::eResult __stdcall Is_Stream_Supported(const GUID *i_pGUID) = 0;

        /// <summary> Increases object reference counter </summary>
        /// <returns> new value of reference counter </returns>  
        virtual tINT32 __stdcall Add_Ref() = 0;

        /// <summary> Decreases object reference counter. If 0 - object will be self-destroyed </summary>
        /// <returns> new value of reference counter </returns>  
        virtual tINT32 __stdcall Release() = 0;
    };


    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// <summary> Plugin interface </summary>
    class IPluginsEnumerator
    {
    public:
        /// <summary> Gets plugins count </summary>
        /// <returns>plugins count</returns>  
        virtual size_t __stdcall Get_Count() = 0;

        /// <summary> Gets plugin interface. Do not forget to call IPlugin::Release() </summary>
        /// <param name="i_szIndex"> plugin index [0 .. (Get_Count() - 1)] </param>
        /// <returns>Plugin interface</returns>  
        virtual Bk::IPlugin* __stdcall Get_Plugin(size_t i_szIndex) = 0;

        /// <summary> Increases object reference counter </summary>
        /// <returns> new value of reference counter </returns>  
        virtual tINT32 __stdcall Add_Ref() = 0;

        /// <summary> Decreases object reference counter. If 0 - object will be self-destroyed </summary>
        /// <returns> new value of reference counter </returns>  
        virtual tINT32 __stdcall Release() = 0;
    };

}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////// Plugins function prototypes ////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

/// <summary> get plugin base info function prototype, main function of every baical plugin </summary>
#define BK_GET_PLUGIN_INFO "Get_Plugin_Info"
typedef Bk::eResult (__cdecl *fnBkGetPluginInfo)(Bk::stPluginInfo *o_pInfo);

/// <summary> check does plugin support stream using i_pGUID </summary>
#define BK_IS_STREAM_SUPPORTED "Is_Stream_Supported"
typedef Bk::eResult (__cdecl *fnBkIsStreamSupported)(const GUID *i_pGUID);

#endif //BK_API_PLUGINS_H