/*

Na zacatku tohoto souboru je nastaveni chovani bloku. Pote jsou zde funkce
nezvytne k vytvoreni instance COMu, a funkce, ktera vraci ukazatele na
rozhrani bloku. Prozatim se predpokladaji pouze 2 pridavna rozhrani k tomuto
objektu. 

-- IBlockConfig --
je urcene ke konfiguraci bloku. Je pouzito
v pripade, kdyz uzivatel klikne pravym tlacitkem mysi na blok a vybere
volbu "properties...". Melo by se otevrit okno s nastavenim, ktere musi
byt implementovano

-- IBlockAutoTrigger --
slouzi k automatickemu spousteni procesu. Vyuzije se napriklad pri realtime
zpracovani zvuku a videa, kdy potrebujeme pravidelne zpracovavat useky dat

*/

#include "stdafx.h"

// jestli ma blok rohrani, odkomentujte prislusny radek
//#define __BLOCKHAVECONFIGWINDOW
//#define __BLOCKHAVEAUTOTRIGGER

#include "imp_block.h"
#include <deque>
#ifdef __BLOCKHAVECONFIGWINDOW
#include "imp_config.h"
#endif
#ifdef __BLOCKHAVEAUTOTRIGGER
#include "imp_autotrigger.h"
#endif
#include <deque>

// jmeno, popis a cesta k bloku
const LPWSTR g_pName = L"Název bloku";
const LPWSTR g_pDesc = L"Popis bloku";
const LPWSTR g_pPath = L"Cesta k bloku"; // odděluje se znakem '\\'

// pocty vstupnich a vystupnich portu
const DWORD g_dwInPortCount = 0; // př. 2
const DWORD g_dwOutPortCount = 0; // př. 2
// nazvy vstupnich a vystupnich portu
const WCHAR *g_pInputNameArray[] = {NULL}; // př. L"i0", L"i1"
const WCHAR *g_pOutputNameArray[] = {NULL}; // př. L"o0", L"o1"

// Tyto funkce nemenit !!!
// funkce volana klientskym programem k vytvoreni instance tridy

HRESULT CreateBlockInstance(REFIID riid, void **ppv)
{
	return CImpBlock::CreateInstance(riid, ppv);
}
// staticka funkce, ktera vytvari instanci tridy
HRESULT CImpBlock::CreateInstance(const IID &riid, void **ppv)
{
	CImpBlock* pObj; 
	pObj = new CImpBlock();
	if (pObj == NULL) 
		return E_OUTOFMEMORY; 
	HRESULT hr; 
	if ( FAILED(hr = pObj->QueryInterface(riid, (void**)ppv))) 
		delete pObj ; 
	return hr; 
}
// funkce, ktera vraci adresu rozhrani
void* CImpBlock::GetInterface(REFIID riid)
{
#ifdef __BLOCKHAVECONFIGWINDOW
	if ( IID_IBlockConfig == riid )
		return m_pxConfig;
#endif
#ifdef __BLOCKHAVEAUTOTRIGGER
	if ( IID_IBlockAutoTrigger == riid )
		return m_pxAutoTrigger;
#endif
	return NULL;
}
// konstruktor
CImpBlock::CImpBlock() : m_pxConfig(NULL), m_pxAutoTrigger(NULL)
{
#ifdef __BLOCKHAVECONFIGWINDOW
	m_pxConfig = new CImpBlockConfig(this);
#endif
#ifdef __BLOCKHAVEAUTOTRIGGER
	m_pxAutoTrigger = new CImpBlockAutoTrigger(this);
#endif
	m_dwInPortCount = g_dwInPortCount;
	m_dwOutPortCount = g_dwOutPortCount;
	m_pName = g_pName;
	m_pDesc = g_pDesc;
	m_pPath = g_pPath;
	m_pInputNameArray = g_pInputNameArray;
	m_pOutputNameArray = g_pOutputNameArray;

	// inicializace promennych // IMPLEMENTOVAT
}
// destruktor
CImpBlock::~CImpBlock()
{
#ifdef __BLOCKHAVEAUTOTRIGGER
	if ( m_pxAutoTrigger )
		delete ( m_pxAutoTrigger );
#endif
#ifdef __BLOCKHAVECONFIGWINDOW
	if ( m_pxConfig )
		delete ( m_pxConfig );
#endif
}

///////////////////////////////
// TYTO FUNKCE IMPLEMENTOVAT //
///////////////////////////////

STDMETHODIMP CImpBlock::InitInstance()
{
	return S_OK;
}

STDMETHODIMP CImpBlock::ExitInstance()
{
	return S_OK;
}

STDMETHODIMP CImpBlock::ProcessRev(const DWORD dwProcessId, REVDATAMAP &rRevDataMap)
{
	// rRevDataMap.insert(std::pair<DWORD, REVDATA>(/*identifikator dat*/, /*struktura revdata*/));
	// musi se provest kontrola, jestli jiz data s timto identifikatorem nejsou v mape
	// jestli ano, vrati se S_FALSE
	return S_OK;
}

STDMETHODIMP CImpBlock::ClearRevMap(REVDATAMAP &rRevDataMapClean)
{
	// smazani zpetnych dat
	// REVDATAMAP::iterator it;
	// it = rRevDataMapClean.find(/*identifikator dat*/);
	// ASSERT (it != rRevDataMapClean.end());
	// rRevDataMapClean.erase(it);
	return S_OK;
}

STDMETHODIMP CImpBlock::ProcessData(const LPBLOCKDATA pInputData)
{
	// implementace zpracovani dat
	return S_OK;
}

STDMETHODIMP_(void) CImpBlock::Serialize(CArchive &ar)
{
	// ukladani dat na disk
	if ( ar.IsStoring() )
	{
		//ar << data1 << data2 << data3;
	}
	else
	{
		//ar >> data1 >> data2 >> data3;
	}
}