////////////////////////////////////////////////////////////////////////////////
//                                                                             /
// 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_PLUGINS_H
#define BK_PLUGINS_H

#include "PSharedLib.h"

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class CPlugin
    : public Bk::IPlugin
{
protected:
    tINT32 volatile       m_lReference;
    CPSharedLib          *m_hDLL;
    Bk::stPluginInfo      m_sPlugin_Info;

    Bk::IUnknown         *m_pBaical;
                         
    IP7_Trace            *m_iP7_Trace;
    IP7_Trace::hModule    m_hP7_TraceModule;
                         
    IP7_Trace::hModule    m_hTrace_Module;
    Bk::IBNode           *m_pNode;
    CProperty            *m_pProp;
    tBOOL                 m_bInitialized;
    CWString              m_cPath;

    fnBkIsStreamSupported m_pIs_Stream_Supported;

public:
    CPlugin(Bk::IUnknown     *i_pBaical,
            CPSharedLib      *i_hDLL,
            Bk::stPluginInfo *i_pPlugin_Info,
            IP7_Trace        *i_iTrace,
            Bk::IBNode       *i_pNode,
            CProperty        *i_pProp,
            const tXCHAR     *i_pPath
           );
    virtual ~CPlugin();

    virtual Bk::eResult Initialize() = 0;

    tBOOL Get_Initialized();

    //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    //Bk::IPlugin interface functions
    Bk::eResult __stdcall Get_Info(Bk::stPluginInfo &o_rInfo);
    Bk::eResult __stdcall Get_Node(Bk::IBNode *&o_rNode);
    Bk::eResult __stdcall Get_Prop(CProperty *&o_rProp);
    Bk::eResult __stdcall Is_Stream_Supported(const GUID *i_pGUID);
    tINT32 __stdcall Add_Ref();
    tINT32 __stdcall Release();
};


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class CProvider
    : public CPlugin
{
    fnBkCreateProvider m_pCreate_Provider;

public:
    Bk::IProvider    *m_iProvider;

    CProvider(Bk::IUnknown     *i_pBaical,
              Bk::IBNode       *i_pNode,
              CProperty        *i_pProp,
              IP7_Trace        *i_iTrace,
              CPSharedLib      *i_hDLL,
              Bk::stPluginInfo *i_pPlugin_Info,
              const tXCHAR     *i_pPath
             );

    Bk::eResult Import(const tXCHAR *i_pPath);
    Bk::eResult Initialize();


    ~CProvider();
};


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class CStorage
    : public CPlugin
{
protected:
   fnBkCreateStorage m_pCreate_Storage;
   fnBkOpenStorage   m_pOpen_Storage;
public:
    CStorage(Bk::IUnknown     *i_pBaical,
             Bk::IBNode       *i_pNode,
             CProperty        *i_pProp,
             IP7_Trace        *i_iTrace,
             CPSharedLib      *i_hDLL,
             Bk::stPluginInfo *i_pPlugin_Info,
             const tXCHAR     *i_pPath
            );

    ~CStorage();
    Bk::IStorage *Create_Storage(Bk::stStreamInfo  *i_pInfo);
    Bk::eResult   Open_Storage(WND_HANDLE i_hParent, Bk::IStorageReader **o_pReader, const tXCHAR *i_pFile);
    Bk::eResult Initialize() { return (m_bInitialized) ? Bk::eOk : Bk::eErrorInternal; }
};


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class CViewer
    : public CPlugin
{
private:
   fnBkCreateViewer m_pCreate_Viewer;
public:
    CViewer(Bk::IUnknown    *i_pBaical,
            Bk::IBNode      *i_pNode,
            CProperty       *i_pProp,
            IP7_Trace       *i_iTrace,
            CPSharedLib     *i_hDLL,
            Bk::stPluginInfo*i_pPlugin_Info,
            const tXCHAR    *i_pPath
           );

    ~CViewer();

    Bk::IViewer *Create_Viewer(WND_HANDLE              i_hParent,
                               Bk::IStorageReader     *i_iReader,
                               Bk::IStreamEx          *i_iExtra,
                               Bk::IViewersEnumerator *i_pEnum
                              );

    Bk::eResult Initialize() { return (m_bInitialized) ? Bk::eOk : Bk::eErrorInternal; }
};



////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class CDispatcher
    : public CPlugin
{
private:
    Bk::IDispatcher *m_pDispatcher;
public:
    CDispatcher(Bk::IUnknown    *i_pBaical,
                Bk::IBNode      *i_pNode,
                CProperty       *i_pProp,
                IP7_Trace       *i_iTrace,
                CPSharedLib     *i_hDLL,
                Bk::stPluginInfo*i_pPlugin_Info,
                const tXCHAR    *i_pPath
               );

    ~CDispatcher();
    Bk::IPlugin* Dispatch(const Bk::stStreamInfo &i_rStreamInfo);
    tUINT8       GetPriority();
    Bk::eResult  Initialize();
};


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class CProcessor
    : public CPlugin
{
private:
    Bk::IProcessor *m_pProcessor;
public:
    CProcessor(Bk::IUnknown    *i_pBaical,
               Bk::IBNode      *i_pNode,
               CProperty       *i_pProp,
               IP7_Trace       *i_iTrace,
               CPSharedLib     *i_hDLL,
               Bk::stPluginInfo*i_pPlugin_Info,
               const tXCHAR    *i_pPath
              );

    ~CProcessor();
    Bk::eResult  Initialize();
};

#endif //BK_PLUGINS_H
