#ifndef LIGHT_INCLUDED
#define LIGHT_INCLUDED

#include <common/node.hpp>
#include <common/objectbase.hpp>

#include <utils/math.hpp>

class Light : public ObjectBase
{
protected:
    // glm::vec3 color;
    node_weak_ptr node;
    bool is_point;
    bool use_rotation;

    glm::vec4 ambient_color;
    glm::vec4 diffuse_color;
    glm::vec4 specular_color;
    glm::vec4 cone_direction;
    
public:
    /* LEGACY CONSTRUCTOR */
    Light(glm::vec3 _color, node_ptr _node, bool _is_point = true) 
    : ambient_color{glm::vec4(_color, 0.0f)}, diffuse_color{glm::vec4(_color, 0.0f)}, specular_color{glm::vec4(_color, 0.0f)}, cone_direction{glm::vec4(0.0f)}, 
      node{_node}, is_point{_is_point} {}
    /*--------------------*/

    Light(node_ptr _node, glm::vec4 _ambient_color, glm::vec4 _diffuse_color, glm::vec4 _specular_color, bool _is_point = true, bool _use_rotation = false)
    : node{_node}, is_point{_is_point}, use_rotation{_use_rotation}, ambient_color{_ambient_color}, diffuse_color{_diffuse_color}, specular_color{_specular_color} {}

    Light(node_ptr _node, glm::vec4 _ambient_color, glm::vec4 _diffuse_color, glm::vec4 _specular_color, glm::vec3 _cone_direction)
    : node{_node}, ambient_color{_ambient_color}, diffuse_color{_diffuse_color}, specular_color{_specular_color}, cone_direction{glm::vec4(_cone_direction, 0.0f)} 
    {
        is_point = true;
    }

    virtual glm::vec4 getPosition() const
    { 
        node_ptr f = node.lock();
        return use_rotation ? glm::vec4(f->getRotationAxisZWorld(), static_cast<float>(is_point))
                            : glm::vec4(f->getPositionWorld(), static_cast<float>(is_point));
    }

    const glm::vec4 &getAmbientColor() const { return ambient_color; }
    const glm::vec4 &getDiffuseColor() const { return diffuse_color; }
    const glm::vec4 &getSpecularColor() const { return specular_color; }
    const glm::vec4 &getConeDirection() const { return cone_direction; }

    virtual ~Light() = default;
};

class DirLight : public Light
{
public:
    using Light::Light;
};

class PointLight : public Light
{
public:
    using Light::Light;
};

#endif