// BlockDirectory.cpp : implementation file
//

#include "stdafx.h"
#include "xpeluc01.h"
#include "BlockDirectory.h"
#include "BlockItem.h"

IMPLEMENT_SERIAL(CBlockDirectory, CObject, 0x00010000);

// CBlockDirectory

CBlockDirectory::CBlockDirectory()
{
}

CBlockDirectory::~CBlockDirectory()
{
	POSITION pos = m_mapDirContent.GetStartPosition();
	CString strKey;
	// mazani bloku v adresari
	
	while ( !m_listItemContent.IsEmpty() )
	{
		CBlockItem *pItem;
		pItem = (CBlockItem*)m_listItemContent.GetHead();
		pItem->Release();
		//delete pItem;
		m_listItemContent.RemoveHead();
	}
	// mazani podadresaru
	while (pos)
	{
		CObject *pItem;
		m_mapDirContent.GetNextAssoc(pos, strKey, pItem);
		if ( pItem )
			delete pItem;
	}

}

BOOL CBlockDirectory::InsertBlock(CString strPath, CBlockItem *pItem)
{
	int x = strPath.Find(L'/');
	CObject *pObj;
	if ( -1 != x || strPath.GetLength() > 0 )
	{
		// vlozit do podadresare
		CString strDirName = (-1 == x) ? strPath : strPath.Left(x);
		if ( m_mapDirContent.Lookup(strDirName, pObj) && pObj->IsKindOf(RUNTIME_CLASS(CBlockDirectory)) )
		{	// adresar jiz existuje
			CString strRemainPath = (-1 == x) ? L"" : strPath.Mid(x+1);
			((CBlockDirectory*)pObj)->InsertBlock(strRemainPath, pItem);
		}
		else
		{	// adresar neexistuje
			pObj = CBlockDirectory::CreateObject();
			m_mapDirContent.SetAt(strDirName, pObj);
			CString strRemainPath = (-1 == x) ? L"" : strPath.Mid(x+1);
			((CBlockDirectory*)pObj)->InsertBlock(strRemainPath, pItem);
		}
	}
	else
	{	// vlozit do tohoto adresare
		CString strBlkName = pItem->GetName();
		CBlockItem *pBlkCopy = pItem->Clone();
		m_listItemContent.AddTail(pBlkCopy);
	}
	return TRUE;
}

typedef struct
{
	POSITION pos;
	BOOL bContinue;
}__FINDDATA, *__LPFINDDATA;

HANDLE CBlockDirectory::FindFirstDir(CString &strKey, CBlockDirectory* &rpDir)
{
	if ( m_mapDirContent.IsEmpty() )
		return NULL;
	__LPFINDDATA ret = new __FINDDATA;
	ret->pos = m_mapDirContent.GetStartPosition();
	ret->bContinue = TRUE;
	m_mapDirContent.GetNextAssoc(ret->pos, strKey, (CObject *&)rpDir);
	return ret;
}

BOOL CBlockDirectory::FindNextDir(HANDLE hFind, CString &strKey, CBlockDirectory*& rpDir)
{
	__LPFINDDATA handle = (__LPFINDDATA)hFind;
	if ( !handle->pos )
	{
		delete handle;
		return FALSE;
	}
	m_mapDirContent.GetNextAssoc(handle->pos, strKey, (CObject *&)rpDir);
	return TRUE;
}

BOOL CBlockDirectory::FindClose(HANDLE hFind)
{
	__LPFINDDATA handle = (__LPFINDDATA)hFind;
	delete handle;
	return TRUE;
}


HANDLE CBlockDirectory::FindFirstItem(CBlockItem*& rpItem)
{
	if ( m_listItemContent.IsEmpty() )
		return NULL;
	__LPFINDDATA ret = new __FINDDATA;
	ret->pos = m_listItemContent.GetHeadPosition();
	ret->bContinue = TRUE;
	rpItem = (CBlockItem*)m_listItemContent.GetAt(ret->pos);
	m_listItemContent.GetNext(ret->pos);
	return ret;
}

BOOL CBlockDirectory::FindNextItem(HANDLE hFind, CBlockItem*& rpItem)
{
	__LPFINDDATA handle = (__LPFINDDATA)hFind;
	if ( !handle->pos )
	{
		delete handle;
		return FALSE;
	}
	rpItem = (CBlockItem*)m_listItemContent.GetAt(handle->pos);
	m_listItemContent.GetNext(handle->pos);
	return TRUE;
}


BOOL CBlockDirectory::Lookup(const CString &strKey, CBlockDirectory*& rpDir)
{

	return m_mapDirContent.Lookup(strKey, (CObject *&)rpDir);
}

// CBlockDirectory member functions
