// FilterManager.cpp: implementation of the CFilterManager class.
//
//////////////////////////////////////////////////////////////////////

/** \file FilterManager.cpp
	\brief implementace tøídy CFilterManager
*/

#include "stdafx.h"
#include "FilterManager.h"


#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
//#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CFilterManager::CFilterManager()
{
	TRACE("-- Entering CFilterManager default constructor --\n");

	m_pSourceArray = NULL;
	m_pTargetArray = NULL;
	m_pos = NULL;
	m_listCreated.RemoveAll();
	m_listRegistred.RemoveAll();
}

CFilterManager::~CFilterManager()
{
	TRACE("-- Entering CFilterManager destructor --\n");

	CFilterBase* pBase;

	while(!m_listCreated.IsEmpty())
		{
			pBase = (CFilterBase*)m_listCreated.RemoveHead();
			cout << "Removing created: " << pBase->GetName() << "\n";
			delete pBase;
		}

	m_listRegistred.RemoveAll();

	if(m_pSourceArray != NULL)
	{
		//MRXXXm_pSourceArray->Destroy();
		m_pSourceArray = NULL;
	}

	if(m_pTargetArray != NULL)
	{
		//MRXXXm_pTargetArray->Destroy();
		m_pTargetArray = NULL;
	}
}


void CFilterManager::AddFilter(CFilterBase* pFilter)
{
	TRACE("-- Entering CFilterManager::Add --\n");	
	TRACE("------> Adding to tail position! \n");

	m_listCreated.AddTail(pFilter);
}


bool CFilterManager::StartProcess()
{
	TRACE("Processing started.....\n");
/*MRXXX
	CFilterBase* pFilter;
	CStructures::Point size;

	if (m_listRegistred.GetCount() > 0)
	{
		//m_pSourceArray = new CPixelArray("Input\\pattern.jpg");	//zdrojovy obraz

		m_pos = m_listRegistred.GetTailPosition();			//Pozice prvni filtru pro vypocet
		
		while(m_pos)
		{
			pFilter = (CFilterBase*)m_listRegistred.GetPrev(m_pos);	//ukazatel na filtr v seznamu
			cout << "\t" << pFilter->GetName();
			size = pFilter->GetSize();								//ziska jeho velikost
			m_pTargetArray = new CPixelArray(size.X, size.Y, 4);		//alokuje pro nej pamet dane velikosti
			pFilter->Transform(m_pSourceArray, m_pTargetArray);			//provede transformaci, vysledek je v m_pTargetArray

			//zobrazeni
			if(pFilter->Display())
				m_pTargetArray->Display(pFilter->GetName());

			//ulozeni
			if(pFilter->Save())
			{	
				const char* name = pFilter->GetName();
				m_pTargetArray->Save(name);
			}
				

			delete m_pSourceArray;				// zdrojovy obraz uz neni treba
			m_pSourceArray = m_pTargetArray;	//novym zdrojem je predchozi vysledek
		
		}

		delete m_pSourceArray;					//uklid po skonceni vypoctu	
		m_pSourceArray = NULL;
		m_pTargetArray = NULL;

		cout << "Done.\n";
		return true;
	}
	else 
		return false;



	/*------- TEST VERSION --------*/
	/*
	if (m_listRegistred.GetCount() > 0)
	{
		m_pos = m_listRegistred.GetHeadPosition();

		while(m_pos)
		{
			pFilter = (CFilterBase*)m_listRegistred.GetNext(m_pos);

			TRACE("Zpracovavam %s\n", pFilter->GetName());
			TRACE("Parameter = %f \n\n",pFilter->GetParam());
		}
		return true;
	}
	else*/
		return false;
	
}



void CFilterManager::RegisterFilter(CFilterBase* pFilter, int index)
{
	TRACE("Entering CFilterManager::RegisterFilter\n");

	POSITION pos;

	pos = m_listRegistred.FindIndex(index);
	
	if (pos == NULL)
	{
		TRACE("------> Adding to tail position! \n");
		m_listRegistred.AddTail(pFilter);
	}
	else
	{
		TRACE("------> Adding to position: %d\n", index );
		m_listRegistred.InsertBefore(pos, pFilter);
	}
}

void CFilterManager::RegisterAll()
{
	POSITION pos;
	CFilterBase* pFB;

	pos = m_listCreated.GetHeadPosition();
	while(pos)
	{
		pFB = (CFilterBase*)m_listCreated.GetNext(pos);
		m_listRegistred.AddTail(pFB);
		pFB->Use(true);
	}
}


void CFilterManager::UnregisterFilter(int index)
{
	TRACE("Entering CFilterManager::UnregisterFilter\n");

	POSITION pos;

	pos = m_listRegistred.FindIndex(index);

	if (pos != NULL)
	{
		TRACE("Removing filter at position: %d\n", index);
		m_listRegistred.RemoveAt(pos);
	}
	else
	{
		TRACE("Filter not found!\n");
	}
}

void CFilterManager::UnregisterAll()
{
	CFilterBase *pFB;

	while(!m_listRegistred.IsEmpty())
		{
			pFB = (CFilterBase*)m_listRegistred.RemoveHead();
			pFB->Use(false);
		}
}

void CFilterManager::Empty()
{
	CFilterBase* pBase;

	//vyprazdni seznam zarazenych filtru
	UnregisterAll();

	//vyprazdni seznam vyrvorenych filtru
	while(!m_listCreated.IsEmpty())
		{
			pBase = (CFilterBase*)m_listCreated.RemoveHead();
			cout << "Removing created: " << pBase->GetName() << "\n";
			delete pBase;
		}
}

//PrepareFilters
bool CFilterManager::PrepareFilters(CCamera* pCamera, CPatternManager* pPatternManager)
{	
	TRACE("Entering CFilterManager::PrepareFiltres\n");

	CStructures::iPoint size;
	CFilterBase* pFilter;
	POSITION pos;

	if (m_listRegistred.GetCount() > 0)
	{
		size = pCamera->GetSize();					//zjistime rozmery kamery
		pos = m_listRegistred.GetHeadPosition();	//nastavi ukazatel na prvni pozici v seznamu filtru

		while(pos)		//dokud nejsme na konci seznamu						
		{
			pFilter = (CFilterBase*) m_listRegistred.GetNext(pos);	//ziska ukazatel na filtr v seznamu
			pFilter->SetSize(size);									//nastavi velikost podle predchoziho filtru
			size = pFilter->GetNextSize();							//vrati velikost potrebnou pro nasledujici filtr
		}

		//potrebna velikost pro MasterImage
		 pPatternManager->SetResolution(size.X, size.Y);


		return true;
	}
	else 
		return false;


	
}


CFilterBase* CFilterManager::GetFilterCreated(int index)
{
	POSITION pos;
	pos = m_listCreated.FindIndex(index);

	if (pos != NULL)
	{
		//printf("Geting filter at position: %d\n", index);
		return (CFilterBase*)m_listCreated.GetAt(pos);
	}
	else
	{
		printf("Filter not found!\n");
		return NULL;
	}

}


CFilterBase* CFilterManager::GetFilterRegistred(int index)
{
	POSITION pos;
	pos = m_listRegistred.FindIndex(index);

	if (pos != NULL)
	{
		//printf("Geting filter at position: %d\n", index);
		return (CFilterBase*)m_listRegistred.GetAt(pos);
	}
	else
	{
		printf("Filter not found!\n");
		return NULL;
	}

}


int CFilterManager::GetCountCreated()
{
	return (m_listCreated.GetCount());
}


int CFilterManager::GetCountRegistred()
{
	return (m_listRegistred.GetCount());
}

void CFilterManager::MoveUp(int index)
{
	POSITION posNew;
	POSITION posCur;
	CFilterBase *pFilter;

	posCur = m_listRegistred.FindIndex(index);
	posNew = m_listRegistred.FindIndex(index - 1);

	if (posCur != NULL)
	{
		pFilter = (CFilterBase*)m_listRegistred.GetAt(posNew);
		m_listRegistred.InsertAfter(posCur, pFilter);
		m_listRegistred.RemoveAt(posNew);
		
	}
}

void CFilterManager::MoveDown(int index)
{
	POSITION posNew;
	POSITION posCur;
	CFilterBase *pFilter;

	posCur = m_listRegistred.FindIndex(index);
	posNew = m_listRegistred.FindIndex(index + 1);

	if (posCur != NULL)
	{
		pFilter = (CFilterBase*)m_listRegistred.GetAt(posCur);
		m_listRegistred.InsertAfter(posNew, pFilter);
		m_listRegistred.RemoveAt(posCur);
		
	}

}

void CFilterManager::LoadPattern(char path[])
{
	TRACE("-- Loading pattern from file %s --\n", path);
	//MRXXXm_pSourceArray = new CPixelArray(path);	//zdrojovy obraz
}


void CFilterManager::LoadPattern(CPixelArray* pPattern)
{
	TRACE("--Loading Created Pattern--\n");
	
	m_pSourceArray = pPattern;
}


void CFilterManager::SetSavePath(CString strPath)
{
	m_strSavePath = strPath;
}

void CFilterManager::SaveCreated()
{
	/*
	
	TRACE("Entering CFilterManager::SaveCreated\n");

	CMarkup xml;
	CFilterBase* pFilter;

	xml.AddElem("PROJEKT");
	xml.IntoElem(); //Inside PROJEKT
	xml.AddElem("FILTRY");
	xml.IntoElem(); //inside FILTRY
	

	if (m_listCreated.GetCount() > 0)
	{
		m_pos = m_listCreated.GetHeadPosition();

		while(m_pos)
		{
			pFilter = (CFilterBase*)m_listCreated.GetNext(m_pos);

			xml.AddElem("FILTR");
			xml.SetAttrib("id", "1");
			xml.SetAttrib("Name", pFilter->GetName());
			xml.IntoElem(); //inside FILTR
			xml.AddElem("ROZMERY");
			xml.IntoElem();
			xml.AddElem("VYSKA", "800");
			xml.AddElem("SIRKA", "600");
			xml.OutOfElem();
			xml.AddElem("PARAMS");
			xml.SetAttrib("Fokus", pFilter->GetCameraFocus());
			xml.SetAttrib("Distance", pFilter->GetDistance());
			xml.SetAttrib("Param", pFilter->GetParam());
			xml.OutOfElem(); // back to FILTRY lvl

			TRACE("Zpracovavam %s\n", pFilter->GetName());
			TRACE("Parameter = %f \n\n",pFilter->GetParam());
		}

		xml.Save("C:\\projekt2.xml");
	}
	*/
}