/**
 * @file Renderer.cpp
 * @author Petr Egert (egertpet@fel.cvut.cz)
 * @brief Contains Renderer class implementation
 */

#ifdef __WINDOWS__
#include <windows.h>
#endif

#include <gl/gl.h>
#include <iostream>
#include "Renderer.h"

using namespace RD;

Renderer *Renderer::instance = NULL;

/**
 * @brief Performs class initialization
 *
 * Sets up OpenGL state and creates a textured quad used in DrawQuad
 * @return RES_OK on success
 */
Result Renderer::Init()
{
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glShadeModel(GL_SMOOTH);
    glDisable(GL_DEPTH_TEST);
    glColor3f(1.0, 1.0, 1.0);
//    glCullFace(GL_NONE);
    glEnable(GL_TEXTURE_2D);
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);


    quadList = GenQuad(1.0, 1.0, vec2(0.5, 0.5));

    return RES_OK;
}

/**
 * @brief Performs class deinitialization
 *
 * Currently does nothing
 * @return RES_OK on success
 */
Result Renderer::Release()
{
    return RES_OK;
}

/**
 * @brief Sets a transformation matrix for the current context
 * @param matrix Transformation matrix
 */
void Renderer::SetTransform(const mat44 &matrix)
{
    glLoadMatrixf(matrix.f);
}

/**
 * @brief Sets a texture for the current context
 */
void Renderer::SetTexture(Texture *texture)
{
    texture->Set();
}

/**
 * @brief Draws the default textured quad
 *
 * The quad has unit size, is facing towards the Z axis and is centered at (0.0, 0.0, 0.0)
 */
void Renderer::DrawQuad()
{
    glColor3f(1.0, 1.0, 1.0);
    glCallList(quadList);
//    glDisable(GL_TEXTURE_2D);
}

/**
 * @brief Generates a quad with the specified size and location
 *
 * The quad is centered at (0.0, 0.0, 0.0) and facing towards the Z axis
 * @param width Width of the quad
 * @param height Height of the quad
 * @param offset XY offset
 * @return Quad display list
 */
unsigned int Renderer::GenQuad(float width, float height, vec2 offset)
{
    width *= 0.5;
    height *= 0.5;
    unsigned int tmpList = glGenLists(1);

    glNewList(tmpList, GL_COMPILE);
    glBegin(GL_QUADS);
    glTexCoord2f(0.0, 1.0);
    glVertex3f(-width + offset.x, height + offset.y, 0.0);

    glTexCoord2f(0.0, 0.0);
    glVertex3f(-width + offset.x, -height + offset.y, 0.0);

    glTexCoord2f(1.0, 0.0);
    glVertex3f(width + offset.x, -height + offset.y, 0.0);

    glTexCoord2f(1.0, 1.0);
    glVertex3f(width + offset.x, height + offset.y, 0.0);
    glEnd();
    glEndList();

    return tmpList;
}
