#pragma once

class McDbDwgFiler;

#include "McRxClass.h"
#include "McRxObject.h"
#include "McDbSymbolTable.h"
#include "McDbObject.h"

class MxIdList;
class McDbDatabaseImp;
class MxUndo;
class McApDocument;

class McDbDictionary;
class McDbRegAppTable;
class McDbRegAppTableRecord;
class McDbDimStyleTable;
class McDbDimStyleTableRecord;
class McDbHandle;
class McDbExternalReferencesDatabaseManager;

class ARXDLL McDbDatabaseReactor 
{
public:	
	virtual void headerSysVarWillChange(LPCMSTR pszName) {};
	virtual void headerSysVarChanged(LPCMSTR pszName, Mdesk::Boolean bSuccess) {};
	virtual void databaseReInit() {};
};

class ARXDLL McDbDatabaseInsertResult {
public:
	McDbDatabaseInsertResult() {
		mIsInsertNewInstanceBlockRecord = false;
		misRegenOpenGLInstance = false;
	}
	// 插入图块后，新需要加载图片定义
	std::vector<McDbObjectId> mVecInsertImageDefinedId;
	
	// 返回值：是否有新的，Instance块表记录，需要重新RegenOpenGLInstance
	bool                                    mIsInsertNewInstanceBlockRecord;

	// 是否要调用RegenOpenGLInstance
	bool                                    misRegenOpenGLInstance;
};


#define ViewportActiveNameStr _MXT("*Active")


#define MX_McDbDatabase_Start_Pool 2000
// -------------------------------------------------------------------------
// Summary:
// 		控件的数据库对象，图形中的所有信息都存放在该对象中，调用MxDraw::GetDatabase()函数得到控件的数据库，调用acdbCurDwg()得到当前活动控件的数据库
// -------------------------------------------------------------------------
class ARXDLL McDbDatabase : public McDbObject
{
public:
	
	// -------------------------------------------------------------------------
	// Summary:
	// 		申明类型信息
	// -------------------------------------------------------------------------
	MCDB_DECLARE_MEMBERS(McDbDatabase);
	// -------------------------------------------------------------------------
	// Summary:
	// 		构造函数
	// Parameters:
	// 		buildDefaultDrawing		-	同时创建数据库中的缺省数据，比如0层，实线型记录等
	//		noDocument				-	没有使用
	// -------------------------------------------------------------------------
	McDbDatabase(bool buildDefaultDrawing = true,bool noDocument = false);

	// -------------------------------------------------------------------------
	// Summary:
	// 		析构函数
	// -------------------------------------------------------------------------
	virtual ~McDbDatabase();


	void              addReactor(McDbDatabaseReactor* pReactor) const;

	// -------------------------------------------------------------------------
	// Summary:
	// 		注销一个数据库事件反应器，用于监视数据库事件
	// Parameters:
	// 		pReactor	-	数据库反应器指针
	// -------------------------------------------------------------------------
	void              removeReactor(McDbDatabaseReactor* pReactor) const;
	
	// -------------------------------------------------------------------------
	// Summary:
	// 		得到块表对象
	// Parameters:
	// 		pTable	-	返回块表指针
	//		mode	-	块表的打开方式，读/写方式
	// Returns:
	// 		如果成功返回Mcad::eOk，如果传递的数据非法则返回Mcad::eInvalidInput
	// -------------------------------------------------------------------------
	Mcad::ErrorStatus getBlockTable     (McDbSymbolTable*& pTable,
		McDb::OpenMode    mode);
	// -------------------------------------------------------------------------
	// Summary:
	// 		得到层表对象
	// Parameters:
	// 		pTable	-	返回层表指针
	//		mode	-	层表的打开方式，读/写方式
	// Returns:
	// 		如果成功返回Mcad::eOk，如果传递的数据非法则返回Mcad::eInvalidInput
	// -------------------------------------------------------------------------
	Mcad::ErrorStatus getLayerTable     (McDbSymbolTable*& pTable,
		McDb::OpenMode    mode);

	// -------------------------------------------------------------------------
	// Summary:
	// 		得到线型表对象
	// Parameters:
	// 		pTable	-	返回线型表指针
	//		mode	-	线型表的打开方式，读/写方式
	// Returns:
	// 		如果成功返回Mcad::eOk，如果传递的数据非法则返回Mcad::eInvalidInput
	// -------------------------------------------------------------------------
	Mcad::ErrorStatus getLinetypeTable  (McDbSymbolTable*& pTable,
		McDb::OpenMode    mode);

	// -------------------------------------------------------------------------
	// Summary:
	// 		得到文字风格表对象
	// Parameters:
	// 		pTable	-	返回文字风格表指针
	//		mode	-	文字风格表的打开方式，读/写方式
	// Returns:
	// 		如果成功返回Mcad::eOk，如果传递的数据非法则返回Mcad::eInvalidInput
	// -------------------------------------------------------------------------
	Mcad::ErrorStatus getTextStyleTable  (McDbSymbolTable*& pTable,
		McDb::OpenMode    mode);

	
	// -------------------------------------------------------------------------
	// Summary:
	// 		得到标注风格表对象
	// Parameters:
	// 		pTable	-	返回标注风格表指针
	//		mode	-	标注风格表的打开方式，读/写方式
	// Returns:
	// 		如果成功返回Mcad::eOk，如果传递的数据非法则返回Mcad::eInvalidInput
	// -------------------------------------------------------------------------
	Mcad::ErrorStatus getDimStyleTable  (McDbSymbolTable*& pTable,
		McDb::OpenMode    mode);

	// -------------------------------------------------------------------------
	// Summary:
	// 		得到块表对象
	// Parameters:
	// 		pTable	-	返回块表指针
	//		mode	-	块表的打开方式，读/写方式
	// Returns:
	// 		如果成功返回Mcad::eOk，如果传递的数据非法则返回Mcad::eInvalidInput
	// -------------------------------------------------------------------------
	Mcad::ErrorStatus getSymbolTable    (McDbBlockTable*&     pTable,
		McDb::OpenMode       mode);
	// -------------------------------------------------------------------------
	// Summary:
	// 		得到层表对象
	// Parameters:
	// 		pTable	-	返回层表指针
	//		mode	-	层表的打开方式，读/写方式
	// Returns:
	// 		如果成功返回Mcad::eOk，如果传递的数据非法则返回Mcad::eInvalidInput
	// -------------------------------------------------------------------------
	Mcad::ErrorStatus getSymbolTable    (McDbLayerTable*&     pTable,
		McDb::OpenMode       mode);
	// -------------------------------------------------------------------------
	// Summary:
	// 		得到线型表对象
	// Parameters:
	// 		pTable	-	返回线型表指针
	//		mode	-	线型表的打开方式，读/写方式
	// Returns:
	// 		如果成功返回Mcad::eOk，如果传递的数据非法则返回Mcad::eInvalidInput
	// -------------------------------------------------------------------------
	Mcad::ErrorStatus getSymbolTable    (McDbLinetypeTable*&  pTable,
		McDb::OpenMode       mode);

	// -------------------------------------------------------------------------
	// Summary:
	// 		得到文字风格表对象
	// Parameters:
	// 		pTable	-	返回文字风格表指针
	//		mode	-	文字风格表的打开方式，读/写方式
	// Returns:
	// 		如果成功返回Mcad::eOk，如果传递的数据非法则返回Mcad::eInvalidInput
	// -------------------------------------------------------------------------
	Mcad::ErrorStatus getSymbolTable    (McDbTextStyleTable*&  pTable,
		McDb::OpenMode       mode);

	

	// -------------------------------------------------------------------------
	// Summary:
	// 		得到标注风格表对象
	// Parameters:
	// 		pTable	-	返回标注风格表指针
	//		mode	-	标注风格表的打开方式，读/写方式
	// Returns:
	// 		如果成功返回Mcad::eOk，如果传递的数据非法则返回Mcad::eInvalidInput
	// -------------------------------------------------------------------------
	Mcad::ErrorStatus getSymbolTable    (McDbDimStyleTable*&    pTable,
		McDb::OpenMode       mode);



	// -------------------------------------------------------------------------
	// Summary:
	// 		得到块表对象
	// Parameters:
	// 		pTable	-	返回块表指针
	//		mode	-	块表的打开方式，读/写方式
	// Returns:
	// 		如果成功返回Mcad::eOk，如果传递的数据非法则返回Mcad::eInvalidInput
	// -------------------------------------------------------------------------
	Mcad::ErrorStatus getBlockTable     (McDbBlockTable*& pTable,
		McDb::OpenMode    mode);

	// -------------------------------------------------------------------------
	// Summary:
	// 		得到层表对象
	// Parameters:
	// 		pTable	-	返回层表指针
	//		mode	-	层表的打开方式，读/写方式
	// Returns:
	// 		如果成功返回Mcad::eOk，如果传递的数据非法则返回Mcad::eInvalidInput
	// -------------------------------------------------------------------------
	Mcad::ErrorStatus getLayerTable     (McDbLayerTable*& pTable,
		McDb::OpenMode    mode);

	// -------------------------------------------------------------------------
	// Summary:
	// 		得到线型表对象
	// Parameters:
	// 		pTable	-	返回线型表指针
	//		mode	-	线型表的打开方式，读/写方式
	// Returns:
	// 		如果成功返回Mcad::eOk，如果传递的数据非法则返回Mcad::eInvalidInput
	// -------------------------------------------------------------------------
	Mcad::ErrorStatus getLinetypeTable  (McDbLinetypeTable*& pTable,
		McDb::OpenMode    mode);

	// -------------------------------------------------------------------------
	// Summary:
	// 		得到文字风格表对象
	// Parameters:
	// 		pTable	-	返回文字风格表指针
	//		mode	-	文字风格表的打开方式，读/写方式
	// Returns:
	// 		如果成功返回Mcad::eOk，如果传递的数据非法则返回Mcad::eInvalidInput
	// -------------------------------------------------------------------------
	Mcad::ErrorStatus getTextStyleTable  (McDbLinetypeTable*& pTable,
		McDb::OpenMode    mode);

	// -------------------------------------------------------------------------
	// Summary:
	// 		返回命名对象字典
	// Parameters:
	// 		pDict	-	返回的字典指针
	// 		pDict	-	对象的打开方式
	// Returns:
	// 		如果成功返回Mcad::eOk，如果传递的数据非法则返回Mcad::eInvalidInput
	// Remarks:
	// 		例如:读取数据命名对象字典中所有数据
	// 		<code>
	// 			LPCMSTR
	// 				CTestCommands::bytesToHexStr(char* buffer, int len, MxString& hexStr)
	// 			{
	// 				unsigned char k;
	// 				int j;
	// 				MxString tmpStr;
	// 
	// 				hexStr.Empty();    // make sure nothing in it yet since we are concatenating it
	// 
	// 				for (j=0;j<len;j++) {
	// 					k = static_cast<unsigned char>(buffer[j]);
	// 					tmpStr.Format(_T("%02hX"), k);
	// 					hexStr += tmpStr;
	// 				}
	// 				return hexStr;
	// 			}
	// 
	// 
	// 			int
	// 				CTestCommands::dxfCodeToDataType(int resType)
	// 			{
	// 				if ((resType >= 0) && (resType <= 9))
	// 					return RTSTR;
	// 				else if ((resType >= 10) && (resType <= 17))
	// 					return RT3DPOINT;
	// 				else if ((resType >= 38) && (resType <= 59))
	// 					return RTREAL;
	// 				else if ((resType >= 60) && (resType <= 79))
	// 					return RTSHORT;
	// 				else if ((resType >= 90) && (resType <= 99))
	// 					return RTLONG;
	// 				else if ((resType == 100) || (resType == 101) || (resType == 102) ||(resType == 105))
	// 					return RTSTR;
	// 				else if ((resType >= 110) && (resType <= 112))
	// 					return RTSTR;
	// 				else if ((resType >= 140) && (resType <= 149))
	// 					return RTREAL;
	// 				else if ((resType >= 170) && (resType <= 179))
	// 					return RTSHORT;
	// 				else if ((resType >= 210) && (resType <= 219))
	// 					return RT3DPOINT;
	// 				else if ((resType >= 270) && (resType <= 299))
	// 					return RTSHORT;
	// 				else if ((resType >= 300) && (resType <= 309))
	// 					return RTSTR;
	// 				// 310-319为二进制数据
	// 				else if ((resType >= 310) && (resType <= 319))
	// 					return resType;
	// 				else if ((resType >= 320) && (resType <= 369))
	// 					return RTENAME;
	// 				else if ((resType >= 370) && (resType <= 379))
	// 					return RTSHORT;
	// 				else if ((resType >= 380) && (resType <= 389))
	// 					return RTSHORT;
	// 				else if ((resType >= 390) && (resType <= 399))
	// 					return RTENAME;
	// 				else if ((resType >= 400) && (resType <= 409))
	// 					return RTSHORT;
	// 				else if ((resType >= 410) && (resType <= 419))
	// 					return RTSTR;
	// 				else if (resType == 1004)
	// 					return resType;        // binary chunk
	// 				else if ((resType >= 999) && (resType <= 1009))
	// 					return RTSTR;
	// 				else if ((resType >= 1010) && (resType <= 1013))
	// 					return RT3DPOINT;
	// 				else if ((resType >= 1038) && (resType <= 1059))
	// 					return RTREAL;
	// 				else if ((resType >= 1060) && (resType <= 1070))
	// 					return RTSHORT;
	// 				else if ((resType == 1071))
	// 					return RTLONG;
	// 				else if ((resType < 0) || (resType > 4999))
	// 					return resType;
	// 				else
	// 					return RTNONE;
	// 			}
	// 
	// 			void
	// 				CTestCommands::dxfToStr(const resbuf* rb, MxString& dxfCodeStr, MxString& valueStr)
	// 			{
	// 				int dataType = dxfCodeToDataType(rb->restype);
	// 				dxfCodeStr.Format(_T("%d"), rb->restype);
	// 
	// 				MxString tmpStr;
	// 
	// 				switch (dataType) {
	// 				case RTSHORT:
	// 					valueStr.Format(_T("%d"), rb->resval.rint);
	// 					break;
	// 				case RTLONG:
	// 					valueStr.Format(_T("%ld"), rb->resval.rlong);
	// 					break;
	// 				case RTREAL:
	// 					valueStr.Format(_T("%g"), rb->resval.rreal);
	// 					break;
	// 				case RTSTR:
	// 					if (rb->resval.rstring == NULL)
	// 						valueStr = _T("(NULL)");
	// 					else
	// 						valueStr.Format(_T("\"%s\""), rb->resval.rstring);
	// 					break;
	// 				case RT3DPOINT:
	// 					valueStr.Format(_T("(%g, %g, %g)"), rb->resval.rpoint[X],
	// 						rb->resval.rpoint[Y], rb->resval.rpoint[Z]);
	// 					break;
	// 				case RTPOINT:
	// 					valueStr.Format(_T("(%g, %g)"), rb->resval.rpoint[X], rb->resval.rpoint[Y]);
	// 					break;
	// 
	// 				case -6:
	// 					valueStr = _T("Extension Dictionary");
	// 					break;
	// 				case -5:
	// 					valueStr = _T("Persistent Reactors");
	// 					break;
	// 				case -4:
	// 					valueStr.Format(_T("Conditional Operator: \"%s\""), rb->resval.rstring);
	// 					break;
	// 				case -3:
	// 					valueStr = _T("Start of Xdata");
	// 					break;
	// 				case -2:
	// 					valueStr.Format(_T("<Entity Name Reference: %8lx>"), rb->resval.rlname[0]);
	// 					break;
	// 				case -1:
	// 				case RTENAME:
	// 					if ((rb->restype >= 330 )&& (rb->restype < 340))
	// 						valueStr.Format(_T("<Soft Pointer: %8lx>"), rb->resval.rlname[0]);
	// 					else if((rb->restype >= 340) && (rb->restype < 350))
	// 						valueStr.Format(_T("<Hard Pointer: %8lx>"), rb->resval.rlname[0]);
	// 					else if((rb->restype >= 350) && (rb->restype < 360))
	// 						valueStr.Format(_T("<Soft Ownership: %8lx>"), rb->resval.rlname[0]);
	// 					else if((rb->restype >= 360) && (rb->restype < 370))
	// 						valueStr.Format(_T("<Hard Ownership: %8lx>"), rb->resval.rlname[0]);
	// 					else if((rb->restype >= 390) && (rb->restype < 399))
	// 						valueStr.Format(_T("<Hard Pointer: %8lx>"), rb->resval.rlname[0]);
	// 					else
	// 						valueStr.Format(_T("<Entity Name: %8lx>"), rb->resval.rlname[0]);
	// 					break;
	// 				case RTPICKS:
	// 					valueStr.Format(_T("<Selection Set: %8lx>"), rb->resval.rlname[0]);
	// 					break;
	// 				case RTLB:
	// 					valueStr = _T("List Begin");
	// 					break;
	// 				case RTLE:
	// 					valueStr = _T("List End");
	// 					break;
	// 				case RTNIL:
	// 					valueStr = _T("NIL");
	// 					break;
	// 				case RTT:
	// 					valueStr = _T("T");
	// 					break;
	// 				default:
	// 					{
	// 						if (dataType == 1004 || (dataType >= 310 && dataType <= 319) ) 
	// 						{
	// 							// 二进制数据。
	// 							valueStr.Format(_T("Binary Chunk: \"%s\""),
	// 								bytesToHexStr(rb->resval.rbinary.buf,
	// 								rb->resval.rbinary.clen, tmpStr));
	// 
	// 						}
	// 						else
	// 						{
	// 							valueStr = _T("*Unknown*");
	// 						}
	// 					}
	// 					break;
	// 				}
	// 			}
	// 
	// 			void
	// 				CTestCommands::printResbufChain(resbuf* const rb)
	// 			{
	// 				MxString dxfCodeStr, valueStr, tmpStr;
	// 				resbuf* tmp = rb;
	// 				while (tmp) {
	// 					dxfToStr(tmp, dxfCodeStr, valueStr);
	// 					tmpStr.Format(_T("\n(%s . %s)"), dxfCodeStr, valueStr);
	// 					acutPrintf(static_cast<LPCMSTR>(tmpStr));
	// 					tmp = tmp->rbnext;
	// 				}
	// 			}
	// 
	// 			void CTestCommands::ReadNamedObjectsDictionary()
	// 			{
	// 				{
	// 					// 把字典中所有的数据都输出
	// 					AcDbDatabase *pDb = acdbHostApplicationServices()->workingDatabase();
	// 					AcDbObjectPointer<AcDbDictionary> spDict(pDb->namedObjectsDictionaryId(),AcDb::kForRead);
	// 					if(spDict.openStatus() == Acad::eOk)
	// 					{
	// 						PrintDictionary(spDict.object() );
	// 					}
	// 				}
	// 
	// 
	// 				// 读取指定的数据.
	// 				AcDbDictionary *pNamedobj;
	// 				AcDbDatabase *pDb = acdbHostApplicationServices()->workingDatabase();
	// 				if(pDb->getNamedObjectsDictionary(pNamedobj, AcDb::kForRead) != Acad::eOk)
	// 				{
	// 					return ;
	// 				}
	// 				AcDbDictionary *pDict;
	// 				if(pNamedobj->getAt(_T("ESTATE_DICT"), (AcDbObject*&)pDict,AcDb::kForRead) != Acad::eOk)
	// 				{
	// 					pNamedobj->close();
	// 					return ;
	// 				}
	// 				pNamedobj->close();
	// 				//得到数据字典LAYERRECORD
	// 				AcDbXrecord *pXrec;
	// 				if(pDict->getAt(_T("LAYERRECORD"), (AcDbObject*&)pXrec,AcDb::kForRead) != Acad::eOk)
	// 				{
	// 					pDict->close();
	// 					return ;
	// 				}
	// 				pDict->close();
	// 
	// 				// 把记录中数据输出.
	// 
	// 				struct resbuf *pRbList;
	// 				pXrec->rbChain(&pRbList);
	// 				printResbufChain(pRbList);
	// 				acutRelRb(pRbList);
	// 
	// 				pXrec->close();
	// 
	// 			}
	// 		</code>
	// -------------------------------------------------------------------------
	Mcad::ErrorStatus getNamedObjectsDictionary(
		McDbDictionary*& pDict,
		McDb::OpenMode mode);

	Mcad::ErrorStatus getGroupDictionary(McDbDictionary*& pDict,
		McDb::OpenMode mode);


	// -------------------------------------------------------------------------
	// Summary:
	// 		得到布局字典
	// Parameters:
	// 		pDict	-	返回的字典指针
	// 		mode	-	对象的打开方式
	// Returns:
	// 		如果成功返回Mcad::eOk，如果传递的数据非法则返回Mcad::eInvalidInput
	// Remarks:
	// 		例如:返回所有布局名
	// 		<code>
	// 			bool GetAllLayoutName(McDbDatabase* pDatabase,
	// 				std::vector<MxString>& allLayoutName)
	// 			{
	// 				if(pDatabase == NULL)
	// 				{
	// 					if(Mx::mcdbHostApplicationServices() != NULL)
	// 						pDatabase =  Mx::mcdbHostApplicationServices()->workingDatabase();
	// 				}
	// 
	// 				if(pDatabase == NULL)
	// 				{
	// 
	// 					return false;
	// 				}
	// 
	// 				McDbDictionary* pDict = NULL;
	// 				if(pDatabase->getLayoutDictionary(pDict,McDb::kForRead) != Mcad::eOk)
	// 				{
	// 
	// 					return false;
	// 				}
	// 
	// 				McDbDictionaryIterator* pIter = pDict->newIterator();
	// 				for(;!pIter->done();pIter->next() )
	// 				{
	// 					McDbObjectPointer<McDbLayout> spLayout(pIter->objectId(),McDb::kForRead);
	// 					if(spLayout.openStatus() != Mcad::eOk)
	// 						continue;
	// 
	// 					LPCMSTR pszLayoutName = NULL;
	// 					spLayout->getLayoutName(pszLayoutName);
	// 
	// 					MxString sTmpLayoutName(pszLayoutName);
	// 
	// 					allLayoutName.push_back(sTmpLayoutName);
	// 				}
	// 
	// 				pDict->close();
	// 				delete pIter;
	// 
	// 				return true;
	// 			}
	// 		</code>
	// -------------------------------------------------------------------------
	Mcad::ErrorStatus getLayoutDictionary  (McDbDictionary*& pDict,
		McDb::OpenMode mode) const;

	
	// -------------------------------------------------------------------------
	// Summary:
	// 		得到标注风格表对象
	// Parameters:
	// 		pTable	-	返回标注风格表指针
	//		mode	-	标注风格表的打开方式，读/写方式
	// Returns:
	// 		如果成功返回Mcad::eOk，如果传递的数据非法则返回Mcad::eInvalidInput
	// -------------------------------------------------------------------------
	Mcad::ErrorStatus getDimStyleTable  (McDbDimStyleTable*& pTable,
		McDb::OpenMode    mode);




	// -------------------------------------------------------------------------
	// Summary:
	// 		返回组字典id
	// -------------------------------------------------------------------------
	McDbObjectId       groupDictionaryId();



	// -------------------------------------------------------------------------
	// Summary:
	// 		返回块表id
	// -------------------------------------------------------------------------
	McDbObjectId		blockTableId();

	// -------------------------------------------------------------------------
	// Summary:
	// 		返回层表id
	// -------------------------------------------------------------------------
	McDbObjectId		layerTableId();

	// -------------------------------------------------------------------------
	// Summary:
	// 		返回线型表id
	// -------------------------------------------------------------------------
	McDbObjectId		linetypeTableId();

	// -------------------------------------------------------------------------
	// Summary:
	// 		返回文字样表id
	// -------------------------------------------------------------------------
	McDbObjectId		textStyleTableId();

	// -------------------------------------------------------------------------
	// Summary:
	// 		返回命名对象字典id
	// -------------------------------------------------------------------------
	McDbObjectId		namedObjectsDictionaryId();

	// -------------------------------------------------------------------------
	// Summary:
	// 		返回布局字典id
	// -------------------------------------------------------------------------
	McDbObjectId		layoutDictionaryId();

	
	// -------------------------------------------------------------------------
	// Summary:
	// 		返回标注风格表id
	// -------------------------------------------------------------------------
	McDbObjectId		dimStyleTableId();

	// -------------------------------------------------------------------------
	// Summary:
	// 		返回当前显示的块表记录id
	// -------------------------------------------------------------------------
	McDbObjectId		currentSpaceId() const;

	// -------------------------------------------------------------------------
	// Summary:
	// 		向数据库中新增加一个对象
	// Parameters:
	// 		pObj	-	 新对象指针
	// Returns:
	// 		如果成功返回Mcad::eOk，如果传递的数据非法则返回Mcad::eInvalidInput
	// -------------------------------------------------------------------------
	Mcad::ErrorStatus addMcDbObject(McDbObject*    pObj);

	// -------------------------------------------------------------------------
	// Summary:
	// 		向数据库中新增加一个对象
	// Parameters:
	// 		pObj	-		新对象指针
	//		objId	-		返回新增加的对象id
	// Returns:
	// 		如果成功返回Mcad::eOk，如果传递的数据非法则返回Mcad::eInvalidInput
	// -------------------------------------------------------------------------
	Mcad::ErrorStatus addMcDbObject(McDbObjectId&  objId,McDbObject*    pObj);

	//:Ignore

	Mcad::ErrorStatus addMcDbObject(McDbObject*    pObj,MxIdList* pList);

	Mcad::ErrorStatus addMcDbObject(McDbObjectId&  objId,McDbObject*    pObj,MxIdList* pList);
	//:End Ignore

	// -------------------------------------------------------------------------
	// Summary:
	// 		把当前对象克隆一个新对象
	// Returns:
	// 		返回新克隆的对象
	// -------------------------------------------------------------------------
	virtual McRxObject*        clone() const;

	// -------------------------------------------------------------------------
	// Summary:
	// 		返回与数据库相关联的文档对象指针
	// -------------------------------------------------------------------------
	McApDocument* GetDocument() const;



	// -------------------------------------------------------------------------
	// Summary:
	// 		返回数据库的当前LTSCALE值，全局的线型缩放比例，它会影响线型的显示缩放比例
	// -------------------------------------------------------------------------
	mxreal ltscale() const;

	// -------------------------------------------------------------------------
	// Summary:
	// 		设置数据库的当前LTSCALE值，全局的线型缩放比例
	// Parameters:
	// 		scale	-	新的缩放比例
	// Returns:
	// 		如果成功返回Mcad::eOk，如果传递的数据非法则返回Mcad::eInvalidInput
	// -------------------------------------------------------------------------
	Mcad::ErrorStatus setLtscale(mxreal scale);

	// -------------------------------------------------------------------------
	// Summary:
	// 		返回新增加到数据库的对象的默认线型缩放比例
	// -------------------------------------------------------------------------
	mxreal celtscale() const;

	// -------------------------------------------------------------------------
	// Summary:
	// 		设置新增加到数据库的对象的默认线型缩放比例
	// Parameters:
	// 		scale	-	新的缩放比例 
	// Returns:
	// 		如果成功返回Mcad::eOk，如果传递的数据非法则返回Mcad::eInvalidInput
	// -------------------------------------------------------------------------
	Mcad::ErrorStatus setCeltscale(mxreal scale);

	// -------------------------------------------------------------------------
	// Summary:
	// 		返回当前的线型id
	// -------------------------------------------------------------------------
	McDbObjectId celtype() const;

	// -------------------------------------------------------------------------
	// Summary:
	// 		设置当前的线型id
	// Parameters:
	// 		objId	-	当前的线型id 
	// Returns:
	// 		如果成功返回Mcad::eOk，如果传递的数据非法则返回Mcad::eInvalidInput
	// -------------------------------------------------------------------------
	Mcad::ErrorStatus setCeltype(McDbObjectId objId);

	// -------------------------------------------------------------------------
	// Summary:
	// 		返回当前的文字样式(McDbTextStyleTableRecord)的id
	// -------------------------------------------------------------------------
	McDbObjectId textstyle() const;

	McDb::LineWeight	celweight() const;
	Mcad::ErrorStatus setCelweight(McDb::LineWeight val);

	bool	getEntitiesInTheGroup(McDbObjectId idEntity, std::set<McDbObjectId>& ids, std::set<MxString>* pSetAdySearchGroutName,bool isSelectOpt = false);
	// -------------------------------------------------------------------------
	// Summary:
	// 		设置当前的文字样式(McDbTextStyleTableRecord)的id
	// Parameters:
	// 		objId	-	当前的文字样式(McDbTextStyleTableRecord)的id
	// Returns:
	// 		如果成功返回Mcad::eOk，如果传递的数据非法则返回Mcad::eInvalidInput
	// -------------------------------------------------------------------------
	Mcad::ErrorStatus setTextstyle(McDbObjectId objId);

	// -------------------------------------------------------------------------
	// Summary:
	// 		返回当前图层id
	// -------------------------------------------------------------------------
	McDbObjectId clayer() const;

	// -------------------------------------------------------------------------
	// Summary:
	// 		设置当前图层id
	// Parameters:
	// 		objId	-	当前图层id 
	// Returns:
	// 		如果成功返回Mcad::eOk，如果传递的数据非法则返回Mcad::eInvalidInput
	// -------------------------------------------------------------------------
	Mcad::ErrorStatus setClayer(McDbObjectId objId);

	// -------------------------------------------------------------------------
	// Summary:
	// 		返回当前颜色
	// -------------------------------------------------------------------------
	McCmColor cecolor() const;

	// -------------------------------------------------------------------------
	// Summary:
	// 		设置当前颜色
	// Parameters:
	// 		color	-	当前颜色 
	// Returns:
	// 		如果成功返回Mcad::eOk，如果传递的数据非法则返回Mcad::eInvalidInput
	// -------------------------------------------------------------------------
	Mcad::ErrorStatus setCecolor(const McCmColor& color);


	// -------------------------------------------------------------------------
	// Summary:
	// 		返回当前的标注样式,对应系统变量DIMSTYLE 的值
	// -------------------------------------------------------------------------
	McDbObjectId dimstyle() const;

	// -------------------------------------------------------------------------
	// Summary:
	// 		设置当前的标注样式,对应系统变量DIMSTYLE 的值
	// Parameters:
	// 		styleId - 标注记录对象id,应该是McDbDimStyleTableRecord对象的id
	// -------------------------------------------------------------------------
	Mcad::ErrorStatus setDimstyle(McDbObjectId styleId);

	// -------------------------------------------------------------------------
	// Summary:
	// 		返回数据库的插入基点，用于图块插入时的对齐点
	// -------------------------------------------------------------------------
	McGePoint3d insbase() const;

	// -------------------------------------------------------------------------
	// Summary:
	// 		设置数据库的插入基点，用于图块插入时的对齐点
	// Parameters:
	// 		base	-	新的对齐点
	// Returns:
	// 		如果成功返回Mcad::eOk，如果传递的数据非法则返回Mcad::eInvalidInput
	// -------------------------------------------------------------------------
	Mcad::ErrorStatus setInsbase(const McGePoint3d& base);

	// -------------------------------------------------------------------------
	// Summary:
	// 		读取DWG文件
	// Parameters:
	// 		pszFileName					-	DWG文件路径
	//		shmode						-	暂没有使用
	//		bAllowCPConversion			-	暂没有使用
	//		wszPassword					-	暂没有使用
	//      rc                          -    指定需要读取的内容,不需要读取的内容可以不读取，这样能提高读取dwg文件的速度,可以取如下值:
	// 										enum ReadContent
	// 										{
	// 											kReadAll		= 0xFFFFFFFF,
	//											kReadNull       = 0x0,				// 下面数据都不读取
	// 											kReadExData		= 0x1,
	// 											kReadHandle		= 0x2,
	// 											kReadBlockRefPreviewIcon	= 0x4,
	// 											kReadBlockLayoutName		= 0x8,
	// 											kReadObjectsDictionary		= 0x10,	// 是否读对象字典，如果不读，字典下所有数据都不会读取.
	// 											kReadGroupDict              = 0x20,	// 是否读取组字典
	// 											kReadLayoutDict             = 0x40,
	// 											kReadMlineStyleDict         = 0x80,
	// 											kReadImageDict				= 0x100,
	// 											kReadXrecord				= 0x200,
	// 											kReadDrawOrder				= 0x400,
	// 											kReadxData					= 0x800,
	// 											kReadExRecord               = 0x1000,
	// 											kReadExternalReference      = 0x2000,
	// 											kReadCustomEntity           = 0x4000  // 是否读取自定义实体，如果该为项为真，则自动让kReadHandle值也为真，因为自定义实体需要名柄支持.
	// 										}; 
	//		pInData						-	如果从内存打开文件，pInData指向内存数据。
	//		lInDataLength				-	内存数据的长度。
	// Returns:
	// 		如果成功返回Mcad::eOk，如果传递的数据非法则返回Mcad::eInvalidInput
	// Remarks:
	// 		例如:打开一个DWG文件，遍历数据库，得到块记录中属性文本
	// 		<code>
	// 			CTestDlg* pDlg = (CTestDlg*)AfxGetApp()->GetMainWnd();
	// 
	// 			CPreviewFileDialog openDlg(TRUE,_T("dwg"),NULL,
	// 				OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
	// 				//_T("dwg(*.dwg) | *.dwg||"),
	// 				_T("DWG files (*.dwg)|*.dwg|DXF files (*.dxf)|*.dxf|Jpg files (*.jpg)|*.jpg|BMP files (*.bmp)|*.bmp||"),
	// 				pDlg);
	// 
	// 			MxString sAppPath = CTestDlgApp::GetAppPath();
	// 
	// 			MxString sInitialDir = AfxGetApp()->GetProfileString(_T("MxDWGTestDlg"),_T("OpenDir"),sAppPath );
	// 
	// 			MxString sFileName;
	// 			openDlg.m_ofn.lpstrInitialDir= sInitialDir; //设置打开文件的缺省路径
	// 			if(openDlg.DoModal() == IDOK)
	// 			{
	// 				sFileName = openDlg.GetPathName();
	// 			}
	// 			else
	// 			{
	// 				return;
	// 			}
	// 
	// 			// 打开文件。
	// 			McDbDatabase dataBase;
	// 			if(dataBase.readDwgFile(sFileName) != Mcad::eOk)
	// 			{
	// 				AfxMessageBox(_T("读取文件失败"));
	// 
	// 				return;
	// 			}
	// 
	// 			// 下面读取图中指定块的属性。
	// 			McDbBlockTableRecordPointer spBlkRec(MCDB_MODEL_SPACE,&dataBase,McDb::kForRead);
	// 			if(spBlkRec.openStatus() != Mcad::eOk)
	// 			{
	// 				return;
	// 			}
	// 
	// 			// 生成遍历数据库用的遍历器.
	// 			McDbBlockTableRecordIterator* pIterator = NULL;
	// 			spBlkRec->newIterator(pIterator);
	// 
	// 			if(pIterator == NULL)
	// 				return;
	// 
	// 			// 遍历数据库
	// 			for(;!pIterator->done();pIterator->step() )
	// 			{
	// 				McDbObjectId id;
	// 				pIterator->getEntityId(id);
	// 
	// 				McDbObjectPointer<McDbBlockReference> spBlkRef(id,McDb::kForRead);
	// 				if(spBlkRef.openStatus() != Mcad::eOk)
	// 					continue;
	// 
	// 				// 读取块引用的属性。
	// 				AcDbObjectIterator* pAttribIter = spBlkRef->attributeIterator();
	// 				if(pAttribIter != NULL)
	// 				{
	// 					acutPrintf(_T("\n 块的属性值为："));
	// 					for(;!pAttribIter->done();pAttribIter->step() )
	// 					{
	// 						AcDbObjectPointer<AcDbAttribute> spAttribute(pAttribIter->objectId(),AcDb::kForRead);
	// 						acutPrintf(_T("\n %s"),spAttribute->textStringConst());
	// 					}
	// 					acutPrintf(_T("\n"));
	// 					delete pAttribIter;
	// 				}
	// 
	// 			}
	// 			delete pIterator;
	// 		</code>
	// -------------------------------------------------------------------------
	
    Mcad::ErrorStatus readDwgFile(LPCMSTR pszFileName,
		int shmode = 0x40,
		bool bAllowCPConversion = false,
		LPCMSTR wszPassword = NULL,int rc = Mcad::kReadDefault, const std::function<MxString(const MxString&)>& callExternalBlockReferenceReplace = NULL
		);



	// -------------------------------------------------------------------------
	// Summary:
	// 		保存DWG文件
	// Parameters:
	// 		pszFileName			-	DWG文件路径
	//		pSecParams			-	暂没使用
	//		wszPassword			-	暂没使用
	//		version				-   DWG文件版本
	//		type				-   文件类型，可以是DWG或DXF
	//		ppRetData			-   把数据保存到内存中,返回的数据需要free函数释放。
	//		pRetDataLength		-	返回数据的长度
	// Returns:
	// 		如果成功返回Mcad::eOk，如果传递的数据非法则返回Mcad::eInvalidInput
	// -------------------------------------------------------------------------
	Mcad::ErrorStatus saveAs(LPCMSTR pszFileName,
		const void* pSecParams = 0,
		LPCMSTR wszPassword = NULL,
		McDb::McDbDwgVersion version = McDb::kDHL_1015, 
		McDb::SaveType type = McDb::kDwg,
		mxbyte** ppRetData =NULL,
		long* pRetDataLength = NULL);



	// -------------------------------------------------------------------------
	// Summary:
	// 		返回数据库中的字符串转换的代码页
	// Returns:
	// 		返回数据库中的字符串转换的代码页
	// Remarks:
	// 		例如:Ansi字串转换成Unicode
	// 		<code>
	//			textFragment.text = CA2W(textStyle.val,pDatabase->getCodePage());
	// 		</code>
	// -------------------------------------------------------------------------
	int               getCodePage();

	// -------------------------------------------------------------------------
	// Summary:
	// 		返回数据库中的视口表
	// Parameters:
	// 		pTable	-	返回符号表指针
	//		mode	-	打开方式
	// Returns:
	// 		成功返回Mcad::eOk;
	// -------------------------------------------------------------------------
	Mcad::ErrorStatus getViewportTable      (McDbSymbolTable*& pTable,
		McDb::OpenMode    mode);

	// -------------------------------------------------------------------------
	// Summary:
	// 		返回数据库中的视口表
	// Parameters:
	// 		pTable	-	返回符号表指针
	//		mode	-	打开方式
	// Returns:
	// 		成功返回Mcad::eOk;
	// -------------------------------------------------------------------------
	Mcad::ErrorStatus getSymbolTable    (McDbViewportTable*&  pTable,
		McDb::OpenMode       mode);

	//:Ignore

	// -------------------------------------------------------------------------
	// Summary:
	// 		返回当前显示的布局对象id.
	// -------------------------------------------------------------------------
	McDbObjectId currentLayoutId() const;

	bool isCurrentModelSpace() const;

	// -------------------------------------------------------------------------
	// Summary:
	// 		返回当前显示的视口对象id.
	// -------------------------------------------------------------------------
	McDbObjectId acitveViewportId() const;

	// -------------------------------------------------------------------------
	// Summary:
	// 		返回数据库的模型空间的显示布局对象。
	// -------------------------------------------------------------------------
	McDbObjectId modelSpaceLayoutId() const;

	

	// -------------------------------------------------------------------------
	// Summary:
	// 		给一个实体的名柄，返回实体的id,调用McDbObject::getAcDbHandle可以由实体id得到实体句柄
	// Parameters:
	// 		retId				-	返回实体的id
	//		createIfNotFound	-	暂没有使用
	//		objHandle			-	传入的实体名柄
	//		xRefId				-	暂没有使用
	// Returns:
	// 		如果成功返回Mcad::eOk，如果传递的数据非法则返回Mcad::eInvalidInput
	// Remarks:
	// 		<code>
	// 			AcDbHandle handle(_T("1A388"));
	// 
	// 			AcDbObjectId retId;
	// 			acdbHostApplicationServices()->workingDatabase()->getAcDbObjectId(retId,false,handle);
	// 
	// 			AcDbObjectPointer<AcDbObject> spObj(retId,AcDb::kForRead);
	// 			if(spObj.openStatus() == Acad::eOk)
	// 			{
	// 				acutPrintf(spObj->isA()->name() );
	// 			}
	// 		</code>
	// -------------------------------------------------------------------------
	Mcad::ErrorStatus getAcDbObjectId(McDbObjectId& retId,
		bool createIfNotFound,
		const McDbHandle& objHandle,
		Mdesk::UInt32 xRefId = 0);

	Mcad::ErrorStatus getAcDbObjectId(McDbObjectId& retId,
		const mxuint32& idIndex
		);


	// -------------------------------------------------------------------------
	// Summary:
	// 		读取mxg文件.
	// Parameters:
	// 		pszFileName  - 文件名
	//		pszPassword  - 文件密码,没有密码，输入NULL
	// Returns:
	// 		成功返回Mcad::eOk.
	// -------------------------------------------------------------------------
	Mcad::ErrorStatus readMxFile(LPCMSTR pszFileName, LPCMSTR pszPassword = NULL,void* pContent = nullptr);

	// -------------------------------------------------------------------------
	// Summary:
	// 		保存mxg文件.
	// Parameters:
	// 		pszFileName - 文件名
	//		version     - 文件版本
	//		pszPassword - 文件密码，没有密码，输入NULL
	//		iCompressionLevel - 文件压缩等级，0不压缩，1为正常压缩，2为高压缩
	// Returns:
	// 		成功返回Mcad::eOk.
	// -------------------------------------------------------------------------
	Mcad::ErrorStatus writeMxFile(LPCMSTR pszFileName,
		McDb::McDbMxgVersion version = McDb::kDHL_MX_CURRENT,
		LPCMSTR pszPassword = NULL,
		int     iCompressionLevel = 1,
		long    lRabinHash = 0,
		bool    isSaveDisplayData = false,
		void* pContent = nullptr,
		sutWriteFileParam* pParam = 0
		);


	void*  GetInteriorData() const;

	// -------------------------------------------------------------------------
	// Summary:
	// 		返回Ucs到Wcs坐标变换矩阵.
	// -------------------------------------------------------------------------
	const McGeMatrix3d* getUcsMatrix();

	void setUcsMatrix(const McGeMatrix3d& mat);

	McDbObjectId modelSpace() const;

	// -------------------------------------------------------------------------
	// Summary:
	// 		把一个数据库当着图块插入到当前数据库中，多用于图块插入操作
	// Parameters:
	// 		blockId					-	返回新插入的图块表记录id
	//		pszBlockName			-	新插入的图块表记录名,图块为空时，就把文件中所有图块都引进到当前图纸中 
	//		pDb						-	插入的数据库指针
	//		preserveSourceDatabase	-	暂没使用
	//		isUpdataSameNameBlock   -   如果插入的数据库的图块名与当前数据库的图块名同名，需要不需要重新更新该图块。
	// Returns:
	// 		如果成功返回Mcad::eOk，如果传递的数据非法则返回Mcad::eInvalidInput
	// Remarks:
	// 		<code>
	// 			{
	// 				AcDbDatabase db(Mdesk::kFalse );
	// 				if( db.readDwgFile( sBlkFileName ) != Acad::eOk )
	// 				{
	// 					return FALSE;
	// 				}
	// 				if ( pDatabase->insert( blkRecId, sBlkName, &db ) != Acad::eOk )
	// 				{
	// 					return FALSE;
	// 				}
	// 			}
	// 		</code>
	// -------------------------------------------------------------------------
	Mcad::ErrorStatus insert(McDbObjectId& blockId, 
		LPCMSTR pszBlockName,
		McDbDatabase* pDb,
		bool isUpdataSameNameBlock = false, McDbDatabaseInsertResult* pResult= 0);


	Mcad::ErrorStatus Marge(McDbDatabase* pDb, McGeMatrix3d* pMat = NULL, std::vector<MxString>* pVecMargeLayerName = NULL);



	// -------------------------------------------------------------------------
	// Summary:
	// 		设置数据库对象是否被修改过.
	// Parameters:
	// 		isModify - 设置修改标记
	// -------------------------------------------------------------------------
	void setModifyed(bool isModify = true);

	// -------------------------------------------------------------------------
	// Summary:
	// 		返回数据库对象是否被修改过
	// -------------------------------------------------------------------------
	bool isModifyed() const;
	//:Ignore
	MxUndo* undoController() const;

	McDbObjectId getZeroLayerId() const;

	//:Ignore

	// -------------------------------------------------------------------------
	// Summary:
	// 		得到应用程序名表对象
	// Parameters:
	// 		pTable	-	返回应用程序名表指针
	//		mode	-	应用程序名表的打开方式，读/写方式
	// Returns:
	// 		如果成功返回Mcad::eOk，如果传递的数据非法则返回Mcad::eInvalidInput
	// -------------------------------------------------------------------------
	Mcad::ErrorStatus getSymbolTable(McDbRegAppTable*&    pTable,
		McDb::OpenMode       mode);


	// -------------------------------------------------------------------------
	// Summary:
	// 		得到应用程序名表对象
	// Parameters:
	// 		pTable	-	返回应用程序名表指针
	//		mode	-	应用程序名表的打开方式，读/写方式
	// Returns:
	// 		如果成功返回Mcad::eOk，如果传递的数据非法则返回Mcad::eInvalidInput
	// -------------------------------------------------------------------------
	Mcad::ErrorStatus getRegAppTable(McDbRegAppTable*& pTable,
		McDb::OpenMode    mode);


	Mdesk::Int16 useri1();
	Mcad::ErrorStatus setUseri1(Mdesk::Int16 val);

	Mdesk::Int16 useri2();
	Mcad::ErrorStatus setUseri2(Mdesk::Int16 val);

	Mdesk::Int16 useri3();
	Mcad::ErrorStatus setUseri3(Mdesk::Int16 val);

	Mdesk::Int16 useri4();
	Mcad::ErrorStatus setUseri4(Mdesk::Int16 val);

	Mdesk::Int16 useri5();
	Mcad::ErrorStatus setUseri5(Mdesk::Int16 val);

	mxreal userr1();
	Mcad::ErrorStatus setUserr1(mxreal val);

	mxreal userr2();
	Mcad::ErrorStatus setUserr2(mxreal val);

	mxreal userr3();
	Mcad::ErrorStatus setUserr3(mxreal val);

	mxreal userr4();
	Mcad::ErrorStatus setUserr4(mxreal val);

	mxreal userr5();
	Mcad::ErrorStatus setUserr5(mxreal val);


	MxString users1();
	Mcad::ErrorStatus setUsers1(LPCMSTR val);

	MxString users2();
	Mcad::ErrorStatus setUsers2(LPCMSTR val);

	MxString users3();
	Mcad::ErrorStatus setUsers3(LPCMSTR val);

	MxString users4();
	Mcad::ErrorStatus setUserr4(LPCMSTR val);

	MxString users5();
	Mcad::ErrorStatus setUsers5(LPCMSTR val);

	bool isHaveTzEntity();
	
	void initCreateBackgroundObject(const std::function<McDbEntity*()>& doCreate);

	McDbObjectId getBackgroundObjectId() const;

	McDbObjectId zeroLayerId() const;

	// -------------------------------------------------------------------------
	// Summary:
	// 		得多线样式对象
	// Parameters:
	// 		pDict	-	返回多线样式字典指针
	//		mode	-	打开方式
	// Returns:
	// 		如果成功返回Mcad::eOk，如果传递的数据非法则返回Mcad::eInvalidInput
	// -------------------------------------------------------------------------
	Mcad::ErrorStatus getMLStyleDictionary(McDbDictionary*& pDict,
		McDb::OpenMode mode);


	// -------------------------------------------------------------------------
	// Summary:
	// 		返回多线样式字典id
	// -------------------------------------------------------------------------
	McDbObjectId       mLStyleDictionaryId();


	McDbObjectId	  getCurrentViewportId() const;


	McDbExternalReferencesDatabaseManager* getMcDbExternalReferencesDatabaseManager() const;

	MxIdIndex getIdIndex() const;

	Mdesk::Boolean freeJsObject();

	bool syncCustomEntityData(bool toCpp = true, bool isCreatePrvViewEntity = false);

	void ReInit();

	Mcad::ErrorStatus wblock(McDbDatabase*& pOutputDb,
		const McDbObjectIdArray& outObjIds,
		const McGePoint3d& basePoint, MxJsonParamValue* pExParam = 0
	);



	Mcad::ErrorStatus wblock(McDbDatabase*& pOutputDb, McDbObjectId blockId, MxJsonParamValue* pExParam = 0);

	//:End Ignore
private:
	// 禁用等号和拷贝操作
	McDbDatabase(const McDbDatabase&){;}			
	McDbDatabase& operator= (const McDbDatabase&){return *this;};

public:
	McDbDatabaseImp* m_pImp;


	//:End Ignore
};

// -------------------------------------------------------------------------
// Summary:
// 		临时设置当前层，在对象释放时，会恢复以前当层设置。
// -------------------------------------------------------------------------
class ARXDLL MxTmpSetCurrentLayer
{
public:
	//:Ignore
	MxTmpSetCurrentLayer(McDbObjectId id, McDbDatabase* pDatabase = NULL);
	virtual ~MxTmpSetCurrentLayer();
private:

	McDbObjectId m_bakLayerId;
	McDbDatabase* m_pDatabase;
	//:End Ignore
};


// MwColor
class ARXDLL MwColor
{
public:
	MwColor();
	MwColor(float _r, float _g, float _b, float _a = 1.0f);
	MwColor(int nColorIndex);
	~MwColor();

	static const MwColor ZERO;
	static const MwColor Black;
	static const MwColor White;
	static const MwColor Red;
	static const MwColor Green;
	static const MwColor Blue;
	static const MwColor Gray;
	static const MwColor Error;
	static const MwColor Mask;				// 遮蔽色

	int GetIntR() const;

	int GetIntG() const;

	int GetIntB() const;

	int GetIntA() const;

public:
	// Summary: 转化成颜色索引。
	int ToColorIndex() const;

	// Summary: 从颜色索引设置。
	void SetFromColorIndex(int nIndex);

public:
	float r;
	float g;
	float b;
	float a;
};



// -------------------------------------------------------------------------
// Summary:
// 		此类用于在控件中表示颜色，如RGB、AutoCAD颜色索引
// -------------------------------------------------------------------------
class ARXDLL McCmColor
{
public:

	//:Ignore

	enum Color
	{ 
		kRed,
		kGreen,
		kBlue
	};
	//:End Ignore

	// -------------------------------------------------------------------------
	// Summary:
	// 		颜色方式,表示颜色是如何储存的
	// -------------------------------------------------------------------------
	enum ColorMethod 
	{   kByLayer = 0x01,		//	颜色随层
	kByBlock = 0x02,				//	颜色随块
	kByColor,				//	颜色值
	kByACI,					//	颜色索引值			
	kByPen,					//	暂没有使用
	kForeground,			//	暂没有使用
	kLayerOff,				//	暂没有使用

	kLayerFrozen,			//	暂没有使用
	kNone					//	暂没有使用
	};

	// -------------------------------------------------------------------------
	// Summary:
	// 		此类的对象储存一个颜色方法和一个颜色，这个颜色根据颜色方法，可能是一个红/绿/蓝（RGB）值、一个AutoCAD颜色索引（ACI）值
	// -------------------------------------------------------------------------
	union RGBM 
	{
		mxuint32   whole;			//	颜色所有数据值
		struct 
		{
			mxuint8 blue;			//  蓝色
			mxuint8 green;			//	绿色
			mxuint8 red;			//  红色
			mxuint8 colorMethod;	//	颜色方式
		
		};
	};

	// -------------------------------------------------------------------------
	// Summary:
	// 		构造函数
	// -------------------------------------------------------------------------
	McCmColor()
	{
		m_rgbM.whole = 0;
		m_rgbM.colorMethod = kByColor;
		m_n = 255;
		
	}

	// -------------------------------------------------------------------------
	// Summary:
	// 		拷贝构造函数
	// -------------------------------------------------------------------------
	McCmColor(const McCmColor& color)
	{
		m_rgbM.whole = color.m_rgbM.whole;
		m_n = color.m_n;
		
	}

	McCmColor(const MwColor& coolor);

	MwColor getMwColor() const;
	// -------------------------------------------------------------------------
	// Summary:
	// 		等号操作符
	// -------------------------------------------------------------------------
	McCmColor& operator=(const McCmColor& inputColor)
	{
		if(this == &inputColor)
			return *this;
		m_rgbM.whole = inputColor.m_rgbM.whole;
		m_n = inputColor.m_n;
		
		return *this;
	}

	// -------------------------------------------------------------------------
	// Summary:
	// 		析构函数
	// -------------------------------------------------------------------------
	~McCmColor()
	{
	}

	// -------------------------------------------------------------------------
	// Summary:
	// 		等于操作符
	// -------------------------------------------------------------------------
	bool operator ==(const McCmColor& color) const
	{
		return (m_rgbM.whole == color.m_rgbM.whole
			&& m_n == color.m_n
			
			);
	}

	// -------------------------------------------------------------------------
	// Summary:
	// 		不等于操作符
	// -------------------------------------------------------------------------
	bool operator !=(const McCmColor& color) const
	{
		return (m_rgbM.whole != color.m_rgbM.whole
			||  m_n != color.m_n
			
			);
	}

	// -------------------------------------------------------------------------
	// Summary:
	// 		返回颜色方式,表示颜色是如何储存的
	// -------------------------------------------------------------------------
	Mdesk::UInt8  colorMethod() const
	{
		return m_rgbM.colorMethod;
	}

	// -------------------------------------------------------------------------
	// Summary:
	// 		设置颜色方式,表示颜色是如何储存的
	// Parameters:
	// 		eColorMethod	-	新的颜色方式
	// Returns:
	// 		如果成功返回Mcad::eOk，如果传递的数据非法则返回Mcad::eInvalidInput
	// -------------------------------------------------------------------------
	Mcad::ErrorStatus setColorMethod(McCmColor::ColorMethod eColorMethod)
	{
		m_rgbM.colorMethod = (mxuint8)eColorMethod;
		
		return Mcad::eOk;
	}

	// -------------------------------------------------------------------------
	// Summary:
	// 		颜色是否RGB色
	// -------------------------------------------------------------------------
	bool    isByColor() const
	{
		return (m_rgbM.colorMethod == kByColor);
	}

	// -------------------------------------------------------------------------
	// Summary:
	// 		颜色是否随层
	// -------------------------------------------------------------------------
	bool    isByLayer() const
	{
		return (m_rgbM.colorMethod == kByLayer);
	}

	// -------------------------------------------------------------------------
	// Summary:
	// 		颜色是否随块
	// -------------------------------------------------------------------------
	bool    isByBlock() const
	{
		return (m_rgbM.colorMethod == kByBlock);
	}

	// -------------------------------------------------------------------------
	// Summary:
	// 		是否是颜色索引值
	// -------------------------------------------------------------------------
	bool    isByACI()   const
	{
		return  (m_rgbM.colorMethod == kByACI);
	}

	//:Ignore

	bool    isByPen () const
	{
		return  (m_rgbM.colorMethod == kByPen);
	}

	bool    isForeground()   const
	{
		return  (m_rgbM.colorMethod == kForeground);
	}
	//:End Ignore

	// -------------------------------------------------------------------------
	// Summary:
	// 		返回颜色所有数据值
	// -------------------------------------------------------------------------
	Mdesk::UInt32     color() const
	{
		return m_rgbM.whole;
	}

	// -------------------------------------------------------------------------
	// Summary:
	// 		设置颜色所有数据值
	// Parameters:
	// 		color	-	颜色数据 
	// Returns:
	// 		如果成功返回Mcad::eOk，如果传递的数据非法则返回Mcad::eInvalidInput
	// -------------------------------------------------------------------------
	Mcad::ErrorStatus setColor(Mdesk::UInt32 color)
	{
		m_rgbM.whole = color;
		
		return Mcad::eOk;
	}

	// -------------------------------------------------------------------------
	// Summary:
	// 		设置颜色的RGB值
	// Parameters:
	// 		red		-	红色
	//		green	-	绿色
	//		blue	-	蓝色
	// Returns:
	// 		如果成功返回Mcad::eOk，如果传递的数据非法则返回Mcad::eInvalidInput
	// -------------------------------------------------------------------------
	Mcad::ErrorStatus setRGB  (Mdesk::UInt8 red, 
		Mdesk::UInt8 green, 
		Mdesk::UInt8 blue)
	{
		m_rgbM.red   = red;
		m_rgbM.green = green;
		m_rgbM.blue  = blue;
		m_rgbM.colorMethod = kByColor;
		
		return Mcad::eOk;
	}

	// -------------------------------------------------------------------------
	// Summary:
	// 		设置颜色的红色值
	// Parameters:
	// 		red		-	红色
	// Returns:
	// 		如果成功返回Mcad::eOk，如果传递的数据非法则返回Mcad::eInvalidInput
	// -------------------------------------------------------------------------
	Mcad::ErrorStatus setRed  (Mdesk::UInt8 red)
	{
		m_rgbM.red = red;
		
		return Mcad::eOk;
	}

	// -------------------------------------------------------------------------
	// Summary:
	// 		设置颜色的绿色值
	// Parameters:
	// 		green		-	绿色
	// Returns:
	// 		如果成功返回Mcad::eOk，如果传递的数据非法则返回Mcad::eInvalidInput
	// -------------------------------------------------------------------------
	Mcad::ErrorStatus setGreen(Mdesk::UInt8 green)
	{
		m_rgbM.green = green;
		
		return Mcad::eOk;
	}

	// -------------------------------------------------------------------------
	// Summary:
	// 		设置颜色的蓝色值
	// Parameters:
	// 		blue		-	蓝色
	// Returns:
	// 		如果成功返回Mcad::eOk，如果传递的数据非法则返回Mcad::eInvalidInput
	// -------------------------------------------------------------------------
	Mcad::ErrorStatus setBlue (Mdesk::UInt8 blue)
	{
		m_rgbM.blue = blue;
		
		return Mcad::eOk;
	}


	// -------------------------------------------------------------------------
	// Summary:
	// 		返回颜色的红色值
	// -------------------------------------------------------------------------
	Mdesk::UInt8      red  () const
	{
		return m_rgbM.red;
	}

	// -------------------------------------------------------------------------
	// Summary:
	// 		返回颜色的绿色值
	// -------------------------------------------------------------------------
	Mdesk::UInt8      green() const
	{
		return m_rgbM.green;
	}

	// -------------------------------------------------------------------------
	// Summary:
	// 		返回颜色的蓝色值
	// -------------------------------------------------------------------------
	Mdesk::UInt8      blue () const
	{
		return m_rgbM.blue;
	}

	// -------------------------------------------------------------------------
	// Summary:
	// 		返回颜色的索引值
	// -------------------------------------------------------------------------
	Mdesk::UInt16     colorIndex() const;

	// -------------------------------------------------------------------------
	// Summary:
	// 		设置颜色的索引值, MrxDbgUtils::Color预定义了一些颜色引值
	// Parameters:
	// 		colorIndex	-	颜色的索引值
	// Returns:
	// 		如果成功返回Mcad::eOk，如果传递的数据非法则返回Mcad::eInvalidInput
	// -------------------------------------------------------------------------
	Mcad::ErrorStatus setColorIndex(Mdesk::UInt16 colorIndex);

	mxuint8 getN() const
	{
		return m_n;
	}

	void setN(mxuint8 n)
	{
		m_n = n;
	}


	
	Mcad::ErrorStatus dwgIn(McDbDwgFiler* pInputFiler);
	Mcad::ErrorStatus dwgOut(McDbDwgFiler *pOutputFiler) const;

	// 最大颜色索引值，当前值为255
	static const Mdesk::UInt16 MaxColorIndex; 
public:
	RGBM m_rgbM;
	mxuint8 m_n;			// 透明色通道.
	
	//:End Ignore
};
