#include "pch.h"
#include "MxHead.h"
#include "MxOptBlockTable.h"
#include "DxfLib\dl_codes.h"
#include "DxfLib\dl_dxf.h"
#include "DxfLib\dl_writer_ascii.h"
#include "MxWriteContext.h"
#include "Tool.h"

#include "MxOptEntity.h"
#include "MxReadContext.h"

MxOptBlockTable::MxOptBlockTable(MxWriteContext* pWriteContext)
	: m_pWriteContext(pWriteContext)
{
	m_pReadContext = NULL;
}

MxOptBlockTable::MxOptBlockTable(MxReadContext* pReadContext)
	: m_pReadContext(pReadContext)
{
	m_pWriteContext = NULL;
}

MxOptBlockTable::~MxOptBlockTable(void)
{
}

bool MxOptBlockTable::Mx2Dxf(DL_WriterA* dw)
{
	// Section BLOCKS:
	dw->sectionBlocks();

	WriteBlock(MCDB_MODEL_SPACE,dw,false);
	WriteBlock(MCDB_PAPER_SPACE,dw,false);
	WriteBlock(_T("*Paper_Space0"),dw,false);

	while(true)
	{
		McDbBlockTablePointer  spBlkTable(m_pWriteContext->GetDatabase(),
			McDb::kForRead);

		if(spBlkTable.openStatus() != Mcad::eOk)
		{
			break;
		}

		McDbBlockTableIterator* pIterator = NULL;
		spBlkTable->newIterator(pIterator);
		if(pIterator == NULL)
			break;

		for(;!pIterator->done();pIterator->step() )
		{
			McDbObjectId recId;
			pIterator->getRecordId(recId);
			McDbObjectPointer<McDbBlockTableRecord> spBlkRec(recId,McDb::kForRead);
			if(spBlkRec.openStatus() != Mcad::eOk)
				continue;

			MxString sName;
			spBlkRec->getName(sName);

			if(sName.CompareNoCase(MCDB_MODEL_SPACE) == 0
				|| sName.CompareNoCase(MCDB_PAPER_SPACE) == 0
				|| sName.CompareNoCase(_T("*Paper_Space0")) == 0
				)
			{
				// 这些块名，是系统中缺省的，已经在前面处理.
			
				continue;

			}
			spBlkRec->close();

			WriteBlock(sName,dw,true);
		}

		delete pIterator;
		break;
	}

	dw->sectionEnd();

	return true;
}


void MxOptBlockTable::WriteEntity(McDbBlockTableRecord* pBlkRec,DL_WriterA* dw) 
{
	// 写实体。
	while(true)
	{
	//	if(pBlkRec->openStatus() != Mcad::eOk)
		//	break;
		//
		McDbBlockTableRecordIterator* pIterator = NULL;
		pBlkRec->newIterator(pIterator);
		if(pIterator == NULL)
			break;

		MxOptEntity optEntity(m_pWriteContext);
		for(;!pIterator->done();pIterator->step() )
		{
			McDbObjectId entId;
			pIterator->getEntityId(entId);

			// 写实体信息.
			optEntity.Mx2Dxf(entId,dw);
		}

		//
		delete pIterator;

		break;
	}

}

void MxOptBlockTable::WriteBlockEntity(MxString sBlkName,DL_WriterA* dw)
{
	McDbBlockTableRecordPointer spBlkRec(sBlkName,
		m_pWriteContext->GetDatabase(),
		McDb::kForRead);

	if(spBlkRec.openStatus() == Mcad::eOk)
	{
		WriteEntity(spBlkRec.object(),dw);
	}
}

void MxOptBlockTable::WriteBlock(MxString sBlkName,DL_WriterA* dw,bool isWriteEntity)
{
	string sBlkNameA = MXDXF_W2A(sBlkName);
	
	McDbBlockTableRecordPointer spBlkRec(sBlkName,
		m_pWriteContext->GetDatabase(),
		McDb::kForRead);

	McGePoint3d basePoint(0,0,0);

	if(spBlkRec.openStatus() == Mcad::eOk)
	{
		basePoint = spBlkRec->origin();
	}

	m_pWriteContext->GetDxf()->writeBlock(*dw,
		DL_BlockData(sBlkNameA, 0,
		basePoint.x,
		basePoint.y,
		basePoint.z)
		);

	if(isWriteEntity 
		&& spBlkRec.openStatus() == Mcad::eOk)
	{
		WriteEntity(spBlkRec.object(),dw);
	}
	

	m_pWriteContext->GetDxf()->writeEndBlock(*dw, sBlkNameA);
}

McDbObjectId MxOptBlockTable::Dxf2Mx(const DL_BlockData& data)
{
	if(m_pReadContext == NULL)
	{
		ASSERT(0);
		return McDbObjectId::kNull;
	}

	McDbBlockTablePointer spBlockTable(m_pReadContext->GetDatabase(),
		McDb::kForWrite);

	if(spBlockTable.openStatus() != Mcad::eOk)
	{
		ASSERT(0);
		return McDbObjectId::kNull;
	}

	McDbObjectId recId;

	MxString sName = MXDXF_A2W(data.name.c_str() );
	if((!Tool::IsSystemDefaultBlockName(sName)) 
		&& (!(spBlockTable->has(sName)) )
		)
	{
		if(spBlockTable->getAt(sName,recId,true) != Mcad::eOk)
		{
			McDbBlockTableRecord* pNew = new McDbBlockTableRecord;
			pNew->setName(sName);

			pNew->setOrigin(McGePoint3d(data.bpx, data.bpy,0.0));

			if(spBlockTable->add(recId,pNew) != Mcad::eOk)
			{
				ASSERT(0);
				delete pNew;
			}
			else
			{
				pNew->close();
			}
		}
	}

	return recId;
}