// Circle.cpp: implementation of the CSieStar class.
//
//////////////////////////////////////////////////////////////////////
/** \file Circle.cpp

	\brief implementace třídy CSieStar
*/
#include "stdafx.h"
#include "frekvenc.h"
#define PI 3.14159265
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
//#define new DEBUG_NEW
#endif


IMPLEMENT_DYNAMIC(CFrekvenc, CPrimitiveBase)

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////


CFrekvenc::CFrekvenc(char *txt):CPrimitiveBase(txt),m_pairs(8)
{
	TRACE("-- Entering CSieStar default constructor --\n");
	
	m_circleCenter.X = 0;
	m_circleCenter.Y = 0;
	
}

//CSieStar::CSieStar(int distance, CStructures::CenterPoint circleCenter, int radius, float ObjectColor, float ObjectAlpha, float EnvColor, float EnvAlpha)
//	:CPrimitiveBase(distance, ObjectColor, ObjectAlpha, EnvColor, EnvAlpha)
//{
//	TRACE("-- Entering CSieStar GRAY constructor --\n");
//
//	m_radius = radius;
//	m_circleCenter = circleCenter;
//
//	CPrimitiveBase::SetCenter(m_circleCenter);
//	CPrimitiveBase::SetSize(2*m_radius, 2*m_radius);
//
//}
/*MR
CSieStar::CSieStar(int distance, CStructures::fPoint circleCenter, int radius, CStructures::ARGBPixel ObjectColor, CStructures::ARGBPixel EnvColor, const char* title)
	:CPrimitiveBase(distance, ObjectColor, EnvColor, title)
{
	TRACE("-- Entering CSieStar RGB constructor --\n");

	m_radius = radius;
	m_circleCenter = circleCenter;

	CPrimitiveBase::SetLayerCenter(m_circleCenter);
	CPrimitiveBase::SetSize(2*m_radius, 2*m_radius);
	CPrimitiveBase::SetXRepetition(2*m_radius, -1);
	CPrimitiveBase::SetYRepetition(2*m_radius, -1);

	m_type = 0;


}
*/
CFrekvenc::~CFrekvenc()
{
	TRACE("-- Entering CSieStar destructor --\n");

	#ifdef _DEBUG
		Dump(afxDump);
	#endif // _DEBUG
}
/*MR
double CSieStar::GetDistanceToCenter(CStructures::iPoint point)
{
	//TRACE("-- Entering CSieStar::GetDistanceToCenter\n");

	double xSize;
	double ySize;

	if(point.X > m_circleCenter.X)
		xSize = point.X - m_circleCenter.X;		//Pokud jsme vpravo od stredu objektu tak stred odecteme
	else
		xSize = m_circleCenter.X - point.X;		//Pokud jsme vlevo od stredu objektu tak odecteme bod

	if(point.Y > m_circleCenter.Y)
		ySize = point.Y - m_circleCenter.Y;		//Pokud jsme vpravo od stredu objektu tak stred odecteme
	else
		ySize = m_circleCenter.Y - point.Y;		//Pokud jsme vlevo od stredu objektu tak odecteme bod 
	
	return sqrt(pow((float)xSize,2) + pow((float)ySize, 2)); //vrati vzdalenost bodu SQRT(a^2+b^2)
}

CStructures::ARGBPixel CSieStar::GetPixelValue(CStructures::iPoint position)
{
	//TRACE("-- Entering CSieStar::GetPixelValue --\n");

	CStructures::ARGBPixel pixel;
	CStructures::iPoint realPoint;

	//ziskani bodu v originalnim vzoru
	realPoint = GetRealPoint(position);


	double distance = GetDistanceToCenter(realPoint);

	if ((distance <= m_radius) && (!m_Overflow))
	{
		//TRACE("---- Pixel lezi v kruhu\n");

		pixel = GetObjectColor(true);
	}
	else
	{
		//TRACE("---- Pixel lezi na pozadi\n");

		pixel = GetObjectColor(false);
	}
	
	//TRACE("Pixel values: A = %f\n", pixel.A);
	//TRACE("              R = %f\n", pixel.R);
	//TRACE("              G = %f\n", pixel.G);
	//TRACE("              B = %f\n", pixel.B);

	return pixel;
}


CStructures::iPoint CSieStar::GetRealPoint(CStructures::iPoint VirtualPosition)
{
	//TRACE("-- Entering CSieStar::GetRealPoint --\n");

	CStructures::iPoint point;
	int Xrepeated = 0;
	int Yrepeated = 0;
	int XperiodCorrection = 0; 
	int YperiodCorrection = 0;
	m_Overflow = false;


	//vypocet period correction - o kolik je perioda opakovani vetsi nez samotny kruh
	if(m_XPeriodCount > 0 || m_XPeriodCount == -1 ) //doplnena podminka pro nekonecne opakovani ( || -1)
		XperiodCorrection = (m_XPeriod / 2) - m_radius;
	if(m_YPeriodCount > 0 || m_YPeriodCount == -1)
		YperiodCorrection = (m_YPeriod / 2) - m_radius;


	//nalezeni X souradnice v originalnim vzoru 
	if(VirtualPosition.X > m_circleCenter.X)
	{
		while((m_circleCenter.X + m_radius + XperiodCorrection ) < VirtualPosition.X)
		{
			VirtualPosition.X -= m_XPeriod;
			Xrepeated++;
		}

	}
	else
	{
		while((m_circleCenter.X - m_radius - XperiodCorrection) > VirtualPosition.X)
		{
			VirtualPosition.X += m_XPeriod;
			Xrepeated++;
		}
	}


	//nalezeni Y souradnice v originalnim vzoru 
	if(VirtualPosition.Y > m_circleCenter.Y)
	{ 
		while((m_circleCenter.Y + m_radius + YperiodCorrection) < VirtualPosition.Y)
		{
			VirtualPosition.Y -= m_YPeriod;
			Yrepeated++;
		}
	}
	else
	{
		while((m_circleCenter.Y - m_radius - YperiodCorrection) > VirtualPosition.Y)
		{
			VirtualPosition.Y += m_YPeriod;
			Yrepeated++;
		}
	}

	//nalezeny bod v originalnim vzoru
	point.X = VirtualPosition.X;
	point.Y = VirtualPosition.Y;

	//nekonecny pocet opakovani
	if(m_XPeriodCount == -1)
		Xrepeated = -1;

	if(m_YPeriodCount == -1)
		Yrepeated = -1;

	if((Xrepeated > m_XPeriodCount) || (Yrepeated > m_YPeriodCount))
		m_Overflow = true;
	

	return point;
}

void CSieStar::Translate(int dx, int dy)
{
	TRACE("-- Entering CSieStar::Translate --\n");

	m_circleCenter.X += dx;
	m_circleCenter.Y += dy;

	//SetCenter(m_circleCenter);
}

void CSieStar::Rotate(double gama)
{
	//TRACE("-- Entering CSieStar::Rotate --\n");

	CStructures::Angle angle;
	double rotX, rotY;
	double gama_rad;
	const double pi = 3.14159;

	gama_rad = pi/180*gama;

	rotX = cos(gama_rad)*m_circleCenter.X - sin(gama_rad)*m_circleCenter.Y;
	rotY = sin(gama_rad)*m_circleCenter.X + cos(gama_rad)*m_circleCenter.Y;

	m_circleCenter.X = (float)rotX;
	m_circleCenter.Y = (float)rotY;

	angle = GetAngle();
	angle.gama = (float)gama;
	SetAngle(angle);

}

void CSieStar::Resample(CStructures::Supersample supersample)
{
	TRACE("Entering CSieStar::Resample\n");

	m_circleCenter.X = m_circleCenter.X * supersample.X;
	m_circleCenter.Y = m_circleCenter.Y * supersample.Y;

	CPrimitiveBase::SetLayerCenter(m_circleCenter);

	if(supersample.X >= supersample.Y)
	{
		m_radius = m_radius * supersample.X;
		/*m_XtPeriod = m_XPeriod * supersample.X;
		m_YPeriod = m_YPeriod * supersample.X;* /
	}
		

	else
	{
		m_radius = m_radius * supersample.Y;
		/*m_XPeriod = m_XPeriod * supersample.Y;
		m_YPeriod = m_YPeriod * supersample.Y;* /
	}
		


	m_XPeriod = m_XPeriod * supersample.X;
	m_YPeriod = m_YPeriod * supersample.Y;

}
*/

CStructures::ARGBPixel CFrekvenc::GetPixelValue(double Position[3]) 
{ // vstupem je průmět bodu v rovině vzoru
	
// zjistím hodnotu jasu v daném bodě 
	CStructures::ARGBPixel pixel;
	 pixel.A = -1;	 pixel.R = -1;	 pixel.G = -1;	 pixel.B = -1; 
// nejdříve se dostat do "základního" čtverce - v něm zjistit souřadnice bodu
/*	 double x = Position[0], y = Position[1];
	 double uhel = atan2(x,y);
	 if (uhel <0) uhel += PI;
	 double uhel_norm = PI / m_pairs;
	 double pomer = uhel  / uhel_norm ;	 
	 if  (int(pomer)&1) 
		 return m_EnvColor;

*/   double xMax=0,A=0,omeg=0,omegMax=0,omegMin;
	 double x = Position[0], y=Position[1];
	 if (x < 0) x *= -1;
	 if (y < 0) y *= -1;
	 xMax=sin(2*PI*y);
	 A=sin(2*PI*x);
//   omegMax=atan2(2*PI*x,y);
/*	 xMax=x;
	 omegMin=y;
	 omeg=(omegMax/xMax)*x+omegMin;
	 A=sin(omeg-x);
	 */
	// if(int(A)&1)
	 if (int(90*xMax*A)&1)
	    return m_EnvColor;


	 return m_ObjectColor;
}

//dumping objektu
#ifdef _DEBUG
void CFrekvenc::Dump(CDumpContext& dc) const
{
	CPrimitiveBase::Dump(dc);
	dc << "Circle center X = " << m_circleCenter.X <<
		"\n              Y = " << m_circleCenter.Y <<
		"\nRadius: " << m_pairs << "\n\n";  
}
#endif // _DEBUG