#ifndef MATERIAL_INCLUDED
#define MATERIAL_INCLUDED

#include <osi/opengl.hpp>
#include <utils/math.hpp>

struct Material
{
    // Contains skybox reflection info (or other) in .w element
    glm::vec4 ambient_color;
    // Contains Opacity in .w element
    glm::vec4 diffuse_color;
    // Contains shininess in .w element
    glm::vec4 specular_color;

    Material(glm::vec4 _ambient_color = glm::vec4(0.0f), glm::vec4 _diffuse_color = glm::vec4(1.0f), glm::vec4 _specular_color = glm::vec4(0.0f))
        : ambient_color{_ambient_color}, diffuse_color{_diffuse_color}, specular_color{_specular_color} {}

    Material(glm::vec3 color) : ambient_color{glm::vec4(0.1f * color, 0.0f)}, diffuse_color{glm::vec4(color, 1.0f)}, specular_color{glm::vec4(0.0f)} {}

};

namespace mat
{
    static const Material chrome = Material(glm::vec4(0.25f), 
                                            glm::vec4(0.4f, 0.4f, 0.4f, 1.0f), 
                                            glm::vec4(0.774597f, 0.774597f, 0.774597f, 10.0f));

    static const Material dark_steel = Material(glm::vec4(0.0025f, 0.0025f, 0.0025f, 0.0f), 
                                                glm::vec4(0.05f, 0.05f, 0.05f, 1.0f), 
                                                glm::vec4(0.5f, 0.5f, 0.5f, 64.0f));

    static const Material window = Material(glm::vec4(0.05f),
                                            glm::vec4(0.25f, 0.25f, 0.25f, 0.2f),
                                            glm::vec4(1.0f, 1.0f, 1.0f, 10.0f));

    static const Material glass = Material(glm::vec4(0.0f),
                                           glm::vec4(0.15f, 0.15f, 0.15f, 0.1f),
                                           glm::vec4(1.0f, 1.0f, 1.0f, 128.0f));

    static const Material bottle = Material(glm::vec4(0.0f),
                                            glm::vec4(1.0f, 1.0f, 1.0f, 0.9f),
                                            glm::vec4(1.0f, 1.0f, 1.0f, 128.0f));

    static const Material steel = Material(glm::vec4(0.0f),
                                           glm::vec4(1.0f),
                                           glm::vec4(0.1f, 0.1f, 0.1f, 32.0f));

    static const Material iron = Material(glm::vec4(0.0f, 0.0f, 0.0f, 1.0f),
                                          glm::vec4(1.0f),
                                          glm::vec4(0.4f, 0.4f, 0.4f, 256.0f));

    static const Material matte_iron = Material(glm::vec4(0.0f, 0.0f, 0.0f, 0.0f),
                                                glm::vec4(1.0f),
                                                glm::vec4(0.1f, 0.1f, 0.1f, 32.0f));

    static const Material gold = Material(glm::vec4(0.0f, 0.0f, 0.0f, 1.0f),
                                          glm::vec4(1.0f),
                                          glm::vec4(0.62f, 0.55f, 0.36f, 51.2f));

    static const Material white_plastic = Material(glm::vec4(0.0f),
                                                   glm::vec4(1.0f),
                                                   glm::vec4(0.7f, 0.7f, 0.7f, 32.0f));

    static const Material red_plastic = Material(glm::vec4(0.0f),
                                                 glm::vec4(1.0f, 0.0f, 0.0f, 1.0f),
                                                 glm::vec4(0.7f, 0.6f, 0.6f, 32.0f));

    static const Material blue_plastic = Material(glm::vec4(0.0f),
                                                  glm::vec4(0.0f, 0.0f, 1.0f, 1.0f),
                                                  glm::vec4(0.5f, 0.5f, 0.5f, 32.0f));

    static const Material yellow_plastic = Material(glm::vec4(0.0f),
                                                    glm::vec4(1.0f, 1.0f, 0.0f, 1.0f),
                                                    glm::vec4(0.6f, 0.6f, 0.5f, 32.0f));

    static const Material black_plastic = Material(glm::vec4(0.1f),
                                                   glm::vec4(0.1f, 0.1f, 0.1f, 1.0f),
                                                   glm::vec4(0.5f, 0.5f, 0.5f, 32.0f));

    static const Material porcelain = Material(glm::vec4(0.0f),
                                               glm::vec4(1.0f),
                                               glm::vec4(0.9f, 0.9f, 0.9f, 256.0f));
                                               
    static const Material black_rubber = Material(glm::vec4(0.02f, 0.02f, 0.02f, 1.0f),
                                                  glm::vec4(0.01f, 0.01f, 0.01f, 1.0f),
                                                  glm::vec4(0.4f, 0.4f, 0.4f, 10.0f));

    static const Material brown_rubber = Material(glm::vec4(0.02f, 0.02f, 0.02f, 0.0f),
                                                  glm::vec4(0.647f, 0.365f, 0.165f, 1.0f),
                                                  glm::vec4(glm::vec3(0.647f, 0.365f, 0.165f) * 0.4f, 10.0f));

    static const Material green_highlight = Material(glm::vec4(0.0f),
                                                  glm::vec4(0.0f, 1.0f, 0.0f, 0.05f),
                                                  glm::vec4(0.0f));
                                                  
    static const Material red_highlight = Material(glm::vec4(0.0f),
                                                  glm::vec4(1.0f, 0.0f, 0.0f, 0.05f),
                                                  glm::vec4(0.0f));

    static const Material empty_material = Material(glm::vec4(0.0f),
                                                    glm::vec4(0.0f),
                                                    glm::vec4(0.0f));
};

namespace color
{
    static const glm::vec3 white = glm::vec3(1.0f, 1.0f, 1.0f);
    static const glm::vec3 red = glm::vec3(1.0f, 0.0f, 0.0f);
    static const glm::vec3 green = glm::vec3(0.0f, 1.0f, 0.0f);
    static const glm::vec3 blue = glm::vec3(0.0f, 0.0f, 1.0f);
    static const glm::vec3 orange = glm::vec3(1.0f, 0.75f, 0.0f);
    static const glm::vec3 pink = glm::vec3(1.0f, 0.1f, 0.2f);
    static const glm::vec3 swamp = glm::vec3(0.0f, 0.78f, 0.561f);
    static const glm::vec3 light_blue = glm::vec3(0.255f, 0.514f, 0.961f);
};

#endif