#include <GL/glew.h>

#include "ring.h"

#include <iostream>
#include <memory>
#include <vector>

//#ifdef _WIN32
//#include <windows.h>
//#endif

//#include <GL/gl.h>

#define GLM_FORCE_RADIANS
#define GLM_SWIZZLE
#include <glm/glm.hpp>
#include <glm/gtc/constants.hpp>
#include <glm/gtx/transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <glm/gtx/perpendicular.hpp>
#include <glm/ext.hpp>

#include "glbase/gltool.hpp"

#include "gui/config.h"

#include "planets/sun.h"

Ring::Ring(std::string name, float innerRadius, float outerRadius, float rotationSpeed, glm::vec3 rotationAxis, std::string texturePath) :
    Drawable(name),
    _innerRadius(innerRadius), _outerRadius(outerRadius),
    _rotationAxis(rotationAxis),
    _rotationSpeed(rotationSpeed),
    _localRotation(0),
    _texturePath(texturePath)
{

}



void Ring::draw(glm::mat4 projection_matrix) const
{
    if(_program == 0){
        std::cerr << "Planet" << _name << "not initialized. Call init() first." << std::endl;
        return;
    }

    // Render: draw geometry
    glUseProgram(_program);

    glUniformMatrix4fv(glGetUniformLocation(_program, "projection_matrix"), 1, GL_FALSE, glm::value_ptr(projection_matrix));
    glBindVertexArray(_vertexArrayObject);

    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, _texture);



    glUniformMatrix4fv(glGetUniformLocation(_program, "modelview_matrix"), 1, GL_FALSE, glm::value_ptr(_modelViewMatrix));
//    glUniform3f(glGetUniformLocation(_program, "sunPos"), sun->getPosition().x, sun->getPosition().y, sun->getPosition().z);
    glUniform1i(glGetUniformLocation(_program, "lighting"), false);

    glDrawElements(GL_TRIANGLES, _numVertices, GL_UNSIGNED_INT, 0);

    // if the ring has any children, you need to draw them here
    glBindVertexArray(0);

    VERIFY(CG::checkError());
}

void Ring::update(float elapsedTimeMs, glm::mat4 modelViewMatrix)
{
    if(Config::localRotation)
        _localRotation += elapsedTimeMs * _rotationSpeed;

    _modelViewMatrix = glm::rotate(modelViewMatrix, glm::radians(_localRotation), _rotationAxis);
}

void Ring::init()
{
    Drawable::init();
    _texture = loadTexture(_texturePath);
}

std::string Ring::getVertexShader() const
{
    return loadShaderFile(":/shader/vs.glsl");
}

std::string Ring::getFragmentShader() const
{
    return loadShaderFile(":/shader/fs.glsl");
}

void Ring::createObject()
{
    /// TODO your code here
}
