#include "StdAfx.h"
#include "C2DObject.h"

/************************************************************************
  二维画图基类
************************************************************************/
C2DObject::C2DObject(void)
{
}

C2DObject::~C2DObject(void)
{
}

C2DObject* C2DObject::CreateObject( enum Draw_Class enumClassType )
{
	switch(enumClassType)
	{
	case CLASS_DRAW_POINT:
		{
			C2DPoint* pPt = new C2DPoint;
			return pPt;
		}
		break;
	case CLASS_DRAW_BEELINE:
		{
			C2DBeeLine* pLine = new C2DBeeLine;
			return pLine;
		}
		break;
	case CLASS_DRAW_POLYLINE:
		{
			C2DPolyLine* pPolyLine = new C2DPolyLine;
			return pPolyLine;
		}
	case CLASS_DRAW_TRIANGLE:
		{
			C2DTriangle* pTriangle = new C2DTriangle;
			return pTriangle;
		}
	case CLASS_DRAW_CIRCLE:
		{
			C2DCircle* pCircle = new C2DCircle;
			return pCircle;
		}
	default:
		TRACE("Error ClassType:%d in C2DObject::CreateObject!\n",enumClassType);
	}

}




/************************************************************************
 二维点类 
************************************************************************/
C2DPoint::C2DPoint(CPoint& pt)
{
	//m_fRadius = 0.5f;
    m_Position = pt;
	m_byR = g_2DObj.m_byR[0];
	m_byG = g_2DObj.m_byG[0];
	m_byB = g_2DObj.m_byB[0];
// 	m_byR = 255;
// 	m_byG = 255;
// 	m_byB = 255;
}

C2DPoint::C2DPoint()
{
	m_Position = CPoint(0, 0);
}

C2DPoint::~C2DPoint()
{

}

void C2DPoint::Serialize( CFile* pFile, BOOL bSave /*= TRUE*/ )
{
	if (bSave)
	{
		C2DAtom::Serialize(pFile,bSave);
		//pFile->Write(&m_fRadius,sizeof(float));
		pFile->Write(&m_byR,sizeof(BYTE));
		pFile->Write(&m_byG,sizeof(BYTE));
		pFile->Write(&m_byB,sizeof(BYTE));
		pFile->Write(&m_Position,sizeof(CPoint));
// 		UINT wEnd = 0;
// 		pFile->Write(&wEnd,sizeof(UINT));
	}
	else
	{
		C2DAtom::Serialize(pFile,bSave);
		//pFile->Read(&m_fRadius,sizeof(float));
		pFile->Read(&m_byR,sizeof(BYTE));
		pFile->Read(&m_byG,sizeof(BYTE));
		pFile->Read(&m_byB,sizeof(BYTE));
		pFile->Read(&m_Position,sizeof(CPoint));
// 		UINT wEnd = 0;
// 		pFile->Read(&wEnd,sizeof(UINT));
	}
}

void C2DPoint::Draw(CDC* pDC)
{
	pDC->SetPixel(m_Position.x, m_Position.y,(COLORREF)GetClrRefFromByte(m_byR,m_byG,m_byB));
}

UINT C2DPoint::GetClass()
{
	return CLASS_DRAW_POINT;
}


/************************************************************************
 二维线类
************************************************************************/
C2DLine::C2DLine()
{
	m_byLineStyle = 0;
	m_wLineWidth  = 1;
}

C2DLine::~C2DLine()
{

}

void C2DLine::Serialize( CFile* pFile, BOOL bSave /*= TRUE*/ )
{
	if (bSave)
	{
		C2DAtom::Serialize(pFile,bSave);
		pFile->Write(&m_byLineStyle,sizeof(BYTE));
		pFile->Write(&m_wLineWidth,sizeof(UINT));
	} 
	else
	{
		C2DAtom::Serialize(pFile,bSave);
		pFile->Read(&m_byLineStyle,sizeof(BYTE));
		pFile->Read(&m_wLineWidth,sizeof(UINT));
	}
}

/************************************************************************
 二维直线类
************************************************************************/
C2DBeeLine::C2DBeeLine( CPoint& ptS, CPoint& ptE )
{
	m_ptStart = ptS;
	m_ptEnd   = ptE;
}

C2DBeeLine::C2DBeeLine()
{
	m_ptStart = CPoint(0, 0); 
	m_ptEnd   = CPoint(0, 0);
}

C2DBeeLine::~C2DBeeLine()
{

}

void C2DBeeLine::Serialize( CFile* pFile, BOOL bSave /*= TRUE*/ )
{
	if (bSave)
	{
		C2DLine::Serialize(pFile,bSave);
		pFile->Write(&m_ptStart,sizeof(CPoint));
		pFile->Write(&m_ptEnd,sizeof(CPoint));
	} 
	else
	{
		C2DLine::Serialize(pFile,bSave);
		pFile->Read(&m_ptStart,sizeof(CPoint));
		pFile->Read(&m_ptEnd,sizeof(CPoint));
	}
}

void C2DBeeLine::Draw( CDC* pDC )
{
	CPen pen(PS_SOLID,0,GetClrRefFromByte(m_byR,m_byG,m_byB));
	CPen* pOldPen = pDC->SelectObject(&pen);
	pDC->MoveTo(m_ptStart);
	pDC->LineTo(m_ptEnd);
	pDC->SelectObject(pOldPen);
}

UINT C2DBeeLine::GetClass()
{
	return CLASS_DRAW_BEELINE;
}

/************************************************************************
 二维折线类
************************************************************************/
C2DPolyLine::C2DPolyLine()
{
	m_arPt.RemoveAll();
}

C2DPolyLine::C2DPolyLine( CArray<CPoint, CPoint&>& arPt)
{
	m_arPt.Copy(arPt);
}

C2DPolyLine::~C2DPolyLine()
{
}

void C2DPolyLine::Serialize( CFile* pFile, BOOL bSave /*= TRUE*/ )
{
	if (bSave)
	{	
		C2DLine::Serialize(pFile,bSave);
		int nCount = m_arPt.GetCount();
		pFile->Write(&nCount, sizeof(int));
		for (int i=0; i!=nCount; ++i)
		{
			CPoint pt;
			pt = m_arPt.GetAt(i);
			pFile->Write(&pt, sizeof(CPoint));
		}
	} 
	else
	{
		C2DLine::Serialize(pFile,bSave);
		int nCount = 0;
		pFile->Read(&nCount, sizeof(int));
		for (int i=0; i != nCount; ++i)
		{
			CPoint pt;
			pFile->Read(&pt, sizeof(CPoint));
			m_arPt.Add(pt);
		}
	}
}

void C2DPolyLine::Draw( CDC* pDC )
{
	CPen pen(PS_SOLID,0,GetClrRefFromByte(m_byR,m_byG,m_byB));
	CPen* pOldPen = pDC->SelectObject(&pen);
 	CPoint pt;
	int nCount = m_arPt.GetCount();
	if (nCount>1)
	{
		pt = m_arPt.GetAt(0);
		for (int i=1; i!=nCount; ++i)
		{
			pDC->MoveTo(pt);
			pDC->LineTo(m_arPt.GetAt(i));
			pt = m_arPt.GetAt(i);
		}
	}
		pDC->SelectObject(pOldPen);
}

UINT C2DPolyLine::GetClass()
{
	return CLASS_DRAW_POLYLINE;
}

/************************************************************************
二维三角形类                                                                      
************************************************************************/
C2DTriangle::C2DTriangle()
{
	m_arPt.RemoveAll();
}

C2DTriangle::C2DTriangle(CArray<CPoint, CPoint&>& arPt)
{
	m_arPt.Copy(arPt);
}

C2DTriangle::~C2DTriangle()
{

}

void C2DTriangle::Serialize( CFile* pFile, BOOL bSave /*= TRUE*/ )
{
	if (bSave)
	{
		C2DLine::Serialize(pFile,bSave);
		int nCount = m_arPt.GetCount();
		pFile->Write(&nCount, sizeof(int));
		for (int i=0; i!=nCount; ++i)
		{
			CPoint pt;
			pt = m_arPt.GetAt(i);
			pFile->Write(&pt, sizeof(CPoint));
		}
	} 
	else
	{
		C2DLine::Serialize(pFile,bSave);
		int nCount = 0;
		pFile->Read(&nCount, sizeof(int));
		for (int i=0; i != nCount; ++i)
		{
			CPoint pt;
			pFile->Read(&pt, sizeof(CPoint));
			m_arPt.Add(pt);
		}
	}
}

void C2DTriangle::Draw( CDC* pDC )
{
	CPen pen(PS_SOLID,0,GetClrRefFromByte(m_byR,m_byG,m_byB));
	CPen* pOldPen = pDC->SelectObject(&pen);
	CPoint pt0,pt1,pt2;
	int nCount = m_arPt.GetCount();
	if (nCount == 3)
	{
		pt0 = m_arPt.GetAt(0);
		pt1 = m_arPt.GetAt(1);
		pt2 = m_arPt.GetAt(2);
		pDC->MoveTo(pt0);
		pDC->LineTo(pt1);
		pDC->MoveTo(pt1);
		pDC->LineTo(pt2);
		pDC->MoveTo(pt2);
		pDC->LineTo(pt0);
	}
	pDC->SelectObject(pOldPen);
}

UINT C2DTriangle::GetClass()
{
	return CLASS_DRAW_TRIANGLE;
}

/************************************************************************
二维空心圆类                                                                    
************************************************************************/
C2DCircle::C2DCircle()
{
	m_pt      = CPoint(0,0);
	m_nRadius = 0;
}

C2DCircle::C2DCircle( CPoint& pt, int nRadius )
{
	m_pt      = pt;
	m_nRadius = nRadius;
}

C2DCircle::~C2DCircle()
{

}

void C2DCircle::Serialize( CFile* pFile, BOOL bSave /*= TRUE*/ )
{
	if (bSave)
	{
		C2DLine::Serialize(pFile,bSave);
		pFile->Write(&m_pt,sizeof(CPoint));
		pFile->Write(&m_nRadius,sizeof(int));
	} 
	else
	{
		C2DLine::Serialize(pFile,bSave);
		pFile->Read(&m_pt,sizeof(CPoint));
		pFile->Read(&m_nRadius,sizeof(int));
	}
}

void C2DCircle::Draw( CDC* pDC )
{
	CPen pen(PS_SOLID,0,GetClrRefFromByte(m_byR,m_byG,m_byB));
	CBrush* pBrush = CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH));
    CBrush* pOlbBs = pDC->SelectObject(pBrush);
	CPen* pOldPen = pDC->SelectObject(&pen);
	pDC->Ellipse(m_pt.x-m_nRadius,m_pt.y-m_nRadius,m_pt.x+m_nRadius,m_pt.y+m_nRadius);
	pDC->SelectObject(pOlbBs);
	pDC->SelectObject(pOldPen);
}

UINT C2DCircle::GetClass()
{
	return CLASS_DRAW_CIRCLE;
}

/************************************************************************
 二维图幅类
************************************************************************/
C2DMap::C2DMap()
{
	m_arObj.RemoveAll();
}

C2DMap::~C2DMap()
{
	int nCount = (int)m_arObj.GetCount();
	C2DObject* pObj = NULL;
	for (int i=0; i!=nCount; ++i)
	{
		pObj = m_arObj.GetAt(i);
		delete pObj;
        pObj =NULL;
	}
	m_arObj.RemoveAll();
	m_arObj.FreeExtra();
}

void C2DMap::Serialize( CFile* pFile, BOOL bSave /*= TRUE */ )
{
	if (bSave)
	{
		C2DObject *pObj = NULL;
		int nCount = (int)m_arObj.GetCount();
		UINT wClassType = 0;
		pFile->Write(&nCount,sizeof(int));
		for (int i=0; i!=nCount; ++i)
		{
			pObj = m_arObj.GetAt(i);
			wClassType = pObj->GetClass();
			pFile->Write(&wClassType,sizeof(UINT));
			pObj->Serialize(pFile, bSave);
		}
	} 
	else
	{
		m_arObj.RemoveAll();
		m_arObj.FreeExtra();
		C2DObject *pObj = NULL;
		int nCount = 0;
		pFile->Read(&nCount,sizeof(int));
		UINT wClassType = 0;
		for (int i=0; i!=nCount; ++i)
		{
			pFile->Read(&wClassType,sizeof(UINT));
			pObj = C2DObject::CreateObject((enum Draw_Class)wClassType);
			if (pObj)
			{
				pObj->Serialize(pFile, bSave);
				m_arObj.Add(pObj);
			}
			else
			{
				TRACE("Warning: 不能识别的对象类型，在C2DMap::Serialize");
			}
		}
	}
}

int C2DMap::AddObject( C2DObject* pObj )
{
	if (pObj==NULL)
	{
		return -1;
	}
    return (int)m_arObj.Add(pObj);
}

void C2DMap::Draw( CDC* pDC )
{
	int nCount = m_arObj.GetCount();
	for (int i=0; i!=nCount; ++i)
	{
		C2DObject* pObj = m_arObj.GetAt(i);
		pObj->Draw(pDC);
	}
}

BOOL C2DMap::Save( CString szFilePath )
{
	CFile file;
	if (!file.Open(szFilePath, CFile::modeCreate|CFile::modeWrite))
	{
		AfxMessageBox(_T("不能写入该文件！"));
		return FALSE;
	}

	TRY 
	{
		CString szMark = _T("Sivan - Draw2D");
		file.Write((const char*)szMark,szMark.GetLength());
		Serialize(&file, TRUE);
		file.Close();
	}
	CATCH (CFileException, e)
	{
		AfxMessageBox(_T("写文件出错！"));
		file.Close();
		return FALSE;
	}
	END_CATCH

	return TRUE;
}

void C2DMap::Open( CString szFilePath )
{
	CFile file;
	if (!file.Open(szFilePath, CFile::modeRead))
	{
		AfxMessageBox(_T("不能打开此文件！"));
		return;
	}

	TRY 
	{
		char szMark[15];
		file.Read(szMark, 14);
		szMark[14] = '\0';
		if (strcmp(szMark, _T("Sivan - Draw2D"))!=0)
		{
			file.Close();
			return;
		}
		Serialize(&file, FALSE);
		file.Close();
	}
	CATCH (CFileException, e)
	{
		AfxMessageBox(_T("读文件出错C2DMap::Open!"));
		file.Close();
		return;
	}
	END_CATCH
 
	return;
}



