#pragma once
#include <vector>
#include <string>
#include <tchar.h>
#include "Framework.h"
#include "Vector3D.h"
#include "Vertex.h"
#include "Matrix.h"
#include "SharedTools.h"
#include "Camera.h"
#include "Model.h"
#include "MD2Loader.h"
#include "Light.h"
#include "AmbientLight.h"
#include "DirectionalLight.h"
#include "PointLight.h"

using namespace std;
using namespace SharedTools;

class Rasteriser : public Framework
{
public:	
	bool Initialise();
	void Update(const Bitmap& bitmap);
	void Render(const Bitmap& bitmap);
	void ClearViewport(const Bitmap& bitmap);
	void DrawString(HDC hDc, int x, int y, LPCTSTR text, COLORREF textColor = 0x00FFFFFF, COLORREF backgroundColor = 0x00000000);

	~Rasteriser();

	void SetCurrentCamera(int index);
	Camera& GetCamera(int index);
	Camera& GetCurrentCamera();

	// Calculate the Lighting for the scene, fullLightRender sets the method to calculate the
	// light values of all verticies otherwise light values are calculated at the polygon level
	void CalculateLighting(Model& currentModel, bool fullLightRender);

	float Interpolate(float y, float x0, float x1, float y0, float y1);
	float Interpolate(int y, int x0, int x1, int y0, int y1);
	float Lerp(float a, float b, float t);
	float Lerp(int a, int b, float t);

	void DrawSquare(HDC hDc, const vector<Vertex> verticies);
	void DrawShape(HDC hDc, const vector<Vertex> verticies);

	void DrawWireFrame(HDC hDc, Model& model);
	void DrawSolidFlat(HDC hDc, Model& model);
	void DrawRasterisedSolidFlat(HDC hDc, Model& model);
	void DrawGouraud(HDC hDc, Model& model);
	void DrawSolidTextured(HDC hDc, Model& model);
		
	void FillPolygonFlat(HDC hDc, vector<Vertex>& verticies, COLORREF colorIn);
	void FillFlatSideTriangle(HDC hDc, const Vertex& v1, const Vertex& v2, const Vertex& v3, COLORREF colorIn);

	void FillPolygonGouraud(HDC hDc, vector<Vertex>& verticies);
	void FillGouraudSideTriangle(HDC hDc, const Vertex& v1, const Vertex& v2, const Vertex& v3);

	void FillPolygonTextured(HDC hDc, Model& model, vector<Vertex>& verticies);
	void FillTexturedSideTriangle(HDC hDc, Model& model, const Vertex& v1, const Vertex& v2, const Vertex& v3, const UVCoord& uv1, const UVCoord& uv2, const UVCoord& uv3);

private:
	vector<Model> _sceneModels;
	vector<Light*> _lights;
	vector<Camera> _cameras;

	int _currentCamera = 0;

	Matrix _currentPerspectiveMatrix;
	Matrix _currentViewMatrix;
	float  _currentAspectRatio = 0.0f;
	int _rotation = 0;

	int _currentDrawMode = 0;

	bool _screenMinimized = false;
	string _modelDataLocation = ".//model_data/";
};

