#pragma once

#include "..\\global\\iblock.h"

__declspec(dllexport) HRESULT CreateBlockInstance(REFIID riid, void **ppv);

class CBlockConfig : public IBlockConfig
{
protected:
	IUnknown* m_pUnkOuter;
public:
	CBlockConfig(IUnknown* pUnkOuter);
	virtual ~CBlockConfig();
	STDMETHODIMP QueryInterface(const IID &riid, void **ppvObject);
	STDMETHODIMP_(ULONG) AddRef(void);
	STDMETHODIMP_(ULONG) Release(void);
	virtual STDMETHODIMP ShowConfig();
	virtual STDMETHODIMP RefreshData();

	BOOL ConfigWindowClosed();
};

class CBlockAutoTrigger : public IBlockAutoTrigger
{
protected:
	IUnknown* m_pUnkOuter;
public:
	CBlockAutoTrigger(IUnknown* pUnkOuter);
	virtual ~CBlockAutoTrigger();
	STDMETHODIMP QueryInterface(const IID &riid, void **ppvObject);
	STDMETHODIMP_(ULONG) AddRef(void);
	STDMETHODIMP_(ULONG) Release(void);
	virtual STDMETHODIMP Start(CDocument *pDoc = NULL);
	virtual STDMETHODIMP Stop();
};

class CBlock : public IBlock
{
private:
	BLOCKDATA m_blockData;
	CRITICAL_SECTION m_csData;
	LONG m_refcount;
	IUnknown* m_pUnkOuter;
	BOOL m_bModified;

	BOOL MultiThreadInit();
	BOOL MultiThreadRelease();
protected:
	
	CBlock();
	virtual ~CBlock();
public:
	DWORD m_dwInPortCount, m_dwOutPortCount;
	LPWSTR m_pName;
	LPWSTR m_pDesc;
	LPWSTR m_pPath;
	const WCHAR **m_pInputNameArray;
	const WCHAR **m_pOutputNameArray;
	virtual void* GetInterface(REFIID riid);
	// metody rozhrani IBlock
	STDMETHODIMP QueryInterface(const IID &riid, void **ppvObject);
	STDMETHODIMP_(ULONG) AddRef(void);
	STDMETHODIMP_(ULONG) Release(void);

	STDMETHODIMP GetInputCount(DWORD *pdwTarget);
	STDMETHODIMP GetOutputCount(DWORD *pdwTarget);
	STDMETHODIMP GetName(CString& rstrName);
	STDMETHODIMP GetDescription(CString& rstrName);
	STDMETHODIMP_(const PORTDATA) GetOutputPortData(DWORD dwPort) const;
	STDMETHODIMP GetBlockPath(CString &rstrPath);

	virtual STDMETHODIMP GetInputPortName(DWORD dwPort, CString& rstrName);
	virtual STDMETHODIMP GetOutputPortName(DWORD dwPort, CString& rstrName);
	virtual STDMETHODIMP InitInstance();
	virtual STDMETHODIMP ExitInstance();
	virtual STDMETHODIMP ProcessRev(const DWORD dwProcessId, REVDATAMAP &rRevDataMapClean);
	virtual STDMETHODIMP ClearRevMap(REVDATAMAP &rRevDataMap);
	virtual STDMETHODIMP ProcessData(const LPBLOCKDATA pInputData);
	virtual STDMETHODIMP_(void) Serialize(CArchive &ar);
	virtual STDMETHODIMP_(LPCRITICAL_SECTION) GetCriticalSectionPtr();
	virtual STDMETHODIMP_(BOOL) GetModifiedFlag();
	virtual STDMETHODIMP_(VOID) SetModifiedFlag(BOOL bModified = TRUE);

	// pomocne funkce

	BOOL DeleteBlockData();
	BOOL PrepareBlockData();
	BOOL NewBlockPortData(DWORD dwPort, DWORD dwLayers);

	VOID LockBlockData();
	VOID UnlockBlockData();
	VOID SetDataPtr(DWORD dwPort, DWORD dwLayer, void* ptr, DWORD dwDataLen);

	// kriticka sekce - pouzit pri synchronizaci

	CRITICAL_SECTION m_cs;
};


