/// Copyright (c) 2009 Ruben Penalva. All rights reserved.
/// Redistribution and use in source and binary forms, with or without modification, 
/// are permitted provided that the following conditions are met:
///    1. Redistributions of source code must retain the above copyright notice, this 
///    list of conditions and the following disclaimer.
///    2. Redistributions in binary form must reproduce the above copyright notice,
///    this list of conditions and the following disclaimer in the documentation and/or
///    other materials provided with the distribution.
///    3. The name of the author may not be used to endorse or promote products derived
///    from this software without specific prior written permission.
///
/// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
/// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
/// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 
/// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 
/// TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
/// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
/// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 
/// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

/// @file LetterCDTTest2dRender.cpp
/// This source file is part of 2dRender LetterCDT Test.
/// The file holds the LetterCDTTest2dRender class implementation.
/// @author Ruben Penalva (ruben.penalva@rpenalva.com)
#include "LetterCDTTest2dRender.h"

#include <GL/glut.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <math.h>


using namespace LetterCDT;

LetterCDTTest2dRender::LetterCDTTest2dRender(void)	:	m_depth(-40.0f), m_pointSize(5.0f)
{
}

LetterCDTTest2dRender::~LetterCDTTest2dRender(void)
{
}

void LetterCDTTest2dRender::LoadPresetConfiguration(int width, int height)
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glClearColor(0.5, 0.5, 0.7, 0.0);
    glColor3f(1.0, 1.0, 1.0);

	glEnable(GL_LINE_SMOOTH);
    glEnable(GL_CULL_FACE);
    glFrontFace(GL_CCW);

    glDisable(GL_DEPTH_TEST);
    glShadeModel(GL_SMOOTH);
	
	glViewport(0, 0, width, height);

	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();

	// Calculate The Aspect Ratio Of The Window
	gluPerspective(45.0f,(GLfloat)width/(GLfloat)height, 0.1f, 100.0f);

	glMatrixMode(GL_MODELVIEW);	
	gluLookAt (0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0);  
	glLoadIdentity();

	glPointSize(m_pointSize);

	glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
}

void LetterCDTTest2dRender::BeginFrame(void)
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}

void LetterCDTTest2dRender::SetMaterial(float red, float green, float blue)
{
	glColor3f(red, green, blue);
}

void LetterCDTTest2dRender::DrawPoints(const std::vector<Point>& points)
{
	int pointsCount = points.size();
	
    glBegin(GL_POINTS);
		for (int i = 0, j = 0; i < pointsCount; ++i, j )
		{
			const Point& point = points[i];
			glVertex3f(point.m_x, point.m_y, m_depth);
		}
    glEnd();
}

void LetterCDTTest2dRender::DrawLines(const std::vector<Line>& lines)
{
	int linesCount = lines.size();
	for (int i = 0; i < linesCount; ++i)
	{
		const Line& line = lines[i];
		glBegin(GL_LINES);
			glVertex3f(line.m_start.m_x, line.m_start.m_y, m_depth);
			glVertex3f(line.m_end.m_x, line.m_end.m_y, m_depth);	
		glEnd();
	}
}

void LetterCDTTest2dRender::DrawTriangles(const std::vector<Point>& points,
										  const std::vector<int>& indices)
{
	glBegin(GL_TRIANGLES);
		int indicesCount = indices.size();
		for (int i = 0; i < indicesCount; i += 3)
		{
			int indexA = indices[i];
			glVertex3f(points[indexA].m_x, points[indexA].m_y, m_depth);

			int indexB = indices[i + 1];
			glVertex3f(points[indexB].m_x, points[indexB].m_y, m_depth);

			int indexC = indices[i + 2];
			glVertex3f(points[indexC].m_x, points[indexC].m_y, m_depth);
		}
	glEnd();
}

void LetterCDTTest2dRender::EndFrame(void)
{
	glutSwapBuffers();
}