#include "stdafx.h"
#include "2DObject.h"

/************************************************************************
 ¶þÎ¬ÇúÏßÀà
************************************************************************/
C2DCurve::C2DCurve()
{
	m_arPt.RemoveAll();
	m_byR = g_2DObj.m_byR[2];
	m_byG = g_2DObj.m_byG[2];
	m_byB = g_2DObj.m_byB[2];
	m_byLineStyle = g_2DObj.m_byLineStyle[2];
	m_wLineWidth  = g_2DObj.m_wLineWidth[2];
}

C2DCurve::C2DCurve( CArray<CPoint, CPoint&>& arPt, enum enumCurveType type )
{
	m_arPt.Copy(arPt);
	m_CurveType = type;
	m_byR = g_2DObj.m_byR[1];
	m_byG = g_2DObj.m_byG[1];
	m_byB = g_2DObj.m_byB[1];
	m_byLineStyle = g_2DObj.m_byLineStyle[2];
	m_wLineWidth  = g_2DObj.m_wLineWidth[2];
}


C2DCurve::~C2DCurve()
{

}

void C2DCurve::Serialize( CFile* pFile, BOOL bSave /*= TRUE*/ )
{
	if (bSave)
	{	
		C2DLine::Serialize(pFile,bSave);
		int nCount = (int)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));
		}
		UINT nClassType = m_CurveType;
		pFile->Write(&nClassType,sizeof(UINT));
	} 
	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);
		}
		UINT nClassType = 0;
		pFile->Read(&nClassType,sizeof(UINT));
		m_CurveType = (enumCurveType)nClassType;
	}
}

void C2DCurve::Draw( CDC* pDC )
{
	CPen pen(m_byLineStyle,m_wLineWidth,GetClrRefFromByte(m_byR,m_byG,m_byB));
	CPen* pOldPen = pDC->SelectObject(&pen);

	m_CurveType = (enumCurveType)g_2DObj.m_CurveType;
	if (m_CurveType == CURVE_BEZIER)
	{
		int nCount = (int)m_arPt.GetCount();
		if (nCount>1)
		{
			// »­ÇúÏß
			pDC->MoveTo(m_arPt.GetAt(0));
			double t,x,y;
			for (t=0; t<=1; t+=0.001)
			{
				x = 0;
				y = 0;
				for (int i=0; i!=nCount; ++i)
				{
					x += Combination(nCount-1,i)*Power(t,i)*Power((1-t),(nCount-1-i))*m_arPt.GetAt(i).x;
					y += Combination(nCount-1,i)*Power(t,i)*Power((1-t),(nCount-1-i))*m_arPt.GetAt(i).y;
				}
				pDC->LineTo((int)x,(int)y);
			}
		}
	}

	pDC->SelectObject(pOldPen);
}

UINT C2DCurve::GetClass()
{
	return CLASS_DRAW_CURVE;
}

void C2DCurve::GetPoint( int nIndex,int& x,int& y )
{
	if (nIndex>=m_arPt.GetCount() || nIndex<0)
	{
		return;
	}
	CPoint pt = m_arPt.GetAt(nIndex);
	x = pt.x;
	y = pt.y;
}

DWORD C2DCurve::GetCount()
{
	return m_arPt.GetCount();
}