#pragma once
#include "Vector3D.h"
#include "UVCoord.h"
#include "windows.h"

class Vertex
{
public:
	Vertex();
	Vertex(float x, float y, float z);
	Vertex(float x, float y, float z, float w);
	Vertex(const Vertex& other);

	// Accessors
	float GetX() const;
	void SetX(const float x);
	float GetY() const;
	void SetY(const float y);
	float GetZ() const;
	void SetZ(const float z);
	float GetW() const;
	void SetW(const float w);

	const int GetContributeCount() const;
	void IncrementContributeCount();
	void ResetContributeCount();

	const Vector3D& GetNormal() const;
	void SetNormal(float x, float y, float z);
	void SetNormal(const Vector3D& normal);
	void NormalizeNormal();
	void ResetNormal(bool resetCount = false);

	const COLORREF GetColor() const;
	int GetR() const;
	void SetR(const int r);
	int GetG() const;
	void SetG(const int g);
	int GetB() const;
	void SetB(const int b);
	void SetColor(const int r, const int g, const int b);
	void SetColor(const COLORREF colorIn);

	int GetUVIndex() const;
	void SetUVIndex(const int index);

	float GetZOriginal() const;
	float GetUOverZ() const;	
	void SetUOverZ(const float value);
	float GetVOverZ() const;	
	void SetVOverZ(const float value);
	float GetZRecip() const;
	void UVCorrect(float u, float v);

	// Accessors for returning the private x, y, z and w values as integeres instead of floats
	// the ceil function to round the number up by defaults but using providing a false param will
	// use the floor function instead to round the number down
	int GetXInt(bool forceRoundUp = false) const;
	int GetYInt(bool forceRoundUp = false) const;
	int GetZInt(bool forceRoundUp = false) const;
	int GetWInt(bool forceRoundUp = false) const;	

	void Dehomogenize();

	// Assignment operator
	Vertex& operator= (const Vertex& rhs);

	bool operator== (const Vertex& rhs) const;

	const Vertex operator+ (const Vertex& rhs) const;
	const Vector3D operator- (const Vertex& rhs) const;

private:
	float _x;
	float _y;
	float _z;
	float _w;

	float _zOriginal;

	int _contributeCount;	
	Vector3D _normal;
	
	int _r;
	int _g;
	int _b;

	int _uvIndex;

	float _uOverZ;
	float _vOverZ;
	float _zRecip;

	void Copy(const Vertex& other);
};

