// PrimitiveBase.h: interface for the CPrimitiveBase class.
//
//////////////////////////////////////////////////////////////////////
/** \file PrimitiveBase.h
	\brief Rozhraní pro třídu CPrimitiveBase
*/

#if !defined(_PRIMITIVE_BASE_H_)
#define _PRIMITIVE_BASE_H_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000


//#include <cv.h> presunuto do stdafx pred include check, kvuli kolizi metody free v matrix.h s knihovnou check a jejimi makry pro free
//#include <math.h>
#include "Structures.h"

#define IDL_CIRCLE 0	///< ID vrstvy circle
#define IDL_LINE 1		///< ID vrstvy line
#define IDL_NEW 2		//Nová vrstva
	
/**
Zahrnuje společné vlastnosti geometrických primitiv (objektů) a operaci s nimi.. 
*/
class CPrimitiveBase : public CObject  
{
DECLARE_DYNAMIC(CPrimitiveBase) 

private:	
	//MR využité proměnné nové


	//MR využité proměnné staré 
	double m_distance;							///< Vzdálenost středu roviny od počátku - pevný bod
	CStructures::Angle m_angle;				///< Úhly natočení objektu okolo os u,v, a vzoru ve stupních
protected: //MR předělat tak aby bylo private
	double m_XPeriod;					///< Šířka (krok) vzoru
	double m_YPeriod;					///< Výška (krok) vzoru
	double Plane2Plane[3][3];
//MR toto patří do odvozené třídy - barva možná, rozměry určitě
	CStructures::ARGBPixel m_ObjectColor;	///< Barva geometrického objetku
	CStructures::ARGBPixel m_EnvColor;		///< Barva okolí gemetrického objektu
private:
	CStructures::fPoint  m_center;		///< posun středu vzoru v rovině du, dv
	
public: //MR tohle je špatně - dát do private
	double Plane[4]	; // popis roviny v homogenních souřadnicích
	void SetPl2PlTr(double Tr[3][3]);
private:
	char* m_LayerName;						///< Název vrstvy vzoru
	int m_len;								///< Délka řetězce názvu

	//MR proměnné určené ke zrušení (některé ještě promyslet)
 
	static int num_primitives;				///< Počet vytvořených instancí třídy
	bool m_bUse;							///< vrstva \c true = zařazena, \c false = nezařazena do výpočtu
	double m_vn[3];							///< Normálový vektor plochy vrstvy.\ Určuje natočení.

	//------------------------původní šedá verze ----------------------------------------
	//float m_ObjectColor;					//Jas grafického objektu
	//float m_ObjectAlpha;					//Prhlednost objektu 255=nepruhledny, 0 = pruhledny 
	//float m_EnvColor;						//Jas okolí objektu
	//float m_EnvAlpha;						//Pruhlednost okoli objektu
	//----------------------------------------------------------------------------------

	

	int m_width;int m_height;

	/** Vrátí pozici pixelu v základním umístění objektu.
		Přepočítá souřadnici aktuálního pixelu na odpovídající pixel objektu v základním umístění.
		Každý objekt je popsán analytickým popisem a umístěn na rovinu vrstvy. Poté se objekt může 
		v rovině libovolně zopakovat.

	    @param[in] VirtualPosition typu CStructures::Point - souřadnice bodu v rovině vrstvy
		@return bod typu CStructures::Point v základním umístění geometrického objektu 
	*/
	virtual CStructures::iPoint GetRealPoint(CStructures::iPoint VirtualPosition); 

public:		
	//MR tohle bych časem dal pryč a nahradil to parametry okrajů
	int m_XPeriodCount;		///< Počet opakování v x-ovém směru, -1 = nekonečně	 
	int m_YPeriodCount;		///< Počet opakování v y-ovém směru, -1 = nekonečně
	
	// definice průmětné roviny - vzdálenost od počátku souřadnic
	void DefinePlane(double Distance, double uhelx, double uhely);
	
	CPrimitiveBase(char *title=NULL);	///< Defaultní konstruktor

	/** Parametrický konstruktor.
		Vytvoří geometrický objekt se zadanými parametry.
		@param distance - vzdálenost od počátku soustavy
		@param ObjectColor typu CStructures::ARGBPixel - barva objektu
		@param EnvColor typu CStructures::ARGBPixel - barva okolí
		@param name typu const char* - název vytvořeného objektu. Defaultně \b "Untitled"
	*/
	//MR CPrimitiveBase(int distance, CStructures::ARGBPixel ObjectColor, CStructures::ARGBPixel EnvColor, const char* name = "Untitled"); 
	//???
	CPrimitiveBase(const CPrimitiveBase & pb);	///< Kopírovací konstruktor
	CPrimitiveBase & operator=(const CPrimitiveBase & pb); ///<Operátor přiřazení
	
	virtual ~CPrimitiveBase();	///< Destruktor

	

	//MR >>>
	void SetDistance(double dist) {m_distance = dist;} ///< nastaveni vzdalenosti vzoru od kamery (bodu nula) \a dist
	void SetXYDistance(double xd, double yd) {m_XPeriod = xd;m_YPeriod = yd;}///< nastaveni rozměru (kroku) vzoru v ploše \a xd,yd 
	void SetColor(CStructures::ARGBPixel ForegroundColor, CStructures::ARGBPixel BackgroundColor)
	{ m_ObjectColor = ForegroundColor; m_EnvColor = BackgroundColor;}

	//MR <<<

	void Rename(const char* newName);		///< Přejmenuje objekt na \a newName
	char* GetName(){return m_LayerName;}	///< Vrátí název objektu

	void SetSize(int width, int height);	///< Nastaví šířku \a width a výšku \a height geometrického objektu
	CStructures::iPoint GetSize() const;			  ///<Vrátí rozměry vzoru
	void SetLayerCenter(CStructures::fPoint center);///< Nastaví střed geometrického objektu \a center
	CStructures::fPoint GetCenter() const;	  ///<Vrátí střed objektu
	void SetXRepetition(int period, int cycles);  ///<Nastaví počet \a cycles a periodu \a period opakování  v X-ovém směru
	void SetYRepetition(int period, int cycles);  ///<Nastaví počet \a cycles a periodu \a period opakování  v Y-ovém směru
	double GetDistanceToCamera() const;			  ///<Vrátí vzdálenost vrstvy od počátku souřadného systému
	void GetPosition(double vn[]);				  ///<Vrátí normálový vektor roviny vzoru uložený do \a vn
	
	void Use(bool bUse){m_bUse = bUse;} ///< Nastaví příznak, zda se má vrstva použít
	bool Use(){return m_bUse;}			///< Vrací příznak zařazení vrstvy do testovacího vzoru

	/** Vrátí barvu geometrického objektu.
		@param[in] OnObject \c true - vnitřní barva geometrického objektu, \c false - barva okolí
		@return ARGB hodnota barvy
	*/
	CStructures::ARGBPixel GetObjectColor(bool OnObject);

	/** Natočí rovinu vzoru okolo os X,Y
		@param[in] angleX - úhel s osou X ve stupních
		@param[in] angleY - úhel s osou Y ve stupních
	*/
	void RotXY(double angleX, double angleY);
	void ResetPosition(); ///< Nastaví normálový vektor do výchozí pozice.\ Rovina je kolmá na osu Z 
	void SetAngle(CStructures::Angle angle);
	CStructures::Angle GetAngle(){ CStructures::Angle angle1;
	angle1.alfa = m_angle.alfa *180 / 3.14159265358979323846		;
	angle1.beta = m_angle.beta *180 / 3.14159265358979323846		;
	angle1.gama = m_angle.gama *180 / 3.14159265358979323846		;
		return 	angle1;}
	/** Vrátí ARGB hodnotu pixelu na zadané pozici.
		@param[in] position typu CStructures::Point - souřadnice pixelu
		@return ARGB hodnota pixelu
	*/
	virtual CStructures::ARGBPixel GetPixelValue(CStructures::iPoint position);
	//MR nová verze - měla by být přetížena
	virtual CStructures::ARGBPixel CPrimitiveBase::GetPixelValue(double point[3]);

	virtual CStructures::ARGBPixel GetPixelValueMR(double Position[3]) ;
	virtual void Translate(int dx, int dy);	///< Posune objekt v rovině o \a dx a \a dy
	virtual void Rotate(double gama);	///< Otočí objekt okolo osy Z o úhel \a gama
	virtual int GetType() {return -1;}	///< Vrátí ID objektu
	virtual void Resample(CStructures::Supersample supersample);

	virtual int GetRadius() const {return 0;}
	virtual	CStructures::iPoint PointBegin();
	virtual CStructures::iPoint PointEnd();
	virtual int Thickness(){return 0;}

	

	//dumping objektu
	#ifdef _DEBUG
		void Dump(CDumpContext& dc) const;
	#endif //_DEBUG


};

#endif // !defined(_PRIMITIVE_BASE_H_)
